authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-27 22:06:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-28 13:21:05-07:00
log240d0b68f62c4fd3562649ec7fc29a51be3698d7
treee0c2a736cff252ccc9c7722754efa686cd1ba315
parent9410b11ca663231e367e3adfd668979c4b870a41

make aro-based translate-c lazily built from source

Part of #19063. Primarily, this moves Aro from deps/ to lib/compiler/ so that it can be lazily compiled from source. src/aro_translate_c.zig is moved to lib/compiler/aro_translate_c.zig and some of Zig CLI logic moved to a main() function there. aro_translate_c.zig becomes the "common" import for clang-based translate-c. Not all of the compiler was able to be detangled from Aro, however, so it still, for now, remains being compiled with the main compiler sources due to the clang-based translate-c depending on it. Once aro-based translate-c achieves feature parity with the clang-based translate-c implementation, the clang-based one can be removed from Zig. Aro made it unnecessarily difficult to depend on with these .def files and all these Zig module requirements. I looked at the .def files and made these observations: - The canonical source is llvm .def files. - Therefore there is an update process to sync with llvm that involves regenerating the .def files in Aro. - Therefore you might as well just regenerate the .zig files directly and check those into Aro. - Also with a small amount of tinkering, the file size on disk of these generated .zig files can be made many times smaller, without compromising type safety in the usage of the data. This would make things much easier on Zig as downstream project, particularly we could remove those pesky stubs when bootstrapping. I have gone ahead with these changes since they unblock me and I will have a chat with Vexu to see what he thinks.

116 files changed, 54514 insertions(+), 60606 deletions(-)

CMakeLists.txt+1-15
......@@ -643,11 +643,8 @@ set(ZIG_STAGE2_SOURCES
643643 "${CMAKE_SOURCE_DIR}/src/target.zig"
644644 "${CMAKE_SOURCE_DIR}/src/tracy.zig"
645645 "${CMAKE_SOURCE_DIR}/src/translate_c.zig"
646 "${CMAKE_SOURCE_DIR}/src/translate_c/ast.zig"
647646 "${CMAKE_SOURCE_DIR}/src/type.zig"
648647 "${CMAKE_SOURCE_DIR}/src/wasi_libc.zig"
649 "${CMAKE_SOURCE_DIR}/src/stubs/aro_builtins.zig"
650 "${CMAKE_SOURCE_DIR}/src/stubs/aro_names.zig"
651648)
652649
653650if(MSVC)
......@@ -822,18 +819,7 @@ set(BUILD_ZIG2_ARGS
822819 --dep "aro"
823820 --mod "root" "src/main.zig"
824821 --mod "build_options" "${ZIG_CONFIG_ZIG_OUT}"
825 --mod "aro_options" "src/stubs/aro_options.zig"
826 --mod "Builtins/Builtin.def" "src/stubs/aro_builtins.zig"
827 --mod "Attribute/names.def" "src/stubs/aro_names.zig"
828 --mod "Diagnostics/messages.def" "src/stubs/aro_messages.zig"
829 --dep "build_options=aro_options"
830 --mod "aro_backend" "deps/aro/backend.zig"
831 --dep "Builtins/Builtin.def"
832 --dep "Attribute/names.def"
833 --dep "Diagnostics/messages.def"
834 --dep "build_options=aro_options"
835 --dep "backend=aro_backend"
836 --mod "aro" "deps/aro/aro.zig"
822 --mod "aro" "lib/compiler/aro/aro.zig"
837823)
838824
839825add_custom_command(
bootstrap.c+1-15
......@@ -156,22 +156,8 @@ int main(int argc, char **argv) {
156156 "--dep", "build_options",
157157 "--dep", "aro",
158158 "--mod", "root", "src/main.zig",
159
160159 "--mod", "build_options", "config.zig",
161 "--mod", "aro_options", "src/stubs/aro_options.zig",
162 "--mod", "Builtins/Builtin.def", "src/stubs/aro_builtins.zig",
163 "--mod", "Attribute/names.def", "src/stubs/aro_names.zig",
164 "--mod", "Diagnostics/messages.def", "src/stubs/aro_messages.zig",
165
166 "--dep", "build_options=aro_options",
167 "--mod", "aro_backend", "deps/aro/backend.zig",
168
169 "--dep", "Builtins/Builtin.def",
170 "--dep", "Attribute/names.def",
171 "--dep", "Diagnostics/messages.def",
172 "--dep", "build_options=aro_options",
173 "--dep", "backend=aro_backend",
174 "--mod", "aro", "deps/aro/aro.zig",
160 "--mod", "aro", "lib/compiler/aro/aro.zig",
175161 NULL,
176162 };
177163 print_and_run(child_argv);
build.zig+8-21
......@@ -8,7 +8,6 @@ const io = std.io;
88const fs = std.fs;
99const InstallDirectoryOptions = std.Build.InstallDirectoryOptions;
1010const assert = std.debug.assert;
11const GenerateDef = @import("deps/aro/build/GenerateDef.zig");
1211
1312const zig_version = std.SemanticVersion{ .major = 0, .minor = 12, .patch = 0 };
1413const stack_size = 32 * 1024 * 1024;
......@@ -636,34 +635,22 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.St
636635 });
637636 exe.stack_size = stack_size;
638637
639 const aro_options = b.addOptions();
640 aro_options.addOption([]const u8, "version_str", "aro-zig");
641 const aro_options_module = aro_options.createModule();
642 const aro_backend = b.createModule(.{
643 .root_source_file = .{ .path = "deps/aro/backend.zig" },
644 .imports = &.{.{
645 .name = "build_options",
646 .module = aro_options_module,
647 }},
648 });
649638 const aro_module = b.createModule(.{
650 .root_source_file = .{ .path = "deps/aro/aro.zig" },
639 .root_source_file = .{ .path = "lib/compiler/aro/aro.zig" },
640 });
641
642 const aro_translate_c_module = b.createModule(.{
643 .root_source_file = .{ .path = "lib/compiler/aro_translate_c.zig" },
651644 .imports = &.{
652645 .{
653 .name = "build_options",
654 .module = aro_options_module,
655 },
656 .{
657 .name = "backend",
658 .module = aro_backend,
646 .name = "aro",
647 .module = aro_module,
659648 },
660 GenerateDef.create(b, .{ .name = "Builtins/Builtin.def", .src_prefix = "deps/aro/aro" }),
661 GenerateDef.create(b, .{ .name = "Attribute/names.def", .src_prefix = "deps/aro/aro" }),
662 GenerateDef.create(b, .{ .name = "Diagnostics/messages.def", .src_prefix = "deps/aro/aro", .kind = .named }),
663649 },
664650 });
665651
666652 exe.root_module.addImport("aro", aro_module);
653 exe.root_module.addImport("aro_translate_c", aro_translate_c_module);
667654 return exe;
668655}
669656
deps/aro/README.md deleted-27
......@@ -1,27 +0,0 @@
1<img src="https://aro.vexu.eu/aro-logo.svg" alt="Aro" width="120px"/>
2
3# Aro
4
5A C compiler with the goal of providing fast compilation and low memory usage with good diagnostics.
6
7Aro is included as an alternative C frontend in the [Zig compiler](https://github.com/ziglang/zig)
8for `translate-c` and eventually compiling C files by translating them to Zig first.
9Aro is developed in https://github.com/Vexu/arocc and the Zig dependency is
10updated from there when needed.
11
12Currently most of standard C is supported up to C23 and as are many of the common
13extensions from GNU, MSVC, and Clang
14
15Basic code generation is supported for x86-64 linux and can produce a valid hello world:
16```sh-session
17$ cat hello.c
18extern int printf(const char *restrict fmt, ...);
19int main(void) {
20 printf("Hello, world!\n");
21 return 0;
22}
23$ zig build run -- hello.c -o hello
24$ ./hello
25Hello, world!
26$
27```
deps/aro/aro.zig deleted-38
......@@ -1,38 +0,0 @@
1pub const CodeGen = @import("aro/CodeGen.zig");
2pub const Compilation = @import("aro/Compilation.zig");
3pub const Diagnostics = @import("aro/Diagnostics.zig");
4pub const Driver = @import("aro/Driver.zig");
5pub const Parser = @import("aro/Parser.zig");
6pub const Preprocessor = @import("aro/Preprocessor.zig");
7pub const Source = @import("aro/Source.zig");
8pub const Tokenizer = @import("aro/Tokenizer.zig");
9pub const Toolchain = @import("aro/Toolchain.zig");
10pub const Tree = @import("aro/Tree.zig");
11pub const Type = @import("aro/Type.zig");
12pub const TypeMapper = @import("aro/StringInterner.zig").TypeMapper;
13pub const target_util = @import("aro/target.zig");
14pub const Value = @import("aro/Value.zig");
15
16const backend = @import("backend");
17pub const Interner = backend.Interner;
18pub const Ir = backend.Ir;
19pub const Object = backend.Object;
20pub const CallingConvention = backend.CallingConvention;
21
22pub const version_str = backend.version_str;
23pub const version = backend.version;
24
25test {
26 _ = @import("aro/Builtins.zig");
27 _ = @import("aro/char_info.zig");
28 _ = @import("aro/Compilation.zig");
29 _ = @import("aro/Driver/Distro.zig");
30 _ = @import("aro/Driver/Filesystem.zig");
31 _ = @import("aro/Driver/GCCVersion.zig");
32 _ = @import("aro/InitList.zig");
33 _ = @import("aro/Preprocessor.zig");
34 _ = @import("aro/target.zig");
35 _ = @import("aro/Tokenizer.zig");
36 _ = @import("aro/toolchains/Linux.zig");
37 _ = @import("aro/Value.zig");
38}
deps/aro/aro/Attribute.zig deleted-1070
......@@ -1,1070 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const ZigType = std.builtin.Type;
4const CallingConvention = @import("backend").CallingConvention;
5const Compilation = @import("Compilation.zig");
6const Diagnostics = @import("Diagnostics.zig");
7const Parser = @import("Parser.zig");
8const Tree = @import("Tree.zig");
9const NodeIndex = Tree.NodeIndex;
10const TokenIndex = Tree.TokenIndex;
11const Type = @import("Type.zig");
12const Value = @import("Value.zig");
13
14const Attribute = @This();
15
16tag: Tag,
17syntax: Syntax,
18args: Arguments,
19
20pub const Syntax = enum {
21 c23,
22 declspec,
23 gnu,
24 keyword,
25};
26
27pub const Kind = enum {
28 c23,
29 declspec,
30 gnu,
31
32 pub fn toSyntax(kind: Kind) Syntax {
33 return switch (kind) {
34 .c23 => .c23,
35 .declspec => .declspec,
36 .gnu => .gnu,
37 };
38 }
39};
40
41pub const ArgumentType = enum {
42 string,
43 identifier,
44 int,
45 alignment,
46 float,
47 expression,
48 nullptr_t,
49
50 pub fn toString(self: ArgumentType) []const u8 {
51 return switch (self) {
52 .string => "a string",
53 .identifier => "an identifier",
54 .int, .alignment => "an integer constant",
55 .nullptr_t => "nullptr",
56 .float => "a floating point number",
57 .expression => "an expression",
58 };
59 }
60};
61
62/// number of required arguments
63pub fn requiredArgCount(attr: Tag) u32 {
64 switch (attr) {
65 inline else => |tag| {
66 comptime var needed = 0;
67 comptime {
68 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
69 for (fields) |arg_field| {
70 if (!mem.eql(u8, arg_field.name, "__name_tok") and @typeInfo(arg_field.type) != .Optional) needed += 1;
71 }
72 }
73 return needed;
74 },
75 }
76}
77
78/// maximum number of args that can be passed
79pub fn maxArgCount(attr: Tag) u32 {
80 switch (attr) {
81 inline else => |tag| {
82 comptime var max = 0;
83 comptime {
84 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
85 for (fields) |arg_field| {
86 if (!mem.eql(u8, arg_field.name, "__name_tok")) max += 1;
87 }
88 }
89 return max;
90 },
91 }
92}
93
94fn UnwrapOptional(comptime T: type) type {
95 return switch (@typeInfo(T)) {
96 .Optional => |optional| optional.child,
97 else => T,
98 };
99}
100
101pub const Formatting = struct {
102 /// The quote char (single or double) to use when printing identifiers/strings corresponding
103 /// to the enum in the first field of the `attr`. Identifier enums use single quotes, string enums
104 /// use double quotes
105 fn quoteChar(attr: Tag) []const u8 {
106 switch (attr) {
107 .calling_convention => unreachable,
108 inline else => |tag| {
109 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
110
111 if (fields.len == 0) unreachable;
112 const Unwrapped = UnwrapOptional(fields[0].type);
113 if (@typeInfo(Unwrapped) != .Enum) unreachable;
114
115 return if (Unwrapped.opts.enum_kind == .identifier) "'" else "\"";
116 },
117 }
118 }
119
120 /// returns a comma-separated string of quoted enum values, representing the valid
121 /// choices for the string or identifier enum of the first field of the `attr`.
122 pub fn choices(attr: Tag) []const u8 {
123 switch (attr) {
124 .calling_convention => unreachable,
125 inline else => |tag| {
126 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
127
128 if (fields.len == 0) unreachable;
129 const Unwrapped = UnwrapOptional(fields[0].type);
130 if (@typeInfo(Unwrapped) != .Enum) unreachable;
131
132 const enum_fields = @typeInfo(Unwrapped).Enum.fields;
133 @setEvalBranchQuota(3000);
134 const quote = comptime quoteChar(@enumFromInt(@intFromEnum(tag)));
135 comptime var values: []const u8 = quote ++ enum_fields[0].name ++ quote;
136 inline for (enum_fields[1..]) |enum_field| {
137 values = values ++ ", ";
138 values = values ++ quote ++ enum_field.name ++ quote;
139 }
140 return values;
141 },
142 }
143 }
144};
145
146/// Checks if the first argument (if it exists) is an identifier enum
147pub fn wantsIdentEnum(attr: Tag) bool {
148 switch (attr) {
149 .calling_convention => return false,
150 inline else => |tag| {
151 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
152
153 if (fields.len == 0) return false;
154 const Unwrapped = UnwrapOptional(fields[0].type);
155 if (@typeInfo(Unwrapped) != .Enum) return false;
156
157 return Unwrapped.opts.enum_kind == .identifier;
158 },
159 }
160}
161
162pub fn diagnoseIdent(attr: Tag, arguments: *Arguments, ident: []const u8) ?Diagnostics.Message {
163 switch (attr) {
164 inline else => |tag| {
165 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
166 if (fields.len == 0) unreachable;
167 const Unwrapped = UnwrapOptional(fields[0].type);
168 if (@typeInfo(Unwrapped) != .Enum) unreachable;
169 if (std.meta.stringToEnum(Unwrapped, normalize(ident))) |enum_val| {
170 @field(@field(arguments, @tagName(tag)), fields[0].name) = enum_val;
171 return null;
172 }
173 return Diagnostics.Message{
174 .tag = .unknown_attr_enum,
175 .extra = .{ .attr_enum = .{ .tag = attr } },
176 };
177 },
178 }
179}
180
181pub fn wantsAlignment(attr: Tag, idx: usize) bool {
182 switch (attr) {
183 inline else => |tag| {
184 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
185 if (fields.len == 0) return false;
186
187 return switch (idx) {
188 inline 0...fields.len - 1 => |i| UnwrapOptional(fields[i].type) == Alignment,
189 else => false,
190 };
191 },
192 }
193}
194
195pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, p: *Parser) !?Diagnostics.Message {
196 switch (attr) {
197 inline else => |tag| {
198 const arg_fields = std.meta.fields(@field(attributes, @tagName(tag)));
199 if (arg_fields.len == 0) unreachable;
200
201 switch (arg_idx) {
202 inline 0...arg_fields.len - 1 => |arg_i| {
203 if (UnwrapOptional(arg_fields[arg_i].type) != Alignment) unreachable;
204
205 if (!res.val.is(.int, p.comp)) return Diagnostics.Message{ .tag = .alignas_unavailable };
206 if (res.val.compare(.lt, Value.zero, p.comp)) {
207 return Diagnostics.Message{ .tag = .negative_alignment, .extra = .{ .str = try res.str(p) } };
208 }
209 const requested = res.val.toInt(u29, p.comp) orelse {
210 return Diagnostics.Message{ .tag = .maximum_alignment, .extra = .{ .str = try res.str(p) } };
211 };
212 if (!std.mem.isValidAlign(requested)) return Diagnostics.Message{ .tag = .non_pow2_align };
213
214 @field(@field(arguments, @tagName(tag)), arg_fields[arg_i].name) = Alignment{ .requested = requested };
215 return null;
216 },
217 else => unreachable,
218 }
219 },
220 }
221}
222
223fn diagnoseField(
224 comptime decl: ZigType.Declaration,
225 comptime field: ZigType.StructField,
226 comptime Wanted: type,
227 arguments: *Arguments,
228 res: Parser.Result,
229 node: Tree.Node,
230 p: *Parser,
231) !?Diagnostics.Message {
232 if (res.val.opt_ref == .none) {
233 if (Wanted == Identifier and node.tag == .decl_ref_expr) {
234 @field(@field(arguments, decl.name), field.name) = Identifier{ .tok = node.data.decl_ref };
235 return null;
236 }
237 return invalidArgMsg(Wanted, .expression);
238 }
239 const key = p.comp.interner.get(res.val.ref());
240 switch (key) {
241 .int => {
242 if (@typeInfo(Wanted) == .Int) {
243 @field(@field(arguments, decl.name), field.name) = res.val.toInt(Wanted, p.comp) orelse return .{
244 .tag = .attribute_int_out_of_range,
245 .extra = .{ .str = try res.str(p) },
246 };
247 return null;
248 }
249 },
250 .bytes => |bytes| {
251 if (Wanted == Value) {
252 std.debug.assert(node.tag == .string_literal_expr);
253 if (!node.ty.elemType().is(.char) and !node.ty.elemType().is(.uchar)) {
254 return .{
255 .tag = .attribute_requires_string,
256 .extra = .{ .str = decl.name },
257 };
258 }
259 @field(@field(arguments, decl.name), field.name) = try p.removeNull(res.val);
260 return null;
261 } else if (@typeInfo(Wanted) == .Enum and @hasDecl(Wanted, "opts") and Wanted.opts.enum_kind == .string) {
262 const str = bytes[0 .. bytes.len - 1];
263 if (std.meta.stringToEnum(Wanted, str)) |enum_val| {
264 @field(@field(arguments, decl.name), field.name) = enum_val;
265 return null;
266 } else {
267 @setEvalBranchQuota(3000);
268 return .{
269 .tag = .unknown_attr_enum,
270 .extra = .{ .attr_enum = .{ .tag = std.meta.stringToEnum(Tag, decl.name).? } },
271 };
272 }
273 }
274 },
275 else => {},
276 }
277 return invalidArgMsg(Wanted, switch (key) {
278 .int => .int,
279 .bytes => .string,
280 .float => .float,
281 .null => .nullptr_t,
282 else => unreachable,
283 });
284}
285
286fn invalidArgMsg(comptime Expected: type, actual: ArgumentType) Diagnostics.Message {
287 return .{
288 .tag = .attribute_arg_invalid,
289 .extra = .{ .attr_arg_type = .{ .expected = switch (Expected) {
290 Value => .string,
291 Identifier => .identifier,
292 u32 => .int,
293 Alignment => .alignment,
294 CallingConvention => .identifier,
295 else => switch (@typeInfo(Expected)) {
296 .Enum => if (Expected.opts.enum_kind == .string) .string else .identifier,
297 else => unreachable,
298 },
299 }, .actual = actual } },
300 };
301}
302
303pub fn diagnose(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, node: Tree.Node, p: *Parser) !?Diagnostics.Message {
304 switch (attr) {
305 inline else => |tag| {
306 const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
307 const max_arg_count = comptime maxArgCount(tag);
308 if (arg_idx >= max_arg_count) return Diagnostics.Message{
309 .tag = .attribute_too_many_args,
310 .extra = .{ .attr_arg_count = .{ .attribute = attr, .expected = max_arg_count } },
311 };
312 const arg_fields = std.meta.fields(@field(attributes, decl.name));
313 switch (arg_idx) {
314 inline 0...arg_fields.len - 1 => |arg_i| {
315 return diagnoseField(decl, arg_fields[arg_i], UnwrapOptional(arg_fields[arg_i].type), arguments, res, node, p);
316 },
317 else => unreachable,
318 }
319 },
320 }
321}
322
323const EnumTypes = enum {
324 string,
325 identifier,
326};
327pub const Alignment = struct {
328 node: NodeIndex = .none,
329 requested: u29,
330};
331pub const Identifier = struct {
332 tok: TokenIndex = 0,
333};
334
335const attributes = struct {
336 pub const access = struct {
337 access_mode: enum {
338 read_only,
339 read_write,
340 write_only,
341 none,
342
343 const opts = struct {
344 const enum_kind = .identifier;
345 };
346 },
347 ref_index: u32,
348 size_index: ?u32 = null,
349 };
350 pub const alias = struct {
351 alias: Value,
352 };
353 pub const aligned = struct {
354 alignment: ?Alignment = null,
355 __name_tok: TokenIndex,
356 };
357 pub const alloc_align = struct {
358 position: u32,
359 };
360 pub const alloc_size = struct {
361 position_1: u32,
362 position_2: ?u32 = null,
363 };
364 pub const allocate = struct {
365 segname: Value,
366 };
367 pub const allocator = struct {};
368 pub const always_inline = struct {};
369 pub const appdomain = struct {};
370 pub const artificial = struct {};
371 pub const assume_aligned = struct {
372 alignment: Alignment,
373 offset: ?u32 = null,
374 };
375 pub const cleanup = struct {
376 function: Identifier,
377 };
378 pub const code_seg = struct {
379 segname: Value,
380 };
381 pub const cold = struct {};
382 pub const common = struct {};
383 pub const @"const" = struct {};
384 pub const constructor = struct {
385 priority: ?u32 = null,
386 };
387 pub const copy = struct {
388 function: Identifier,
389 };
390 pub const deprecated = struct {
391 msg: ?Value = null,
392 __name_tok: TokenIndex,
393 };
394 pub const designated_init = struct {};
395 pub const destructor = struct {
396 priority: ?u32 = null,
397 };
398 pub const dllexport = struct {};
399 pub const dllimport = struct {};
400 pub const @"error" = struct {
401 msg: Value,
402 __name_tok: TokenIndex,
403 };
404 pub const externally_visible = struct {};
405 pub const fallthrough = struct {};
406 pub const flatten = struct {};
407 pub const format = struct {
408 archetype: enum {
409 printf,
410 scanf,
411 strftime,
412 strfmon,
413
414 const opts = struct {
415 const enum_kind = .identifier;
416 };
417 },
418 string_index: u32,
419 first_to_check: u32,
420 };
421 pub const format_arg = struct {
422 string_index: u32,
423 };
424 pub const gnu_inline = struct {};
425 pub const hot = struct {};
426 pub const ifunc = struct {
427 resolver: Value,
428 };
429 pub const interrupt = struct {};
430 pub const interrupt_handler = struct {};
431 pub const jitintrinsic = struct {};
432 pub const leaf = struct {};
433 pub const malloc = struct {};
434 pub const may_alias = struct {};
435 pub const mode = struct {
436 mode: enum {
437 // zig fmt: off
438 byte, word, pointer,
439 BI, QI, HI,
440 PSI, SI, PDI,
441 DI, TI, OI,
442 XI, QF, HF,
443 TQF, SF, DF,
444 XF, SD, DD,
445 TD, TF, QQ,
446 HQ, SQ, DQ,
447 TQ, UQQ, UHQ,
448 USQ, UDQ, UTQ,
449 HA, SA, DA,
450 TA, UHA, USA,
451 UDA, UTA, CC,
452 BLK, VOID, QC,
453 HC, SC, DC,
454 XC, TC, CQI,
455 CHI, CSI, CDI,
456 CTI, COI, CPSI,
457 BND32, BND64,
458 // zig fmt: on
459
460 const opts = struct {
461 const enum_kind = .identifier;
462 };
463 },
464 };
465 pub const naked = struct {};
466 pub const no_address_safety_analysis = struct {};
467 pub const no_icf = struct {};
468 pub const no_instrument_function = struct {};
469 pub const no_profile_instrument_function = struct {};
470 pub const no_reorder = struct {};
471 pub const no_sanitize = struct {
472 /// Todo: represent args as union?
473 alignment: Value,
474 object_size: ?Value = null,
475 };
476 pub const no_sanitize_address = struct {};
477 pub const no_sanitize_coverage = struct {};
478 pub const no_sanitize_thread = struct {};
479 pub const no_sanitize_undefined = struct {};
480 pub const no_split_stack = struct {};
481 pub const no_stack_limit = struct {};
482 pub const no_stack_protector = struct {};
483 pub const @"noalias" = struct {};
484 pub const noclone = struct {};
485 pub const nocommon = struct {};
486 pub const nodiscard = struct {};
487 pub const noinit = struct {};
488 pub const @"noinline" = struct {};
489 pub const noipa = struct {};
490 // TODO: arbitrary number of arguments
491 // const nonnull = struct {
492 // // arg_index: []const u32,
493 // };
494 // };
495 pub const nonstring = struct {};
496 pub const noplt = struct {};
497 pub const @"noreturn" = struct {};
498 // TODO: union args ?
499 // const optimize = struct {
500 // // optimize, // u32 | []const u8 -- optimize?
501 // };
502 // };
503 pub const @"packed" = struct {};
504 pub const patchable_function_entry = struct {};
505 pub const persistent = struct {};
506 pub const process = struct {};
507 pub const pure = struct {};
508 pub const reproducible = struct {};
509 pub const restrict = struct {};
510 pub const retain = struct {};
511 pub const returns_nonnull = struct {};
512 pub const returns_twice = struct {};
513 pub const safebuffers = struct {};
514 pub const scalar_storage_order = struct {
515 order: enum {
516 @"little-endian",
517 @"big-endian",
518
519 const opts = struct {
520 const enum_kind = .string;
521 };
522 },
523 };
524 pub const section = struct {
525 name: Value,
526 };
527 pub const selectany = struct {};
528 pub const sentinel = struct {
529 position: ?u32 = null,
530 };
531 pub const simd = struct {
532 mask: ?enum {
533 notinbranch,
534 inbranch,
535
536 const opts = struct {
537 const enum_kind = .string;
538 };
539 } = null,
540 };
541 pub const spectre = struct {
542 arg: enum {
543 nomitigation,
544
545 const opts = struct {
546 const enum_kind = .identifier;
547 };
548 },
549 };
550 pub const stack_protect = struct {};
551 pub const symver = struct {
552 version: Value, // TODO: validate format "name2@nodename"
553
554 };
555 pub const target = struct {
556 options: Value, // TODO: multiple arguments
557
558 };
559 pub const target_clones = struct {
560 options: Value, // TODO: multiple arguments
561
562 };
563 pub const thread = struct {};
564 pub const tls_model = struct {
565 model: enum {
566 @"global-dynamic",
567 @"local-dynamic",
568 @"initial-exec",
569 @"local-exec",
570
571 const opts = struct {
572 const enum_kind = .string;
573 };
574 },
575 };
576 pub const transparent_union = struct {};
577 pub const unavailable = struct {
578 msg: ?Value = null,
579 __name_tok: TokenIndex,
580 };
581 pub const uninitialized = struct {};
582 pub const unsequenced = struct {};
583 pub const unused = struct {};
584 pub const used = struct {};
585 pub const uuid = struct {
586 uuid: Value,
587 };
588 pub const vector_size = struct {
589 bytes: u32, // TODO: validate "The bytes argument must be a positive power-of-two multiple of the base type size"
590
591 };
592 pub const visibility = struct {
593 visibility_type: enum {
594 default,
595 hidden,
596 internal,
597 protected,
598
599 const opts = struct {
600 const enum_kind = .string;
601 };
602 },
603 };
604 pub const warn_if_not_aligned = struct {
605 alignment: Alignment,
606 };
607 pub const warn_unused_result = struct {};
608 pub const warning = struct {
609 msg: Value,
610 __name_tok: TokenIndex,
611 };
612 pub const weak = struct {};
613 pub const weakref = struct {
614 target: ?Value = null,
615 };
616 pub const zero_call_used_regs = struct {
617 choice: enum {
618 skip,
619 used,
620 @"used-gpr",
621 @"used-arg",
622 @"used-gpr-arg",
623 all,
624 @"all-gpr",
625 @"all-arg",
626 @"all-gpr-arg",
627
628 const opts = struct {
629 const enum_kind = .string;
630 };
631 },
632 };
633 pub const asm_label = struct {
634 name: Value,
635 };
636 pub const calling_convention = struct {
637 cc: CallingConvention,
638 };
639};
640
641pub const Tag = std.meta.DeclEnum(attributes);
642
643pub const Arguments = blk: {
644 const decls = @typeInfo(attributes).Struct.decls;
645 var union_fields: [decls.len]ZigType.UnionField = undefined;
646 for (decls, &union_fields) |decl, *field| {
647 field.* = .{
648 .name = decl.name ++ "",
649 .type = @field(attributes, decl.name),
650 .alignment = 0,
651 };
652 }
653
654 break :blk @Type(.{
655 .Union = .{
656 .layout = .Auto,
657 .tag_type = null,
658 .fields = &union_fields,
659 .decls = &.{},
660 },
661 });
662};
663
664pub fn ArgumentsForTag(comptime tag: Tag) type {
665 const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
666 return @field(attributes, decl.name);
667}
668
669pub fn initArguments(tag: Tag, name_tok: TokenIndex) Arguments {
670 switch (tag) {
671 inline else => |arg_tag| {
672 const union_element = @field(attributes, @tagName(arg_tag));
673 const init = std.mem.zeroInit(union_element, .{});
674 var args = @unionInit(Arguments, @tagName(arg_tag), init);
675 if (@hasField(@field(attributes, @tagName(arg_tag)), "__name_tok")) {
676 @field(args, @tagName(arg_tag)).__name_tok = name_tok;
677 }
678 return args;
679 },
680 }
681}
682
683pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag {
684 const Properties = struct {
685 tag: Tag,
686 gnu: bool = false,
687 declspec: bool = false,
688 c23: bool = false,
689 };
690 const attribute_names = @import("Attribute/names.def").with(Properties);
691
692 const normalized = normalize(name);
693 const actual_kind: Kind = if (namespace) |ns| blk: {
694 const normalized_ns = normalize(ns);
695 if (mem.eql(u8, normalized_ns, "gnu")) {
696 break :blk .gnu;
697 }
698 return null;
699 } else kind;
700
701 const tag_and_opts = attribute_names.fromName(normalized) orelse return null;
702 switch (actual_kind) {
703 inline else => |tag| {
704 if (@field(tag_and_opts.properties, @tagName(tag)))
705 return tag_and_opts.properties.tag;
706 },
707 }
708 return null;
709}
710
711pub fn normalize(name: []const u8) []const u8 {
712 if (name.len >= 4 and mem.startsWith(u8, name, "__") and mem.endsWith(u8, name, "__")) {
713 return name[2 .. name.len - 2];
714 }
715 return name;
716}
717
718fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {
719 const strings_top = p.strings.items.len;
720 defer p.strings.items.len = strings_top;
721
722 try p.strings.writer().print("attribute '{s}' ignored on {s}", .{ @tagName(attr), context });
723 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
724 try p.errStr(.ignored_attribute, tok, str);
725}
726
727pub const applyParameterAttributes = applyVariableAttributes;
728pub fn applyVariableAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
729 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
730 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
731 p.attr_application_buf.items.len = 0;
732 var base_ty = ty;
733 if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
734 var common = false;
735 var nocommon = false;
736 for (attrs, toks) |attr, tok| switch (attr.tag) {
737 // zig fmt: off
738 .alias, .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .weak, .used,
739 .noinit, .retain, .persistent, .section, .mode, .asm_label,
740 => try p.attr_application_buf.append(p.gpa, attr),
741 // zig fmt: on
742 .common => if (nocommon) {
743 try p.errTok(.ignore_common, tok);
744 } else {
745 try p.attr_application_buf.append(p.gpa, attr);
746 common = true;
747 },
748 .nocommon => if (common) {
749 try p.errTok(.ignore_nocommon, tok);
750 } else {
751 try p.attr_application_buf.append(p.gpa, attr);
752 nocommon = true;
753 },
754 .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
755 .aligned => try attr.applyAligned(p, base_ty, tag),
756 .nonstring => if (!base_ty.isArray() or !(base_ty.is(.char) or base_ty.is(.uchar) or base_ty.is(.schar))) {
757 try p.errStr(.non_string_ignored, tok, try p.typeStr(ty));
758 } else {
759 try p.attr_application_buf.append(p.gpa, attr);
760 },
761 .uninitialized => if (p.func.ty == null) {
762 try p.errStr(.local_variable_attribute, tok, "uninitialized");
763 } else {
764 try p.attr_application_buf.append(p.gpa, attr);
765 },
766 .cleanup => if (p.func.ty == null) {
767 try p.errStr(.local_variable_attribute, tok, "cleanup");
768 } else {
769 try p.attr_application_buf.append(p.gpa, attr);
770 },
771 .alloc_size,
772 .copy,
773 .tls_model,
774 .visibility,
775 => std.debug.panic("apply variable attribute {s}", .{@tagName(attr.tag)}),
776 else => try ignoredAttrErr(p, tok, attr.tag, "variables"),
777 };
778 const existing = ty.getAttributes();
779 if (existing.len == 0 and p.attr_application_buf.items.len == 0) return base_ty;
780 if (existing.len == 0) return base_ty.withAttributes(p.arena, p.attr_application_buf.items);
781
782 const attributed_type = try Type.Attributed.create(p.arena, base_ty, existing, p.attr_application_buf.items);
783 return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } };
784}
785
786pub fn applyFieldAttributes(p: *Parser, field_ty: *Type, attr_buf_start: usize) ![]const Attribute {
787 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
788 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
789 p.attr_application_buf.items.len = 0;
790 for (attrs, toks) |attr, tok| switch (attr.tag) {
791 // zig fmt: off
792 .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
793 => try p.attr_application_buf.append(p.gpa, attr),
794 // zig fmt: on
795 .vector_size => try attr.applyVectorSize(p, tok, field_ty),
796 .aligned => try attr.applyAligned(p, field_ty.*, null),
797 else => try ignoredAttrErr(p, tok, attr.tag, "fields"),
798 };
799 if (p.attr_application_buf.items.len == 0) return &[0]Attribute{};
800 return p.arena.dupe(Attribute, p.attr_application_buf.items);
801}
802
803pub fn applyTypeAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
804 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
805 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
806 p.attr_application_buf.items.len = 0;
807 var base_ty = ty;
808 if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
809 for (attrs, toks) |attr, tok| switch (attr.tag) {
810 // zig fmt: off
811 .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
812 => try p.attr_application_buf.append(p.gpa, attr),
813 // zig fmt: on
814 .transparent_union => try attr.applyTransparentUnion(p, tok, base_ty),
815 .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
816 .aligned => try attr.applyAligned(p, base_ty, tag),
817 .designated_init => if (base_ty.is(.@"struct")) {
818 try p.attr_application_buf.append(p.gpa, attr);
819 } else {
820 try p.errTok(.designated_init_invalid, tok);
821 },
822 .alloc_size,
823 .copy,
824 .scalar_storage_order,
825 .nonstring,
826 => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
827 else => try ignoredAttrErr(p, tok, attr.tag, "types"),
828 };
829
830 const existing = ty.getAttributes();
831 // TODO: the alignment annotation on a type should override
832 // the decl it refers to. This might not be true for others. Maybe bug.
833
834 // if there are annotations on this type def use those.
835 if (p.attr_application_buf.items.len > 0) {
836 return try base_ty.withAttributes(p.arena, p.attr_application_buf.items);
837 } else if (existing.len > 0) {
838 // else use the ones on the typedef decl we were refering to.
839 return try base_ty.withAttributes(p.arena, existing);
840 }
841 return base_ty;
842}
843
844pub fn applyFunctionAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
845 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
846 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
847 p.attr_application_buf.items.len = 0;
848 var base_ty = ty;
849 if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
850 var hot = false;
851 var cold = false;
852 var @"noinline" = false;
853 var always_inline = false;
854 for (attrs, toks) |attr, tok| switch (attr.tag) {
855 // zig fmt: off
856 .noreturn, .unused, .used, .warning, .deprecated, .unavailable, .weak, .pure, .leaf,
857 .@"const", .warn_unused_result, .section, .returns_nonnull, .returns_twice, .@"error",
858 .externally_visible, .retain, .flatten, .gnu_inline, .alias, .asm_label, .nodiscard,
859 .reproducible, .unsequenced,
860 => try p.attr_application_buf.append(p.gpa, attr),
861 // zig fmt: on
862 .hot => if (cold) {
863 try p.errTok(.ignore_hot, tok);
864 } else {
865 try p.attr_application_buf.append(p.gpa, attr);
866 hot = true;
867 },
868 .cold => if (hot) {
869 try p.errTok(.ignore_cold, tok);
870 } else {
871 try p.attr_application_buf.append(p.gpa, attr);
872 cold = true;
873 },
874 .always_inline => if (@"noinline") {
875 try p.errTok(.ignore_always_inline, tok);
876 } else {
877 try p.attr_application_buf.append(p.gpa, attr);
878 always_inline = true;
879 },
880 .@"noinline" => if (always_inline) {
881 try p.errTok(.ignore_noinline, tok);
882 } else {
883 try p.attr_application_buf.append(p.gpa, attr);
884 @"noinline" = true;
885 },
886 .aligned => try attr.applyAligned(p, base_ty, null),
887 .format => try attr.applyFormat(p, base_ty),
888 .calling_convention => switch (attr.args.calling_convention.cc) {
889 .C => continue,
890 .stdcall, .thiscall => switch (p.comp.target.cpu.arch) {
891 .x86 => try p.attr_application_buf.append(p.gpa, attr),
892 else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
893 },
894 .vectorcall => switch (p.comp.target.cpu.arch) {
895 .x86, .aarch64, .aarch64_be, .aarch64_32 => try p.attr_application_buf.append(p.gpa, attr),
896 else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
897 },
898 },
899 .access,
900 .alloc_align,
901 .alloc_size,
902 .artificial,
903 .assume_aligned,
904 .constructor,
905 .copy,
906 .destructor,
907 .format_arg,
908 .ifunc,
909 .interrupt,
910 .interrupt_handler,
911 .malloc,
912 .no_address_safety_analysis,
913 .no_icf,
914 .no_instrument_function,
915 .no_profile_instrument_function,
916 .no_reorder,
917 .no_sanitize,
918 .no_sanitize_address,
919 .no_sanitize_coverage,
920 .no_sanitize_thread,
921 .no_sanitize_undefined,
922 .no_split_stack,
923 .no_stack_limit,
924 .no_stack_protector,
925 .noclone,
926 .noipa,
927 // .nonnull,
928 .noplt,
929 // .optimize,
930 .patchable_function_entry,
931 .sentinel,
932 .simd,
933 .stack_protect,
934 .symver,
935 .target,
936 .target_clones,
937 .visibility,
938 .weakref,
939 .zero_call_used_regs,
940 => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
941 else => try ignoredAttrErr(p, tok, attr.tag, "functions"),
942 };
943 return ty.withAttributes(p.arena, p.attr_application_buf.items);
944}
945
946pub fn applyLabelAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
947 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
948 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
949 p.attr_application_buf.items.len = 0;
950 var hot = false;
951 var cold = false;
952 for (attrs, toks) |attr, tok| switch (attr.tag) {
953 .unused => try p.attr_application_buf.append(p.gpa, attr),
954 .hot => if (cold) {
955 try p.errTok(.ignore_hot, tok);
956 } else {
957 try p.attr_application_buf.append(p.gpa, attr);
958 hot = true;
959 },
960 .cold => if (hot) {
961 try p.errTok(.ignore_cold, tok);
962 } else {
963 try p.attr_application_buf.append(p.gpa, attr);
964 cold = true;
965 },
966 else => try ignoredAttrErr(p, tok, attr.tag, "labels"),
967 };
968 return ty.withAttributes(p.arena, p.attr_application_buf.items);
969}
970
971pub fn applyStatementAttributes(p: *Parser, ty: Type, expr_start: TokenIndex, attr_buf_start: usize) !Type {
972 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
973 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
974 p.attr_application_buf.items.len = 0;
975 for (attrs, toks) |attr, tok| switch (attr.tag) {
976 .fallthrough => if (p.tok_ids[p.tok_i] != .keyword_case and p.tok_ids[p.tok_i] != .keyword_default) {
977 // TODO: this condition is not completely correct; the last statement of a compound
978 // statement is also valid if it precedes a switch label (so intervening '}' are ok,
979 // but only if they close a compound statement)
980 try p.errTok(.invalid_fallthrough, expr_start);
981 } else {
982 try p.attr_application_buf.append(p.gpa, attr);
983 },
984 else => try p.errStr(.cannot_apply_attribute_to_statement, tok, @tagName(attr.tag)),
985 };
986 return ty.withAttributes(p.arena, p.attr_application_buf.items);
987}
988
989pub fn applyEnumeratorAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
990 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
991 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
992 p.attr_application_buf.items.len = 0;
993 for (attrs, toks) |attr, tok| switch (attr.tag) {
994 .deprecated, .unavailable => try p.attr_application_buf.append(p.gpa, attr),
995 else => try ignoredAttrErr(p, tok, attr.tag, "enums"),
996 };
997 return ty.withAttributes(p.arena, p.attr_application_buf.items);
998}
999
1000fn applyAligned(attr: Attribute, p: *Parser, ty: Type, tag: ?Diagnostics.Tag) !void {
1001 const base = ty.canonicalize(.standard);
1002 if (attr.args.aligned.alignment) |alignment| alignas: {
1003 if (attr.syntax != .keyword) break :alignas;
1004
1005 const align_tok = attr.args.aligned.__name_tok;
1006 if (tag) |t| try p.errTok(t, align_tok);
1007
1008 const default_align = base.alignof(p.comp);
1009 if (ty.isFunc()) {
1010 try p.errTok(.alignas_on_func, align_tok);
1011 } else if (alignment.requested < default_align) {
1012 try p.errExtra(.minimum_alignment, align_tok, .{ .unsigned = default_align });
1013 }
1014 }
1015 try p.attr_application_buf.append(p.gpa, attr);
1016}
1017
1018fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type) !void {
1019 const union_ty = ty.get(.@"union") orelse {
1020 return p.errTok(.transparent_union_wrong_type, tok);
1021 };
1022 // TODO validate union defined at end
1023 if (union_ty.data.record.isIncomplete()) return;
1024 const fields = union_ty.data.record.fields;
1025 if (fields.len == 0) {
1026 return p.errTok(.transparent_union_one_field, tok);
1027 }
1028 const first_field_size = fields[0].ty.bitSizeof(p.comp).?;
1029 for (fields[1..]) |field| {
1030 const field_size = field.ty.bitSizeof(p.comp).?;
1031 if (field_size == first_field_size) continue;
1032 const mapper = p.comp.string_interner.getSlowTypeMapper();
1033 const str = try std.fmt.allocPrint(
1034 p.comp.diagnostics.arena.allocator(),
1035 "'{s}' ({d}",
1036 .{ mapper.lookup(field.name), field_size },
1037 );
1038 try p.errStr(.transparent_union_size, field.name_tok, str);
1039 return p.errExtra(.transparent_union_size_note, fields[0].name_tok, .{ .unsigned = first_field_size });
1040 }
1041
1042 try p.attr_application_buf.append(p.gpa, attr);
1043}
1044
1045fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !void {
1046 if (!(ty.isInt() or ty.isFloat()) or !ty.isReal()) {
1047 const orig_ty = try p.typeStr(ty.*);
1048 ty.* = Type.invalid;
1049 return p.errStr(.invalid_vec_elem_ty, tok, orig_ty);
1050 }
1051 const vec_bytes = attr.args.vector_size.bytes;
1052 const ty_size = ty.sizeof(p.comp).?;
1053 if (vec_bytes % ty_size != 0) {
1054 return p.errTok(.vec_size_not_multiple, tok);
1055 }
1056 const vec_size = vec_bytes / ty_size;
1057
1058 const arr_ty = try p.arena.create(Type.Array);
1059 arr_ty.* = .{ .elem = ty.*, .len = vec_size };
1060 ty.* = Type{
1061 .specifier = .vector,
1062 .data = .{ .array = arr_ty },
1063 };
1064}
1065
1066fn applyFormat(attr: Attribute, p: *Parser, ty: Type) !void {
1067 // TODO validate
1068 _ = ty;
1069 try p.attr_application_buf.append(p.gpa, attr);
1070}
deps/aro/aro/Attribute/names.def deleted-431
......@@ -1,431 +0,0 @@
1# multiple
2deprecated
3 .tag = .deprecated
4 .c23 = true
5 .gnu = true
6 .declspec = true
7
8fallthrough
9 .tag = .fallthrough
10 .c23 = true
11 .gnu = true
12
13noreturn
14 .tag = .@"noreturn"
15 .c23 = true
16 .gnu = true
17 .declspec = true
18
19no_sanitize_address
20 .tag = .no_sanitize_address
21 .gnu = true
22 .declspec = true
23
24noinline
25 .tag = .@"noinline"
26 .gnu = true
27 .declspec = true
28
29# c23 only
30nodiscard
31 .tag = .nodiscard
32 .c23 = true
33
34reproducible
35 .tag = .reproducible
36 .c23 = true
37
38unsequenced
39 .tag = .unsequenced
40 .c23 = true
41
42maybe_unused
43 .tag = .unused
44 .c23 = true
45
46# gnu only
47access
48 .tag = .access
49 .gnu = true
50
51alias
52 .tag = .alias
53 .gnu = true
54
55aligned
56 .tag = .aligned
57 .gnu = true
58
59alloc_align
60 .tag = .alloc_align
61 .gnu = true
62
63alloc_size
64 .tag = .alloc_size
65 .gnu = true
66
67always_inline
68 .tag = .always_inline
69 .gnu = true
70
71artificial
72 .tag = .artificial
73 .gnu = true
74
75assume_aligned
76 .tag = .assume_aligned
77 .gnu = true
78
79cleanup
80 .tag = .cleanup
81 .gnu = true
82
83cold
84 .tag = .cold
85 .gnu = true
86
87common
88 .tag = .common
89 .gnu = true
90
91const
92 .tag = .@"const"
93 .gnu = true
94
95constructor
96 .tag = .constructor
97 .gnu = true
98
99copy
100 .tag = .copy
101 .gnu = true
102
103designated_init
104 .tag = .designated_init
105 .gnu = true
106
107destructor
108 .tag = .destructor
109 .gnu = true
110
111error
112 .tag = .@"error"
113 .gnu = true
114
115externally_visible
116 .tag = .externally_visible
117 .gnu = true
118
119flatten
120 .tag = .flatten
121 .gnu = true
122
123format
124 .tag = .format
125 .gnu = true
126
127format_arg
128 .tag = .format_arg
129 .gnu = true
130
131gnu_inline
132 .tag = .gnu_inline
133 .gnu = true
134
135hot
136 .tag = .hot
137 .gnu = true
138
139ifunc
140 .tag = .ifunc
141 .gnu = true
142
143interrupt
144 .tag = .interrupt
145 .gnu = true
146
147interrupt_handler
148 .tag = .interrupt_handler
149 .gnu = true
150
151leaf
152 .tag = .leaf
153 .gnu = true
154
155malloc
156 .tag = .malloc
157 .gnu = true
158
159may_alias
160 .tag = .may_alias
161 .gnu = true
162
163mode
164 .tag = .mode
165 .gnu = true
166
167no_address_safety_analysis
168 .tag = .no_address_safety_analysis
169 .gnu = true
170
171no_icf
172 .tag = .no_icf
173 .gnu = true
174
175no_instrument_function
176 .tag = .no_instrument_function
177 .gnu = true
178
179no_profile_instrument_function
180 .tag = .no_profile_instrument_function
181 .gnu = true
182
183no_reorder
184 .tag = .no_reorder
185 .gnu = true
186
187no_sanitize
188 .tag = .no_sanitize
189 .gnu = true
190
191no_sanitize_coverage
192 .tag = .no_sanitize_coverage
193 .gnu = true
194
195no_sanitize_thread
196 .tag = .no_sanitize_thread
197 .gnu = true
198
199no_sanitize_undefined
200 .tag = .no_sanitize_undefined
201 .gnu = true
202
203no_split_stack
204 .tag = .no_split_stack
205 .gnu = true
206
207no_stack_limit
208 .tag = .no_stack_limit
209 .gnu = true
210
211no_stack_protector
212 .tag = .no_stack_protector
213 .gnu = true
214
215noclone
216 .tag = .noclone
217 .gnu = true
218
219nocommon
220 .tag = .nocommon
221 .gnu = true
222
223noinit
224 .tag = .noinit
225 .gnu = true
226
227noipa
228 .tag = .noipa
229 .gnu = true
230
231# nonnull
232# .tag = .nonnull
233# .gnu = true
234
235nonstring
236 .tag = .nonstring
237 .gnu = true
238
239noplt
240 .tag = .noplt
241 .gnu = true
242
243# optimize
244# .tag = .optimize
245# .gnu = true
246
247packed
248 .tag = .@"packed"
249 .gnu = true
250
251patchable_function_entry
252 .tag = .patchable_function_entry
253 .gnu = true
254
255persistent
256 .tag = .persistent
257 .gnu = true
258
259pure
260 .tag = .pure
261 .gnu = true
262
263retain
264 .tag = .retain
265 .gnu = true
266
267returns_nonnull
268 .tag = .returns_nonnull
269 .gnu = true
270
271returns_twice
272 .tag = .returns_twice
273 .gnu = true
274
275scalar_storage_order
276 .tag = .scalar_storage_order
277 .gnu = true
278
279section
280 .tag = .section
281 .gnu = true
282
283sentinel
284 .tag = .sentinel
285 .gnu = true
286
287simd
288 .tag = .simd
289 .gnu = true
290
291stack_protect
292 .tag = .stack_protect
293 .gnu = true
294
295symver
296 .tag = .symver
297 .gnu = true
298
299target
300 .tag = .target
301 .gnu = true
302
303target_clones
304 .tag = .target_clones
305 .gnu = true
306
307tls_model
308 .tag = .tls_model
309 .gnu = true
310
311transparent_union
312 .tag = .transparent_union
313 .gnu = true
314
315unavailable
316 .tag = .unavailable
317 .gnu = true
318
319uninitialized
320 .tag = .uninitialized
321 .gnu = true
322
323unused
324 .tag = .unused
325 .gnu = true
326
327used
328 .tag = .used
329 .gnu = true
330
331vector_size
332 .tag = .vector_size
333 .gnu = true
334
335visibility
336 .tag = .visibility
337 .gnu = true
338
339warn_if_not_aligned
340 .tag = .warn_if_not_aligned
341 .gnu = true
342
343warn_unused_result
344 .tag = .warn_unused_result
345 .gnu = true
346
347warning
348 .tag = .warning
349 .gnu = true
350
351weak
352 .tag = .weak
353 .gnu = true
354
355weakref
356 .tag = .weakref
357 .gnu = true
358
359zero_call_used_regs
360 .tag = .zero_call_used_regs
361 .gnu = true
362
363# declspec only
364align
365 .tag = .aligned
366 .declspec = true
367
368allocate
369 .tag = .allocate
370 .declspec = true
371
372allocator
373 .tag = .allocator
374 .declspec = true
375
376appdomain
377 .tag = .appdomain
378 .declspec = true
379
380code_seg
381 .tag = .code_seg
382 .declspec = true
383
384dllexport
385 .tag = .dllexport
386 .declspec = true
387
388dllimport
389 .tag = .dllimport
390 .declspec = true
391
392jitintrinsic
393 .tag = .jitintrinsic
394 .declspec = true
395
396naked
397 .tag = .naked
398 .declspec = true
399
400noalias
401 .tag = .@"noalias"
402 .declspec = true
403
404process
405 .tag = .process
406 .declspec = true
407
408restrict
409 .tag = .restrict
410 .declspec = true
411
412safebuffers
413 .tag = .safebuffers
414 .declspec = true
415
416selectany
417 .tag = .selectany
418 .declspec = true
419
420spectre
421 .tag = .spectre
422 .declspec = true
423
424thread
425 .tag = .thread
426 .declspec = true
427
428uuid
429 .tag = .uuid
430 .declspec = true
431
deps/aro/aro/Builtins.zig deleted-397
......@@ -1,397 +0,0 @@
1const std = @import("std");
2const Compilation = @import("Compilation.zig");
3const Type = @import("Type.zig");
4const TypeDescription = @import("Builtins/TypeDescription.zig");
5const target_util = @import("target.zig");
6const StringId = @import("StringInterner.zig").StringId;
7const LangOpts = @import("LangOpts.zig");
8const Parser = @import("Parser.zig");
9
10const Properties = @import("Builtins/Properties.zig");
11pub const Builtin = @import("Builtins/Builtin.def").with(Properties);
12
13const Expanded = struct {
14 ty: Type,
15 builtin: Builtin,
16};
17
18const NameToTypeMap = std.StringHashMapUnmanaged(Type);
19
20const Builtins = @This();
21
22_name_to_type_map: NameToTypeMap = .{},
23
24pub fn deinit(b: *Builtins, gpa: std.mem.Allocator) void {
25 b._name_to_type_map.deinit(gpa);
26}
27
28fn specForSize(comp: *const Compilation, size_bits: u32) Type.Builder.Specifier {
29 var ty = Type{ .specifier = .short };
30 if (ty.sizeof(comp).? * 8 == size_bits) return .short;
31
32 ty.specifier = .int;
33 if (ty.sizeof(comp).? * 8 == size_bits) return .int;
34
35 ty.specifier = .long;
36 if (ty.sizeof(comp).? * 8 == size_bits) return .long;
37
38 ty.specifier = .long_long;
39 if (ty.sizeof(comp).? * 8 == size_bits) return .long_long;
40
41 unreachable;
42}
43
44fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *const Compilation, allocator: std.mem.Allocator) !Type {
45 var builder: Type.Builder = .{ .error_on_invalid = true };
46 var require_native_int32 = false;
47 var require_native_int64 = false;
48 for (desc.prefix) |prefix| {
49 switch (prefix) {
50 .L => builder.combine(undefined, .long, 0) catch unreachable,
51 .LL => {
52 builder.combine(undefined, .long, 0) catch unreachable;
53 builder.combine(undefined, .long, 0) catch unreachable;
54 },
55 .LLL => {
56 switch (builder.specifier) {
57 .none => builder.specifier = .int128,
58 .signed => builder.specifier = .sint128,
59 .unsigned => builder.specifier = .uint128,
60 else => unreachable,
61 }
62 },
63 .Z => require_native_int32 = true,
64 .W => require_native_int64 = true,
65 .N => {
66 std.debug.assert(desc.spec == .i);
67 if (!target_util.isLP64(comp.target)) {
68 builder.combine(undefined, .long, 0) catch unreachable;
69 }
70 },
71 .O => {
72 builder.combine(undefined, .long, 0) catch unreachable;
73 if (comp.target.os.tag != .opencl) {
74 builder.combine(undefined, .long, 0) catch unreachable;
75 }
76 },
77 .S => builder.combine(undefined, .signed, 0) catch unreachable,
78 .U => builder.combine(undefined, .unsigned, 0) catch unreachable,
79 .I => {
80 // Todo: compile-time constant integer
81 },
82 }
83 }
84 switch (desc.spec) {
85 .v => builder.combine(undefined, .void, 0) catch unreachable,
86 .b => builder.combine(undefined, .bool, 0) catch unreachable,
87 .c => builder.combine(undefined, .char, 0) catch unreachable,
88 .s => builder.combine(undefined, .short, 0) catch unreachable,
89 .i => {
90 if (require_native_int32) {
91 builder.specifier = specForSize(comp, 32);
92 } else if (require_native_int64) {
93 builder.specifier = specForSize(comp, 64);
94 } else {
95 switch (builder.specifier) {
96 .int128, .sint128, .uint128 => {},
97 else => builder.combine(undefined, .int, 0) catch unreachable,
98 }
99 }
100 },
101 .h => builder.combine(undefined, .fp16, 0) catch unreachable,
102 .x => {
103 // Todo: _Float16
104 return .{ .specifier = .invalid };
105 },
106 .y => {
107 // Todo: __bf16
108 return .{ .specifier = .invalid };
109 },
110 .f => builder.combine(undefined, .float, 0) catch unreachable,
111 .d => {
112 if (builder.specifier == .long_long) {
113 builder.specifier = .float128;
114 } else {
115 builder.combine(undefined, .double, 0) catch unreachable;
116 }
117 },
118 .z => {
119 std.debug.assert(builder.specifier == .none);
120 builder.specifier = Type.Builder.fromType(comp.types.size);
121 },
122 .w => {
123 std.debug.assert(builder.specifier == .none);
124 builder.specifier = Type.Builder.fromType(comp.types.wchar);
125 },
126 .F => {
127 std.debug.assert(builder.specifier == .none);
128 builder.specifier = Type.Builder.fromType(comp.types.ns_constant_string.ty);
129 },
130 .G => {
131 // Todo: id
132 return .{ .specifier = .invalid };
133 },
134 .H => {
135 // Todo: SEL
136 return .{ .specifier = .invalid };
137 },
138 .M => {
139 // Todo: struct objc_super
140 return .{ .specifier = .invalid };
141 },
142 .a => {
143 std.debug.assert(builder.specifier == .none);
144 std.debug.assert(desc.suffix.len == 0);
145 builder.specifier = Type.Builder.fromType(comp.types.va_list);
146 },
147 .A => {
148 std.debug.assert(builder.specifier == .none);
149 std.debug.assert(desc.suffix.len == 0);
150 var va_list = comp.types.va_list;
151 if (va_list.isArray()) va_list.decayArray();
152 builder.specifier = Type.Builder.fromType(va_list);
153 },
154 .V => |element_count| {
155 std.debug.assert(desc.suffix.len == 0);
156 const child_desc = it.next().?;
157 const child_ty = try createType(child_desc, undefined, comp, allocator);
158 const arr_ty = try allocator.create(Type.Array);
159 arr_ty.* = .{
160 .len = element_count,
161 .elem = child_ty,
162 };
163 const vector_ty = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
164 builder.specifier = Type.Builder.fromType(vector_ty);
165 },
166 .q => {
167 // Todo: scalable vector
168 return .{ .specifier = .invalid };
169 },
170 .E => {
171 // Todo: ext_vector (OpenCL vector)
172 return .{ .specifier = .invalid };
173 },
174 .X => |child| {
175 builder.combine(undefined, .complex, 0) catch unreachable;
176 switch (child) {
177 .float => builder.combine(undefined, .float, 0) catch unreachable,
178 .double => builder.combine(undefined, .double, 0) catch unreachable,
179 .longdouble => {
180 builder.combine(undefined, .long, 0) catch unreachable;
181 builder.combine(undefined, .double, 0) catch unreachable;
182 },
183 }
184 },
185 .Y => {
186 std.debug.assert(builder.specifier == .none);
187 std.debug.assert(desc.suffix.len == 0);
188 builder.specifier = Type.Builder.fromType(comp.types.ptrdiff);
189 },
190 .P => {
191 std.debug.assert(builder.specifier == .none);
192 if (comp.types.file.specifier == .invalid) {
193 return comp.types.file;
194 }
195 builder.specifier = Type.Builder.fromType(comp.types.file);
196 },
197 .J => {
198 std.debug.assert(builder.specifier == .none);
199 std.debug.assert(desc.suffix.len == 0);
200 if (comp.types.jmp_buf.specifier == .invalid) {
201 return comp.types.jmp_buf;
202 }
203 builder.specifier = Type.Builder.fromType(comp.types.jmp_buf);
204 },
205 .SJ => {
206 std.debug.assert(builder.specifier == .none);
207 std.debug.assert(desc.suffix.len == 0);
208 if (comp.types.sigjmp_buf.specifier == .invalid) {
209 return comp.types.sigjmp_buf;
210 }
211 builder.specifier = Type.Builder.fromType(comp.types.sigjmp_buf);
212 },
213 .K => {
214 std.debug.assert(builder.specifier == .none);
215 if (comp.types.ucontext_t.specifier == .invalid) {
216 return comp.types.ucontext_t;
217 }
218 builder.specifier = Type.Builder.fromType(comp.types.ucontext_t);
219 },
220 .p => {
221 std.debug.assert(builder.specifier == .none);
222 std.debug.assert(desc.suffix.len == 0);
223 builder.specifier = Type.Builder.fromType(comp.types.pid_t);
224 },
225 .@"!" => return .{ .specifier = .invalid },
226 }
227 for (desc.suffix) |suffix| {
228 switch (suffix) {
229 .@"*" => |address_space| {
230 _ = address_space; // TODO: handle address space
231 const elem_ty = try allocator.create(Type);
232 elem_ty.* = builder.finish(undefined) catch unreachable;
233 const ty = Type{
234 .specifier = .pointer,
235 .data = .{ .sub_type = elem_ty },
236 };
237 builder.qual = .{};
238 builder.specifier = Type.Builder.fromType(ty);
239 },
240 .C => builder.qual.@"const" = 0,
241 .D => builder.qual.@"volatile" = 0,
242 .R => builder.qual.restrict = 0,
243 }
244 }
245 return builder.finish(undefined) catch unreachable;
246}
247
248fn createBuiltin(comp: *const Compilation, builtin: Builtin, type_arena: std.mem.Allocator) !Type {
249 var it = TypeDescription.TypeIterator.init(builtin.properties.param_str);
250
251 const ret_ty_desc = it.next().?;
252 if (ret_ty_desc.spec == .@"!") {
253 // Todo: handle target-dependent definition
254 }
255 const ret_ty = try createType(ret_ty_desc, &it, comp, type_arena);
256 var param_count: usize = 0;
257 var params: [Builtin.max_param_count]Type.Func.Param = undefined;
258 while (it.next()) |desc| : (param_count += 1) {
259 params[param_count] = .{ .name_tok = 0, .ty = try createType(desc, &it, comp, type_arena), .name = .empty };
260 }
261
262 const duped_params = try type_arena.dupe(Type.Func.Param, params[0..param_count]);
263 const func = try type_arena.create(Type.Func);
264
265 func.* = .{
266 .return_type = ret_ty,
267 .params = duped_params,
268 };
269 return .{
270 .specifier = if (builtin.properties.isVarArgs()) .var_args_func else .func,
271 .data = .{ .func = func },
272 };
273}
274
275/// Asserts that the builtin has already been created
276pub fn lookup(b: *const Builtins, name: []const u8) Expanded {
277 const builtin = Builtin.fromName(name).?;
278 const ty = b._name_to_type_map.get(name).?;
279 return .{
280 .builtin = builtin,
281 .ty = ty,
282 };
283}
284
285pub fn getOrCreate(b: *Builtins, comp: *Compilation, name: []const u8, type_arena: std.mem.Allocator) !?Expanded {
286 const ty = b._name_to_type_map.get(name) orelse {
287 const builtin = Builtin.fromName(name) orelse return null;
288 if (!comp.hasBuiltinFunction(builtin)) return null;
289
290 try b._name_to_type_map.ensureUnusedCapacity(comp.gpa, 1);
291 const ty = try createBuiltin(comp, builtin, type_arena);
292 b._name_to_type_map.putAssumeCapacity(name, ty);
293
294 return .{
295 .builtin = builtin,
296 .ty = ty,
297 };
298 };
299 const builtin = Builtin.fromName(name).?;
300 return .{
301 .builtin = builtin,
302 .ty = ty,
303 };
304}
305
306pub const Iterator = struct {
307 index: u16 = 1,
308 name_buf: [Builtin.longest_name]u8 = undefined,
309
310 pub const Entry = struct {
311 /// Memory of this slice is overwritten on every call to `next`
312 name: []const u8,
313 builtin: Builtin,
314 };
315
316 pub fn next(self: *Iterator) ?Entry {
317 if (self.index > Builtin.data.len) return null;
318 const index = self.index;
319 const data_index = index - 1;
320 self.index += 1;
321 return .{
322 .name = Builtin.nameFromUniqueIndex(index, &self.name_buf),
323 .builtin = Builtin.data[data_index],
324 };
325 }
326};
327
328test Iterator {
329 var it = Iterator{};
330
331 var seen = std.StringHashMap(Builtin).init(std.testing.allocator);
332 defer seen.deinit();
333
334 var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);
335 defer arena_state.deinit();
336 const arena = arena_state.allocator();
337
338 while (it.next()) |entry| {
339 const index = Builtin.uniqueIndex(entry.name).?;
340 var buf: [Builtin.longest_name]u8 = undefined;
341 const name_from_index = Builtin.nameFromUniqueIndex(index, &buf);
342 try std.testing.expectEqualStrings(entry.name, name_from_index);
343
344 if (seen.contains(entry.name)) {
345 std.debug.print("iterated over {s} twice\n", .{entry.name});
346 std.debug.print("current data: {}\n", .{entry.builtin});
347 std.debug.print("previous data: {}\n", .{seen.get(entry.name).?});
348 return error.TestExpectedUniqueEntries;
349 }
350 try seen.put(try arena.dupe(u8, entry.name), entry.builtin);
351 }
352 try std.testing.expectEqual(@as(usize, Builtin.data.len), seen.count());
353}
354
355test "All builtins" {
356 var comp = Compilation.init(std.testing.allocator);
357 defer comp.deinit();
358 _ = try comp.generateBuiltinMacros(.include_system_defines);
359 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
360 defer arena.deinit();
361
362 const type_arena = arena.allocator();
363
364 var builtin_it = Iterator{};
365 while (builtin_it.next()) |entry| {
366 const name = try type_arena.dupe(u8, entry.name);
367 if (try comp.builtins.getOrCreate(&comp, name, type_arena)) |func_ty| {
368 const get_again = (try comp.builtins.getOrCreate(&comp, name, std.testing.failing_allocator)).?;
369 const found_by_lookup = comp.builtins.lookup(name);
370 try std.testing.expectEqual(func_ty.builtin.tag, get_again.builtin.tag);
371 try std.testing.expectEqual(func_ty.builtin.tag, found_by_lookup.builtin.tag);
372 }
373 }
374}
375
376test "Allocation failures" {
377 const Test = struct {
378 fn testOne(allocator: std.mem.Allocator) !void {
379 var comp = Compilation.init(allocator);
380 defer comp.deinit();
381 _ = try comp.generateBuiltinMacros(.include_system_defines);
382 var arena = std.heap.ArenaAllocator.init(comp.gpa);
383 defer arena.deinit();
384
385 const type_arena = arena.allocator();
386
387 const num_builtins = 40;
388 var builtin_it = Iterator{};
389 for (0..num_builtins) |_| {
390 const entry = builtin_it.next().?;
391 _ = try comp.builtins.getOrCreate(&comp, entry.name, type_arena);
392 }
393 }
394 };
395
396 try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.testOne, .{});
397}
deps/aro/aro/Builtins/Builtin.def deleted-17162
......@@ -1,17162 +0,0 @@
1const TargetSet = Properties.TargetSet;
2
3# TODO this file is generated from LLVM sources and
4# needs cleanup to be considered source.
5
6pub const max_param_count = 12;
7
8_Block_object_assign
9 .param_str = "vv*vC*iC"
10 .header = .blocks
11 .attributes = .{ .lib_function_without_prefix = true }
12
13_Block_object_dispose
14 .param_str = "vvC*iC"
15 .header = .blocks
16 .attributes = .{ .lib_function_without_prefix = true }
17
18_Exit
19 .param_str = "vi"
20 .header = .stdlib
21 .attributes = .{ .noreturn = true, .lib_function_without_prefix = true }
22
23_InterlockedAnd
24 .param_str = "NiNiD*Ni"
25 .language = .all_ms_languages
26
27_InterlockedAnd16
28 .param_str = "ssD*s"
29 .language = .all_ms_languages
30
31_InterlockedAnd8
32 .param_str = "ccD*c"
33 .language = .all_ms_languages
34
35_InterlockedCompareExchange
36 .param_str = "NiNiD*NiNi"
37 .language = .all_ms_languages
38
39_InterlockedCompareExchange16
40 .param_str = "ssD*ss"
41 .language = .all_ms_languages
42
43_InterlockedCompareExchange64
44 .param_str = "LLiLLiD*LLiLLi"
45 .language = .all_ms_languages
46
47_InterlockedCompareExchange8
48 .param_str = "ccD*cc"
49 .language = .all_ms_languages
50
51_InterlockedCompareExchangePointer
52 .param_str = "v*v*D*v*v*"
53 .language = .all_ms_languages
54
55_InterlockedCompareExchangePointer_nf
56 .param_str = "v*v*D*v*v*"
57 .language = .all_ms_languages
58
59_InterlockedDecrement
60 .param_str = "NiNiD*"
61 .language = .all_ms_languages
62
63_InterlockedDecrement16
64 .param_str = "ssD*"
65 .language = .all_ms_languages
66
67_InterlockedExchange
68 .param_str = "NiNiD*Ni"
69 .language = .all_ms_languages
70
71_InterlockedExchange16
72 .param_str = "ssD*s"
73 .language = .all_ms_languages
74
75_InterlockedExchange8
76 .param_str = "ccD*c"
77 .language = .all_ms_languages
78
79_InterlockedExchangeAdd
80 .param_str = "NiNiD*Ni"
81 .language = .all_ms_languages
82
83_InterlockedExchangeAdd16
84 .param_str = "ssD*s"
85 .language = .all_ms_languages
86
87_InterlockedExchangeAdd8
88 .param_str = "ccD*c"
89 .language = .all_ms_languages
90
91_InterlockedExchangePointer
92 .param_str = "v*v*D*v*"
93 .language = .all_ms_languages
94
95_InterlockedExchangeSub
96 .param_str = "NiNiD*Ni"
97 .language = .all_ms_languages
98
99_InterlockedExchangeSub16
100 .param_str = "ssD*s"
101 .language = .all_ms_languages
102
103_InterlockedExchangeSub8
104 .param_str = "ccD*c"
105 .language = .all_ms_languages
106
107_InterlockedIncrement
108 .param_str = "NiNiD*"
109 .language = .all_ms_languages
110
111_InterlockedIncrement16
112 .param_str = "ssD*"
113 .language = .all_ms_languages
114
115_InterlockedOr
116 .param_str = "NiNiD*Ni"
117 .language = .all_ms_languages
118
119_InterlockedOr16
120 .param_str = "ssD*s"
121 .language = .all_ms_languages
122
123_InterlockedOr8
124 .param_str = "ccD*c"
125 .language = .all_ms_languages
126
127_InterlockedXor
128 .param_str = "NiNiD*Ni"
129 .language = .all_ms_languages
130
131_InterlockedXor16
132 .param_str = "ssD*s"
133 .language = .all_ms_languages
134
135_InterlockedXor8
136 .param_str = "ccD*c"
137 .language = .all_ms_languages
138
139_MoveFromCoprocessor
140 .param_str = "UiIUiIUiIUiIUiIUi"
141 .language = .all_ms_languages
142 .target_set = TargetSet.initOne(.arm)
143
144_MoveFromCoprocessor2
145 .param_str = "UiIUiIUiIUiIUiIUi"
146 .language = .all_ms_languages
147 .target_set = TargetSet.initOne(.arm)
148
149_MoveToCoprocessor
150 .param_str = "vUiIUiIUiIUiIUiIUi"
151 .language = .all_ms_languages
152 .target_set = TargetSet.initOne(.arm)
153
154_MoveToCoprocessor2
155 .param_str = "vUiIUiIUiIUiIUiIUi"
156 .language = .all_ms_languages
157 .target_set = TargetSet.initOne(.arm)
158
159_ReturnAddress
160 .param_str = "v*"
161 .language = .all_ms_languages
162
163__GetExceptionInfo
164 .param_str = "v*."
165 .language = .all_ms_languages
166 .attributes = .{ .custom_typecheck = true, .eval_args = false }
167
168__abnormal_termination
169 .param_str = "i"
170 .language = .all_ms_languages
171
172__annotation
173 .param_str = "wC*."
174 .language = .all_ms_languages
175
176__arithmetic_fence
177 .param_str = "v."
178 .attributes = .{ .custom_typecheck = true, .const_evaluable = true }
179
180__assume
181 .param_str = "vb"
182 .language = .all_ms_languages
183 .attributes = .{ .const_evaluable = true }
184
185__atomic_always_lock_free
186 .param_str = "bzvCD*"
187 .attributes = .{ .const_evaluable = true }
188
189__atomic_clear
190 .param_str = "vvD*i"
191
192__atomic_is_lock_free
193 .param_str = "bzvCD*"
194 .attributes = .{ .const_evaluable = true }
195
196__atomic_signal_fence
197 .param_str = "vi"
198
199__atomic_test_and_set
200 .param_str = "bvD*i"
201
202__atomic_thread_fence
203 .param_str = "vi"
204
205__builtin___CFStringMakeConstantString
206 .param_str = "FC*cC*"
207 .attributes = .{ .@"const" = true, .const_evaluable = true }
208
209__builtin___NSStringMakeConstantString
210 .param_str = "FC*cC*"
211 .attributes = .{ .@"const" = true, .const_evaluable = true }
212
213__builtin___clear_cache
214 .param_str = "vc*c*"
215
216__builtin___fprintf_chk
217 .param_str = "iP*RicC*R."
218 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 2 }
219
220__builtin___get_unsafe_stack_bottom
221 .param_str = "v*"
222 .attributes = .{ .lib_function_with_builtin_prefix = true }
223
224__builtin___get_unsafe_stack_ptr
225 .param_str = "v*"
226 .attributes = .{ .lib_function_with_builtin_prefix = true }
227
228__builtin___get_unsafe_stack_start
229 .param_str = "v*"
230 .attributes = .{ .lib_function_with_builtin_prefix = true }
231
232__builtin___get_unsafe_stack_top
233 .param_str = "v*"
234 .attributes = .{ .lib_function_with_builtin_prefix = true }
235
236__builtin___memccpy_chk
237 .param_str = "v*v*vC*izz"
238 .attributes = .{ .lib_function_with_builtin_prefix = true }
239
240__builtin___memcpy_chk
241 .param_str = "v*v*vC*zz"
242 .attributes = .{ .lib_function_with_builtin_prefix = true }
243
244__builtin___memmove_chk
245 .param_str = "v*v*vC*zz"
246 .attributes = .{ .lib_function_with_builtin_prefix = true }
247
248__builtin___mempcpy_chk
249 .param_str = "v*v*vC*zz"
250 .attributes = .{ .lib_function_with_builtin_prefix = true }
251
252__builtin___memset_chk
253 .param_str = "v*v*izz"
254 .attributes = .{ .lib_function_with_builtin_prefix = true }
255
256__builtin___printf_chk
257 .param_str = "iicC*R."
258 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 }
259
260__builtin___snprintf_chk
261 .param_str = "ic*RzizcC*R."
262 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 4 }
263
264__builtin___sprintf_chk
265 .param_str = "ic*RizcC*R."
266 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 3 }
267
268__builtin___stpcpy_chk
269 .param_str = "c*c*cC*z"
270 .attributes = .{ .lib_function_with_builtin_prefix = true }
271
272__builtin___stpncpy_chk
273 .param_str = "c*c*cC*zz"
274 .attributes = .{ .lib_function_with_builtin_prefix = true }
275
276__builtin___strcat_chk
277 .param_str = "c*c*cC*z"
278 .attributes = .{ .lib_function_with_builtin_prefix = true }
279
280__builtin___strcpy_chk
281 .param_str = "c*c*cC*z"
282 .attributes = .{ .lib_function_with_builtin_prefix = true }
283
284__builtin___strlcat_chk
285 .param_str = "zc*cC*zz"
286 .attributes = .{ .lib_function_with_builtin_prefix = true }
287
288__builtin___strlcpy_chk
289 .param_str = "zc*cC*zz"
290 .attributes = .{ .lib_function_with_builtin_prefix = true }
291
292__builtin___strncat_chk
293 .param_str = "c*c*cC*zz"
294 .attributes = .{ .lib_function_with_builtin_prefix = true }
295
296__builtin___strncpy_chk
297 .param_str = "c*c*cC*zz"
298 .attributes = .{ .lib_function_with_builtin_prefix = true }
299
300__builtin___vfprintf_chk
301 .param_str = "iP*RicC*Ra"
302 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 2 }
303
304__builtin___vprintf_chk
305 .param_str = "iicC*Ra"
306 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 }
307
308__builtin___vsnprintf_chk
309 .param_str = "ic*RzizcC*Ra"
310 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 4 }
311
312__builtin___vsprintf_chk
313 .param_str = "ic*RizcC*Ra"
314 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 3 }
315
316__builtin_abort
317 .param_str = "v"
318 .attributes = .{ .noreturn = true, .lib_function_with_builtin_prefix = true }
319
320__builtin_abs
321 .param_str = "ii"
322 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
323
324__builtin_acos
325 .param_str = "dd"
326 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
327
328__builtin_acosf
329 .param_str = "ff"
330 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
331
332__builtin_acosf128
333 .param_str = "LLdLLd"
334 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
335
336__builtin_acosh
337 .param_str = "dd"
338 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
339
340__builtin_acoshf
341 .param_str = "ff"
342 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
343
344__builtin_acoshf128
345 .param_str = "LLdLLd"
346 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
347
348__builtin_acoshl
349 .param_str = "LdLd"
350 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
351
352__builtin_acosl
353 .param_str = "LdLd"
354 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
355
356__builtin_add_overflow
357 .param_str = "b."
358 .attributes = .{ .custom_typecheck = true, .const_evaluable = true }
359
360__builtin_addc
361 .param_str = "UiUiCUiCUiCUi*"
362
363__builtin_addcb
364 .param_str = "UcUcCUcCUcCUc*"
365
366__builtin_addcl
367 .param_str = "ULiULiCULiCULiCULi*"
368
369__builtin_addcll
370 .param_str = "ULLiULLiCULLiCULLiCULLi*"
371
372__builtin_addcs
373 .param_str = "UsUsCUsCUsCUs*"
374
375__builtin_align_down
376 .param_str = "v*vC*z"
377 .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true }
378
379__builtin_align_up
380 .param_str = "v*vC*z"
381 .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true }
382
383__builtin_alloca
384 .param_str = "v*z"
385 .attributes = .{ .lib_function_with_builtin_prefix = true }
386
387__builtin_alloca_uninitialized
388 .param_str = "v*z"
389 .attributes = .{ .lib_function_with_builtin_prefix = true }
390
391__builtin_alloca_with_align
392 .param_str = "v*zIz"
393 .attributes = .{ .lib_function_with_builtin_prefix = true }
394
395__builtin_alloca_with_align_uninitialized
396 .param_str = "v*zIz"
397 .attributes = .{ .lib_function_with_builtin_prefix = true }
398
399__builtin_amdgcn_alignbit
400 .param_str = "UiUiUiUi"
401 .target_set = TargetSet.initOne(.amdgpu)
402 .attributes = .{ .@"const" = true }
403
404__builtin_amdgcn_alignbyte
405 .param_str = "UiUiUiUi"
406 .target_set = TargetSet.initOne(.amdgpu)
407 .attributes = .{ .@"const" = true }
408
409__builtin_amdgcn_atomic_dec32
410 .param_str = "UZiUZiD*UZiUicC*"
411 .target_set = TargetSet.initOne(.amdgpu)
412
413__builtin_amdgcn_atomic_dec64
414 .param_str = "UWiUWiD*UWiUicC*"
415 .target_set = TargetSet.initOne(.amdgpu)
416
417__builtin_amdgcn_atomic_inc32
418 .param_str = "UZiUZiD*UZiUicC*"
419 .target_set = TargetSet.initOne(.amdgpu)
420
421__builtin_amdgcn_atomic_inc64
422 .param_str = "UWiUWiD*UWiUicC*"
423 .target_set = TargetSet.initOne(.amdgpu)
424
425__builtin_amdgcn_buffer_wbinvl1
426 .param_str = "v"
427 .target_set = TargetSet.initOne(.amdgpu)
428
429__builtin_amdgcn_class
430 .param_str = "bdi"
431 .target_set = TargetSet.initOne(.amdgpu)
432 .attributes = .{ .@"const" = true }
433
434__builtin_amdgcn_classf
435 .param_str = "bfi"
436 .target_set = TargetSet.initOne(.amdgpu)
437 .attributes = .{ .@"const" = true }
438
439__builtin_amdgcn_cosf
440 .param_str = "ff"
441 .target_set = TargetSet.initOne(.amdgpu)
442 .attributes = .{ .@"const" = true }
443
444__builtin_amdgcn_cubeid
445 .param_str = "ffff"
446 .target_set = TargetSet.initOne(.amdgpu)
447 .attributes = .{ .@"const" = true }
448
449__builtin_amdgcn_cubema
450 .param_str = "ffff"
451 .target_set = TargetSet.initOne(.amdgpu)
452 .attributes = .{ .@"const" = true }
453
454__builtin_amdgcn_cubesc
455 .param_str = "ffff"
456 .target_set = TargetSet.initOne(.amdgpu)
457 .attributes = .{ .@"const" = true }
458
459__builtin_amdgcn_cubetc
460 .param_str = "ffff"
461 .target_set = TargetSet.initOne(.amdgpu)
462 .attributes = .{ .@"const" = true }
463
464__builtin_amdgcn_cvt_pk_i16
465 .param_str = "E2sii"
466 .target_set = TargetSet.initOne(.amdgpu)
467 .attributes = .{ .@"const" = true }
468
469__builtin_amdgcn_cvt_pk_u16
470 .param_str = "E2UsUiUi"
471 .target_set = TargetSet.initOne(.amdgpu)
472 .attributes = .{ .@"const" = true }
473
474__builtin_amdgcn_cvt_pk_u8_f32
475 .param_str = "UifUiUi"
476 .target_set = TargetSet.initOne(.amdgpu)
477 .attributes = .{ .@"const" = true }
478
479__builtin_amdgcn_cvt_pknorm_i16
480 .param_str = "E2sff"
481 .target_set = TargetSet.initOne(.amdgpu)
482 .attributes = .{ .@"const" = true }
483
484__builtin_amdgcn_cvt_pknorm_u16
485 .param_str = "E2Usff"
486 .target_set = TargetSet.initOne(.amdgpu)
487 .attributes = .{ .@"const" = true }
488
489__builtin_amdgcn_cvt_pkrtz
490 .param_str = "E2hff"
491 .target_set = TargetSet.initOne(.amdgpu)
492 .attributes = .{ .@"const" = true }
493
494__builtin_amdgcn_dispatch_ptr
495 .param_str = "v*4"
496 .target_set = TargetSet.initOne(.amdgpu)
497 .attributes = .{ .@"const" = true }
498
499__builtin_amdgcn_div_fixup
500 .param_str = "dddd"
501 .target_set = TargetSet.initOne(.amdgpu)
502 .attributes = .{ .@"const" = true }
503
504__builtin_amdgcn_div_fixupf
505 .param_str = "ffff"
506 .target_set = TargetSet.initOne(.amdgpu)
507 .attributes = .{ .@"const" = true }
508
509__builtin_amdgcn_div_fmas
510 .param_str = "ddddb"
511 .target_set = TargetSet.initOne(.amdgpu)
512 .attributes = .{ .@"const" = true }
513
514__builtin_amdgcn_div_fmasf
515 .param_str = "ffffb"
516 .target_set = TargetSet.initOne(.amdgpu)
517 .attributes = .{ .@"const" = true }
518
519__builtin_amdgcn_div_scale
520 .param_str = "dddbb*"
521 .target_set = TargetSet.initOne(.amdgpu)
522
523__builtin_amdgcn_div_scalef
524 .param_str = "fffbb*"
525 .target_set = TargetSet.initOne(.amdgpu)
526
527__builtin_amdgcn_ds_append
528 .param_str = "ii*3"
529 .target_set = TargetSet.initOne(.amdgpu)
530
531__builtin_amdgcn_ds_bpermute
532 .param_str = "iii"
533 .target_set = TargetSet.initOne(.amdgpu)
534 .attributes = .{ .@"const" = true }
535
536__builtin_amdgcn_ds_consume
537 .param_str = "ii*3"
538 .target_set = TargetSet.initOne(.amdgpu)
539
540__builtin_amdgcn_ds_faddf
541 .param_str = "ff*3fIiIiIb"
542 .target_set = TargetSet.initOne(.amdgpu)
543
544__builtin_amdgcn_ds_fmaxf
545 .param_str = "ff*3fIiIiIb"
546 .target_set = TargetSet.initOne(.amdgpu)
547
548__builtin_amdgcn_ds_fminf
549 .param_str = "ff*3fIiIiIb"
550 .target_set = TargetSet.initOne(.amdgpu)
551
552__builtin_amdgcn_ds_permute
553 .param_str = "iii"
554 .target_set = TargetSet.initOne(.amdgpu)
555 .attributes = .{ .@"const" = true }
556
557__builtin_amdgcn_ds_swizzle
558 .param_str = "iiIi"
559 .target_set = TargetSet.initOne(.amdgpu)
560 .attributes = .{ .@"const" = true }
561
562__builtin_amdgcn_endpgm
563 .param_str = "v"
564 .target_set = TargetSet.initOne(.amdgpu)
565 .attributes = .{ .noreturn = true }
566
567__builtin_amdgcn_exp2f
568 .param_str = "ff"
569 .target_set = TargetSet.initOne(.amdgpu)
570 .attributes = .{ .@"const" = true }
571
572__builtin_amdgcn_fcmp
573 .param_str = "WUiddIi"
574 .target_set = TargetSet.initOne(.amdgpu)
575 .attributes = .{ .@"const" = true }
576
577__builtin_amdgcn_fcmpf
578 .param_str = "WUiffIi"
579 .target_set = TargetSet.initOne(.amdgpu)
580 .attributes = .{ .@"const" = true }
581
582__builtin_amdgcn_fence
583 .param_str = "vUicC*"
584 .target_set = TargetSet.initOne(.amdgpu)
585
586__builtin_amdgcn_fmed3f
587 .param_str = "ffff"
588 .target_set = TargetSet.initOne(.amdgpu)
589 .attributes = .{ .@"const" = true }
590
591__builtin_amdgcn_fract
592 .param_str = "dd"
593 .target_set = TargetSet.initOne(.amdgpu)
594 .attributes = .{ .@"const" = true }
595
596__builtin_amdgcn_fractf
597 .param_str = "ff"
598 .target_set = TargetSet.initOne(.amdgpu)
599 .attributes = .{ .@"const" = true }
600
601__builtin_amdgcn_frexp_exp
602 .param_str = "id"
603 .target_set = TargetSet.initOne(.amdgpu)
604 .attributes = .{ .@"const" = true }
605
606__builtin_amdgcn_frexp_expf
607 .param_str = "if"
608 .target_set = TargetSet.initOne(.amdgpu)
609 .attributes = .{ .@"const" = true }
610
611__builtin_amdgcn_frexp_mant
612 .param_str = "dd"
613 .target_set = TargetSet.initOne(.amdgpu)
614 .attributes = .{ .@"const" = true }
615
616__builtin_amdgcn_frexp_mantf
617 .param_str = "ff"
618 .target_set = TargetSet.initOne(.amdgpu)
619 .attributes = .{ .@"const" = true }
620
621__builtin_amdgcn_grid_size_x
622 .param_str = "Ui"
623 .target_set = TargetSet.initOne(.amdgpu)
624 .attributes = .{ .@"const" = true }
625
626__builtin_amdgcn_grid_size_y
627 .param_str = "Ui"
628 .target_set = TargetSet.initOne(.amdgpu)
629 .attributes = .{ .@"const" = true }
630
631__builtin_amdgcn_grid_size_z
632 .param_str = "Ui"
633 .target_set = TargetSet.initOne(.amdgpu)
634 .attributes = .{ .@"const" = true }
635
636__builtin_amdgcn_groupstaticsize
637 .param_str = "Ui"
638 .target_set = TargetSet.initOne(.amdgpu)
639
640__builtin_amdgcn_iglp_opt
641 .param_str = "vIi"
642 .target_set = TargetSet.initOne(.amdgpu)
643
644__builtin_amdgcn_implicitarg_ptr
645 .param_str = "v*4"
646 .target_set = TargetSet.initOne(.amdgpu)
647 .attributes = .{ .@"const" = true }
648
649__builtin_amdgcn_interp_mov
650 .param_str = "fUiUiUiUi"
651 .target_set = TargetSet.initOne(.amdgpu)
652 .attributes = .{ .@"const" = true }
653
654__builtin_amdgcn_interp_p1
655 .param_str = "ffUiUiUi"
656 .target_set = TargetSet.initOne(.amdgpu)
657 .attributes = .{ .@"const" = true }
658
659__builtin_amdgcn_interp_p1_f16
660 .param_str = "ffUiUibUi"
661 .target_set = TargetSet.initOne(.amdgpu)
662 .attributes = .{ .@"const" = true }
663
664__builtin_amdgcn_interp_p2
665 .param_str = "fffUiUiUi"
666 .target_set = TargetSet.initOne(.amdgpu)
667 .attributes = .{ .@"const" = true }
668
669__builtin_amdgcn_interp_p2_f16
670 .param_str = "hffUiUibUi"
671 .target_set = TargetSet.initOne(.amdgpu)
672 .attributes = .{ .@"const" = true }
673
674__builtin_amdgcn_is_private
675 .param_str = "bvC*0"
676 .target_set = TargetSet.initOne(.amdgpu)
677 .attributes = .{ .@"const" = true }
678
679__builtin_amdgcn_is_shared
680 .param_str = "bvC*0"
681 .target_set = TargetSet.initOne(.amdgpu)
682 .attributes = .{ .@"const" = true }
683
684__builtin_amdgcn_kernarg_segment_ptr
685 .param_str = "v*4"
686 .target_set = TargetSet.initOne(.amdgpu)
687 .attributes = .{ .@"const" = true }
688
689__builtin_amdgcn_ldexp
690 .param_str = "ddi"
691 .target_set = TargetSet.initOne(.amdgpu)
692 .attributes = .{ .@"const" = true }
693
694__builtin_amdgcn_ldexpf
695 .param_str = "ffi"
696 .target_set = TargetSet.initOne(.amdgpu)
697 .attributes = .{ .@"const" = true }
698
699__builtin_amdgcn_lerp
700 .param_str = "UiUiUiUi"
701 .target_set = TargetSet.initOne(.amdgpu)
702 .attributes = .{ .@"const" = true }
703
704__builtin_amdgcn_log_clampf
705 .param_str = "ff"
706 .target_set = TargetSet.initOne(.amdgpu)
707 .attributes = .{ .@"const" = true }
708
709__builtin_amdgcn_logf
710 .param_str = "ff"
711 .target_set = TargetSet.initOne(.amdgpu)
712 .attributes = .{ .@"const" = true }
713
714__builtin_amdgcn_mbcnt_hi
715 .param_str = "UiUiUi"
716 .target_set = TargetSet.initOne(.amdgpu)
717 .attributes = .{ .@"const" = true }
718
719__builtin_amdgcn_mbcnt_lo
720 .param_str = "UiUiUi"
721 .target_set = TargetSet.initOne(.amdgpu)
722 .attributes = .{ .@"const" = true }
723
724__builtin_amdgcn_mqsad_pk_u16_u8
725 .param_str = "WUiWUiUiWUi"
726 .target_set = TargetSet.initOne(.amdgpu)
727 .attributes = .{ .@"const" = true }
728
729__builtin_amdgcn_mqsad_u32_u8
730 .param_str = "V4UiWUiUiV4Ui"
731 .target_set = TargetSet.initOne(.amdgpu)
732 .attributes = .{ .@"const" = true }
733
734__builtin_amdgcn_msad_u8
735 .param_str = "UiUiUiUi"
736 .target_set = TargetSet.initOne(.amdgpu)
737 .attributes = .{ .@"const" = true }
738
739__builtin_amdgcn_qsad_pk_u16_u8
740 .param_str = "WUiWUiUiWUi"
741 .target_set = TargetSet.initOne(.amdgpu)
742 .attributes = .{ .@"const" = true }
743
744__builtin_amdgcn_queue_ptr
745 .param_str = "v*4"
746 .target_set = TargetSet.initOne(.amdgpu)
747 .attributes = .{ .@"const" = true }
748
749__builtin_amdgcn_rcp
750 .param_str = "dd"
751 .target_set = TargetSet.initOne(.amdgpu)
752 .attributes = .{ .@"const" = true }
753
754__builtin_amdgcn_rcpf
755 .param_str = "ff"
756 .target_set = TargetSet.initOne(.amdgpu)
757 .attributes = .{ .@"const" = true }
758
759__builtin_amdgcn_read_exec
760 .param_str = "WUi"
761 .target_set = TargetSet.initOne(.amdgpu)
762 .attributes = .{ .@"const" = true }
763
764__builtin_amdgcn_read_exec_hi
765 .param_str = "Ui"
766 .target_set = TargetSet.initOne(.amdgpu)
767 .attributes = .{ .@"const" = true }
768
769__builtin_amdgcn_read_exec_lo
770 .param_str = "Ui"
771 .target_set = TargetSet.initOne(.amdgpu)
772 .attributes = .{ .@"const" = true }
773
774__builtin_amdgcn_readfirstlane
775 .param_str = "ii"
776 .target_set = TargetSet.initOne(.amdgpu)
777 .attributes = .{ .@"const" = true }
778
779__builtin_amdgcn_readlane
780 .param_str = "iii"
781 .target_set = TargetSet.initOne(.amdgpu)
782 .attributes = .{ .@"const" = true }
783
784__builtin_amdgcn_rsq
785 .param_str = "dd"
786 .target_set = TargetSet.initOne(.amdgpu)
787 .attributes = .{ .@"const" = true }
788
789__builtin_amdgcn_rsq_clamp
790 .param_str = "dd"
791 .target_set = TargetSet.initOne(.amdgpu)
792 .attributes = .{ .@"const" = true }
793
794__builtin_amdgcn_rsq_clampf
795 .param_str = "ff"
796 .target_set = TargetSet.initOne(.amdgpu)
797 .attributes = .{ .@"const" = true }
798
799__builtin_amdgcn_rsqf
800 .param_str = "ff"
801 .target_set = TargetSet.initOne(.amdgpu)
802 .attributes = .{ .@"const" = true }
803
804__builtin_amdgcn_s_barrier
805 .param_str = "v"
806 .target_set = TargetSet.initOne(.amdgpu)
807
808__builtin_amdgcn_s_dcache_inv
809 .param_str = "v"
810 .target_set = TargetSet.initOne(.amdgpu)
811
812__builtin_amdgcn_s_decperflevel
813 .param_str = "vIi"
814 .target_set = TargetSet.initOne(.amdgpu)
815
816__builtin_amdgcn_s_getpc
817 .param_str = "WUi"
818 .target_set = TargetSet.initOne(.amdgpu)
819
820__builtin_amdgcn_s_getreg
821 .param_str = "UiIi"
822 .target_set = TargetSet.initOne(.amdgpu)
823
824__builtin_amdgcn_s_incperflevel
825 .param_str = "vIi"
826 .target_set = TargetSet.initOne(.amdgpu)
827
828__builtin_amdgcn_s_sendmsg
829 .param_str = "vIiUi"
830 .target_set = TargetSet.initOne(.amdgpu)
831
832__builtin_amdgcn_s_sendmsghalt
833 .param_str = "vIiUi"
834 .target_set = TargetSet.initOne(.amdgpu)
835
836__builtin_amdgcn_s_setprio
837 .param_str = "vIs"
838 .target_set = TargetSet.initOne(.amdgpu)
839
840__builtin_amdgcn_s_setreg
841 .param_str = "vIiUi"
842 .target_set = TargetSet.initOne(.amdgpu)
843
844__builtin_amdgcn_s_sleep
845 .param_str = "vIi"
846 .target_set = TargetSet.initOne(.amdgpu)
847
848__builtin_amdgcn_s_waitcnt
849 .param_str = "vIi"
850 .target_set = TargetSet.initOne(.amdgpu)
851
852__builtin_amdgcn_sad_hi_u8
853 .param_str = "UiUiUiUi"
854 .target_set = TargetSet.initOne(.amdgpu)
855 .attributes = .{ .@"const" = true }
856
857__builtin_amdgcn_sad_u16
858 .param_str = "UiUiUiUi"
859 .target_set = TargetSet.initOne(.amdgpu)
860 .attributes = .{ .@"const" = true }
861
862__builtin_amdgcn_sad_u8
863 .param_str = "UiUiUiUi"
864 .target_set = TargetSet.initOne(.amdgpu)
865 .attributes = .{ .@"const" = true }
866
867__builtin_amdgcn_sbfe
868 .param_str = "UiUiUiUi"
869 .target_set = TargetSet.initOne(.amdgpu)
870 .attributes = .{ .@"const" = true }
871
872__builtin_amdgcn_sched_barrier
873 .param_str = "vIi"
874 .target_set = TargetSet.initOne(.amdgpu)
875
876__builtin_amdgcn_sched_group_barrier
877 .param_str = "vIiIiIi"
878 .target_set = TargetSet.initOne(.amdgpu)
879
880__builtin_amdgcn_sicmp
881 .param_str = "WUiiiIi"
882 .target_set = TargetSet.initOne(.amdgpu)
883 .attributes = .{ .@"const" = true }
884
885__builtin_amdgcn_sicmpl
886 .param_str = "WUiWiWiIi"
887 .target_set = TargetSet.initOne(.amdgpu)
888 .attributes = .{ .@"const" = true }
889
890__builtin_amdgcn_sinf
891 .param_str = "ff"
892 .target_set = TargetSet.initOne(.amdgpu)
893 .attributes = .{ .@"const" = true }
894
895__builtin_amdgcn_sqrt
896 .param_str = "dd"
897 .target_set = TargetSet.initOne(.amdgpu)
898 .attributes = .{ .@"const" = true }
899
900__builtin_amdgcn_sqrtf
901 .param_str = "ff"
902 .target_set = TargetSet.initOne(.amdgpu)
903 .attributes = .{ .@"const" = true }
904
905__builtin_amdgcn_trig_preop
906 .param_str = "ddi"
907 .target_set = TargetSet.initOne(.amdgpu)
908 .attributes = .{ .@"const" = true }
909
910__builtin_amdgcn_trig_preopf
911 .param_str = "ffi"
912 .target_set = TargetSet.initOne(.amdgpu)
913 .attributes = .{ .@"const" = true }
914
915__builtin_amdgcn_ubfe
916 .param_str = "UiUiUiUi"
917 .target_set = TargetSet.initOne(.amdgpu)
918 .attributes = .{ .@"const" = true }
919
920__builtin_amdgcn_uicmp
921 .param_str = "WUiUiUiIi"
922 .target_set = TargetSet.initOne(.amdgpu)
923 .attributes = .{ .@"const" = true }
924
925__builtin_amdgcn_uicmpl
926 .param_str = "WUiWUiWUiIi"
927 .target_set = TargetSet.initOne(.amdgpu)
928 .attributes = .{ .@"const" = true }
929
930__builtin_amdgcn_wave_barrier
931 .param_str = "v"
932 .target_set = TargetSet.initOne(.amdgpu)
933
934__builtin_amdgcn_workgroup_id_x
935 .param_str = "Ui"
936 .target_set = TargetSet.initOne(.amdgpu)
937 .attributes = .{ .@"const" = true }
938
939__builtin_amdgcn_workgroup_id_y
940 .param_str = "Ui"
941 .target_set = TargetSet.initOne(.amdgpu)
942 .attributes = .{ .@"const" = true }
943
944__builtin_amdgcn_workgroup_id_z
945 .param_str = "Ui"
946 .target_set = TargetSet.initOne(.amdgpu)
947 .attributes = .{ .@"const" = true }
948
949__builtin_amdgcn_workgroup_size_x
950 .param_str = "Us"
951 .target_set = TargetSet.initOne(.amdgpu)
952 .attributes = .{ .@"const" = true }
953
954__builtin_amdgcn_workgroup_size_y
955 .param_str = "Us"
956 .target_set = TargetSet.initOne(.amdgpu)
957 .attributes = .{ .@"const" = true }
958
959__builtin_amdgcn_workgroup_size_z
960 .param_str = "Us"
961 .target_set = TargetSet.initOne(.amdgpu)
962 .attributes = .{ .@"const" = true }
963
964__builtin_amdgcn_workitem_id_x
965 .param_str = "Ui"
966 .target_set = TargetSet.initOne(.amdgpu)
967 .attributes = .{ .@"const" = true }
968
969__builtin_amdgcn_workitem_id_y
970 .param_str = "Ui"
971 .target_set = TargetSet.initOne(.amdgpu)
972 .attributes = .{ .@"const" = true }
973
974__builtin_amdgcn_workitem_id_z
975 .param_str = "Ui"
976 .target_set = TargetSet.initOne(.amdgpu)
977 .attributes = .{ .@"const" = true }
978
979__builtin_annotation
980 .param_str = "v."
981 .attributes = .{ .custom_typecheck = true }
982
983__builtin_arm_cdp
984 .param_str = "vUIiUIiUIiUIiUIiUIi"
985 .target_set = TargetSet.initOne(.arm)
986
987__builtin_arm_cdp2
988 .param_str = "vUIiUIiUIiUIiUIiUIi"
989 .target_set = TargetSet.initOne(.arm)
990
991__builtin_arm_clrex
992 .param_str = "v"
993 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
994
995__builtin_arm_cls
996 .param_str = "UiZUi"
997 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
998 .attributes = .{ .@"const" = true }
999
1000__builtin_arm_cls64
1001 .param_str = "UiWUi"
1002 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1003 .attributes = .{ .@"const" = true }
1004
1005__builtin_arm_clz
1006 .param_str = "UiZUi"
1007 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1008 .attributes = .{ .@"const" = true }
1009
1010__builtin_arm_clz64
1011 .param_str = "UiWUi"
1012 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1013 .attributes = .{ .@"const" = true }
1014
1015__builtin_arm_cmse_TT
1016 .param_str = "Uiv*"
1017 .target_set = TargetSet.initOne(.arm)
1018
1019__builtin_arm_cmse_TTA
1020 .param_str = "Uiv*"
1021 .target_set = TargetSet.initOne(.arm)
1022
1023__builtin_arm_cmse_TTAT
1024 .param_str = "Uiv*"
1025 .target_set = TargetSet.initOne(.arm)
1026
1027__builtin_arm_cmse_TTT
1028 .param_str = "Uiv*"
1029 .target_set = TargetSet.initOne(.arm)
1030
1031__builtin_arm_dbg
1032 .param_str = "vUi"
1033 .target_set = TargetSet.initOne(.arm)
1034
1035__builtin_arm_dmb
1036 .param_str = "vUi"
1037 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1038 .attributes = .{ .@"const" = true }
1039
1040__builtin_arm_dsb
1041 .param_str = "vUi"
1042 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1043 .attributes = .{ .@"const" = true }
1044
1045__builtin_arm_get_fpscr
1046 .param_str = "Ui"
1047 .target_set = TargetSet.initOne(.arm)
1048 .attributes = .{ .@"const" = true }
1049
1050__builtin_arm_isb
1051 .param_str = "vUi"
1052 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1053 .attributes = .{ .@"const" = true }
1054
1055__builtin_arm_ldaex
1056 .param_str = "v."
1057 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1058 .attributes = .{ .custom_typecheck = true }
1059
1060__builtin_arm_ldc
1061 .param_str = "vUIiUIivC*"
1062 .target_set = TargetSet.initOne(.arm)
1063
1064__builtin_arm_ldc2
1065 .param_str = "vUIiUIivC*"
1066 .target_set = TargetSet.initOne(.arm)
1067
1068__builtin_arm_ldc2l
1069 .param_str = "vUIiUIivC*"
1070 .target_set = TargetSet.initOne(.arm)
1071
1072__builtin_arm_ldcl
1073 .param_str = "vUIiUIivC*"
1074 .target_set = TargetSet.initOne(.arm)
1075
1076__builtin_arm_ldrex
1077 .param_str = "v."
1078 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1079 .attributes = .{ .custom_typecheck = true }
1080
1081__builtin_arm_ldrexd
1082 .param_str = "LLUiv*"
1083 .target_set = TargetSet.initOne(.arm)
1084
1085__builtin_arm_mcr
1086 .param_str = "vUIiUIiUiUIiUIiUIi"
1087 .target_set = TargetSet.initOne(.arm)
1088
1089__builtin_arm_mcr2
1090 .param_str = "vUIiUIiUiUIiUIiUIi"
1091 .target_set = TargetSet.initOne(.arm)
1092
1093__builtin_arm_mcrr
1094 .param_str = "vUIiUIiLLUiUIi"
1095 .target_set = TargetSet.initOne(.arm)
1096
1097__builtin_arm_mcrr2
1098 .param_str = "vUIiUIiLLUiUIi"
1099 .target_set = TargetSet.initOne(.arm)
1100
1101__builtin_arm_mrc
1102 .param_str = "UiUIiUIiUIiUIiUIi"
1103 .target_set = TargetSet.initOne(.arm)
1104
1105__builtin_arm_mrc2
1106 .param_str = "UiUIiUIiUIiUIiUIi"
1107 .target_set = TargetSet.initOne(.arm)
1108
1109__builtin_arm_mrrc
1110 .param_str = "LLUiUIiUIiUIi"
1111 .target_set = TargetSet.initOne(.arm)
1112
1113__builtin_arm_mrrc2
1114 .param_str = "LLUiUIiUIiUIi"
1115 .target_set = TargetSet.initOne(.arm)
1116
1117__builtin_arm_nop
1118 .param_str = "v"
1119 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1120
1121__builtin_arm_prefetch
1122 .param_str = "!"
1123 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1124 .attributes = .{ .@"const" = true }
1125
1126__builtin_arm_qadd
1127 .param_str = "iii"
1128 .target_set = TargetSet.initOne(.arm)
1129 .attributes = .{ .@"const" = true }
1130
1131__builtin_arm_qadd16
1132 .param_str = "iii"
1133 .target_set = TargetSet.initOne(.arm)
1134 .attributes = .{ .@"const" = true }
1135
1136__builtin_arm_qadd8
1137 .param_str = "iii"
1138 .target_set = TargetSet.initOne(.arm)
1139 .attributes = .{ .@"const" = true }
1140
1141__builtin_arm_qasx
1142 .param_str = "iii"
1143 .target_set = TargetSet.initOne(.arm)
1144 .attributes = .{ .@"const" = true }
1145
1146__builtin_arm_qdbl
1147 .param_str = "ii"
1148 .target_set = TargetSet.initOne(.arm)
1149 .attributes = .{ .@"const" = true }
1150
1151__builtin_arm_qsax
1152 .param_str = "iii"
1153 .target_set = TargetSet.initOne(.arm)
1154 .attributes = .{ .@"const" = true }
1155
1156__builtin_arm_qsub
1157 .param_str = "iii"
1158 .target_set = TargetSet.initOne(.arm)
1159 .attributes = .{ .@"const" = true }
1160
1161__builtin_arm_qsub16
1162 .param_str = "iii"
1163 .target_set = TargetSet.initOne(.arm)
1164 .attributes = .{ .@"const" = true }
1165
1166__builtin_arm_qsub8
1167 .param_str = "iii"
1168 .target_set = TargetSet.initOne(.arm)
1169 .attributes = .{ .@"const" = true }
1170
1171__builtin_arm_rbit
1172 .param_str = "UiUi"
1173 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1174 .attributes = .{ .@"const" = true }
1175
1176__builtin_arm_rbit64
1177 .param_str = "WUiWUi"
1178 .target_set = TargetSet.initOne(.aarch64)
1179 .attributes = .{ .@"const" = true }
1180
1181__builtin_arm_rsr
1182 .param_str = "UicC*"
1183 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1184 .attributes = .{ .@"const" = true }
1185
1186__builtin_arm_rsr64
1187 .param_str = "!"
1188 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1189 .attributes = .{ .@"const" = true }
1190
1191__builtin_arm_rsrp
1192 .param_str = "v*cC*"
1193 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1194 .attributes = .{ .@"const" = true }
1195
1196__builtin_arm_sadd16
1197 .param_str = "iii"
1198 .target_set = TargetSet.initOne(.arm)
1199 .attributes = .{ .@"const" = true }
1200
1201__builtin_arm_sadd8
1202 .param_str = "iii"
1203 .target_set = TargetSet.initOne(.arm)
1204 .attributes = .{ .@"const" = true }
1205
1206__builtin_arm_sasx
1207 .param_str = "iii"
1208 .target_set = TargetSet.initOne(.arm)
1209 .attributes = .{ .@"const" = true }
1210
1211__builtin_arm_sel
1212 .param_str = "iii"
1213 .target_set = TargetSet.initOne(.arm)
1214 .attributes = .{ .@"const" = true }
1215
1216__builtin_arm_set_fpscr
1217 .param_str = "vUi"
1218 .target_set = TargetSet.initOne(.arm)
1219 .attributes = .{ .@"const" = true }
1220
1221__builtin_arm_sev
1222 .param_str = "v"
1223 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1224
1225__builtin_arm_sevl
1226 .param_str = "v"
1227 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1228
1229__builtin_arm_shadd16
1230 .param_str = "iii"
1231 .target_set = TargetSet.initOne(.arm)
1232 .attributes = .{ .@"const" = true }
1233
1234__builtin_arm_shadd8
1235 .param_str = "iii"
1236 .target_set = TargetSet.initOne(.arm)
1237 .attributes = .{ .@"const" = true }
1238
1239__builtin_arm_shasx
1240 .param_str = "iii"
1241 .target_set = TargetSet.initOne(.arm)
1242 .attributes = .{ .@"const" = true }
1243
1244__builtin_arm_shsax
1245 .param_str = "iii"
1246 .target_set = TargetSet.initOne(.arm)
1247 .attributes = .{ .@"const" = true }
1248
1249__builtin_arm_shsub16
1250 .param_str = "iii"
1251 .target_set = TargetSet.initOne(.arm)
1252 .attributes = .{ .@"const" = true }
1253
1254__builtin_arm_shsub8
1255 .param_str = "iii"
1256 .target_set = TargetSet.initOne(.arm)
1257 .attributes = .{ .@"const" = true }
1258
1259__builtin_arm_smlabb
1260 .param_str = "iiii"
1261 .target_set = TargetSet.initOne(.arm)
1262 .attributes = .{ .@"const" = true }
1263
1264__builtin_arm_smlabt
1265 .param_str = "iiii"
1266 .target_set = TargetSet.initOne(.arm)
1267 .attributes = .{ .@"const" = true }
1268
1269__builtin_arm_smlad
1270 .param_str = "iiii"
1271 .target_set = TargetSet.initOne(.arm)
1272 .attributes = .{ .@"const" = true }
1273
1274__builtin_arm_smladx
1275 .param_str = "iiii"
1276 .target_set = TargetSet.initOne(.arm)
1277 .attributes = .{ .@"const" = true }
1278
1279__builtin_arm_smlald
1280 .param_str = "LLiiiLLi"
1281 .target_set = TargetSet.initOne(.arm)
1282 .attributes = .{ .@"const" = true }
1283
1284__builtin_arm_smlaldx
1285 .param_str = "LLiiiLLi"
1286 .target_set = TargetSet.initOne(.arm)
1287 .attributes = .{ .@"const" = true }
1288
1289__builtin_arm_smlatb
1290 .param_str = "iiii"
1291 .target_set = TargetSet.initOne(.arm)
1292 .attributes = .{ .@"const" = true }
1293
1294__builtin_arm_smlatt
1295 .param_str = "iiii"
1296 .target_set = TargetSet.initOne(.arm)
1297 .attributes = .{ .@"const" = true }
1298
1299__builtin_arm_smlawb
1300 .param_str = "iiii"
1301 .target_set = TargetSet.initOne(.arm)
1302 .attributes = .{ .@"const" = true }
1303
1304__builtin_arm_smlawt
1305 .param_str = "iiii"
1306 .target_set = TargetSet.initOne(.arm)
1307 .attributes = .{ .@"const" = true }
1308
1309__builtin_arm_smlsd
1310 .param_str = "iiii"
1311 .target_set = TargetSet.initOne(.arm)
1312 .attributes = .{ .@"const" = true }
1313
1314__builtin_arm_smlsdx
1315 .param_str = "iiii"
1316 .target_set = TargetSet.initOne(.arm)
1317 .attributes = .{ .@"const" = true }
1318
1319__builtin_arm_smlsld
1320 .param_str = "LLiiiLLi"
1321 .target_set = TargetSet.initOne(.arm)
1322 .attributes = .{ .@"const" = true }
1323
1324__builtin_arm_smlsldx
1325 .param_str = "LLiiiLLi"
1326 .target_set = TargetSet.initOne(.arm)
1327 .attributes = .{ .@"const" = true }
1328
1329__builtin_arm_smuad
1330 .param_str = "iii"
1331 .target_set = TargetSet.initOne(.arm)
1332 .attributes = .{ .@"const" = true }
1333
1334__builtin_arm_smuadx
1335 .param_str = "iii"
1336 .target_set = TargetSet.initOne(.arm)
1337 .attributes = .{ .@"const" = true }
1338
1339__builtin_arm_smulbb
1340 .param_str = "iii"
1341 .target_set = TargetSet.initOne(.arm)
1342 .attributes = .{ .@"const" = true }
1343
1344__builtin_arm_smulbt
1345 .param_str = "iii"
1346 .target_set = TargetSet.initOne(.arm)
1347 .attributes = .{ .@"const" = true }
1348
1349__builtin_arm_smultb
1350 .param_str = "iii"
1351 .target_set = TargetSet.initOne(.arm)
1352 .attributes = .{ .@"const" = true }
1353
1354__builtin_arm_smultt
1355 .param_str = "iii"
1356 .target_set = TargetSet.initOne(.arm)
1357 .attributes = .{ .@"const" = true }
1358
1359__builtin_arm_smulwb
1360 .param_str = "iii"
1361 .target_set = TargetSet.initOne(.arm)
1362 .attributes = .{ .@"const" = true }
1363
1364__builtin_arm_smulwt
1365 .param_str = "iii"
1366 .target_set = TargetSet.initOne(.arm)
1367 .attributes = .{ .@"const" = true }
1368
1369__builtin_arm_smusd
1370 .param_str = "iii"
1371 .target_set = TargetSet.initOne(.arm)
1372 .attributes = .{ .@"const" = true }
1373
1374__builtin_arm_smusdx
1375 .param_str = "iii"
1376 .target_set = TargetSet.initOne(.arm)
1377 .attributes = .{ .@"const" = true }
1378
1379__builtin_arm_ssat
1380 .param_str = "iiUi"
1381 .target_set = TargetSet.initOne(.arm)
1382 .attributes = .{ .@"const" = true }
1383
1384__builtin_arm_ssat16
1385 .param_str = "iii"
1386 .target_set = TargetSet.initOne(.arm)
1387 .attributes = .{ .@"const" = true }
1388
1389__builtin_arm_ssax
1390 .param_str = "iii"
1391 .target_set = TargetSet.initOne(.arm)
1392 .attributes = .{ .@"const" = true }
1393
1394__builtin_arm_ssub16
1395 .param_str = "iii"
1396 .target_set = TargetSet.initOne(.arm)
1397 .attributes = .{ .@"const" = true }
1398
1399__builtin_arm_ssub8
1400 .param_str = "iii"
1401 .target_set = TargetSet.initOne(.arm)
1402 .attributes = .{ .@"const" = true }
1403
1404__builtin_arm_stc
1405 .param_str = "vUIiUIiv*"
1406 .target_set = TargetSet.initOne(.arm)
1407
1408__builtin_arm_stc2
1409 .param_str = "vUIiUIiv*"
1410 .target_set = TargetSet.initOne(.arm)
1411
1412__builtin_arm_stc2l
1413 .param_str = "vUIiUIiv*"
1414 .target_set = TargetSet.initOne(.arm)
1415
1416__builtin_arm_stcl
1417 .param_str = "vUIiUIiv*"
1418 .target_set = TargetSet.initOne(.arm)
1419
1420__builtin_arm_stlex
1421 .param_str = "i."
1422 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1423 .attributes = .{ .custom_typecheck = true }
1424
1425__builtin_arm_strex
1426 .param_str = "i."
1427 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1428 .attributes = .{ .custom_typecheck = true }
1429
1430__builtin_arm_strexd
1431 .param_str = "iLLUiv*"
1432 .target_set = TargetSet.initOne(.arm)
1433
1434__builtin_arm_sxtab16
1435 .param_str = "iii"
1436 .target_set = TargetSet.initOne(.arm)
1437 .attributes = .{ .@"const" = true }
1438
1439__builtin_arm_sxtb16
1440 .param_str = "ii"
1441 .target_set = TargetSet.initOne(.arm)
1442 .attributes = .{ .@"const" = true }
1443
1444__builtin_arm_tcancel
1445 .param_str = "vWUIi"
1446 .target_set = TargetSet.initOne(.aarch64)
1447
1448__builtin_arm_tcommit
1449 .param_str = "v"
1450 .target_set = TargetSet.initOne(.aarch64)
1451
1452__builtin_arm_tstart
1453 .param_str = "WUi"
1454 .target_set = TargetSet.initOne(.aarch64)
1455 .attributes = .{ .returns_twice = true }
1456
1457__builtin_arm_ttest
1458 .param_str = "WUi"
1459 .target_set = TargetSet.initOne(.aarch64)
1460 .attributes = .{ .@"const" = true }
1461
1462__builtin_arm_uadd16
1463 .param_str = "UiUiUi"
1464 .target_set = TargetSet.initOne(.arm)
1465 .attributes = .{ .@"const" = true }
1466
1467__builtin_arm_uadd8
1468 .param_str = "UiUiUi"
1469 .target_set = TargetSet.initOne(.arm)
1470 .attributes = .{ .@"const" = true }
1471
1472__builtin_arm_uasx
1473 .param_str = "UiUiUi"
1474 .target_set = TargetSet.initOne(.arm)
1475 .attributes = .{ .@"const" = true }
1476
1477__builtin_arm_uhadd16
1478 .param_str = "UiUiUi"
1479 .target_set = TargetSet.initOne(.arm)
1480 .attributes = .{ .@"const" = true }
1481
1482__builtin_arm_uhadd8
1483 .param_str = "UiUiUi"
1484 .target_set = TargetSet.initOne(.arm)
1485 .attributes = .{ .@"const" = true }
1486
1487__builtin_arm_uhasx
1488 .param_str = "UiUiUi"
1489 .target_set = TargetSet.initOne(.arm)
1490 .attributes = .{ .@"const" = true }
1491
1492__builtin_arm_uhsax
1493 .param_str = "UiUiUi"
1494 .target_set = TargetSet.initOne(.arm)
1495 .attributes = .{ .@"const" = true }
1496
1497__builtin_arm_uhsub16
1498 .param_str = "UiUiUi"
1499 .target_set = TargetSet.initOne(.arm)
1500 .attributes = .{ .@"const" = true }
1501
1502__builtin_arm_uhsub8
1503 .param_str = "UiUiUi"
1504 .target_set = TargetSet.initOne(.arm)
1505 .attributes = .{ .@"const" = true }
1506
1507__builtin_arm_uqadd16
1508 .param_str = "UiUiUi"
1509 .target_set = TargetSet.initOne(.arm)
1510 .attributes = .{ .@"const" = true }
1511
1512__builtin_arm_uqadd8
1513 .param_str = "UiUiUi"
1514 .target_set = TargetSet.initOne(.arm)
1515 .attributes = .{ .@"const" = true }
1516
1517__builtin_arm_uqasx
1518 .param_str = "UiUiUi"
1519 .target_set = TargetSet.initOne(.arm)
1520 .attributes = .{ .@"const" = true }
1521
1522__builtin_arm_uqsax
1523 .param_str = "UiUiUi"
1524 .target_set = TargetSet.initOne(.arm)
1525 .attributes = .{ .@"const" = true }
1526
1527__builtin_arm_uqsub16
1528 .param_str = "UiUiUi"
1529 .target_set = TargetSet.initOne(.arm)
1530 .attributes = .{ .@"const" = true }
1531
1532__builtin_arm_uqsub8
1533 .param_str = "UiUiUi"
1534 .target_set = TargetSet.initOne(.arm)
1535 .attributes = .{ .@"const" = true }
1536
1537__builtin_arm_usad8
1538 .param_str = "UiUiUi"
1539 .target_set = TargetSet.initOne(.arm)
1540 .attributes = .{ .@"const" = true }
1541
1542__builtin_arm_usada8
1543 .param_str = "UiUiUiUi"
1544 .target_set = TargetSet.initOne(.arm)
1545 .attributes = .{ .@"const" = true }
1546
1547__builtin_arm_usat
1548 .param_str = "UiiUi"
1549 .target_set = TargetSet.initOne(.arm)
1550 .attributes = .{ .@"const" = true }
1551
1552__builtin_arm_usat16
1553 .param_str = "iii"
1554 .target_set = TargetSet.initOne(.arm)
1555 .attributes = .{ .@"const" = true }
1556
1557__builtin_arm_usax
1558 .param_str = "UiUiUi"
1559 .target_set = TargetSet.initOne(.arm)
1560 .attributes = .{ .@"const" = true }
1561
1562__builtin_arm_usub16
1563 .param_str = "UiUiUi"
1564 .target_set = TargetSet.initOne(.arm)
1565 .attributes = .{ .@"const" = true }
1566
1567__builtin_arm_usub8
1568 .param_str = "UiUiUi"
1569 .target_set = TargetSet.initOne(.arm)
1570 .attributes = .{ .@"const" = true }
1571
1572__builtin_arm_uxtab16
1573 .param_str = "iii"
1574 .target_set = TargetSet.initOne(.arm)
1575 .attributes = .{ .@"const" = true }
1576
1577__builtin_arm_uxtb16
1578 .param_str = "ii"
1579 .target_set = TargetSet.initOne(.arm)
1580 .attributes = .{ .@"const" = true }
1581
1582__builtin_arm_vcvtr_d
1583 .param_str = "fdi"
1584 .target_set = TargetSet.initOne(.arm)
1585 .attributes = .{ .@"const" = true }
1586
1587__builtin_arm_vcvtr_f
1588 .param_str = "ffi"
1589 .target_set = TargetSet.initOne(.arm)
1590 .attributes = .{ .@"const" = true }
1591
1592__builtin_arm_wfe
1593 .param_str = "v"
1594 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1595
1596__builtin_arm_wfi
1597 .param_str = "v"
1598 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1599
1600__builtin_arm_wsr
1601 .param_str = "vcC*Ui"
1602 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1603 .attributes = .{ .@"const" = true }
1604
1605__builtin_arm_wsr64
1606 .param_str = "!"
1607 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1608 .attributes = .{ .@"const" = true }
1609
1610__builtin_arm_wsrp
1611 .param_str = "vcC*vC*"
1612 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1613 .attributes = .{ .@"const" = true }
1614
1615__builtin_arm_yield
1616 .param_str = "v"
1617 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
1618
1619__builtin_asin
1620 .param_str = "dd"
1621 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1622
1623__builtin_asinf
1624 .param_str = "ff"
1625 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1626
1627__builtin_asinf128
1628 .param_str = "LLdLLd"
1629 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1630
1631__builtin_asinh
1632 .param_str = "dd"
1633 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1634
1635__builtin_asinhf
1636 .param_str = "ff"
1637 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1638
1639__builtin_asinhf128
1640 .param_str = "LLdLLd"
1641 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1642
1643__builtin_asinhl
1644 .param_str = "LdLd"
1645 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1646
1647__builtin_asinl
1648 .param_str = "LdLd"
1649 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1650
1651__builtin_assume
1652 .param_str = "vb"
1653 .attributes = .{ .const_evaluable = true }
1654
1655__builtin_assume_aligned
1656 .param_str = "v*vC*z."
1657 .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true }
1658
1659__builtin_assume_separate_storage
1660 .param_str = "vvCD*vCD*"
1661 .attributes = .{ .const_evaluable = true }
1662
1663__builtin_atan
1664 .param_str = "dd"
1665 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1666
1667__builtin_atan2
1668 .param_str = "ddd"
1669 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1670
1671__builtin_atan2f
1672 .param_str = "fff"
1673 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1674
1675__builtin_atan2f128
1676 .param_str = "LLdLLdLLd"
1677 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1678
1679__builtin_atan2l
1680 .param_str = "LdLdLd"
1681 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1682
1683__builtin_atanf
1684 .param_str = "ff"
1685 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1686
1687__builtin_atanf128
1688 .param_str = "LLdLLd"
1689 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1690
1691__builtin_atanh
1692 .param_str = "dd"
1693 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1694
1695__builtin_atanhf
1696 .param_str = "ff"
1697 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1698
1699__builtin_atanhf128
1700 .param_str = "LLdLLd"
1701 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1702
1703__builtin_atanhl
1704 .param_str = "LdLd"
1705 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1706
1707__builtin_atanl
1708 .param_str = "LdLd"
1709 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1710
1711__builtin_bcmp
1712 .param_str = "ivC*vC*z"
1713 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
1714
1715__builtin_bcopy
1716 .param_str = "vvC*v*z"
1717 .attributes = .{ .lib_function_with_builtin_prefix = true }
1718
1719__builtin_bitrev
1720 .param_str = "UiUi"
1721 .target_set = TargetSet.initOne(.xcore)
1722 .attributes = .{ .@"const" = true }
1723
1724__builtin_bitreverse16
1725 .param_str = "UsUs"
1726 .attributes = .{ .@"const" = true, .const_evaluable = true }
1727
1728__builtin_bitreverse32
1729 .param_str = "UZiUZi"
1730 .attributes = .{ .@"const" = true, .const_evaluable = true }
1731
1732__builtin_bitreverse64
1733 .param_str = "UWiUWi"
1734 .attributes = .{ .@"const" = true, .const_evaluable = true }
1735
1736__builtin_bitreverse8
1737 .param_str = "UcUc"
1738 .attributes = .{ .@"const" = true, .const_evaluable = true }
1739
1740__builtin_bswap16
1741 .param_str = "UsUs"
1742 .attributes = .{ .@"const" = true, .const_evaluable = true }
1743
1744__builtin_bswap32
1745 .param_str = "UZiUZi"
1746 .attributes = .{ .@"const" = true, .const_evaluable = true }
1747
1748__builtin_bswap64
1749 .param_str = "UWiUWi"
1750 .attributes = .{ .@"const" = true, .const_evaluable = true }
1751
1752__builtin_bzero
1753 .param_str = "vv*z"
1754 .attributes = .{ .lib_function_with_builtin_prefix = true }
1755
1756__builtin_cabs
1757 .param_str = "dXd"
1758 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1759
1760__builtin_cabsf
1761 .param_str = "fXf"
1762 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1763
1764__builtin_cabsl
1765 .param_str = "LdXLd"
1766 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1767
1768__builtin_cacos
1769 .param_str = "XdXd"
1770 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1771
1772__builtin_cacosf
1773 .param_str = "XfXf"
1774 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1775
1776__builtin_cacosh
1777 .param_str = "XdXd"
1778 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1779
1780__builtin_cacoshf
1781 .param_str = "XfXf"
1782 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1783
1784__builtin_cacoshl
1785 .param_str = "XLdXLd"
1786 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1787
1788__builtin_cacosl
1789 .param_str = "XLdXLd"
1790 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1791
1792__builtin_call_with_static_chain
1793 .param_str = "v."
1794 .attributes = .{ .custom_typecheck = true }
1795
1796__builtin_calloc
1797 .param_str = "v*zz"
1798 .attributes = .{ .lib_function_with_builtin_prefix = true }
1799
1800__builtin_canonicalize
1801 .param_str = "dd"
1802 .attributes = .{ .@"const" = true }
1803
1804__builtin_canonicalizef
1805 .param_str = "ff"
1806 .attributes = .{ .@"const" = true }
1807
1808__builtin_canonicalizef16
1809 .param_str = "hh"
1810 .attributes = .{ .@"const" = true }
1811
1812__builtin_canonicalizel
1813 .param_str = "LdLd"
1814 .attributes = .{ .@"const" = true }
1815
1816__builtin_carg
1817 .param_str = "dXd"
1818 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1819
1820__builtin_cargf
1821 .param_str = "fXf"
1822 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1823
1824__builtin_cargl
1825 .param_str = "LdXLd"
1826 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1827
1828__builtin_casin
1829 .param_str = "XdXd"
1830 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1831
1832__builtin_casinf
1833 .param_str = "XfXf"
1834 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1835
1836__builtin_casinh
1837 .param_str = "XdXd"
1838 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1839
1840__builtin_casinhf
1841 .param_str = "XfXf"
1842 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1843
1844__builtin_casinhl
1845 .param_str = "XLdXLd"
1846 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1847
1848__builtin_casinl
1849 .param_str = "XLdXLd"
1850 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1851
1852__builtin_catan
1853 .param_str = "XdXd"
1854 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1855
1856__builtin_catanf
1857 .param_str = "XfXf"
1858 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1859
1860__builtin_catanh
1861 .param_str = "XdXd"
1862 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1863
1864__builtin_catanhf
1865 .param_str = "XfXf"
1866 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1867
1868__builtin_catanhl
1869 .param_str = "XLdXLd"
1870 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1871
1872__builtin_catanl
1873 .param_str = "XLdXLd"
1874 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1875
1876__builtin_cbrt
1877 .param_str = "dd"
1878 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1879
1880__builtin_cbrtf
1881 .param_str = "ff"
1882 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1883
1884__builtin_cbrtf128
1885 .param_str = "LLdLLd"
1886 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1887
1888__builtin_cbrtl
1889 .param_str = "LdLd"
1890 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1891
1892__builtin_ccos
1893 .param_str = "XdXd"
1894 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1895
1896__builtin_ccosf
1897 .param_str = "XfXf"
1898 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1899
1900__builtin_ccosh
1901 .param_str = "XdXd"
1902 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1903
1904__builtin_ccoshf
1905 .param_str = "XfXf"
1906 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1907
1908__builtin_ccoshl
1909 .param_str = "XLdXLd"
1910 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1911
1912__builtin_ccosl
1913 .param_str = "XLdXLd"
1914 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1915
1916__builtin_ceil
1917 .param_str = "dd"
1918 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1919
1920__builtin_ceilf
1921 .param_str = "ff"
1922 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1923
1924__builtin_ceilf128
1925 .param_str = "LLdLLd"
1926 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1927
1928__builtin_ceilf16
1929 .param_str = "hh"
1930 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1931
1932__builtin_ceill
1933 .param_str = "LdLd"
1934 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1935
1936__builtin_cexp
1937 .param_str = "XdXd"
1938 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1939
1940__builtin_cexpf
1941 .param_str = "XfXf"
1942 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1943
1944__builtin_cexpl
1945 .param_str = "XLdXLd"
1946 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1947
1948__builtin_char_memchr
1949 .param_str = "c*cC*iz"
1950 .attributes = .{ .const_evaluable = true }
1951
1952__builtin_cimag
1953 .param_str = "dXd"
1954 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1955
1956__builtin_cimagf
1957 .param_str = "fXf"
1958 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1959
1960__builtin_cimagl
1961 .param_str = "LdXLd"
1962 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
1963
1964__builtin_classify_type
1965 .param_str = "i."
1966 .attributes = .{ .@"const" = true, .custom_typecheck = true, .eval_args = false, .const_evaluable = true }
1967
1968__builtin_clog
1969 .param_str = "XdXd"
1970 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1971
1972__builtin_clogf
1973 .param_str = "XfXf"
1974 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1975
1976__builtin_clogl
1977 .param_str = "XLdXLd"
1978 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
1979
1980__builtin_clrsb
1981 .param_str = "ii"
1982 .attributes = .{ .@"const" = true, .const_evaluable = true }
1983
1984__builtin_clrsbl
1985 .param_str = "iLi"
1986 .attributes = .{ .@"const" = true, .const_evaluable = true }
1987
1988__builtin_clrsbll
1989 .param_str = "iLLi"
1990 .attributes = .{ .@"const" = true, .const_evaluable = true }
1991
1992__builtin_clz
1993 .param_str = "iUi"
1994 .attributes = .{ .@"const" = true, .const_evaluable = true }
1995
1996__builtin_clzl
1997 .param_str = "iULi"
1998 .attributes = .{ .@"const" = true, .const_evaluable = true }
1999
2000__builtin_clzll
2001 .param_str = "iULLi"
2002 .attributes = .{ .@"const" = true, .const_evaluable = true }
2003
2004__builtin_clzs
2005 .param_str = "iUs"
2006 .attributes = .{ .@"const" = true, .const_evaluable = true }
2007
2008__builtin_complex
2009 .param_str = "v."
2010 .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true }
2011
2012__builtin_conj
2013 .param_str = "XdXd"
2014 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2015
2016__builtin_conjf
2017 .param_str = "XfXf"
2018 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2019
2020__builtin_conjl
2021 .param_str = "XLdXLd"
2022 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2023
2024__builtin_constant_p
2025 .param_str = "i."
2026 .attributes = .{ .@"const" = true, .custom_typecheck = true, .eval_args = false, .const_evaluable = true }
2027
2028__builtin_convertvector
2029 .param_str = "v."
2030 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2031
2032__builtin_copysign
2033 .param_str = "ddd"
2034 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2035
2036__builtin_copysignf
2037 .param_str = "fff"
2038 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2039
2040__builtin_copysignf128
2041 .param_str = "LLdLLdLLd"
2042 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2043
2044__builtin_copysignf16
2045 .param_str = "hhh"
2046 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2047
2048__builtin_copysignl
2049 .param_str = "LdLdLd"
2050 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2051
2052__builtin_cos
2053 .param_str = "dd"
2054 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2055
2056__builtin_cosf
2057 .param_str = "ff"
2058 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2059
2060__builtin_cosf128
2061 .param_str = "LLdLLd"
2062 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2063
2064__builtin_cosf16
2065 .param_str = "hh"
2066 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2067
2068__builtin_cosh
2069 .param_str = "dd"
2070 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2071
2072__builtin_coshf
2073 .param_str = "ff"
2074 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2075
2076__builtin_coshf128
2077 .param_str = "LLdLLd"
2078 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2079
2080__builtin_coshl
2081 .param_str = "LdLd"
2082 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2083
2084__builtin_cosl
2085 .param_str = "LdLd"
2086 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2087
2088__builtin_cpow
2089 .param_str = "XdXdXd"
2090 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2091
2092__builtin_cpowf
2093 .param_str = "XfXfXf"
2094 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2095
2096__builtin_cpowl
2097 .param_str = "XLdXLdXLd"
2098 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2099
2100__builtin_cproj
2101 .param_str = "XdXd"
2102 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2103
2104__builtin_cprojf
2105 .param_str = "XfXf"
2106 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2107
2108__builtin_cprojl
2109 .param_str = "XLdXLd"
2110 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2111
2112__builtin_cpu_init
2113 .param_str = "v"
2114 .target_set = TargetSet.initOne(.x86)
2115
2116__builtin_cpu_is
2117 .param_str = "bcC*"
2118 .target_set = TargetSet.initOne(.x86)
2119 .attributes = .{ .@"const" = true }
2120
2121__builtin_cpu_supports
2122 .param_str = "bcC*"
2123 .target_set = TargetSet.initOne(.x86)
2124 .attributes = .{ .@"const" = true }
2125
2126__builtin_creal
2127 .param_str = "dXd"
2128 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2129
2130__builtin_crealf
2131 .param_str = "fXf"
2132 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2133
2134__builtin_creall
2135 .param_str = "LdXLd"
2136 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2137
2138__builtin_csin
2139 .param_str = "XdXd"
2140 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2141
2142__builtin_csinf
2143 .param_str = "XfXf"
2144 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2145
2146__builtin_csinh
2147 .param_str = "XdXd"
2148 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2149
2150__builtin_csinhf
2151 .param_str = "XfXf"
2152 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2153
2154__builtin_csinhl
2155 .param_str = "XLdXLd"
2156 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2157
2158__builtin_csinl
2159 .param_str = "XLdXLd"
2160 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2161
2162__builtin_csqrt
2163 .param_str = "XdXd"
2164 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2165
2166__builtin_csqrtf
2167 .param_str = "XfXf"
2168 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2169
2170__builtin_csqrtl
2171 .param_str = "XLdXLd"
2172 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2173
2174__builtin_ctan
2175 .param_str = "XdXd"
2176 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2177
2178__builtin_ctanf
2179 .param_str = "XfXf"
2180 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2181
2182__builtin_ctanh
2183 .param_str = "XdXd"
2184 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2185
2186__builtin_ctanhf
2187 .param_str = "XfXf"
2188 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2189
2190__builtin_ctanhl
2191 .param_str = "XLdXLd"
2192 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2193
2194__builtin_ctanl
2195 .param_str = "XLdXLd"
2196 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2197
2198__builtin_ctz
2199 .param_str = "iUi"
2200 .attributes = .{ .@"const" = true, .const_evaluable = true }
2201
2202__builtin_ctzl
2203 .param_str = "iULi"
2204 .attributes = .{ .@"const" = true, .const_evaluable = true }
2205
2206__builtin_ctzll
2207 .param_str = "iULLi"
2208 .attributes = .{ .@"const" = true, .const_evaluable = true }
2209
2210__builtin_ctzs
2211 .param_str = "iUs"
2212 .attributes = .{ .@"const" = true, .const_evaluable = true }
2213
2214__builtin_dcbf
2215 .param_str = "vvC*"
2216 .target_set = TargetSet.initOne(.ppc)
2217
2218__builtin_debugtrap
2219 .param_str = "v"
2220
2221__builtin_dump_struct
2222 .param_str = "v."
2223 .attributes = .{ .custom_typecheck = true }
2224
2225__builtin_dwarf_cfa
2226 .param_str = "v*"
2227
2228__builtin_dwarf_sp_column
2229 .param_str = "Ui"
2230
2231__builtin_dynamic_object_size
2232 .param_str = "zvC*i"
2233 .attributes = .{ .eval_args = false, .const_evaluable = true }
2234
2235__builtin_eh_return
2236 .param_str = "vzv*"
2237 .attributes = .{ .noreturn = true }
2238
2239__builtin_eh_return_data_regno
2240 .param_str = "iIi"
2241 .attributes = .{ .@"const" = true, .const_evaluable = true }
2242
2243__builtin_elementwise_abs
2244 .param_str = "v."
2245 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2246
2247__builtin_elementwise_add_sat
2248 .param_str = "v."
2249 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2250
2251__builtin_elementwise_bitreverse
2252 .param_str = "v."
2253 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2254
2255__builtin_elementwise_canonicalize
2256 .param_str = "v."
2257 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2258
2259__builtin_elementwise_ceil
2260 .param_str = "v."
2261 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2262
2263__builtin_elementwise_copysign
2264 .param_str = "v."
2265 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2266
2267__builtin_elementwise_cos
2268 .param_str = "v."
2269 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2270
2271__builtin_elementwise_exp
2272 .param_str = "v."
2273 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2274
2275__builtin_elementwise_exp2
2276 .param_str = "v."
2277 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2278
2279__builtin_elementwise_floor
2280 .param_str = "v."
2281 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2282
2283__builtin_elementwise_fma
2284 .param_str = "v."
2285 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2286
2287__builtin_elementwise_log
2288 .param_str = "v."
2289 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2290
2291__builtin_elementwise_log10
2292 .param_str = "v."
2293 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2294
2295__builtin_elementwise_log2
2296 .param_str = "v."
2297 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2298
2299__builtin_elementwise_max
2300 .param_str = "v."
2301 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2302
2303__builtin_elementwise_min
2304 .param_str = "v."
2305 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2306
2307__builtin_elementwise_nearbyint
2308 .param_str = "v."
2309 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2310
2311__builtin_elementwise_pow
2312 .param_str = "v."
2313 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2314
2315__builtin_elementwise_rint
2316 .param_str = "v."
2317 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2318
2319__builtin_elementwise_round
2320 .param_str = "v."
2321 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2322
2323__builtin_elementwise_roundeven
2324 .param_str = "v."
2325 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2326
2327__builtin_elementwise_sin
2328 .param_str = "v."
2329 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2330
2331__builtin_elementwise_sqrt
2332 .param_str = "v."
2333 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2334
2335__builtin_elementwise_sub_sat
2336 .param_str = "v."
2337 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2338
2339__builtin_elementwise_trunc
2340 .param_str = "v."
2341 .attributes = .{ .@"const" = true, .custom_typecheck = true }
2342
2343__builtin_erf
2344 .param_str = "dd"
2345 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2346
2347__builtin_erfc
2348 .param_str = "dd"
2349 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2350
2351__builtin_erfcf
2352 .param_str = "ff"
2353 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2354
2355__builtin_erfcf128
2356 .param_str = "LLdLLd"
2357 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2358
2359__builtin_erfcl
2360 .param_str = "LdLd"
2361 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2362
2363__builtin_erff
2364 .param_str = "ff"
2365 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2366
2367__builtin_erff128
2368 .param_str = "LLdLLd"
2369 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2370
2371__builtin_erfl
2372 .param_str = "LdLd"
2373 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2374
2375__builtin_exp
2376 .param_str = "dd"
2377 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2378
2379__builtin_exp10
2380 .param_str = "dd"
2381 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2382
2383__builtin_exp10f
2384 .param_str = "ff"
2385 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2386
2387__builtin_exp10f128
2388 .param_str = "LLdLLd"
2389 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2390
2391__builtin_exp10f16
2392 .param_str = "hh"
2393 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2394
2395__builtin_exp10l
2396 .param_str = "LdLd"
2397 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2398
2399__builtin_exp2
2400 .param_str = "dd"
2401 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2402
2403__builtin_exp2f
2404 .param_str = "ff"
2405 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2406
2407__builtin_exp2f128
2408 .param_str = "LLdLLd"
2409 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2410
2411__builtin_exp2f16
2412 .param_str = "hh"
2413 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2414
2415__builtin_exp2l
2416 .param_str = "LdLd"
2417 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2418
2419__builtin_expect
2420 .param_str = "LiLiLi"
2421 .attributes = .{ .@"const" = true, .const_evaluable = true }
2422
2423__builtin_expect_with_probability
2424 .param_str = "LiLiLid"
2425 .attributes = .{ .@"const" = true, .const_evaluable = true }
2426
2427__builtin_expf
2428 .param_str = "ff"
2429 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2430
2431__builtin_expf128
2432 .param_str = "LLdLLd"
2433 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2434
2435__builtin_expf16
2436 .param_str = "hh"
2437 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2438
2439__builtin_expl
2440 .param_str = "LdLd"
2441 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2442
2443__builtin_expm1
2444 .param_str = "dd"
2445 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2446
2447__builtin_expm1f
2448 .param_str = "ff"
2449 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2450
2451__builtin_expm1f128
2452 .param_str = "LLdLLd"
2453 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2454
2455__builtin_expm1l
2456 .param_str = "LdLd"
2457 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2458
2459__builtin_extend_pointer
2460 .param_str = "ULLiv*"
2461
2462__builtin_extract_return_addr
2463 .param_str = "v*v*"
2464
2465__builtin_fabs
2466 .param_str = "dd"
2467 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2468
2469__builtin_fabsf
2470 .param_str = "ff"
2471 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2472
2473__builtin_fabsf128
2474 .param_str = "LLdLLd"
2475 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2476
2477__builtin_fabsf16
2478 .param_str = "hh"
2479 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2480
2481__builtin_fabsl
2482 .param_str = "LdLd"
2483 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2484
2485__builtin_fdim
2486 .param_str = "ddd"
2487 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2488
2489__builtin_fdimf
2490 .param_str = "fff"
2491 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2492
2493__builtin_fdimf128
2494 .param_str = "LLdLLdLLd"
2495 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2496
2497__builtin_fdiml
2498 .param_str = "LdLdLd"
2499 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2500
2501__builtin_ffs
2502 .param_str = "ii"
2503 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2504
2505__builtin_ffsl
2506 .param_str = "iLi"
2507 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2508
2509__builtin_ffsll
2510 .param_str = "iLLi"
2511 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2512
2513__builtin_floor
2514 .param_str = "dd"
2515 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2516
2517__builtin_floorf
2518 .param_str = "ff"
2519 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2520
2521__builtin_floorf128
2522 .param_str = "LLdLLd"
2523 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2524
2525__builtin_floorf16
2526 .param_str = "hh"
2527 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2528
2529__builtin_floorl
2530 .param_str = "LdLd"
2531 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2532
2533__builtin_flt_rounds
2534 .param_str = "i"
2535
2536__builtin_fma
2537 .param_str = "dddd"
2538 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2539
2540__builtin_fmaf
2541 .param_str = "ffff"
2542 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2543
2544__builtin_fmaf128
2545 .param_str = "LLdLLdLLdLLd"
2546 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2547
2548__builtin_fmaf16
2549 .param_str = "hhhh"
2550 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2551
2552__builtin_fmal
2553 .param_str = "LdLdLdLd"
2554 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2555
2556__builtin_fmax
2557 .param_str = "ddd"
2558 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2559
2560__builtin_fmaxf
2561 .param_str = "fff"
2562 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2563
2564__builtin_fmaxf128
2565 .param_str = "LLdLLdLLd"
2566 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2567
2568__builtin_fmaxf16
2569 .param_str = "hhh"
2570 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2571
2572__builtin_fmaxl
2573 .param_str = "LdLdLd"
2574 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2575
2576__builtin_fmin
2577 .param_str = "ddd"
2578 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2579
2580__builtin_fminf
2581 .param_str = "fff"
2582 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2583
2584__builtin_fminf128
2585 .param_str = "LLdLLdLLd"
2586 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2587
2588__builtin_fminf16
2589 .param_str = "hhh"
2590 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2591
2592__builtin_fminl
2593 .param_str = "LdLdLd"
2594 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2595
2596__builtin_fmod
2597 .param_str = "ddd"
2598 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2599
2600__builtin_fmodf
2601 .param_str = "fff"
2602 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2603
2604__builtin_fmodf128
2605 .param_str = "LLdLLdLLd"
2606 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2607
2608__builtin_fmodf16
2609 .param_str = "hhh"
2610 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2611
2612__builtin_fmodl
2613 .param_str = "LdLdLd"
2614 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2615
2616__builtin_fpclassify
2617 .param_str = "iiiiii."
2618 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2619
2620__builtin_fprintf
2621 .param_str = "iP*RcC*R."
2622 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 }
2623
2624__builtin_frame_address
2625 .param_str = "v*IUi"
2626
2627__builtin_free
2628 .param_str = "vv*"
2629 .attributes = .{ .lib_function_with_builtin_prefix = true }
2630
2631__builtin_frexp
2632 .param_str = "ddi*"
2633 .attributes = .{ .lib_function_with_builtin_prefix = true }
2634
2635__builtin_frexpf
2636 .param_str = "ffi*"
2637 .attributes = .{ .lib_function_with_builtin_prefix = true }
2638
2639__builtin_frexpf128
2640 .param_str = "LLdLLdi*"
2641 .attributes = .{ .lib_function_with_builtin_prefix = true }
2642
2643__builtin_frexpf16
2644 .param_str = "hhi*"
2645 .attributes = .{ .lib_function_with_builtin_prefix = true }
2646
2647__builtin_frexpl
2648 .param_str = "LdLdi*"
2649 .attributes = .{ .lib_function_with_builtin_prefix = true }
2650
2651__builtin_frob_return_addr
2652 .param_str = "v*v*"
2653
2654__builtin_fscanf
2655 .param_str = "iP*RcC*R."
2656 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf, .format_string_position = 1 }
2657
2658__builtin_getid
2659 .param_str = "Si"
2660 .target_set = TargetSet.initOne(.xcore)
2661 .attributes = .{ .@"const" = true }
2662
2663__builtin_getps
2664 .param_str = "UiUi"
2665 .target_set = TargetSet.initOne(.xcore)
2666
2667__builtin_huge_val
2668 .param_str = "d"
2669 .attributes = .{ .@"const" = true, .const_evaluable = true }
2670
2671__builtin_huge_valf
2672 .param_str = "f"
2673 .attributes = .{ .@"const" = true, .const_evaluable = true }
2674
2675__builtin_huge_valf128
2676 .param_str = "LLd"
2677 .attributes = .{ .@"const" = true, .const_evaluable = true }
2678
2679__builtin_huge_valf16
2680 .param_str = "x"
2681 .attributes = .{ .@"const" = true, .const_evaluable = true }
2682
2683__builtin_huge_vall
2684 .param_str = "Ld"
2685 .attributes = .{ .@"const" = true, .const_evaluable = true }
2686
2687__builtin_hypot
2688 .param_str = "ddd"
2689 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2690
2691__builtin_hypotf
2692 .param_str = "fff"
2693 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2694
2695__builtin_hypotf128
2696 .param_str = "LLdLLdLLd"
2697 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2698
2699__builtin_hypotl
2700 .param_str = "LdLdLd"
2701 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2702
2703__builtin_ia32_rdpmc
2704 .param_str = "UOii"
2705 .target_set = TargetSet.initOne(.x86)
2706
2707__builtin_ia32_rdtsc
2708 .param_str = "UOi"
2709 .target_set = TargetSet.initOne(.x86)
2710
2711__builtin_ia32_rdtscp
2712 .param_str = "UOiUi*"
2713 .target_set = TargetSet.initOne(.x86)
2714
2715__builtin_ilogb
2716 .param_str = "id"
2717 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2718
2719__builtin_ilogbf
2720 .param_str = "if"
2721 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2722
2723__builtin_ilogbf128
2724 .param_str = "iLLd"
2725 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2726
2727__builtin_ilogbl
2728 .param_str = "iLd"
2729 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2730
2731__builtin_index
2732 .param_str = "c*cC*i"
2733 .attributes = .{ .lib_function_with_builtin_prefix = true }
2734
2735__builtin_inf
2736 .param_str = "d"
2737 .attributes = .{ .@"const" = true, .const_evaluable = true }
2738
2739__builtin_inff
2740 .param_str = "f"
2741 .attributes = .{ .@"const" = true, .const_evaluable = true }
2742
2743__builtin_inff128
2744 .param_str = "LLd"
2745 .attributes = .{ .@"const" = true, .const_evaluable = true }
2746
2747__builtin_inff16
2748 .param_str = "x"
2749 .attributes = .{ .@"const" = true, .const_evaluable = true }
2750
2751__builtin_infl
2752 .param_str = "Ld"
2753 .attributes = .{ .@"const" = true, .const_evaluable = true }
2754
2755__builtin_init_dwarf_reg_size_table
2756 .param_str = "vv*"
2757
2758__builtin_is_aligned
2759 .param_str = "bvC*z"
2760 .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true }
2761
2762__builtin_isfinite
2763 .param_str = "i."
2764 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2765
2766__builtin_isfpclass
2767 .param_str = "i."
2768 .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true }
2769
2770__builtin_isgreater
2771 .param_str = "i."
2772 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
2773
2774__builtin_isgreaterequal
2775 .param_str = "i."
2776 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
2777
2778__builtin_isinf
2779 .param_str = "i."
2780 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2781
2782__builtin_isinf_sign
2783 .param_str = "i."
2784 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2785
2786__builtin_isless
2787 .param_str = "i."
2788 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
2789
2790__builtin_islessequal
2791 .param_str = "i."
2792 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
2793
2794__builtin_islessgreater
2795 .param_str = "i."
2796 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
2797
2798__builtin_isnan
2799 .param_str = "i."
2800 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2801
2802__builtin_isnormal
2803 .param_str = "i."
2804 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
2805
2806__builtin_isunordered
2807 .param_str = "i."
2808 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
2809
2810__builtin_labs
2811 .param_str = "LiLi"
2812 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2813
2814__builtin_launder
2815 .param_str = "v*v*"
2816 .attributes = .{ .custom_typecheck = true, .const_evaluable = true }
2817
2818__builtin_ldexp
2819 .param_str = "ddi"
2820 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2821
2822__builtin_ldexpf
2823 .param_str = "ffi"
2824 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2825
2826__builtin_ldexpf128
2827 .param_str = "LLdLLdi"
2828 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2829
2830__builtin_ldexpf16
2831 .param_str = "hhi"
2832 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2833
2834__builtin_ldexpl
2835 .param_str = "LdLdi"
2836 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2837
2838__builtin_lgamma
2839 .param_str = "dd"
2840 .attributes = .{ .lib_function_with_builtin_prefix = true }
2841
2842__builtin_lgammaf
2843 .param_str = "ff"
2844 .attributes = .{ .lib_function_with_builtin_prefix = true }
2845
2846__builtin_lgammaf128
2847 .param_str = "LLdLLd"
2848 .attributes = .{ .lib_function_with_builtin_prefix = true }
2849
2850__builtin_lgammal
2851 .param_str = "LdLd"
2852 .attributes = .{ .lib_function_with_builtin_prefix = true }
2853
2854__builtin_llabs
2855 .param_str = "LLiLLi"
2856 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
2857
2858__builtin_llrint
2859 .param_str = "LLid"
2860 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2861
2862__builtin_llrintf
2863 .param_str = "LLif"
2864 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2865
2866__builtin_llrintf128
2867 .param_str = "LLiLLd"
2868 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2869
2870__builtin_llrintl
2871 .param_str = "LLiLd"
2872 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2873
2874__builtin_llround
2875 .param_str = "LLid"
2876 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2877
2878__builtin_llroundf
2879 .param_str = "LLif"
2880 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2881
2882__builtin_llroundf128
2883 .param_str = "LLiLLd"
2884 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2885
2886__builtin_llroundl
2887 .param_str = "LLiLd"
2888 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2889
2890__builtin_log
2891 .param_str = "dd"
2892 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2893
2894__builtin_log10
2895 .param_str = "dd"
2896 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2897
2898__builtin_log10f
2899 .param_str = "ff"
2900 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2901
2902__builtin_log10f128
2903 .param_str = "LLdLLd"
2904 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2905
2906__builtin_log10f16
2907 .param_str = "hh"
2908 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2909
2910__builtin_log10l
2911 .param_str = "LdLd"
2912 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2913
2914__builtin_log1p
2915 .param_str = "dd"
2916 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2917
2918__builtin_log1pf
2919 .param_str = "ff"
2920 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2921
2922__builtin_log1pf128
2923 .param_str = "LLdLLd"
2924 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2925
2926__builtin_log1pl
2927 .param_str = "LdLd"
2928 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2929
2930__builtin_log2
2931 .param_str = "dd"
2932 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2933
2934__builtin_log2f
2935 .param_str = "ff"
2936 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2937
2938__builtin_log2f128
2939 .param_str = "LLdLLd"
2940 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2941
2942__builtin_log2f16
2943 .param_str = "hh"
2944 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2945
2946__builtin_log2l
2947 .param_str = "LdLd"
2948 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2949
2950__builtin_logb
2951 .param_str = "dd"
2952 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2953
2954__builtin_logbf
2955 .param_str = "ff"
2956 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2957
2958__builtin_logbf128
2959 .param_str = "LLdLLd"
2960 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2961
2962__builtin_logbl
2963 .param_str = "LdLd"
2964 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2965
2966__builtin_logf
2967 .param_str = "ff"
2968 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2969
2970__builtin_logf128
2971 .param_str = "LLdLLd"
2972 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2973
2974__builtin_logf16
2975 .param_str = "hh"
2976 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2977
2978__builtin_logl
2979 .param_str = "LdLd"
2980 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2981
2982__builtin_longjmp
2983 .param_str = "vv**i"
2984 .attributes = .{ .noreturn = true }
2985
2986__builtin_lrint
2987 .param_str = "Lid"
2988 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2989
2990__builtin_lrintf
2991 .param_str = "Lif"
2992 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2993
2994__builtin_lrintf128
2995 .param_str = "LiLLd"
2996 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
2997
2998__builtin_lrintl
2999 .param_str = "LiLd"
3000 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
3001
3002__builtin_lround
3003 .param_str = "Lid"
3004 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
3005
3006__builtin_lroundf
3007 .param_str = "Lif"
3008 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
3009
3010__builtin_lroundf128
3011 .param_str = "LiLLd"
3012 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
3013
3014__builtin_lroundl
3015 .param_str = "LiLd"
3016 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
3017
3018__builtin_malloc
3019 .param_str = "v*z"
3020 .attributes = .{ .lib_function_with_builtin_prefix = true }
3021
3022__builtin_matrix_column_major_load
3023 .param_str = "v."
3024 .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
3025
3026__builtin_matrix_column_major_store
3027 .param_str = "v."
3028 .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
3029
3030__builtin_matrix_transpose
3031 .param_str = "v."
3032 .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
3033
3034__builtin_memchr
3035 .param_str = "v*vC*iz"
3036 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
3037
3038__builtin_memcmp
3039 .param_str = "ivC*vC*z"
3040 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
3041
3042__builtin_memcpy
3043 .param_str = "v*v*vC*z"
3044 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
3045
3046__builtin_memcpy_inline
3047 .param_str = "vv*vC*Iz"
3048
3049__builtin_memmove
3050 .param_str = "v*v*vC*z"
3051 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
3052
3053__builtin_mempcpy
3054 .param_str = "v*v*vC*z"
3055 .attributes = .{ .lib_function_with_builtin_prefix = true }
3056
3057__builtin_memset
3058 .param_str = "v*v*iz"
3059 .attributes = .{ .lib_function_with_builtin_prefix = true }
3060
3061__builtin_memset_inline
3062 .param_str = "vv*iIz"
3063
3064__builtin_mips_absq_s_ph
3065 .param_str = "V2sV2s"
3066 .target_set = TargetSet.initOne(.mips)
3067
3068__builtin_mips_absq_s_qb
3069 .param_str = "V4ScV4Sc"
3070 .target_set = TargetSet.initOne(.mips)
3071
3072__builtin_mips_absq_s_w
3073 .param_str = "ii"
3074 .target_set = TargetSet.initOne(.mips)
3075
3076__builtin_mips_addq_ph
3077 .param_str = "V2sV2sV2s"
3078 .target_set = TargetSet.initOne(.mips)
3079
3080__builtin_mips_addq_s_ph
3081 .param_str = "V2sV2sV2s"
3082 .target_set = TargetSet.initOne(.mips)
3083
3084__builtin_mips_addq_s_w
3085 .param_str = "iii"
3086 .target_set = TargetSet.initOne(.mips)
3087
3088__builtin_mips_addqh_ph
3089 .param_str = "V2sV2sV2s"
3090 .target_set = TargetSet.initOne(.mips)
3091 .attributes = .{ .@"const" = true }
3092
3093__builtin_mips_addqh_r_ph
3094 .param_str = "V2sV2sV2s"
3095 .target_set = TargetSet.initOne(.mips)
3096 .attributes = .{ .@"const" = true }
3097
3098__builtin_mips_addqh_r_w
3099 .param_str = "iii"
3100 .target_set = TargetSet.initOne(.mips)
3101 .attributes = .{ .@"const" = true }
3102
3103__builtin_mips_addqh_w
3104 .param_str = "iii"
3105 .target_set = TargetSet.initOne(.mips)
3106 .attributes = .{ .@"const" = true }
3107
3108__builtin_mips_addsc
3109 .param_str = "iii"
3110 .target_set = TargetSet.initOne(.mips)
3111
3112__builtin_mips_addu_ph
3113 .param_str = "V2sV2sV2s"
3114 .target_set = TargetSet.initOne(.mips)
3115
3116__builtin_mips_addu_qb
3117 .param_str = "V4ScV4ScV4Sc"
3118 .target_set = TargetSet.initOne(.mips)
3119
3120__builtin_mips_addu_s_ph
3121 .param_str = "V2sV2sV2s"
3122 .target_set = TargetSet.initOne(.mips)
3123
3124__builtin_mips_addu_s_qb
3125 .param_str = "V4ScV4ScV4Sc"
3126 .target_set = TargetSet.initOne(.mips)
3127
3128__builtin_mips_adduh_qb
3129 .param_str = "V4ScV4ScV4Sc"
3130 .target_set = TargetSet.initOne(.mips)
3131 .attributes = .{ .@"const" = true }
3132
3133__builtin_mips_adduh_r_qb
3134 .param_str = "V4ScV4ScV4Sc"
3135 .target_set = TargetSet.initOne(.mips)
3136 .attributes = .{ .@"const" = true }
3137
3138__builtin_mips_addwc
3139 .param_str = "iii"
3140 .target_set = TargetSet.initOne(.mips)
3141
3142__builtin_mips_append
3143 .param_str = "iiiIi"
3144 .target_set = TargetSet.initOne(.mips)
3145 .attributes = .{ .@"const" = true }
3146
3147__builtin_mips_balign
3148 .param_str = "iiiIi"
3149 .target_set = TargetSet.initOne(.mips)
3150 .attributes = .{ .@"const" = true }
3151
3152__builtin_mips_bitrev
3153 .param_str = "ii"
3154 .target_set = TargetSet.initOne(.mips)
3155 .attributes = .{ .@"const" = true }
3156
3157__builtin_mips_bposge32
3158 .param_str = "i"
3159 .target_set = TargetSet.initOne(.mips)
3160
3161__builtin_mips_cmp_eq_ph
3162 .param_str = "vV2sV2s"
3163 .target_set = TargetSet.initOne(.mips)
3164
3165__builtin_mips_cmp_le_ph
3166 .param_str = "vV2sV2s"
3167 .target_set = TargetSet.initOne(.mips)
3168
3169__builtin_mips_cmp_lt_ph
3170 .param_str = "vV2sV2s"
3171 .target_set = TargetSet.initOne(.mips)
3172
3173__builtin_mips_cmpgdu_eq_qb
3174 .param_str = "iV4ScV4Sc"
3175 .target_set = TargetSet.initOne(.mips)
3176
3177__builtin_mips_cmpgdu_le_qb
3178 .param_str = "iV4ScV4Sc"
3179 .target_set = TargetSet.initOne(.mips)
3180
3181__builtin_mips_cmpgdu_lt_qb
3182 .param_str = "iV4ScV4Sc"
3183 .target_set = TargetSet.initOne(.mips)
3184
3185__builtin_mips_cmpgu_eq_qb
3186 .param_str = "iV4ScV4Sc"
3187 .target_set = TargetSet.initOne(.mips)
3188
3189__builtin_mips_cmpgu_le_qb
3190 .param_str = "iV4ScV4Sc"
3191 .target_set = TargetSet.initOne(.mips)
3192
3193__builtin_mips_cmpgu_lt_qb
3194 .param_str = "iV4ScV4Sc"
3195 .target_set = TargetSet.initOne(.mips)
3196
3197__builtin_mips_cmpu_eq_qb
3198 .param_str = "vV4ScV4Sc"
3199 .target_set = TargetSet.initOne(.mips)
3200
3201__builtin_mips_cmpu_le_qb
3202 .param_str = "vV4ScV4Sc"
3203 .target_set = TargetSet.initOne(.mips)
3204
3205__builtin_mips_cmpu_lt_qb
3206 .param_str = "vV4ScV4Sc"
3207 .target_set = TargetSet.initOne(.mips)
3208
3209__builtin_mips_dpa_w_ph
3210 .param_str = "LLiLLiV2sV2s"
3211 .target_set = TargetSet.initOne(.mips)
3212 .attributes = .{ .@"const" = true }
3213
3214__builtin_mips_dpaq_s_w_ph
3215 .param_str = "LLiLLiV2sV2s"
3216 .target_set = TargetSet.initOne(.mips)
3217
3218__builtin_mips_dpaq_sa_l_w
3219 .param_str = "LLiLLiii"
3220 .target_set = TargetSet.initOne(.mips)
3221
3222__builtin_mips_dpaqx_s_w_ph
3223 .param_str = "LLiLLiV2sV2s"
3224 .target_set = TargetSet.initOne(.mips)
3225
3226__builtin_mips_dpaqx_sa_w_ph
3227 .param_str = "LLiLLiV2sV2s"
3228 .target_set = TargetSet.initOne(.mips)
3229
3230__builtin_mips_dpau_h_qbl
3231 .param_str = "LLiLLiV4ScV4Sc"
3232 .target_set = TargetSet.initOne(.mips)
3233 .attributes = .{ .@"const" = true }
3234
3235__builtin_mips_dpau_h_qbr
3236 .param_str = "LLiLLiV4ScV4Sc"
3237 .target_set = TargetSet.initOne(.mips)
3238 .attributes = .{ .@"const" = true }
3239
3240__builtin_mips_dpax_w_ph
3241 .param_str = "LLiLLiV2sV2s"
3242 .target_set = TargetSet.initOne(.mips)
3243 .attributes = .{ .@"const" = true }
3244
3245__builtin_mips_dps_w_ph
3246 .param_str = "LLiLLiV2sV2s"
3247 .target_set = TargetSet.initOne(.mips)
3248 .attributes = .{ .@"const" = true }
3249
3250__builtin_mips_dpsq_s_w_ph
3251 .param_str = "LLiLLiV2sV2s"
3252 .target_set = TargetSet.initOne(.mips)
3253
3254__builtin_mips_dpsq_sa_l_w
3255 .param_str = "LLiLLiii"
3256 .target_set = TargetSet.initOne(.mips)
3257
3258__builtin_mips_dpsqx_s_w_ph
3259 .param_str = "LLiLLiV2sV2s"
3260 .target_set = TargetSet.initOne(.mips)
3261
3262__builtin_mips_dpsqx_sa_w_ph
3263 .param_str = "LLiLLiV2sV2s"
3264 .target_set = TargetSet.initOne(.mips)
3265
3266__builtin_mips_dpsu_h_qbl
3267 .param_str = "LLiLLiV4ScV4Sc"
3268 .target_set = TargetSet.initOne(.mips)
3269 .attributes = .{ .@"const" = true }
3270
3271__builtin_mips_dpsu_h_qbr
3272 .param_str = "LLiLLiV4ScV4Sc"
3273 .target_set = TargetSet.initOne(.mips)
3274 .attributes = .{ .@"const" = true }
3275
3276__builtin_mips_dpsx_w_ph
3277 .param_str = "LLiLLiV2sV2s"
3278 .target_set = TargetSet.initOne(.mips)
3279 .attributes = .{ .@"const" = true }
3280
3281__builtin_mips_extp
3282 .param_str = "iLLii"
3283 .target_set = TargetSet.initOne(.mips)
3284
3285__builtin_mips_extpdp
3286 .param_str = "iLLii"
3287 .target_set = TargetSet.initOne(.mips)
3288
3289__builtin_mips_extr_r_w
3290 .param_str = "iLLii"
3291 .target_set = TargetSet.initOne(.mips)
3292
3293__builtin_mips_extr_rs_w
3294 .param_str = "iLLii"
3295 .target_set = TargetSet.initOne(.mips)
3296
3297__builtin_mips_extr_s_h
3298 .param_str = "iLLii"
3299 .target_set = TargetSet.initOne(.mips)
3300
3301__builtin_mips_extr_w
3302 .param_str = "iLLii"
3303 .target_set = TargetSet.initOne(.mips)
3304
3305__builtin_mips_insv
3306 .param_str = "iii"
3307 .target_set = TargetSet.initOne(.mips)
3308
3309__builtin_mips_lbux
3310 .param_str = "iv*i"
3311 .target_set = TargetSet.initOne(.mips)
3312
3313__builtin_mips_lhx
3314 .param_str = "iv*i"
3315 .target_set = TargetSet.initOne(.mips)
3316
3317__builtin_mips_lwx
3318 .param_str = "iv*i"
3319 .target_set = TargetSet.initOne(.mips)
3320
3321__builtin_mips_madd
3322 .param_str = "LLiLLiii"
3323 .target_set = TargetSet.initOne(.mips)
3324 .attributes = .{ .@"const" = true }
3325
3326__builtin_mips_maddu
3327 .param_str = "LLiLLiUiUi"
3328 .target_set = TargetSet.initOne(.mips)
3329 .attributes = .{ .@"const" = true }
3330
3331__builtin_mips_maq_s_w_phl
3332 .param_str = "LLiLLiV2sV2s"
3333 .target_set = TargetSet.initOne(.mips)
3334
3335__builtin_mips_maq_s_w_phr
3336 .param_str = "LLiLLiV2sV2s"
3337 .target_set = TargetSet.initOne(.mips)
3338
3339__builtin_mips_maq_sa_w_phl
3340 .param_str = "LLiLLiV2sV2s"
3341 .target_set = TargetSet.initOne(.mips)
3342
3343__builtin_mips_maq_sa_w_phr
3344 .param_str = "LLiLLiV2sV2s"
3345 .target_set = TargetSet.initOne(.mips)
3346
3347__builtin_mips_modsub
3348 .param_str = "iii"
3349 .target_set = TargetSet.initOne(.mips)
3350 .attributes = .{ .@"const" = true }
3351
3352__builtin_mips_msub
3353 .param_str = "LLiLLiii"
3354 .target_set = TargetSet.initOne(.mips)
3355 .attributes = .{ .@"const" = true }
3356
3357__builtin_mips_msubu
3358 .param_str = "LLiLLiUiUi"
3359 .target_set = TargetSet.initOne(.mips)
3360 .attributes = .{ .@"const" = true }
3361
3362__builtin_mips_mthlip
3363 .param_str = "LLiLLii"
3364 .target_set = TargetSet.initOne(.mips)
3365
3366__builtin_mips_mul_ph
3367 .param_str = "V2sV2sV2s"
3368 .target_set = TargetSet.initOne(.mips)
3369
3370__builtin_mips_mul_s_ph
3371 .param_str = "V2sV2sV2s"
3372 .target_set = TargetSet.initOne(.mips)
3373
3374__builtin_mips_muleq_s_w_phl
3375 .param_str = "iV2sV2s"
3376 .target_set = TargetSet.initOne(.mips)
3377
3378__builtin_mips_muleq_s_w_phr
3379 .param_str = "iV2sV2s"
3380 .target_set = TargetSet.initOne(.mips)
3381
3382__builtin_mips_muleu_s_ph_qbl
3383 .param_str = "V2sV4ScV2s"
3384 .target_set = TargetSet.initOne(.mips)
3385
3386__builtin_mips_muleu_s_ph_qbr
3387 .param_str = "V2sV4ScV2s"
3388 .target_set = TargetSet.initOne(.mips)
3389
3390__builtin_mips_mulq_rs_ph
3391 .param_str = "V2sV2sV2s"
3392 .target_set = TargetSet.initOne(.mips)
3393
3394__builtin_mips_mulq_rs_w
3395 .param_str = "iii"
3396 .target_set = TargetSet.initOne(.mips)
3397
3398__builtin_mips_mulq_s_ph
3399 .param_str = "V2sV2sV2s"
3400 .target_set = TargetSet.initOne(.mips)
3401
3402__builtin_mips_mulq_s_w
3403 .param_str = "iii"
3404 .target_set = TargetSet.initOne(.mips)
3405
3406__builtin_mips_mulsa_w_ph
3407 .param_str = "LLiLLiV2sV2s"
3408 .target_set = TargetSet.initOne(.mips)
3409 .attributes = .{ .@"const" = true }
3410
3411__builtin_mips_mulsaq_s_w_ph
3412 .param_str = "LLiLLiV2sV2s"
3413 .target_set = TargetSet.initOne(.mips)
3414
3415__builtin_mips_mult
3416 .param_str = "LLiii"
3417 .target_set = TargetSet.initOne(.mips)
3418 .attributes = .{ .@"const" = true }
3419
3420__builtin_mips_multu
3421 .param_str = "LLiUiUi"
3422 .target_set = TargetSet.initOne(.mips)
3423 .attributes = .{ .@"const" = true }
3424
3425__builtin_mips_packrl_ph
3426 .param_str = "V2sV2sV2s"
3427 .target_set = TargetSet.initOne(.mips)
3428 .attributes = .{ .@"const" = true }
3429
3430__builtin_mips_pick_ph
3431 .param_str = "V2sV2sV2s"
3432 .target_set = TargetSet.initOne(.mips)
3433
3434__builtin_mips_pick_qb
3435 .param_str = "V4ScV4ScV4Sc"
3436 .target_set = TargetSet.initOne(.mips)
3437
3438__builtin_mips_preceq_w_phl
3439 .param_str = "iV2s"
3440 .target_set = TargetSet.initOne(.mips)
3441 .attributes = .{ .@"const" = true }
3442
3443__builtin_mips_preceq_w_phr
3444 .param_str = "iV2s"
3445 .target_set = TargetSet.initOne(.mips)
3446 .attributes = .{ .@"const" = true }
3447
3448__builtin_mips_precequ_ph_qbl
3449 .param_str = "V2sV4Sc"
3450 .target_set = TargetSet.initOne(.mips)
3451 .attributes = .{ .@"const" = true }
3452
3453__builtin_mips_precequ_ph_qbla
3454 .param_str = "V2sV4Sc"
3455 .target_set = TargetSet.initOne(.mips)
3456 .attributes = .{ .@"const" = true }
3457
3458__builtin_mips_precequ_ph_qbr
3459 .param_str = "V2sV4Sc"
3460 .target_set = TargetSet.initOne(.mips)
3461 .attributes = .{ .@"const" = true }
3462
3463__builtin_mips_precequ_ph_qbra
3464 .param_str = "V2sV4Sc"
3465 .target_set = TargetSet.initOne(.mips)
3466 .attributes = .{ .@"const" = true }
3467
3468__builtin_mips_preceu_ph_qbl
3469 .param_str = "V2sV4Sc"
3470 .target_set = TargetSet.initOne(.mips)
3471 .attributes = .{ .@"const" = true }
3472
3473__builtin_mips_preceu_ph_qbla
3474 .param_str = "V2sV4Sc"
3475 .target_set = TargetSet.initOne(.mips)
3476 .attributes = .{ .@"const" = true }
3477
3478__builtin_mips_preceu_ph_qbr
3479 .param_str = "V2sV4Sc"
3480 .target_set = TargetSet.initOne(.mips)
3481 .attributes = .{ .@"const" = true }
3482
3483__builtin_mips_preceu_ph_qbra
3484 .param_str = "V2sV4Sc"
3485 .target_set = TargetSet.initOne(.mips)
3486 .attributes = .{ .@"const" = true }
3487
3488__builtin_mips_precr_qb_ph
3489 .param_str = "V4ScV2sV2s"
3490 .target_set = TargetSet.initOne(.mips)
3491
3492__builtin_mips_precr_sra_ph_w
3493 .param_str = "V2siiIi"
3494 .target_set = TargetSet.initOne(.mips)
3495 .attributes = .{ .@"const" = true }
3496
3497__builtin_mips_precr_sra_r_ph_w
3498 .param_str = "V2siiIi"
3499 .target_set = TargetSet.initOne(.mips)
3500 .attributes = .{ .@"const" = true }
3501
3502__builtin_mips_precrq_ph_w
3503 .param_str = "V2sii"
3504 .target_set = TargetSet.initOne(.mips)
3505 .attributes = .{ .@"const" = true }
3506
3507__builtin_mips_precrq_qb_ph
3508 .param_str = "V4ScV2sV2s"
3509 .target_set = TargetSet.initOne(.mips)
3510 .attributes = .{ .@"const" = true }
3511
3512__builtin_mips_precrq_rs_ph_w
3513 .param_str = "V2sii"
3514 .target_set = TargetSet.initOne(.mips)
3515
3516__builtin_mips_precrqu_s_qb_ph
3517 .param_str = "V4ScV2sV2s"
3518 .target_set = TargetSet.initOne(.mips)
3519
3520__builtin_mips_prepend
3521 .param_str = "iiiIi"
3522 .target_set = TargetSet.initOne(.mips)
3523 .attributes = .{ .@"const" = true }
3524
3525__builtin_mips_raddu_w_qb
3526 .param_str = "iV4Sc"
3527 .target_set = TargetSet.initOne(.mips)
3528 .attributes = .{ .@"const" = true }
3529
3530__builtin_mips_rddsp
3531 .param_str = "iIi"
3532 .target_set = TargetSet.initOne(.mips)
3533
3534__builtin_mips_repl_ph
3535 .param_str = "V2si"
3536 .target_set = TargetSet.initOne(.mips)
3537 .attributes = .{ .@"const" = true }
3538
3539__builtin_mips_repl_qb
3540 .param_str = "V4Sci"
3541 .target_set = TargetSet.initOne(.mips)
3542 .attributes = .{ .@"const" = true }
3543
3544__builtin_mips_shilo
3545 .param_str = "LLiLLii"
3546 .target_set = TargetSet.initOne(.mips)
3547 .attributes = .{ .@"const" = true }
3548
3549__builtin_mips_shll_ph
3550 .param_str = "V2sV2si"
3551 .target_set = TargetSet.initOne(.mips)
3552
3553__builtin_mips_shll_qb
3554 .param_str = "V4ScV4Sci"
3555 .target_set = TargetSet.initOne(.mips)
3556
3557__builtin_mips_shll_s_ph
3558 .param_str = "V2sV2si"
3559 .target_set = TargetSet.initOne(.mips)
3560
3561__builtin_mips_shll_s_w
3562 .param_str = "iii"
3563 .target_set = TargetSet.initOne(.mips)
3564
3565__builtin_mips_shra_ph
3566 .param_str = "V2sV2si"
3567 .target_set = TargetSet.initOne(.mips)
3568 .attributes = .{ .@"const" = true }
3569
3570__builtin_mips_shra_qb
3571 .param_str = "V4ScV4Sci"
3572 .target_set = TargetSet.initOne(.mips)
3573 .attributes = .{ .@"const" = true }
3574
3575__builtin_mips_shra_r_ph
3576 .param_str = "V2sV2si"
3577 .target_set = TargetSet.initOne(.mips)
3578 .attributes = .{ .@"const" = true }
3579
3580__builtin_mips_shra_r_qb
3581 .param_str = "V4ScV4Sci"
3582 .target_set = TargetSet.initOne(.mips)
3583 .attributes = .{ .@"const" = true }
3584
3585__builtin_mips_shra_r_w
3586 .param_str = "iii"
3587 .target_set = TargetSet.initOne(.mips)
3588 .attributes = .{ .@"const" = true }
3589
3590__builtin_mips_shrl_ph
3591 .param_str = "V2sV2si"
3592 .target_set = TargetSet.initOne(.mips)
3593 .attributes = .{ .@"const" = true }
3594
3595__builtin_mips_shrl_qb
3596 .param_str = "V4ScV4Sci"
3597 .target_set = TargetSet.initOne(.mips)
3598 .attributes = .{ .@"const" = true }
3599
3600__builtin_mips_subq_ph
3601 .param_str = "V2sV2sV2s"
3602 .target_set = TargetSet.initOne(.mips)
3603
3604__builtin_mips_subq_s_ph
3605 .param_str = "V2sV2sV2s"
3606 .target_set = TargetSet.initOne(.mips)
3607
3608__builtin_mips_subq_s_w
3609 .param_str = "iii"
3610 .target_set = TargetSet.initOne(.mips)
3611
3612__builtin_mips_subqh_ph
3613 .param_str = "V2sV2sV2s"
3614 .target_set = TargetSet.initOne(.mips)
3615 .attributes = .{ .@"const" = true }
3616
3617__builtin_mips_subqh_r_ph
3618 .param_str = "V2sV2sV2s"
3619 .target_set = TargetSet.initOne(.mips)
3620 .attributes = .{ .@"const" = true }
3621
3622__builtin_mips_subqh_r_w
3623 .param_str = "iii"
3624 .target_set = TargetSet.initOne(.mips)
3625 .attributes = .{ .@"const" = true }
3626
3627__builtin_mips_subqh_w
3628 .param_str = "iii"
3629 .target_set = TargetSet.initOne(.mips)
3630 .attributes = .{ .@"const" = true }
3631
3632__builtin_mips_subu_ph
3633 .param_str = "V2sV2sV2s"
3634 .target_set = TargetSet.initOne(.mips)
3635
3636__builtin_mips_subu_qb
3637 .param_str = "V4ScV4ScV4Sc"
3638 .target_set = TargetSet.initOne(.mips)
3639
3640__builtin_mips_subu_s_ph
3641 .param_str = "V2sV2sV2s"
3642 .target_set = TargetSet.initOne(.mips)
3643
3644__builtin_mips_subu_s_qb
3645 .param_str = "V4ScV4ScV4Sc"
3646 .target_set = TargetSet.initOne(.mips)
3647
3648__builtin_mips_subuh_qb
3649 .param_str = "V4ScV4ScV4Sc"
3650 .target_set = TargetSet.initOne(.mips)
3651 .attributes = .{ .@"const" = true }
3652
3653__builtin_mips_subuh_r_qb
3654 .param_str = "V4ScV4ScV4Sc"
3655 .target_set = TargetSet.initOne(.mips)
3656 .attributes = .{ .@"const" = true }
3657
3658__builtin_mips_wrdsp
3659 .param_str = "viIi"
3660 .target_set = TargetSet.initOne(.mips)
3661
3662__builtin_modf
3663 .param_str = "ddd*"
3664 .attributes = .{ .lib_function_with_builtin_prefix = true }
3665
3666__builtin_modff
3667 .param_str = "fff*"
3668 .attributes = .{ .lib_function_with_builtin_prefix = true }
3669
3670__builtin_modff128
3671 .param_str = "LLdLLdLLd*"
3672 .attributes = .{ .lib_function_with_builtin_prefix = true }
3673
3674__builtin_modfl
3675 .param_str = "LdLdLd*"
3676 .attributes = .{ .lib_function_with_builtin_prefix = true }
3677
3678__builtin_msa_add_a_b
3679 .param_str = "V16ScV16ScV16Sc"
3680 .target_set = TargetSet.initOne(.mips)
3681 .attributes = .{ .@"const" = true }
3682
3683__builtin_msa_add_a_d
3684 .param_str = "V2SLLiV2SLLiV2SLLi"
3685 .target_set = TargetSet.initOne(.mips)
3686 .attributes = .{ .@"const" = true }
3687
3688__builtin_msa_add_a_h
3689 .param_str = "V8SsV8SsV8Ss"
3690 .target_set = TargetSet.initOne(.mips)
3691 .attributes = .{ .@"const" = true }
3692
3693__builtin_msa_add_a_w
3694 .param_str = "V4SiV4SiV4Si"
3695 .target_set = TargetSet.initOne(.mips)
3696 .attributes = .{ .@"const" = true }
3697
3698__builtin_msa_adds_a_b
3699 .param_str = "V16ScV16ScV16Sc"
3700 .target_set = TargetSet.initOne(.mips)
3701 .attributes = .{ .@"const" = true }
3702
3703__builtin_msa_adds_a_d
3704 .param_str = "V2SLLiV2SLLiV2SLLi"
3705 .target_set = TargetSet.initOne(.mips)
3706 .attributes = .{ .@"const" = true }
3707
3708__builtin_msa_adds_a_h
3709 .param_str = "V8SsV8SsV8Ss"
3710 .target_set = TargetSet.initOne(.mips)
3711 .attributes = .{ .@"const" = true }
3712
3713__builtin_msa_adds_a_w
3714 .param_str = "V4SiV4SiV4Si"
3715 .target_set = TargetSet.initOne(.mips)
3716 .attributes = .{ .@"const" = true }
3717
3718__builtin_msa_adds_s_b
3719 .param_str = "V16ScV16ScV16Sc"
3720 .target_set = TargetSet.initOne(.mips)
3721 .attributes = .{ .@"const" = true }
3722
3723__builtin_msa_adds_s_d
3724 .param_str = "V2SLLiV2SLLiV2SLLi"
3725 .target_set = TargetSet.initOne(.mips)
3726 .attributes = .{ .@"const" = true }
3727
3728__builtin_msa_adds_s_h
3729 .param_str = "V8SsV8SsV8Ss"
3730 .target_set = TargetSet.initOne(.mips)
3731 .attributes = .{ .@"const" = true }
3732
3733__builtin_msa_adds_s_w
3734 .param_str = "V4SiV4SiV4Si"
3735 .target_set = TargetSet.initOne(.mips)
3736 .attributes = .{ .@"const" = true }
3737
3738__builtin_msa_adds_u_b
3739 .param_str = "V16UcV16UcV16Uc"
3740 .target_set = TargetSet.initOne(.mips)
3741 .attributes = .{ .@"const" = true }
3742
3743__builtin_msa_adds_u_d
3744 .param_str = "V2ULLiV2ULLiV2ULLi"
3745 .target_set = TargetSet.initOne(.mips)
3746 .attributes = .{ .@"const" = true }
3747
3748__builtin_msa_adds_u_h
3749 .param_str = "V8UsV8UsV8Us"
3750 .target_set = TargetSet.initOne(.mips)
3751 .attributes = .{ .@"const" = true }
3752
3753__builtin_msa_adds_u_w
3754 .param_str = "V4UiV4UiV4Ui"
3755 .target_set = TargetSet.initOne(.mips)
3756 .attributes = .{ .@"const" = true }
3757
3758__builtin_msa_addv_b
3759 .param_str = "V16cV16cV16c"
3760 .target_set = TargetSet.initOne(.mips)
3761 .attributes = .{ .@"const" = true }
3762
3763__builtin_msa_addv_d
3764 .param_str = "V2LLiV2LLiV2LLi"
3765 .target_set = TargetSet.initOne(.mips)
3766 .attributes = .{ .@"const" = true }
3767
3768__builtin_msa_addv_h
3769 .param_str = "V8sV8sV8s"
3770 .target_set = TargetSet.initOne(.mips)
3771 .attributes = .{ .@"const" = true }
3772
3773__builtin_msa_addv_w
3774 .param_str = "V4iV4iV4i"
3775 .target_set = TargetSet.initOne(.mips)
3776 .attributes = .{ .@"const" = true }
3777
3778__builtin_msa_addvi_b
3779 .param_str = "V16cV16cIUi"
3780 .target_set = TargetSet.initOne(.mips)
3781 .attributes = .{ .@"const" = true }
3782
3783__builtin_msa_addvi_d
3784 .param_str = "V2LLiV2LLiIUi"
3785 .target_set = TargetSet.initOne(.mips)
3786 .attributes = .{ .@"const" = true }
3787
3788__builtin_msa_addvi_h
3789 .param_str = "V8sV8sIUi"
3790 .target_set = TargetSet.initOne(.mips)
3791 .attributes = .{ .@"const" = true }
3792
3793__builtin_msa_addvi_w
3794 .param_str = "V4iV4iIUi"
3795 .target_set = TargetSet.initOne(.mips)
3796 .attributes = .{ .@"const" = true }
3797
3798__builtin_msa_and_v
3799 .param_str = "V16UcV16UcV16Uc"
3800 .target_set = TargetSet.initOne(.mips)
3801 .attributes = .{ .@"const" = true }
3802
3803__builtin_msa_andi_b
3804 .param_str = "V16UcV16UcIUi"
3805 .target_set = TargetSet.initOne(.mips)
3806 .attributes = .{ .@"const" = true }
3807
3808__builtin_msa_asub_s_b
3809 .param_str = "V16ScV16ScV16Sc"
3810 .target_set = TargetSet.initOne(.mips)
3811 .attributes = .{ .@"const" = true }
3812
3813__builtin_msa_asub_s_d
3814 .param_str = "V2SLLiV2SLLiV2SLLi"
3815 .target_set = TargetSet.initOne(.mips)
3816 .attributes = .{ .@"const" = true }
3817
3818__builtin_msa_asub_s_h
3819 .param_str = "V8SsV8SsV8Ss"
3820 .target_set = TargetSet.initOne(.mips)
3821 .attributes = .{ .@"const" = true }
3822
3823__builtin_msa_asub_s_w
3824 .param_str = "V4SiV4SiV4Si"
3825 .target_set = TargetSet.initOne(.mips)
3826 .attributes = .{ .@"const" = true }
3827
3828__builtin_msa_asub_u_b
3829 .param_str = "V16UcV16UcV16Uc"
3830 .target_set = TargetSet.initOne(.mips)
3831 .attributes = .{ .@"const" = true }
3832
3833__builtin_msa_asub_u_d
3834 .param_str = "V2ULLiV2ULLiV2ULLi"
3835 .target_set = TargetSet.initOne(.mips)
3836 .attributes = .{ .@"const" = true }
3837
3838__builtin_msa_asub_u_h
3839 .param_str = "V8UsV8UsV8Us"
3840 .target_set = TargetSet.initOne(.mips)
3841 .attributes = .{ .@"const" = true }
3842
3843__builtin_msa_asub_u_w
3844 .param_str = "V4UiV4UiV4Ui"
3845 .target_set = TargetSet.initOne(.mips)
3846 .attributes = .{ .@"const" = true }
3847
3848__builtin_msa_ave_s_b
3849 .param_str = "V16ScV16ScV16Sc"
3850 .target_set = TargetSet.initOne(.mips)
3851 .attributes = .{ .@"const" = true }
3852
3853__builtin_msa_ave_s_d
3854 .param_str = "V2SLLiV2SLLiV2SLLi"
3855 .target_set = TargetSet.initOne(.mips)
3856 .attributes = .{ .@"const" = true }
3857
3858__builtin_msa_ave_s_h
3859 .param_str = "V8SsV8SsV8Ss"
3860 .target_set = TargetSet.initOne(.mips)
3861 .attributes = .{ .@"const" = true }
3862
3863__builtin_msa_ave_s_w
3864 .param_str = "V4SiV4SiV4Si"
3865 .target_set = TargetSet.initOne(.mips)
3866 .attributes = .{ .@"const" = true }
3867
3868__builtin_msa_ave_u_b
3869 .param_str = "V16UcV16UcV16Uc"
3870 .target_set = TargetSet.initOne(.mips)
3871 .attributes = .{ .@"const" = true }
3872
3873__builtin_msa_ave_u_d
3874 .param_str = "V2ULLiV2ULLiV2ULLi"
3875 .target_set = TargetSet.initOne(.mips)
3876 .attributes = .{ .@"const" = true }
3877
3878__builtin_msa_ave_u_h
3879 .param_str = "V8UsV8UsV8Us"
3880 .target_set = TargetSet.initOne(.mips)
3881 .attributes = .{ .@"const" = true }
3882
3883__builtin_msa_ave_u_w
3884 .param_str = "V4UiV4UiV4Ui"
3885 .target_set = TargetSet.initOne(.mips)
3886 .attributes = .{ .@"const" = true }
3887
3888__builtin_msa_aver_s_b
3889 .param_str = "V16ScV16ScV16Sc"
3890 .target_set = TargetSet.initOne(.mips)
3891 .attributes = .{ .@"const" = true }
3892
3893__builtin_msa_aver_s_d
3894 .param_str = "V2SLLiV2SLLiV2SLLi"
3895 .target_set = TargetSet.initOne(.mips)
3896 .attributes = .{ .@"const" = true }
3897
3898__builtin_msa_aver_s_h
3899 .param_str = "V8SsV8SsV8Ss"
3900 .target_set = TargetSet.initOne(.mips)
3901 .attributes = .{ .@"const" = true }
3902
3903__builtin_msa_aver_s_w
3904 .param_str = "V4SiV4SiV4Si"
3905 .target_set = TargetSet.initOne(.mips)
3906 .attributes = .{ .@"const" = true }
3907
3908__builtin_msa_aver_u_b
3909 .param_str = "V16UcV16UcV16Uc"
3910 .target_set = TargetSet.initOne(.mips)
3911 .attributes = .{ .@"const" = true }
3912
3913__builtin_msa_aver_u_d
3914 .param_str = "V2ULLiV2ULLiV2ULLi"
3915 .target_set = TargetSet.initOne(.mips)
3916 .attributes = .{ .@"const" = true }
3917
3918__builtin_msa_aver_u_h
3919 .param_str = "V8UsV8UsV8Us"
3920 .target_set = TargetSet.initOne(.mips)
3921 .attributes = .{ .@"const" = true }
3922
3923__builtin_msa_aver_u_w
3924 .param_str = "V4UiV4UiV4Ui"
3925 .target_set = TargetSet.initOne(.mips)
3926 .attributes = .{ .@"const" = true }
3927
3928__builtin_msa_bclr_b
3929 .param_str = "V16UcV16UcV16Uc"
3930 .target_set = TargetSet.initOne(.mips)
3931 .attributes = .{ .@"const" = true }
3932
3933__builtin_msa_bclr_d
3934 .param_str = "V2ULLiV2ULLiV2ULLi"
3935 .target_set = TargetSet.initOne(.mips)
3936 .attributes = .{ .@"const" = true }
3937
3938__builtin_msa_bclr_h
3939 .param_str = "V8UsV8UsV8Us"
3940 .target_set = TargetSet.initOne(.mips)
3941 .attributes = .{ .@"const" = true }
3942
3943__builtin_msa_bclr_w
3944 .param_str = "V4UiV4UiV4Ui"
3945 .target_set = TargetSet.initOne(.mips)
3946 .attributes = .{ .@"const" = true }
3947
3948__builtin_msa_bclri_b
3949 .param_str = "V16UcV16UcIUi"
3950 .target_set = TargetSet.initOne(.mips)
3951 .attributes = .{ .@"const" = true }
3952
3953__builtin_msa_bclri_d
3954 .param_str = "V2ULLiV2ULLiIUi"
3955 .target_set = TargetSet.initOne(.mips)
3956 .attributes = .{ .@"const" = true }
3957
3958__builtin_msa_bclri_h
3959 .param_str = "V8UsV8UsIUi"
3960 .target_set = TargetSet.initOne(.mips)
3961 .attributes = .{ .@"const" = true }
3962
3963__builtin_msa_bclri_w
3964 .param_str = "V4UiV4UiIUi"
3965 .target_set = TargetSet.initOne(.mips)
3966 .attributes = .{ .@"const" = true }
3967
3968__builtin_msa_binsl_b
3969 .param_str = "V16UcV16UcV16UcV16Uc"
3970 .target_set = TargetSet.initOne(.mips)
3971 .attributes = .{ .@"const" = true }
3972
3973__builtin_msa_binsl_d
3974 .param_str = "V2ULLiV2ULLiV2ULLiV2ULLi"
3975 .target_set = TargetSet.initOne(.mips)
3976 .attributes = .{ .@"const" = true }
3977
3978__builtin_msa_binsl_h
3979 .param_str = "V8UsV8UsV8UsV8Us"
3980 .target_set = TargetSet.initOne(.mips)
3981 .attributes = .{ .@"const" = true }
3982
3983__builtin_msa_binsl_w
3984 .param_str = "V4UiV4UiV4UiV4Ui"
3985 .target_set = TargetSet.initOne(.mips)
3986 .attributes = .{ .@"const" = true }
3987
3988__builtin_msa_binsli_b
3989 .param_str = "V16UcV16UcV16UcIUi"
3990 .target_set = TargetSet.initOne(.mips)
3991 .attributes = .{ .@"const" = true }
3992
3993__builtin_msa_binsli_d
3994 .param_str = "V2ULLiV2ULLiV2ULLiIUi"
3995 .target_set = TargetSet.initOne(.mips)
3996 .attributes = .{ .@"const" = true }
3997
3998__builtin_msa_binsli_h
3999 .param_str = "V8UsV8UsV8UsIUi"
4000 .target_set = TargetSet.initOne(.mips)
4001 .attributes = .{ .@"const" = true }
4002
4003__builtin_msa_binsli_w
4004 .param_str = "V4UiV4UiV4UiIUi"
4005 .target_set = TargetSet.initOne(.mips)
4006 .attributes = .{ .@"const" = true }
4007
4008__builtin_msa_binsr_b
4009 .param_str = "V16UcV16UcV16UcV16Uc"
4010 .target_set = TargetSet.initOne(.mips)
4011 .attributes = .{ .@"const" = true }
4012
4013__builtin_msa_binsr_d
4014 .param_str = "V2ULLiV2ULLiV2ULLiV2ULLi"
4015 .target_set = TargetSet.initOne(.mips)
4016 .attributes = .{ .@"const" = true }
4017
4018__builtin_msa_binsr_h
4019 .param_str = "V8UsV8UsV8UsV8Us"
4020 .target_set = TargetSet.initOne(.mips)
4021 .attributes = .{ .@"const" = true }
4022
4023__builtin_msa_binsr_w
4024 .param_str = "V4UiV4UiV4UiV4Ui"
4025 .target_set = TargetSet.initOne(.mips)
4026 .attributes = .{ .@"const" = true }
4027
4028__builtin_msa_binsri_b
4029 .param_str = "V16UcV16UcV16UcIUi"
4030 .target_set = TargetSet.initOne(.mips)
4031 .attributes = .{ .@"const" = true }
4032
4033__builtin_msa_binsri_d
4034 .param_str = "V2ULLiV2ULLiV2ULLiIUi"
4035 .target_set = TargetSet.initOne(.mips)
4036 .attributes = .{ .@"const" = true }
4037
4038__builtin_msa_binsri_h
4039 .param_str = "V8UsV8UsV8UsIUi"
4040 .target_set = TargetSet.initOne(.mips)
4041 .attributes = .{ .@"const" = true }
4042
4043__builtin_msa_binsri_w
4044 .param_str = "V4UiV4UiV4UiIUi"
4045 .target_set = TargetSet.initOne(.mips)
4046 .attributes = .{ .@"const" = true }
4047
4048__builtin_msa_bmnz_v
4049 .param_str = "V16UcV16UcV16UcV16Uc"
4050 .target_set = TargetSet.initOne(.mips)
4051 .attributes = .{ .@"const" = true }
4052
4053__builtin_msa_bmnzi_b
4054 .param_str = "V16UcV16UcV16UcIUi"
4055 .target_set = TargetSet.initOne(.mips)
4056 .attributes = .{ .@"const" = true }
4057
4058__builtin_msa_bmz_v
4059 .param_str = "V16UcV16UcV16UcV16Uc"
4060 .target_set = TargetSet.initOne(.mips)
4061 .attributes = .{ .@"const" = true }
4062
4063__builtin_msa_bmzi_b
4064 .param_str = "V16UcV16UcV16UcIUi"
4065 .target_set = TargetSet.initOne(.mips)
4066 .attributes = .{ .@"const" = true }
4067
4068__builtin_msa_bneg_b
4069 .param_str = "V16UcV16UcV16Uc"
4070 .target_set = TargetSet.initOne(.mips)
4071 .attributes = .{ .@"const" = true }
4072
4073__builtin_msa_bneg_d
4074 .param_str = "V2ULLiV2ULLiV2ULLi"
4075 .target_set = TargetSet.initOne(.mips)
4076 .attributes = .{ .@"const" = true }
4077
4078__builtin_msa_bneg_h
4079 .param_str = "V8UsV8UsV8Us"
4080 .target_set = TargetSet.initOne(.mips)
4081 .attributes = .{ .@"const" = true }
4082
4083__builtin_msa_bneg_w
4084 .param_str = "V4UiV4UiV4Ui"
4085 .target_set = TargetSet.initOne(.mips)
4086 .attributes = .{ .@"const" = true }
4087
4088__builtin_msa_bnegi_b
4089 .param_str = "V16UcV16UcIUi"
4090 .target_set = TargetSet.initOne(.mips)
4091 .attributes = .{ .@"const" = true }
4092
4093__builtin_msa_bnegi_d
4094 .param_str = "V2ULLiV2ULLiIUi"
4095 .target_set = TargetSet.initOne(.mips)
4096 .attributes = .{ .@"const" = true }
4097
4098__builtin_msa_bnegi_h
4099 .param_str = "V8UsV8UsIUi"
4100 .target_set = TargetSet.initOne(.mips)
4101 .attributes = .{ .@"const" = true }
4102
4103__builtin_msa_bnegi_w
4104 .param_str = "V4UiV4UiIUi"
4105 .target_set = TargetSet.initOne(.mips)
4106 .attributes = .{ .@"const" = true }
4107
4108__builtin_msa_bnz_b
4109 .param_str = "iV16Uc"
4110 .target_set = TargetSet.initOne(.mips)
4111 .attributes = .{ .@"const" = true }
4112
4113__builtin_msa_bnz_d
4114 .param_str = "iV2ULLi"
4115 .target_set = TargetSet.initOne(.mips)
4116 .attributes = .{ .@"const" = true }
4117
4118__builtin_msa_bnz_h
4119 .param_str = "iV8Us"
4120 .target_set = TargetSet.initOne(.mips)
4121 .attributes = .{ .@"const" = true }
4122
4123__builtin_msa_bnz_v
4124 .param_str = "iV16Uc"
4125 .target_set = TargetSet.initOne(.mips)
4126 .attributes = .{ .@"const" = true }
4127
4128__builtin_msa_bnz_w
4129 .param_str = "iV4Ui"
4130 .target_set = TargetSet.initOne(.mips)
4131 .attributes = .{ .@"const" = true }
4132
4133__builtin_msa_bsel_v
4134 .param_str = "V16UcV16UcV16UcV16Uc"
4135 .target_set = TargetSet.initOne(.mips)
4136 .attributes = .{ .@"const" = true }
4137
4138__builtin_msa_bseli_b
4139 .param_str = "V16UcV16UcV16UcIUi"
4140 .target_set = TargetSet.initOne(.mips)
4141 .attributes = .{ .@"const" = true }
4142
4143__builtin_msa_bset_b
4144 .param_str = "V16UcV16UcV16Uc"
4145 .target_set = TargetSet.initOne(.mips)
4146 .attributes = .{ .@"const" = true }
4147
4148__builtin_msa_bset_d
4149 .param_str = "V2ULLiV2ULLiV2ULLi"
4150 .target_set = TargetSet.initOne(.mips)
4151 .attributes = .{ .@"const" = true }
4152
4153__builtin_msa_bset_h
4154 .param_str = "V8UsV8UsV8Us"
4155 .target_set = TargetSet.initOne(.mips)
4156 .attributes = .{ .@"const" = true }
4157
4158__builtin_msa_bset_w
4159 .param_str = "V4UiV4UiV4Ui"
4160 .target_set = TargetSet.initOne(.mips)
4161 .attributes = .{ .@"const" = true }
4162
4163__builtin_msa_bseti_b
4164 .param_str = "V16UcV16UcIUi"
4165 .target_set = TargetSet.initOne(.mips)
4166 .attributes = .{ .@"const" = true }
4167
4168__builtin_msa_bseti_d
4169 .param_str = "V2ULLiV2ULLiIUi"
4170 .target_set = TargetSet.initOne(.mips)
4171 .attributes = .{ .@"const" = true }
4172
4173__builtin_msa_bseti_h
4174 .param_str = "V8UsV8UsIUi"
4175 .target_set = TargetSet.initOne(.mips)
4176 .attributes = .{ .@"const" = true }
4177
4178__builtin_msa_bseti_w
4179 .param_str = "V4UiV4UiIUi"
4180 .target_set = TargetSet.initOne(.mips)
4181 .attributes = .{ .@"const" = true }
4182
4183__builtin_msa_bz_b
4184 .param_str = "iV16Uc"
4185 .target_set = TargetSet.initOne(.mips)
4186 .attributes = .{ .@"const" = true }
4187
4188__builtin_msa_bz_d
4189 .param_str = "iV2ULLi"
4190 .target_set = TargetSet.initOne(.mips)
4191 .attributes = .{ .@"const" = true }
4192
4193__builtin_msa_bz_h
4194 .param_str = "iV8Us"
4195 .target_set = TargetSet.initOne(.mips)
4196 .attributes = .{ .@"const" = true }
4197
4198__builtin_msa_bz_v
4199 .param_str = "iV16Uc"
4200 .target_set = TargetSet.initOne(.mips)
4201 .attributes = .{ .@"const" = true }
4202
4203__builtin_msa_bz_w
4204 .param_str = "iV4Ui"
4205 .target_set = TargetSet.initOne(.mips)
4206 .attributes = .{ .@"const" = true }
4207
4208__builtin_msa_ceq_b
4209 .param_str = "V16ScV16ScV16Sc"
4210 .target_set = TargetSet.initOne(.mips)
4211 .attributes = .{ .@"const" = true }
4212
4213__builtin_msa_ceq_d
4214 .param_str = "V2SLLiV2SLLiV2SLLi"
4215 .target_set = TargetSet.initOne(.mips)
4216 .attributes = .{ .@"const" = true }
4217
4218__builtin_msa_ceq_h
4219 .param_str = "V8SsV8SsV8Ss"
4220 .target_set = TargetSet.initOne(.mips)
4221 .attributes = .{ .@"const" = true }
4222
4223__builtin_msa_ceq_w
4224 .param_str = "V4SiV4SiV4Si"
4225 .target_set = TargetSet.initOne(.mips)
4226 .attributes = .{ .@"const" = true }
4227
4228__builtin_msa_ceqi_b
4229 .param_str = "V16ScV16ScISi"
4230 .target_set = TargetSet.initOne(.mips)
4231 .attributes = .{ .@"const" = true }
4232
4233__builtin_msa_ceqi_d
4234 .param_str = "V2SLLiV2SLLiISi"
4235 .target_set = TargetSet.initOne(.mips)
4236 .attributes = .{ .@"const" = true }
4237
4238__builtin_msa_ceqi_h
4239 .param_str = "V8SsV8SsISi"
4240 .target_set = TargetSet.initOne(.mips)
4241 .attributes = .{ .@"const" = true }
4242
4243__builtin_msa_ceqi_w
4244 .param_str = "V4SiV4SiISi"
4245 .target_set = TargetSet.initOne(.mips)
4246 .attributes = .{ .@"const" = true }
4247
4248__builtin_msa_cfcmsa
4249 .param_str = "iIi"
4250 .target_set = TargetSet.initOne(.mips)
4251
4252__builtin_msa_cle_s_b
4253 .param_str = "V16ScV16ScV16Sc"
4254 .target_set = TargetSet.initOne(.mips)
4255 .attributes = .{ .@"const" = true }
4256
4257__builtin_msa_cle_s_d
4258 .param_str = "V2SLLiV2SLLiV2SLLi"
4259 .target_set = TargetSet.initOne(.mips)
4260 .attributes = .{ .@"const" = true }
4261
4262__builtin_msa_cle_s_h
4263 .param_str = "V8SsV8SsV8Ss"
4264 .target_set = TargetSet.initOne(.mips)
4265 .attributes = .{ .@"const" = true }
4266
4267__builtin_msa_cle_s_w
4268 .param_str = "V4SiV4SiV4Si"
4269 .target_set = TargetSet.initOne(.mips)
4270 .attributes = .{ .@"const" = true }
4271
4272__builtin_msa_cle_u_b
4273 .param_str = "V16ScV16UcV16Uc"
4274 .target_set = TargetSet.initOne(.mips)
4275 .attributes = .{ .@"const" = true }
4276
4277__builtin_msa_cle_u_d
4278 .param_str = "V2SLLiV2ULLiV2ULLi"
4279 .target_set = TargetSet.initOne(.mips)
4280 .attributes = .{ .@"const" = true }
4281
4282__builtin_msa_cle_u_h
4283 .param_str = "V8SsV8UsV8Us"
4284 .target_set = TargetSet.initOne(.mips)
4285 .attributes = .{ .@"const" = true }
4286
4287__builtin_msa_cle_u_w
4288 .param_str = "V4SiV4UiV4Ui"
4289 .target_set = TargetSet.initOne(.mips)
4290 .attributes = .{ .@"const" = true }
4291
4292__builtin_msa_clei_s_b
4293 .param_str = "V16ScV16ScISi"
4294 .target_set = TargetSet.initOne(.mips)
4295 .attributes = .{ .@"const" = true }
4296
4297__builtin_msa_clei_s_d
4298 .param_str = "V2SLLiV2SLLiISi"
4299 .target_set = TargetSet.initOne(.mips)
4300 .attributes = .{ .@"const" = true }
4301
4302__builtin_msa_clei_s_h
4303 .param_str = "V8SsV8SsISi"
4304 .target_set = TargetSet.initOne(.mips)
4305 .attributes = .{ .@"const" = true }
4306
4307__builtin_msa_clei_s_w
4308 .param_str = "V4SiV4SiISi"
4309 .target_set = TargetSet.initOne(.mips)
4310 .attributes = .{ .@"const" = true }
4311
4312__builtin_msa_clei_u_b
4313 .param_str = "V16ScV16UcIUi"
4314 .target_set = TargetSet.initOne(.mips)
4315 .attributes = .{ .@"const" = true }
4316
4317__builtin_msa_clei_u_d
4318 .param_str = "V2SLLiV2ULLiIUi"
4319 .target_set = TargetSet.initOne(.mips)
4320 .attributes = .{ .@"const" = true }
4321
4322__builtin_msa_clei_u_h
4323 .param_str = "V8SsV8UsIUi"
4324 .target_set = TargetSet.initOne(.mips)
4325 .attributes = .{ .@"const" = true }
4326
4327__builtin_msa_clei_u_w
4328 .param_str = "V4SiV4UiIUi"
4329 .target_set = TargetSet.initOne(.mips)
4330 .attributes = .{ .@"const" = true }
4331
4332__builtin_msa_clt_s_b
4333 .param_str = "V16ScV16ScV16Sc"
4334 .target_set = TargetSet.initOne(.mips)
4335 .attributes = .{ .@"const" = true }
4336
4337__builtin_msa_clt_s_d
4338 .param_str = "V2SLLiV2SLLiV2SLLi"
4339 .target_set = TargetSet.initOne(.mips)
4340 .attributes = .{ .@"const" = true }
4341
4342__builtin_msa_clt_s_h
4343 .param_str = "V8SsV8SsV8Ss"
4344 .target_set = TargetSet.initOne(.mips)
4345 .attributes = .{ .@"const" = true }
4346
4347__builtin_msa_clt_s_w
4348 .param_str = "V4SiV4SiV4Si"
4349 .target_set = TargetSet.initOne(.mips)
4350 .attributes = .{ .@"const" = true }
4351
4352__builtin_msa_clt_u_b
4353 .param_str = "V16ScV16UcV16Uc"
4354 .target_set = TargetSet.initOne(.mips)
4355 .attributes = .{ .@"const" = true }
4356
4357__builtin_msa_clt_u_d
4358 .param_str = "V2SLLiV2ULLiV2ULLi"
4359 .target_set = TargetSet.initOne(.mips)
4360 .attributes = .{ .@"const" = true }
4361
4362__builtin_msa_clt_u_h
4363 .param_str = "V8SsV8UsV8Us"
4364 .target_set = TargetSet.initOne(.mips)
4365 .attributes = .{ .@"const" = true }
4366
4367__builtin_msa_clt_u_w
4368 .param_str = "V4SiV4UiV4Ui"
4369 .target_set = TargetSet.initOne(.mips)
4370 .attributes = .{ .@"const" = true }
4371
4372__builtin_msa_clti_s_b
4373 .param_str = "V16ScV16ScISi"
4374 .target_set = TargetSet.initOne(.mips)
4375 .attributes = .{ .@"const" = true }
4376
4377__builtin_msa_clti_s_d
4378 .param_str = "V2SLLiV2SLLiISi"
4379 .target_set = TargetSet.initOne(.mips)
4380 .attributes = .{ .@"const" = true }
4381
4382__builtin_msa_clti_s_h
4383 .param_str = "V8SsV8SsISi"
4384 .target_set = TargetSet.initOne(.mips)
4385 .attributes = .{ .@"const" = true }
4386
4387__builtin_msa_clti_s_w
4388 .param_str = "V4SiV4SiISi"
4389 .target_set = TargetSet.initOne(.mips)
4390 .attributes = .{ .@"const" = true }
4391
4392__builtin_msa_clti_u_b
4393 .param_str = "V16ScV16UcIUi"
4394 .target_set = TargetSet.initOne(.mips)
4395 .attributes = .{ .@"const" = true }
4396
4397__builtin_msa_clti_u_d
4398 .param_str = "V2SLLiV2ULLiIUi"
4399 .target_set = TargetSet.initOne(.mips)
4400 .attributes = .{ .@"const" = true }
4401
4402__builtin_msa_clti_u_h
4403 .param_str = "V8SsV8UsIUi"
4404 .target_set = TargetSet.initOne(.mips)
4405 .attributes = .{ .@"const" = true }
4406
4407__builtin_msa_clti_u_w
4408 .param_str = "V4SiV4UiIUi"
4409 .target_set = TargetSet.initOne(.mips)
4410 .attributes = .{ .@"const" = true }
4411
4412__builtin_msa_copy_s_b
4413 .param_str = "iV16ScIUi"
4414 .target_set = TargetSet.initOne(.mips)
4415 .attributes = .{ .@"const" = true }
4416
4417__builtin_msa_copy_s_d
4418 .param_str = "LLiV2SLLiIUi"
4419 .target_set = TargetSet.initOne(.mips)
4420 .attributes = .{ .@"const" = true }
4421
4422__builtin_msa_copy_s_h
4423 .param_str = "iV8SsIUi"
4424 .target_set = TargetSet.initOne(.mips)
4425 .attributes = .{ .@"const" = true }
4426
4427__builtin_msa_copy_s_w
4428 .param_str = "iV4SiIUi"
4429 .target_set = TargetSet.initOne(.mips)
4430 .attributes = .{ .@"const" = true }
4431
4432__builtin_msa_copy_u_b
4433 .param_str = "iV16UcIUi"
4434 .target_set = TargetSet.initOne(.mips)
4435 .attributes = .{ .@"const" = true }
4436
4437__builtin_msa_copy_u_d
4438 .param_str = "LLiV2ULLiIUi"
4439 .target_set = TargetSet.initOne(.mips)
4440 .attributes = .{ .@"const" = true }
4441
4442__builtin_msa_copy_u_h
4443 .param_str = "iV8UsIUi"
4444 .target_set = TargetSet.initOne(.mips)
4445 .attributes = .{ .@"const" = true }
4446
4447__builtin_msa_copy_u_w
4448 .param_str = "iV4UiIUi"
4449 .target_set = TargetSet.initOne(.mips)
4450 .attributes = .{ .@"const" = true }
4451
4452__builtin_msa_ctcmsa
4453 .param_str = "vIii"
4454 .target_set = TargetSet.initOne(.mips)
4455
4456__builtin_msa_div_s_b
4457 .param_str = "V16ScV16ScV16Sc"
4458 .target_set = TargetSet.initOne(.mips)
4459 .attributes = .{ .@"const" = true }
4460
4461__builtin_msa_div_s_d
4462 .param_str = "V2SLLiV2SLLiV2SLLi"
4463 .target_set = TargetSet.initOne(.mips)
4464 .attributes = .{ .@"const" = true }
4465
4466__builtin_msa_div_s_h
4467 .param_str = "V8SsV8SsV8Ss"
4468 .target_set = TargetSet.initOne(.mips)
4469 .attributes = .{ .@"const" = true }
4470
4471__builtin_msa_div_s_w
4472 .param_str = "V4SiV4SiV4Si"
4473 .target_set = TargetSet.initOne(.mips)
4474 .attributes = .{ .@"const" = true }
4475
4476__builtin_msa_div_u_b
4477 .param_str = "V16UcV16UcV16Uc"
4478 .target_set = TargetSet.initOne(.mips)
4479 .attributes = .{ .@"const" = true }
4480
4481__builtin_msa_div_u_d
4482 .param_str = "V2ULLiV2ULLiV2ULLi"
4483 .target_set = TargetSet.initOne(.mips)
4484 .attributes = .{ .@"const" = true }
4485
4486__builtin_msa_div_u_h
4487 .param_str = "V8UsV8UsV8Us"
4488 .target_set = TargetSet.initOne(.mips)
4489 .attributes = .{ .@"const" = true }
4490
4491__builtin_msa_div_u_w
4492 .param_str = "V4UiV4UiV4Ui"
4493 .target_set = TargetSet.initOne(.mips)
4494 .attributes = .{ .@"const" = true }
4495
4496__builtin_msa_dotp_s_d
4497 .param_str = "V2SLLiV4SiV4Si"
4498 .target_set = TargetSet.initOne(.mips)
4499 .attributes = .{ .@"const" = true }
4500
4501__builtin_msa_dotp_s_h
4502 .param_str = "V8SsV16ScV16Sc"
4503 .target_set = TargetSet.initOne(.mips)
4504 .attributes = .{ .@"const" = true }
4505
4506__builtin_msa_dotp_s_w
4507 .param_str = "V4SiV8SsV8Ss"
4508 .target_set = TargetSet.initOne(.mips)
4509 .attributes = .{ .@"const" = true }
4510
4511__builtin_msa_dotp_u_d
4512 .param_str = "V2ULLiV4UiV4Ui"
4513 .target_set = TargetSet.initOne(.mips)
4514 .attributes = .{ .@"const" = true }
4515
4516__builtin_msa_dotp_u_h
4517 .param_str = "V8UsV16UcV16Uc"
4518 .target_set = TargetSet.initOne(.mips)
4519 .attributes = .{ .@"const" = true }
4520
4521__builtin_msa_dotp_u_w
4522 .param_str = "V4UiV8UsV8Us"
4523 .target_set = TargetSet.initOne(.mips)
4524 .attributes = .{ .@"const" = true }
4525
4526__builtin_msa_dpadd_s_d
4527 .param_str = "V2SLLiV2SLLiV4SiV4Si"
4528 .target_set = TargetSet.initOne(.mips)
4529 .attributes = .{ .@"const" = true }
4530
4531__builtin_msa_dpadd_s_h
4532 .param_str = "V8SsV8SsV16ScV16Sc"
4533 .target_set = TargetSet.initOne(.mips)
4534 .attributes = .{ .@"const" = true }
4535
4536__builtin_msa_dpadd_s_w
4537 .param_str = "V4SiV4SiV8SsV8Ss"
4538 .target_set = TargetSet.initOne(.mips)
4539 .attributes = .{ .@"const" = true }
4540
4541__builtin_msa_dpadd_u_d
4542 .param_str = "V2ULLiV2ULLiV4UiV4Ui"
4543 .target_set = TargetSet.initOne(.mips)
4544 .attributes = .{ .@"const" = true }
4545
4546__builtin_msa_dpadd_u_h
4547 .param_str = "V8UsV8UsV16UcV16Uc"
4548 .target_set = TargetSet.initOne(.mips)
4549 .attributes = .{ .@"const" = true }
4550
4551__builtin_msa_dpadd_u_w
4552 .param_str = "V4UiV4UiV8UsV8Us"
4553 .target_set = TargetSet.initOne(.mips)
4554 .attributes = .{ .@"const" = true }
4555
4556__builtin_msa_dpsub_s_d
4557 .param_str = "V2SLLiV2SLLiV4SiV4Si"
4558 .target_set = TargetSet.initOne(.mips)
4559 .attributes = .{ .@"const" = true }
4560
4561__builtin_msa_dpsub_s_h
4562 .param_str = "V8SsV8SsV16ScV16Sc"
4563 .target_set = TargetSet.initOne(.mips)
4564 .attributes = .{ .@"const" = true }
4565
4566__builtin_msa_dpsub_s_w
4567 .param_str = "V4SiV4SiV8SsV8Ss"
4568 .target_set = TargetSet.initOne(.mips)
4569 .attributes = .{ .@"const" = true }
4570
4571__builtin_msa_dpsub_u_d
4572 .param_str = "V2ULLiV2ULLiV4UiV4Ui"
4573 .target_set = TargetSet.initOne(.mips)
4574 .attributes = .{ .@"const" = true }
4575
4576__builtin_msa_dpsub_u_h
4577 .param_str = "V8UsV8UsV16UcV16Uc"
4578 .target_set = TargetSet.initOne(.mips)
4579 .attributes = .{ .@"const" = true }
4580
4581__builtin_msa_dpsub_u_w
4582 .param_str = "V4UiV4UiV8UsV8Us"
4583 .target_set = TargetSet.initOne(.mips)
4584 .attributes = .{ .@"const" = true }
4585
4586__builtin_msa_fadd_d
4587 .param_str = "V2dV2dV2d"
4588 .target_set = TargetSet.initOne(.mips)
4589 .attributes = .{ .@"const" = true }
4590
4591__builtin_msa_fadd_w
4592 .param_str = "V4fV4fV4f"
4593 .target_set = TargetSet.initOne(.mips)
4594 .attributes = .{ .@"const" = true }
4595
4596__builtin_msa_fcaf_d
4597 .param_str = "V2LLiV2dV2d"
4598 .target_set = TargetSet.initOne(.mips)
4599 .attributes = .{ .@"const" = true }
4600
4601__builtin_msa_fcaf_w
4602 .param_str = "V4iV4fV4f"
4603 .target_set = TargetSet.initOne(.mips)
4604 .attributes = .{ .@"const" = true }
4605
4606__builtin_msa_fceq_d
4607 .param_str = "V2LLiV2dV2d"
4608 .target_set = TargetSet.initOne(.mips)
4609 .attributes = .{ .@"const" = true }
4610
4611__builtin_msa_fceq_w
4612 .param_str = "V4iV4fV4f"
4613 .target_set = TargetSet.initOne(.mips)
4614 .attributes = .{ .@"const" = true }
4615
4616__builtin_msa_fclass_d
4617 .param_str = "V2LLiV2d"
4618 .target_set = TargetSet.initOne(.mips)
4619 .attributes = .{ .@"const" = true }
4620
4621__builtin_msa_fclass_w
4622 .param_str = "V4iV4f"
4623 .target_set = TargetSet.initOne(.mips)
4624 .attributes = .{ .@"const" = true }
4625
4626__builtin_msa_fcle_d
4627 .param_str = "V2LLiV2dV2d"
4628 .target_set = TargetSet.initOne(.mips)
4629 .attributes = .{ .@"const" = true }
4630
4631__builtin_msa_fcle_w
4632 .param_str = "V4iV4fV4f"
4633 .target_set = TargetSet.initOne(.mips)
4634 .attributes = .{ .@"const" = true }
4635
4636__builtin_msa_fclt_d
4637 .param_str = "V2LLiV2dV2d"
4638 .target_set = TargetSet.initOne(.mips)
4639 .attributes = .{ .@"const" = true }
4640
4641__builtin_msa_fclt_w
4642 .param_str = "V4iV4fV4f"
4643 .target_set = TargetSet.initOne(.mips)
4644 .attributes = .{ .@"const" = true }
4645
4646__builtin_msa_fcne_d
4647 .param_str = "V2LLiV2dV2d"
4648 .target_set = TargetSet.initOne(.mips)
4649 .attributes = .{ .@"const" = true }
4650
4651__builtin_msa_fcne_w
4652 .param_str = "V4iV4fV4f"
4653 .target_set = TargetSet.initOne(.mips)
4654 .attributes = .{ .@"const" = true }
4655
4656__builtin_msa_fcor_d
4657 .param_str = "V2LLiV2dV2d"
4658 .target_set = TargetSet.initOne(.mips)
4659 .attributes = .{ .@"const" = true }
4660
4661__builtin_msa_fcor_w
4662 .param_str = "V4iV4fV4f"
4663 .target_set = TargetSet.initOne(.mips)
4664 .attributes = .{ .@"const" = true }
4665
4666__builtin_msa_fcueq_d
4667 .param_str = "V2LLiV2dV2d"
4668 .target_set = TargetSet.initOne(.mips)
4669 .attributes = .{ .@"const" = true }
4670
4671__builtin_msa_fcueq_w
4672 .param_str = "V4iV4fV4f"
4673 .target_set = TargetSet.initOne(.mips)
4674 .attributes = .{ .@"const" = true }
4675
4676__builtin_msa_fcule_d
4677 .param_str = "V2LLiV2dV2d"
4678 .target_set = TargetSet.initOne(.mips)
4679 .attributes = .{ .@"const" = true }
4680
4681__builtin_msa_fcule_w
4682 .param_str = "V4iV4fV4f"
4683 .target_set = TargetSet.initOne(.mips)
4684 .attributes = .{ .@"const" = true }
4685
4686__builtin_msa_fcult_d
4687 .param_str = "V2LLiV2dV2d"
4688 .target_set = TargetSet.initOne(.mips)
4689 .attributes = .{ .@"const" = true }
4690
4691__builtin_msa_fcult_w
4692 .param_str = "V4iV4fV4f"
4693 .target_set = TargetSet.initOne(.mips)
4694 .attributes = .{ .@"const" = true }
4695
4696__builtin_msa_fcun_d
4697 .param_str = "V2LLiV2dV2d"
4698 .target_set = TargetSet.initOne(.mips)
4699 .attributes = .{ .@"const" = true }
4700
4701__builtin_msa_fcun_w
4702 .param_str = "V4iV4fV4f"
4703 .target_set = TargetSet.initOne(.mips)
4704 .attributes = .{ .@"const" = true }
4705
4706__builtin_msa_fcune_d
4707 .param_str = "V2LLiV2dV2d"
4708 .target_set = TargetSet.initOne(.mips)
4709 .attributes = .{ .@"const" = true }
4710
4711__builtin_msa_fcune_w
4712 .param_str = "V4iV4fV4f"
4713 .target_set = TargetSet.initOne(.mips)
4714 .attributes = .{ .@"const" = true }
4715
4716__builtin_msa_fdiv_d
4717 .param_str = "V2dV2dV2d"
4718 .target_set = TargetSet.initOne(.mips)
4719 .attributes = .{ .@"const" = true }
4720
4721__builtin_msa_fdiv_w
4722 .param_str = "V4fV4fV4f"
4723 .target_set = TargetSet.initOne(.mips)
4724 .attributes = .{ .@"const" = true }
4725
4726__builtin_msa_fexdo_h
4727 .param_str = "V8hV4fV4f"
4728 .target_set = TargetSet.initOne(.mips)
4729 .attributes = .{ .@"const" = true }
4730
4731__builtin_msa_fexdo_w
4732 .param_str = "V4fV2dV2d"
4733 .target_set = TargetSet.initOne(.mips)
4734 .attributes = .{ .@"const" = true }
4735
4736__builtin_msa_fexp2_d
4737 .param_str = "V2dV2dV2LLi"
4738 .target_set = TargetSet.initOne(.mips)
4739 .attributes = .{ .@"const" = true }
4740
4741__builtin_msa_fexp2_w
4742 .param_str = "V4fV4fV4i"
4743 .target_set = TargetSet.initOne(.mips)
4744 .attributes = .{ .@"const" = true }
4745
4746__builtin_msa_fexupl_d
4747 .param_str = "V2dV4f"
4748 .target_set = TargetSet.initOne(.mips)
4749 .attributes = .{ .@"const" = true }
4750
4751__builtin_msa_fexupl_w
4752 .param_str = "V4fV8h"
4753 .target_set = TargetSet.initOne(.mips)
4754 .attributes = .{ .@"const" = true }
4755
4756__builtin_msa_fexupr_d
4757 .param_str = "V2dV4f"
4758 .target_set = TargetSet.initOne(.mips)
4759 .attributes = .{ .@"const" = true }
4760
4761__builtin_msa_fexupr_w
4762 .param_str = "V4fV8h"
4763 .target_set = TargetSet.initOne(.mips)
4764 .attributes = .{ .@"const" = true }
4765
4766__builtin_msa_ffint_s_d
4767 .param_str = "V2dV2SLLi"
4768 .target_set = TargetSet.initOne(.mips)
4769 .attributes = .{ .@"const" = true }
4770
4771__builtin_msa_ffint_s_w
4772 .param_str = "V4fV4Si"
4773 .target_set = TargetSet.initOne(.mips)
4774 .attributes = .{ .@"const" = true }
4775
4776__builtin_msa_ffint_u_d
4777 .param_str = "V2dV2ULLi"
4778 .target_set = TargetSet.initOne(.mips)
4779 .attributes = .{ .@"const" = true }
4780
4781__builtin_msa_ffint_u_w
4782 .param_str = "V4fV4Ui"
4783 .target_set = TargetSet.initOne(.mips)
4784 .attributes = .{ .@"const" = true }
4785
4786__builtin_msa_ffql_d
4787 .param_str = "V2dV4Si"
4788 .target_set = TargetSet.initOne(.mips)
4789 .attributes = .{ .@"const" = true }
4790
4791__builtin_msa_ffql_w
4792 .param_str = "V4fV8Ss"
4793 .target_set = TargetSet.initOne(.mips)
4794 .attributes = .{ .@"const" = true }
4795
4796__builtin_msa_ffqr_d
4797 .param_str = "V2dV4Si"
4798 .target_set = TargetSet.initOne(.mips)
4799 .attributes = .{ .@"const" = true }
4800
4801__builtin_msa_ffqr_w
4802 .param_str = "V4fV8Ss"
4803 .target_set = TargetSet.initOne(.mips)
4804 .attributes = .{ .@"const" = true }
4805
4806__builtin_msa_fill_b
4807 .param_str = "V16Sci"
4808 .target_set = TargetSet.initOne(.mips)
4809 .attributes = .{ .@"const" = true }
4810
4811__builtin_msa_fill_d
4812 .param_str = "V2SLLiLLi"
4813 .target_set = TargetSet.initOne(.mips)
4814 .attributes = .{ .@"const" = true }
4815
4816__builtin_msa_fill_h
4817 .param_str = "V8Ssi"
4818 .target_set = TargetSet.initOne(.mips)
4819 .attributes = .{ .@"const" = true }
4820
4821__builtin_msa_fill_w
4822 .param_str = "V4Sii"
4823 .target_set = TargetSet.initOne(.mips)
4824 .attributes = .{ .@"const" = true }
4825
4826__builtin_msa_flog2_d
4827 .param_str = "V2dV2d"
4828 .target_set = TargetSet.initOne(.mips)
4829 .attributes = .{ .@"const" = true }
4830
4831__builtin_msa_flog2_w
4832 .param_str = "V4fV4f"
4833 .target_set = TargetSet.initOne(.mips)
4834 .attributes = .{ .@"const" = true }
4835
4836__builtin_msa_fmadd_d
4837 .param_str = "V2dV2dV2dV2d"
4838 .target_set = TargetSet.initOne(.mips)
4839 .attributes = .{ .@"const" = true }
4840
4841__builtin_msa_fmadd_w
4842 .param_str = "V4fV4fV4fV4f"
4843 .target_set = TargetSet.initOne(.mips)
4844 .attributes = .{ .@"const" = true }
4845
4846__builtin_msa_fmax_a_d
4847 .param_str = "V2dV2dV2d"
4848 .target_set = TargetSet.initOne(.mips)
4849 .attributes = .{ .@"const" = true }
4850
4851__builtin_msa_fmax_a_w
4852 .param_str = "V4fV4fV4f"
4853 .target_set = TargetSet.initOne(.mips)
4854 .attributes = .{ .@"const" = true }
4855
4856__builtin_msa_fmax_d
4857 .param_str = "V2dV2dV2d"
4858 .target_set = TargetSet.initOne(.mips)
4859 .attributes = .{ .@"const" = true }
4860
4861__builtin_msa_fmax_w
4862 .param_str = "V4fV4fV4f"
4863 .target_set = TargetSet.initOne(.mips)
4864 .attributes = .{ .@"const" = true }
4865
4866__builtin_msa_fmin_a_d
4867 .param_str = "V2dV2dV2d"
4868 .target_set = TargetSet.initOne(.mips)
4869 .attributes = .{ .@"const" = true }
4870
4871__builtin_msa_fmin_a_w
4872 .param_str = "V4fV4fV4f"
4873 .target_set = TargetSet.initOne(.mips)
4874 .attributes = .{ .@"const" = true }
4875
4876__builtin_msa_fmin_d
4877 .param_str = "V2dV2dV2d"
4878 .target_set = TargetSet.initOne(.mips)
4879 .attributes = .{ .@"const" = true }
4880
4881__builtin_msa_fmin_w
4882 .param_str = "V4fV4fV4f"
4883 .target_set = TargetSet.initOne(.mips)
4884 .attributes = .{ .@"const" = true }
4885
4886__builtin_msa_fmsub_d
4887 .param_str = "V2dV2dV2dV2d"
4888 .target_set = TargetSet.initOne(.mips)
4889 .attributes = .{ .@"const" = true }
4890
4891__builtin_msa_fmsub_w
4892 .param_str = "V4fV4fV4fV4f"
4893 .target_set = TargetSet.initOne(.mips)
4894 .attributes = .{ .@"const" = true }
4895
4896__builtin_msa_fmul_d
4897 .param_str = "V2dV2dV2d"
4898 .target_set = TargetSet.initOne(.mips)
4899 .attributes = .{ .@"const" = true }
4900
4901__builtin_msa_fmul_w
4902 .param_str = "V4fV4fV4f"
4903 .target_set = TargetSet.initOne(.mips)
4904 .attributes = .{ .@"const" = true }
4905
4906__builtin_msa_frcp_d
4907 .param_str = "V2dV2d"
4908 .target_set = TargetSet.initOne(.mips)
4909 .attributes = .{ .@"const" = true }
4910
4911__builtin_msa_frcp_w
4912 .param_str = "V4fV4f"
4913 .target_set = TargetSet.initOne(.mips)
4914 .attributes = .{ .@"const" = true }
4915
4916__builtin_msa_frint_d
4917 .param_str = "V2dV2d"
4918 .target_set = TargetSet.initOne(.mips)
4919 .attributes = .{ .@"const" = true }
4920
4921__builtin_msa_frint_w
4922 .param_str = "V4fV4f"
4923 .target_set = TargetSet.initOne(.mips)
4924 .attributes = .{ .@"const" = true }
4925
4926__builtin_msa_frsqrt_d
4927 .param_str = "V2dV2d"
4928 .target_set = TargetSet.initOne(.mips)
4929 .attributes = .{ .@"const" = true }
4930
4931__builtin_msa_frsqrt_w
4932 .param_str = "V4fV4f"
4933 .target_set = TargetSet.initOne(.mips)
4934 .attributes = .{ .@"const" = true }
4935
4936__builtin_msa_fsaf_d
4937 .param_str = "V2LLiV2dV2d"
4938 .target_set = TargetSet.initOne(.mips)
4939 .attributes = .{ .@"const" = true }
4940
4941__builtin_msa_fsaf_w
4942 .param_str = "V4iV4fV4f"
4943 .target_set = TargetSet.initOne(.mips)
4944 .attributes = .{ .@"const" = true }
4945
4946__builtin_msa_fseq_d
4947 .param_str = "V2LLiV2dV2d"
4948 .target_set = TargetSet.initOne(.mips)
4949 .attributes = .{ .@"const" = true }
4950
4951__builtin_msa_fseq_w
4952 .param_str = "V4iV4fV4f"
4953 .target_set = TargetSet.initOne(.mips)
4954 .attributes = .{ .@"const" = true }
4955
4956__builtin_msa_fsle_d
4957 .param_str = "V2LLiV2dV2d"
4958 .target_set = TargetSet.initOne(.mips)
4959 .attributes = .{ .@"const" = true }
4960
4961__builtin_msa_fsle_w
4962 .param_str = "V4iV4fV4f"
4963 .target_set = TargetSet.initOne(.mips)
4964 .attributes = .{ .@"const" = true }
4965
4966__builtin_msa_fslt_d
4967 .param_str = "V2LLiV2dV2d"
4968 .target_set = TargetSet.initOne(.mips)
4969 .attributes = .{ .@"const" = true }
4970
4971__builtin_msa_fslt_w
4972 .param_str = "V4iV4fV4f"
4973 .target_set = TargetSet.initOne(.mips)
4974 .attributes = .{ .@"const" = true }
4975
4976__builtin_msa_fsne_d
4977 .param_str = "V2LLiV2dV2d"
4978 .target_set = TargetSet.initOne(.mips)
4979 .attributes = .{ .@"const" = true }
4980
4981__builtin_msa_fsne_w
4982 .param_str = "V4iV4fV4f"
4983 .target_set = TargetSet.initOne(.mips)
4984 .attributes = .{ .@"const" = true }
4985
4986__builtin_msa_fsor_d
4987 .param_str = "V2LLiV2dV2d"
4988 .target_set = TargetSet.initOne(.mips)
4989 .attributes = .{ .@"const" = true }
4990
4991__builtin_msa_fsor_w
4992 .param_str = "V4iV4fV4f"
4993 .target_set = TargetSet.initOne(.mips)
4994 .attributes = .{ .@"const" = true }
4995
4996__builtin_msa_fsqrt_d
4997 .param_str = "V2dV2d"
4998 .target_set = TargetSet.initOne(.mips)
4999 .attributes = .{ .@"const" = true }
5000
5001__builtin_msa_fsqrt_w
5002 .param_str = "V4fV4f"
5003 .target_set = TargetSet.initOne(.mips)
5004 .attributes = .{ .@"const" = true }
5005
5006__builtin_msa_fsub_d
5007 .param_str = "V2dV2dV2d"
5008 .target_set = TargetSet.initOne(.mips)
5009 .attributes = .{ .@"const" = true }
5010
5011__builtin_msa_fsub_w
5012 .param_str = "V4fV4fV4f"
5013 .target_set = TargetSet.initOne(.mips)
5014 .attributes = .{ .@"const" = true }
5015
5016__builtin_msa_fsueq_d
5017 .param_str = "V2LLiV2dV2d"
5018 .target_set = TargetSet.initOne(.mips)
5019 .attributes = .{ .@"const" = true }
5020
5021__builtin_msa_fsueq_w
5022 .param_str = "V4iV4fV4f"
5023 .target_set = TargetSet.initOne(.mips)
5024 .attributes = .{ .@"const" = true }
5025
5026__builtin_msa_fsule_d
5027 .param_str = "V2LLiV2dV2d"
5028 .target_set = TargetSet.initOne(.mips)
5029 .attributes = .{ .@"const" = true }
5030
5031__builtin_msa_fsule_w
5032 .param_str = "V4iV4fV4f"
5033 .target_set = TargetSet.initOne(.mips)
5034 .attributes = .{ .@"const" = true }
5035
5036__builtin_msa_fsult_d
5037 .param_str = "V2LLiV2dV2d"
5038 .target_set = TargetSet.initOne(.mips)
5039 .attributes = .{ .@"const" = true }
5040
5041__builtin_msa_fsult_w
5042 .param_str = "V4iV4fV4f"
5043 .target_set = TargetSet.initOne(.mips)
5044 .attributes = .{ .@"const" = true }
5045
5046__builtin_msa_fsun_d
5047 .param_str = "V2LLiV2dV2d"
5048 .target_set = TargetSet.initOne(.mips)
5049 .attributes = .{ .@"const" = true }
5050
5051__builtin_msa_fsun_w
5052 .param_str = "V4iV4fV4f"
5053 .target_set = TargetSet.initOne(.mips)
5054 .attributes = .{ .@"const" = true }
5055
5056__builtin_msa_fsune_d
5057 .param_str = "V2LLiV2dV2d"
5058 .target_set = TargetSet.initOne(.mips)
5059 .attributes = .{ .@"const" = true }
5060
5061__builtin_msa_fsune_w
5062 .param_str = "V4iV4fV4f"
5063 .target_set = TargetSet.initOne(.mips)
5064 .attributes = .{ .@"const" = true }
5065
5066__builtin_msa_ftint_s_d
5067 .param_str = "V2SLLiV2d"
5068 .target_set = TargetSet.initOne(.mips)
5069 .attributes = .{ .@"const" = true }
5070
5071__builtin_msa_ftint_s_w
5072 .param_str = "V4SiV4f"
5073 .target_set = TargetSet.initOne(.mips)
5074 .attributes = .{ .@"const" = true }
5075
5076__builtin_msa_ftint_u_d
5077 .param_str = "V2ULLiV2d"
5078 .target_set = TargetSet.initOne(.mips)
5079 .attributes = .{ .@"const" = true }
5080
5081__builtin_msa_ftint_u_w
5082 .param_str = "V4UiV4f"
5083 .target_set = TargetSet.initOne(.mips)
5084 .attributes = .{ .@"const" = true }
5085
5086__builtin_msa_ftq_h
5087 .param_str = "V4UiV4fV4f"
5088 .target_set = TargetSet.initOne(.mips)
5089 .attributes = .{ .@"const" = true }
5090
5091__builtin_msa_ftq_w
5092 .param_str = "V2ULLiV2dV2d"
5093 .target_set = TargetSet.initOne(.mips)
5094 .attributes = .{ .@"const" = true }
5095
5096__builtin_msa_ftrunc_s_d
5097 .param_str = "V2SLLiV2d"
5098 .target_set = TargetSet.initOne(.mips)
5099 .attributes = .{ .@"const" = true }
5100
5101__builtin_msa_ftrunc_s_w
5102 .param_str = "V4SiV4f"
5103 .target_set = TargetSet.initOne(.mips)
5104 .attributes = .{ .@"const" = true }
5105
5106__builtin_msa_ftrunc_u_d
5107 .param_str = "V2ULLiV2d"
5108 .target_set = TargetSet.initOne(.mips)
5109 .attributes = .{ .@"const" = true }
5110
5111__builtin_msa_ftrunc_u_w
5112 .param_str = "V4UiV4f"
5113 .target_set = TargetSet.initOne(.mips)
5114 .attributes = .{ .@"const" = true }
5115
5116__builtin_msa_hadd_s_d
5117 .param_str = "V2SLLiV4SiV4Si"
5118 .target_set = TargetSet.initOne(.mips)
5119 .attributes = .{ .@"const" = true }
5120
5121__builtin_msa_hadd_s_h
5122 .param_str = "V8SsV16ScV16Sc"
5123 .target_set = TargetSet.initOne(.mips)
5124 .attributes = .{ .@"const" = true }
5125
5126__builtin_msa_hadd_s_w
5127 .param_str = "V4SiV8SsV8Ss"
5128 .target_set = TargetSet.initOne(.mips)
5129 .attributes = .{ .@"const" = true }
5130
5131__builtin_msa_hadd_u_d
5132 .param_str = "V2ULLiV4UiV4Ui"
5133 .target_set = TargetSet.initOne(.mips)
5134 .attributes = .{ .@"const" = true }
5135
5136__builtin_msa_hadd_u_h
5137 .param_str = "V8UsV16UcV16Uc"
5138 .target_set = TargetSet.initOne(.mips)
5139 .attributes = .{ .@"const" = true }
5140
5141__builtin_msa_hadd_u_w
5142 .param_str = "V4UiV8UsV8Us"
5143 .target_set = TargetSet.initOne(.mips)
5144 .attributes = .{ .@"const" = true }
5145
5146__builtin_msa_hsub_s_d
5147 .param_str = "V2SLLiV4SiV4Si"
5148 .target_set = TargetSet.initOne(.mips)
5149 .attributes = .{ .@"const" = true }
5150
5151__builtin_msa_hsub_s_h
5152 .param_str = "V8SsV16ScV16Sc"
5153 .target_set = TargetSet.initOne(.mips)
5154 .attributes = .{ .@"const" = true }
5155
5156__builtin_msa_hsub_s_w
5157 .param_str = "V4SiV8SsV8Ss"
5158 .target_set = TargetSet.initOne(.mips)
5159 .attributes = .{ .@"const" = true }
5160
5161__builtin_msa_hsub_u_d
5162 .param_str = "V2ULLiV4UiV4Ui"
5163 .target_set = TargetSet.initOne(.mips)
5164 .attributes = .{ .@"const" = true }
5165
5166__builtin_msa_hsub_u_h
5167 .param_str = "V8UsV16UcV16Uc"
5168 .target_set = TargetSet.initOne(.mips)
5169 .attributes = .{ .@"const" = true }
5170
5171__builtin_msa_hsub_u_w
5172 .param_str = "V4UiV8UsV8Us"
5173 .target_set = TargetSet.initOne(.mips)
5174 .attributes = .{ .@"const" = true }
5175
5176__builtin_msa_ilvev_b
5177 .param_str = "V16cV16cV16c"
5178 .target_set = TargetSet.initOne(.mips)
5179 .attributes = .{ .@"const" = true }
5180
5181__builtin_msa_ilvev_d
5182 .param_str = "V2LLiV2LLiV2LLi"
5183 .target_set = TargetSet.initOne(.mips)
5184 .attributes = .{ .@"const" = true }
5185
5186__builtin_msa_ilvev_h
5187 .param_str = "V8sV8sV8s"
5188 .target_set = TargetSet.initOne(.mips)
5189 .attributes = .{ .@"const" = true }
5190
5191__builtin_msa_ilvev_w
5192 .param_str = "V4iV4iV4i"
5193 .target_set = TargetSet.initOne(.mips)
5194 .attributes = .{ .@"const" = true }
5195
5196__builtin_msa_ilvl_b
5197 .param_str = "V16cV16cV16c"
5198 .target_set = TargetSet.initOne(.mips)
5199 .attributes = .{ .@"const" = true }
5200
5201__builtin_msa_ilvl_d
5202 .param_str = "V2LLiV2LLiV2LLi"
5203 .target_set = TargetSet.initOne(.mips)
5204 .attributes = .{ .@"const" = true }
5205
5206__builtin_msa_ilvl_h
5207 .param_str = "V8sV8sV8s"
5208 .target_set = TargetSet.initOne(.mips)
5209 .attributes = .{ .@"const" = true }
5210
5211__builtin_msa_ilvl_w
5212 .param_str = "V4iV4iV4i"
5213 .target_set = TargetSet.initOne(.mips)
5214 .attributes = .{ .@"const" = true }
5215
5216__builtin_msa_ilvod_b
5217 .param_str = "V16cV16cV16c"
5218 .target_set = TargetSet.initOne(.mips)
5219 .attributes = .{ .@"const" = true }
5220
5221__builtin_msa_ilvod_d
5222 .param_str = "V2LLiV2LLiV2LLi"
5223 .target_set = TargetSet.initOne(.mips)
5224 .attributes = .{ .@"const" = true }
5225
5226__builtin_msa_ilvod_h
5227 .param_str = "V8sV8sV8s"
5228 .target_set = TargetSet.initOne(.mips)
5229 .attributes = .{ .@"const" = true }
5230
5231__builtin_msa_ilvod_w
5232 .param_str = "V4iV4iV4i"
5233 .target_set = TargetSet.initOne(.mips)
5234 .attributes = .{ .@"const" = true }
5235
5236__builtin_msa_ilvr_b
5237 .param_str = "V16cV16cV16c"
5238 .target_set = TargetSet.initOne(.mips)
5239 .attributes = .{ .@"const" = true }
5240
5241__builtin_msa_ilvr_d
5242 .param_str = "V2LLiV2LLiV2LLi"
5243 .target_set = TargetSet.initOne(.mips)
5244 .attributes = .{ .@"const" = true }
5245
5246__builtin_msa_ilvr_h
5247 .param_str = "V8sV8sV8s"
5248 .target_set = TargetSet.initOne(.mips)
5249 .attributes = .{ .@"const" = true }
5250
5251__builtin_msa_ilvr_w
5252 .param_str = "V4iV4iV4i"
5253 .target_set = TargetSet.initOne(.mips)
5254 .attributes = .{ .@"const" = true }
5255
5256__builtin_msa_insert_b
5257 .param_str = "V16ScV16ScIUii"
5258 .target_set = TargetSet.initOne(.mips)
5259 .attributes = .{ .@"const" = true }
5260
5261__builtin_msa_insert_d
5262 .param_str = "V2SLLiV2SLLiIUiLLi"
5263 .target_set = TargetSet.initOne(.mips)
5264 .attributes = .{ .@"const" = true }
5265
5266__builtin_msa_insert_h
5267 .param_str = "V8SsV8SsIUii"
5268 .target_set = TargetSet.initOne(.mips)
5269 .attributes = .{ .@"const" = true }
5270
5271__builtin_msa_insert_w
5272 .param_str = "V4SiV4SiIUii"
5273 .target_set = TargetSet.initOne(.mips)
5274 .attributes = .{ .@"const" = true }
5275
5276__builtin_msa_insve_b
5277 .param_str = "V16ScV16ScIUiV16Sc"
5278 .target_set = TargetSet.initOne(.mips)
5279 .attributes = .{ .@"const" = true }
5280
5281__builtin_msa_insve_d
5282 .param_str = "V2SLLiV2SLLiIUiV2SLLi"
5283 .target_set = TargetSet.initOne(.mips)
5284 .attributes = .{ .@"const" = true }
5285
5286__builtin_msa_insve_h
5287 .param_str = "V8SsV8SsIUiV8Ss"
5288 .target_set = TargetSet.initOne(.mips)
5289 .attributes = .{ .@"const" = true }
5290
5291__builtin_msa_insve_w
5292 .param_str = "V4SiV4SiIUiV4Si"
5293 .target_set = TargetSet.initOne(.mips)
5294 .attributes = .{ .@"const" = true }
5295
5296__builtin_msa_ld_b
5297 .param_str = "V16Scv*Ii"
5298 .target_set = TargetSet.initOne(.mips)
5299 .attributes = .{ .@"const" = true }
5300
5301__builtin_msa_ld_d
5302 .param_str = "V2SLLiv*Ii"
5303 .target_set = TargetSet.initOne(.mips)
5304 .attributes = .{ .@"const" = true }
5305
5306__builtin_msa_ld_h
5307 .param_str = "V8Ssv*Ii"
5308 .target_set = TargetSet.initOne(.mips)
5309 .attributes = .{ .@"const" = true }
5310
5311__builtin_msa_ld_w
5312 .param_str = "V4Siv*Ii"
5313 .target_set = TargetSet.initOne(.mips)
5314 .attributes = .{ .@"const" = true }
5315
5316__builtin_msa_ldi_b
5317 .param_str = "V16cIi"
5318 .target_set = TargetSet.initOne(.mips)
5319 .attributes = .{ .@"const" = true }
5320
5321__builtin_msa_ldi_d
5322 .param_str = "V2LLiIi"
5323 .target_set = TargetSet.initOne(.mips)
5324 .attributes = .{ .@"const" = true }
5325
5326__builtin_msa_ldi_h
5327 .param_str = "V8sIi"
5328 .target_set = TargetSet.initOne(.mips)
5329 .attributes = .{ .@"const" = true }
5330
5331__builtin_msa_ldi_w
5332 .param_str = "V4iIi"
5333 .target_set = TargetSet.initOne(.mips)
5334 .attributes = .{ .@"const" = true }
5335
5336__builtin_msa_ldr_d
5337 .param_str = "V2SLLiv*Ii"
5338 .target_set = TargetSet.initOne(.mips)
5339 .attributes = .{ .@"const" = true }
5340
5341__builtin_msa_ldr_w
5342 .param_str = "V4Siv*Ii"
5343 .target_set = TargetSet.initOne(.mips)
5344 .attributes = .{ .@"const" = true }
5345
5346__builtin_msa_madd_q_h
5347 .param_str = "V8SsV8SsV8SsV8Ss"
5348 .target_set = TargetSet.initOne(.mips)
5349 .attributes = .{ .@"const" = true }
5350
5351__builtin_msa_madd_q_w
5352 .param_str = "V4SiV4SiV4SiV4Si"
5353 .target_set = TargetSet.initOne(.mips)
5354 .attributes = .{ .@"const" = true }
5355
5356__builtin_msa_maddr_q_h
5357 .param_str = "V8SsV8SsV8SsV8Ss"
5358 .target_set = TargetSet.initOne(.mips)
5359 .attributes = .{ .@"const" = true }
5360
5361__builtin_msa_maddr_q_w
5362 .param_str = "V4SiV4SiV4SiV4Si"
5363 .target_set = TargetSet.initOne(.mips)
5364 .attributes = .{ .@"const" = true }
5365
5366__builtin_msa_maddv_b
5367 .param_str = "V16ScV16ScV16ScV16Sc"
5368 .target_set = TargetSet.initOne(.mips)
5369 .attributes = .{ .@"const" = true }
5370
5371__builtin_msa_maddv_d
5372 .param_str = "V2SLLiV2SLLiV2SLLiV2SLLi"
5373 .target_set = TargetSet.initOne(.mips)
5374 .attributes = .{ .@"const" = true }
5375
5376__builtin_msa_maddv_h
5377 .param_str = "V8SsV8SsV8SsV8Ss"
5378 .target_set = TargetSet.initOne(.mips)
5379 .attributes = .{ .@"const" = true }
5380
5381__builtin_msa_maddv_w
5382 .param_str = "V4SiV4SiV4SiV4Si"
5383 .target_set = TargetSet.initOne(.mips)
5384 .attributes = .{ .@"const" = true }
5385
5386__builtin_msa_max_a_b
5387 .param_str = "V16ScV16ScV16Sc"
5388 .target_set = TargetSet.initOne(.mips)
5389 .attributes = .{ .@"const" = true }
5390
5391__builtin_msa_max_a_d
5392 .param_str = "V2SLLiV2SLLiV2SLLi"
5393 .target_set = TargetSet.initOne(.mips)
5394 .attributes = .{ .@"const" = true }
5395
5396__builtin_msa_max_a_h
5397 .param_str = "V8SsV8SsV8Ss"
5398 .target_set = TargetSet.initOne(.mips)
5399 .attributes = .{ .@"const" = true }
5400
5401__builtin_msa_max_a_w
5402 .param_str = "V4SiV4SiV4Si"
5403 .target_set = TargetSet.initOne(.mips)
5404 .attributes = .{ .@"const" = true }
5405
5406__builtin_msa_max_s_b
5407 .param_str = "V16ScV16ScV16Sc"
5408 .target_set = TargetSet.initOne(.mips)
5409 .attributes = .{ .@"const" = true }
5410
5411__builtin_msa_max_s_d
5412 .param_str = "V2SLLiV2SLLiV2SLLi"
5413 .target_set = TargetSet.initOne(.mips)
5414 .attributes = .{ .@"const" = true }
5415
5416__builtin_msa_max_s_h
5417 .param_str = "V8SsV8SsV8Ss"
5418 .target_set = TargetSet.initOne(.mips)
5419 .attributes = .{ .@"const" = true }
5420
5421__builtin_msa_max_s_w
5422 .param_str = "V4SiV4SiV4Si"
5423 .target_set = TargetSet.initOne(.mips)
5424 .attributes = .{ .@"const" = true }
5425
5426__builtin_msa_max_u_b
5427 .param_str = "V16UcV16UcV16Uc"
5428 .target_set = TargetSet.initOne(.mips)
5429 .attributes = .{ .@"const" = true }
5430
5431__builtin_msa_max_u_d
5432 .param_str = "V2ULLiV2ULLiV2ULLi"
5433 .target_set = TargetSet.initOne(.mips)
5434 .attributes = .{ .@"const" = true }
5435
5436__builtin_msa_max_u_h
5437 .param_str = "V8UsV8UsV8Us"
5438 .target_set = TargetSet.initOne(.mips)
5439 .attributes = .{ .@"const" = true }
5440
5441__builtin_msa_max_u_w
5442 .param_str = "V4UiV4UiV4Ui"
5443 .target_set = TargetSet.initOne(.mips)
5444 .attributes = .{ .@"const" = true }
5445
5446__builtin_msa_maxi_s_b
5447 .param_str = "V16ScV16ScIi"
5448 .target_set = TargetSet.initOne(.mips)
5449 .attributes = .{ .@"const" = true }
5450
5451__builtin_msa_maxi_s_d
5452 .param_str = "V2SLLiV2SLLiIi"
5453 .target_set = TargetSet.initOne(.mips)
5454 .attributes = .{ .@"const" = true }
5455
5456__builtin_msa_maxi_s_h
5457 .param_str = "V8SsV8SsIi"
5458 .target_set = TargetSet.initOne(.mips)
5459 .attributes = .{ .@"const" = true }
5460
5461__builtin_msa_maxi_s_w
5462 .param_str = "V4SiV4SiIi"
5463 .target_set = TargetSet.initOne(.mips)
5464 .attributes = .{ .@"const" = true }
5465
5466__builtin_msa_maxi_u_b
5467 .param_str = "V16UcV16UcIi"
5468 .target_set = TargetSet.initOne(.mips)
5469 .attributes = .{ .@"const" = true }
5470
5471__builtin_msa_maxi_u_d
5472 .param_str = "V2ULLiV2ULLiIi"
5473 .target_set = TargetSet.initOne(.mips)
5474 .attributes = .{ .@"const" = true }
5475
5476__builtin_msa_maxi_u_h
5477 .param_str = "V8UsV8UsIi"
5478 .target_set = TargetSet.initOne(.mips)
5479 .attributes = .{ .@"const" = true }
5480
5481__builtin_msa_maxi_u_w
5482 .param_str = "V4UiV4UiIi"
5483 .target_set = TargetSet.initOne(.mips)
5484 .attributes = .{ .@"const" = true }
5485
5486__builtin_msa_min_a_b
5487 .param_str = "V16ScV16ScV16Sc"
5488 .target_set = TargetSet.initOne(.mips)
5489 .attributes = .{ .@"const" = true }
5490
5491__builtin_msa_min_a_d
5492 .param_str = "V2SLLiV2SLLiV2SLLi"
5493 .target_set = TargetSet.initOne(.mips)
5494 .attributes = .{ .@"const" = true }
5495
5496__builtin_msa_min_a_h
5497 .param_str = "V8SsV8SsV8Ss"
5498 .target_set = TargetSet.initOne(.mips)
5499 .attributes = .{ .@"const" = true }
5500
5501__builtin_msa_min_a_w
5502 .param_str = "V4SiV4SiV4Si"
5503 .target_set = TargetSet.initOne(.mips)
5504 .attributes = .{ .@"const" = true }
5505
5506__builtin_msa_min_s_b
5507 .param_str = "V16ScV16ScV16Sc"
5508 .target_set = TargetSet.initOne(.mips)
5509 .attributes = .{ .@"const" = true }
5510
5511__builtin_msa_min_s_d
5512 .param_str = "V2SLLiV2SLLiV2SLLi"
5513 .target_set = TargetSet.initOne(.mips)
5514 .attributes = .{ .@"const" = true }
5515
5516__builtin_msa_min_s_h
5517 .param_str = "V8SsV8SsV8Ss"
5518 .target_set = TargetSet.initOne(.mips)
5519 .attributes = .{ .@"const" = true }
5520
5521__builtin_msa_min_s_w
5522 .param_str = "V4SiV4SiV4Si"
5523 .target_set = TargetSet.initOne(.mips)
5524 .attributes = .{ .@"const" = true }
5525
5526__builtin_msa_min_u_b
5527 .param_str = "V16UcV16UcV16Uc"
5528 .target_set = TargetSet.initOne(.mips)
5529 .attributes = .{ .@"const" = true }
5530
5531__builtin_msa_min_u_d
5532 .param_str = "V2ULLiV2ULLiV2ULLi"
5533 .target_set = TargetSet.initOne(.mips)
5534 .attributes = .{ .@"const" = true }
5535
5536__builtin_msa_min_u_h
5537 .param_str = "V8UsV8UsV8Us"
5538 .target_set = TargetSet.initOne(.mips)
5539 .attributes = .{ .@"const" = true }
5540
5541__builtin_msa_min_u_w
5542 .param_str = "V4UiV4UiV4Ui"
5543 .target_set = TargetSet.initOne(.mips)
5544 .attributes = .{ .@"const" = true }
5545
5546__builtin_msa_mini_s_b
5547 .param_str = "V16ScV16ScIi"
5548 .target_set = TargetSet.initOne(.mips)
5549 .attributes = .{ .@"const" = true }
5550
5551__builtin_msa_mini_s_d
5552 .param_str = "V2SLLiV2SLLiIi"
5553 .target_set = TargetSet.initOne(.mips)
5554 .attributes = .{ .@"const" = true }
5555
5556__builtin_msa_mini_s_h
5557 .param_str = "V8SsV8SsIi"
5558 .target_set = TargetSet.initOne(.mips)
5559 .attributes = .{ .@"const" = true }
5560
5561__builtin_msa_mini_s_w
5562 .param_str = "V4SiV4SiIi"
5563 .target_set = TargetSet.initOne(.mips)
5564 .attributes = .{ .@"const" = true }
5565
5566__builtin_msa_mini_u_b
5567 .param_str = "V16UcV16UcIi"
5568 .target_set = TargetSet.initOne(.mips)
5569 .attributes = .{ .@"const" = true }
5570
5571__builtin_msa_mini_u_d
5572 .param_str = "V2ULLiV2ULLiIi"
5573 .target_set = TargetSet.initOne(.mips)
5574 .attributes = .{ .@"const" = true }
5575
5576__builtin_msa_mini_u_h
5577 .param_str = "V8UsV8UsIi"
5578 .target_set = TargetSet.initOne(.mips)
5579 .attributes = .{ .@"const" = true }
5580
5581__builtin_msa_mini_u_w
5582 .param_str = "V4UiV4UiIi"
5583 .target_set = TargetSet.initOne(.mips)
5584 .attributes = .{ .@"const" = true }
5585
5586__builtin_msa_mod_s_b
5587 .param_str = "V16ScV16ScV16Sc"
5588 .target_set = TargetSet.initOne(.mips)
5589 .attributes = .{ .@"const" = true }
5590
5591__builtin_msa_mod_s_d
5592 .param_str = "V2SLLiV2SLLiV2SLLi"
5593 .target_set = TargetSet.initOne(.mips)
5594 .attributes = .{ .@"const" = true }
5595
5596__builtin_msa_mod_s_h
5597 .param_str = "V8SsV8SsV8Ss"
5598 .target_set = TargetSet.initOne(.mips)
5599 .attributes = .{ .@"const" = true }
5600
5601__builtin_msa_mod_s_w
5602 .param_str = "V4SiV4SiV4Si"
5603 .target_set = TargetSet.initOne(.mips)
5604 .attributes = .{ .@"const" = true }
5605
5606__builtin_msa_mod_u_b
5607 .param_str = "V16UcV16UcV16Uc"
5608 .target_set = TargetSet.initOne(.mips)
5609 .attributes = .{ .@"const" = true }
5610
5611__builtin_msa_mod_u_d
5612 .param_str = "V2ULLiV2ULLiV2ULLi"
5613 .target_set = TargetSet.initOne(.mips)
5614 .attributes = .{ .@"const" = true }
5615
5616__builtin_msa_mod_u_h
5617 .param_str = "V8UsV8UsV8Us"
5618 .target_set = TargetSet.initOne(.mips)
5619 .attributes = .{ .@"const" = true }
5620
5621__builtin_msa_mod_u_w
5622 .param_str = "V4UiV4UiV4Ui"
5623 .target_set = TargetSet.initOne(.mips)
5624 .attributes = .{ .@"const" = true }
5625
5626__builtin_msa_move_v
5627 .param_str = "V16ScV16Sc"
5628 .target_set = TargetSet.initOne(.mips)
5629 .attributes = .{ .@"const" = true }
5630
5631__builtin_msa_msub_q_h
5632 .param_str = "V8SsV8SsV8SsV8Ss"
5633 .target_set = TargetSet.initOne(.mips)
5634 .attributes = .{ .@"const" = true }
5635
5636__builtin_msa_msub_q_w
5637 .param_str = "V4SiV4SiV4SiV4Si"
5638 .target_set = TargetSet.initOne(.mips)
5639 .attributes = .{ .@"const" = true }
5640
5641__builtin_msa_msubr_q_h
5642 .param_str = "V8SsV8SsV8SsV8Ss"
5643 .target_set = TargetSet.initOne(.mips)
5644 .attributes = .{ .@"const" = true }
5645
5646__builtin_msa_msubr_q_w
5647 .param_str = "V4SiV4SiV4SiV4Si"
5648 .target_set = TargetSet.initOne(.mips)
5649 .attributes = .{ .@"const" = true }
5650
5651__builtin_msa_msubv_b
5652 .param_str = "V16ScV16ScV16ScV16Sc"
5653 .target_set = TargetSet.initOne(.mips)
5654 .attributes = .{ .@"const" = true }
5655
5656__builtin_msa_msubv_d
5657 .param_str = "V2SLLiV2SLLiV2SLLiV2SLLi"
5658 .target_set = TargetSet.initOne(.mips)
5659 .attributes = .{ .@"const" = true }
5660
5661__builtin_msa_msubv_h
5662 .param_str = "V8SsV8SsV8SsV8Ss"
5663 .target_set = TargetSet.initOne(.mips)
5664 .attributes = .{ .@"const" = true }
5665
5666__builtin_msa_msubv_w
5667 .param_str = "V4SiV4SiV4SiV4Si"
5668 .target_set = TargetSet.initOne(.mips)
5669 .attributes = .{ .@"const" = true }
5670
5671__builtin_msa_mul_q_h
5672 .param_str = "V8SsV8SsV8Ss"
5673 .target_set = TargetSet.initOne(.mips)
5674 .attributes = .{ .@"const" = true }
5675
5676__builtin_msa_mul_q_w
5677 .param_str = "V4SiV4SiV4Si"
5678 .target_set = TargetSet.initOne(.mips)
5679 .attributes = .{ .@"const" = true }
5680
5681__builtin_msa_mulr_q_h
5682 .param_str = "V8SsV8SsV8Ss"
5683 .target_set = TargetSet.initOne(.mips)
5684 .attributes = .{ .@"const" = true }
5685
5686__builtin_msa_mulr_q_w
5687 .param_str = "V4SiV4SiV4Si"
5688 .target_set = TargetSet.initOne(.mips)
5689 .attributes = .{ .@"const" = true }
5690
5691__builtin_msa_mulv_b
5692 .param_str = "V16ScV16ScV16Sc"
5693 .target_set = TargetSet.initOne(.mips)
5694 .attributes = .{ .@"const" = true }
5695
5696__builtin_msa_mulv_d
5697 .param_str = "V2SLLiV2SLLiV2SLLi"
5698 .target_set = TargetSet.initOne(.mips)
5699 .attributes = .{ .@"const" = true }
5700
5701__builtin_msa_mulv_h
5702 .param_str = "V8SsV8SsV8Ss"
5703 .target_set = TargetSet.initOne(.mips)
5704 .attributes = .{ .@"const" = true }
5705
5706__builtin_msa_mulv_w
5707 .param_str = "V4SiV4SiV4Si"
5708 .target_set = TargetSet.initOne(.mips)
5709 .attributes = .{ .@"const" = true }
5710
5711__builtin_msa_nloc_b
5712 .param_str = "V16ScV16Sc"
5713 .target_set = TargetSet.initOne(.mips)
5714 .attributes = .{ .@"const" = true }
5715
5716__builtin_msa_nloc_d
5717 .param_str = "V2SLLiV2SLLi"
5718 .target_set = TargetSet.initOne(.mips)
5719 .attributes = .{ .@"const" = true }
5720
5721__builtin_msa_nloc_h
5722 .param_str = "V8SsV8Ss"
5723 .target_set = TargetSet.initOne(.mips)
5724 .attributes = .{ .@"const" = true }
5725
5726__builtin_msa_nloc_w
5727 .param_str = "V4SiV4Si"
5728 .target_set = TargetSet.initOne(.mips)
5729 .attributes = .{ .@"const" = true }
5730
5731__builtin_msa_nlzc_b
5732 .param_str = "V16ScV16Sc"
5733 .target_set = TargetSet.initOne(.mips)
5734 .attributes = .{ .@"const" = true }
5735
5736__builtin_msa_nlzc_d
5737 .param_str = "V2SLLiV2SLLi"
5738 .target_set = TargetSet.initOne(.mips)
5739 .attributes = .{ .@"const" = true }
5740
5741__builtin_msa_nlzc_h
5742 .param_str = "V8SsV8Ss"
5743 .target_set = TargetSet.initOne(.mips)
5744 .attributes = .{ .@"const" = true }
5745
5746__builtin_msa_nlzc_w
5747 .param_str = "V4SiV4Si"
5748 .target_set = TargetSet.initOne(.mips)
5749 .attributes = .{ .@"const" = true }
5750
5751__builtin_msa_nor_v
5752 .param_str = "V16UcV16UcV16Uc"
5753 .target_set = TargetSet.initOne(.mips)
5754 .attributes = .{ .@"const" = true }
5755
5756__builtin_msa_nori_b
5757 .param_str = "V16UcV16cIUi"
5758 .target_set = TargetSet.initOne(.mips)
5759 .attributes = .{ .@"const" = true }
5760
5761__builtin_msa_or_v
5762 .param_str = "V16UcV16UcV16Uc"
5763 .target_set = TargetSet.initOne(.mips)
5764 .attributes = .{ .@"const" = true }
5765
5766__builtin_msa_ori_b
5767 .param_str = "V16UcV16UcIUi"
5768 .target_set = TargetSet.initOne(.mips)
5769 .attributes = .{ .@"const" = true }
5770
5771__builtin_msa_pckev_b
5772 .param_str = "V16cV16cV16c"
5773 .target_set = TargetSet.initOne(.mips)
5774 .attributes = .{ .@"const" = true }
5775
5776__builtin_msa_pckev_d
5777 .param_str = "V2LLiV2LLiV2LLi"
5778 .target_set = TargetSet.initOne(.mips)
5779 .attributes = .{ .@"const" = true }
5780
5781__builtin_msa_pckev_h
5782 .param_str = "V8sV8sV8s"
5783 .target_set = TargetSet.initOne(.mips)
5784 .attributes = .{ .@"const" = true }
5785
5786__builtin_msa_pckev_w
5787 .param_str = "V4iV4iV4i"
5788 .target_set = TargetSet.initOne(.mips)
5789 .attributes = .{ .@"const" = true }
5790
5791__builtin_msa_pckod_b
5792 .param_str = "V16cV16cV16c"
5793 .target_set = TargetSet.initOne(.mips)
5794 .attributes = .{ .@"const" = true }
5795
5796__builtin_msa_pckod_d
5797 .param_str = "V2LLiV2LLiV2LLi"
5798 .target_set = TargetSet.initOne(.mips)
5799 .attributes = .{ .@"const" = true }
5800
5801__builtin_msa_pckod_h
5802 .param_str = "V8sV8sV8s"
5803 .target_set = TargetSet.initOne(.mips)
5804 .attributes = .{ .@"const" = true }
5805
5806__builtin_msa_pckod_w
5807 .param_str = "V4iV4iV4i"
5808 .target_set = TargetSet.initOne(.mips)
5809 .attributes = .{ .@"const" = true }
5810
5811__builtin_msa_pcnt_b
5812 .param_str = "V16ScV16Sc"
5813 .target_set = TargetSet.initOne(.mips)
5814 .attributes = .{ .@"const" = true }
5815
5816__builtin_msa_pcnt_d
5817 .param_str = "V2SLLiV2SLLi"
5818 .target_set = TargetSet.initOne(.mips)
5819 .attributes = .{ .@"const" = true }
5820
5821__builtin_msa_pcnt_h
5822 .param_str = "V8SsV8Ss"
5823 .target_set = TargetSet.initOne(.mips)
5824 .attributes = .{ .@"const" = true }
5825
5826__builtin_msa_pcnt_w
5827 .param_str = "V4SiV4Si"
5828 .target_set = TargetSet.initOne(.mips)
5829 .attributes = .{ .@"const" = true }
5830
5831__builtin_msa_sat_s_b
5832 .param_str = "V16ScV16ScIUi"
5833 .target_set = TargetSet.initOne(.mips)
5834 .attributes = .{ .@"const" = true }
5835
5836__builtin_msa_sat_s_d
5837 .param_str = "V2SLLiV2SLLiIUi"
5838 .target_set = TargetSet.initOne(.mips)
5839 .attributes = .{ .@"const" = true }
5840
5841__builtin_msa_sat_s_h
5842 .param_str = "V8SsV8SsIUi"
5843 .target_set = TargetSet.initOne(.mips)
5844 .attributes = .{ .@"const" = true }
5845
5846__builtin_msa_sat_s_w
5847 .param_str = "V4SiV4SiIUi"
5848 .target_set = TargetSet.initOne(.mips)
5849 .attributes = .{ .@"const" = true }
5850
5851__builtin_msa_sat_u_b
5852 .param_str = "V16UcV16UcIUi"
5853 .target_set = TargetSet.initOne(.mips)
5854 .attributes = .{ .@"const" = true }
5855
5856__builtin_msa_sat_u_d
5857 .param_str = "V2ULLiV2ULLiIUi"
5858 .target_set = TargetSet.initOne(.mips)
5859 .attributes = .{ .@"const" = true }
5860
5861__builtin_msa_sat_u_h
5862 .param_str = "V8UsV8UsIUi"
5863 .target_set = TargetSet.initOne(.mips)
5864 .attributes = .{ .@"const" = true }
5865
5866__builtin_msa_sat_u_w
5867 .param_str = "V4UiV4UiIUi"
5868 .target_set = TargetSet.initOne(.mips)
5869 .attributes = .{ .@"const" = true }
5870
5871__builtin_msa_shf_b
5872 .param_str = "V16cV16cIUi"
5873 .target_set = TargetSet.initOne(.mips)
5874 .attributes = .{ .@"const" = true }
5875
5876__builtin_msa_shf_h
5877 .param_str = "V8sV8sIUi"
5878 .target_set = TargetSet.initOne(.mips)
5879 .attributes = .{ .@"const" = true }
5880
5881__builtin_msa_shf_w
5882 .param_str = "V4iV4iIUi"
5883 .target_set = TargetSet.initOne(.mips)
5884 .attributes = .{ .@"const" = true }
5885
5886__builtin_msa_sld_b
5887 .param_str = "V16cV16cV16cUi"
5888 .target_set = TargetSet.initOne(.mips)
5889 .attributes = .{ .@"const" = true }
5890
5891__builtin_msa_sld_d
5892 .param_str = "V2LLiV2LLiV2LLiUi"
5893 .target_set = TargetSet.initOne(.mips)
5894 .attributes = .{ .@"const" = true }
5895
5896__builtin_msa_sld_h
5897 .param_str = "V8sV8sV8sUi"
5898 .target_set = TargetSet.initOne(.mips)
5899 .attributes = .{ .@"const" = true }
5900
5901__builtin_msa_sld_w
5902 .param_str = "V4iV4iV4iUi"
5903 .target_set = TargetSet.initOne(.mips)
5904 .attributes = .{ .@"const" = true }
5905
5906__builtin_msa_sldi_b
5907 .param_str = "V16cV16cV16cIUi"
5908 .target_set = TargetSet.initOne(.mips)
5909 .attributes = .{ .@"const" = true }
5910
5911__builtin_msa_sldi_d
5912 .param_str = "V2LLiV2LLiV2LLiIUi"
5913 .target_set = TargetSet.initOne(.mips)
5914 .attributes = .{ .@"const" = true }
5915
5916__builtin_msa_sldi_h
5917 .param_str = "V8sV8sV8sIUi"
5918 .target_set = TargetSet.initOne(.mips)
5919 .attributes = .{ .@"const" = true }
5920
5921__builtin_msa_sldi_w
5922 .param_str = "V4iV4iV4iIUi"
5923 .target_set = TargetSet.initOne(.mips)
5924 .attributes = .{ .@"const" = true }
5925
5926__builtin_msa_sll_b
5927 .param_str = "V16cV16cV16c"
5928 .target_set = TargetSet.initOne(.mips)
5929 .attributes = .{ .@"const" = true }
5930
5931__builtin_msa_sll_d
5932 .param_str = "V2LLiV2LLiV2LLi"
5933 .target_set = TargetSet.initOne(.mips)
5934 .attributes = .{ .@"const" = true }
5935
5936__builtin_msa_sll_h
5937 .param_str = "V8sV8sV8s"
5938 .target_set = TargetSet.initOne(.mips)
5939 .attributes = .{ .@"const" = true }
5940
5941__builtin_msa_sll_w
5942 .param_str = "V4iV4iV4i"
5943 .target_set = TargetSet.initOne(.mips)
5944 .attributes = .{ .@"const" = true }
5945
5946__builtin_msa_slli_b
5947 .param_str = "V16cV16cIUi"
5948 .target_set = TargetSet.initOne(.mips)
5949 .attributes = .{ .@"const" = true }
5950
5951__builtin_msa_slli_d
5952 .param_str = "V2LLiV2LLiIUi"
5953 .target_set = TargetSet.initOne(.mips)
5954 .attributes = .{ .@"const" = true }
5955
5956__builtin_msa_slli_h
5957 .param_str = "V8sV8sIUi"
5958 .target_set = TargetSet.initOne(.mips)
5959 .attributes = .{ .@"const" = true }
5960
5961__builtin_msa_slli_w
5962 .param_str = "V4iV4iIUi"
5963 .target_set = TargetSet.initOne(.mips)
5964 .attributes = .{ .@"const" = true }
5965
5966__builtin_msa_splat_b
5967 .param_str = "V16cV16cUi"
5968 .target_set = TargetSet.initOne(.mips)
5969 .attributes = .{ .@"const" = true }
5970
5971__builtin_msa_splat_d
5972 .param_str = "V2LLiV2LLiUi"
5973 .target_set = TargetSet.initOne(.mips)
5974 .attributes = .{ .@"const" = true }
5975
5976__builtin_msa_splat_h
5977 .param_str = "V8sV8sUi"
5978 .target_set = TargetSet.initOne(.mips)
5979 .attributes = .{ .@"const" = true }
5980
5981__builtin_msa_splat_w
5982 .param_str = "V4iV4iUi"
5983 .target_set = TargetSet.initOne(.mips)
5984 .attributes = .{ .@"const" = true }
5985
5986__builtin_msa_splati_b
5987 .param_str = "V16cV16cIUi"
5988 .target_set = TargetSet.initOne(.mips)
5989 .attributes = .{ .@"const" = true }
5990
5991__builtin_msa_splati_d
5992 .param_str = "V2LLiV2LLiIUi"
5993 .target_set = TargetSet.initOne(.mips)
5994 .attributes = .{ .@"const" = true }
5995
5996__builtin_msa_splati_h
5997 .param_str = "V8sV8sIUi"
5998 .target_set = TargetSet.initOne(.mips)
5999 .attributes = .{ .@"const" = true }
6000
6001__builtin_msa_splati_w
6002 .param_str = "V4iV4iIUi"
6003 .target_set = TargetSet.initOne(.mips)
6004 .attributes = .{ .@"const" = true }
6005
6006__builtin_msa_sra_b
6007 .param_str = "V16cV16cV16c"
6008 .target_set = TargetSet.initOne(.mips)
6009 .attributes = .{ .@"const" = true }
6010
6011__builtin_msa_sra_d
6012 .param_str = "V2LLiV2LLiV2LLi"
6013 .target_set = TargetSet.initOne(.mips)
6014 .attributes = .{ .@"const" = true }
6015
6016__builtin_msa_sra_h
6017 .param_str = "V8sV8sV8s"
6018 .target_set = TargetSet.initOne(.mips)
6019 .attributes = .{ .@"const" = true }
6020
6021__builtin_msa_sra_w
6022 .param_str = "V4iV4iV4i"
6023 .target_set = TargetSet.initOne(.mips)
6024 .attributes = .{ .@"const" = true }
6025
6026__builtin_msa_srai_b
6027 .param_str = "V16cV16cIUi"
6028 .target_set = TargetSet.initOne(.mips)
6029 .attributes = .{ .@"const" = true }
6030
6031__builtin_msa_srai_d
6032 .param_str = "V2LLiV2LLiIUi"
6033 .target_set = TargetSet.initOne(.mips)
6034 .attributes = .{ .@"const" = true }
6035
6036__builtin_msa_srai_h
6037 .param_str = "V8sV8sIUi"
6038 .target_set = TargetSet.initOne(.mips)
6039 .attributes = .{ .@"const" = true }
6040
6041__builtin_msa_srai_w
6042 .param_str = "V4iV4iIUi"
6043 .target_set = TargetSet.initOne(.mips)
6044 .attributes = .{ .@"const" = true }
6045
6046__builtin_msa_srar_b
6047 .param_str = "V16cV16cV16c"
6048 .target_set = TargetSet.initOne(.mips)
6049 .attributes = .{ .@"const" = true }
6050
6051__builtin_msa_srar_d
6052 .param_str = "V2LLiV2LLiV2LLi"
6053 .target_set = TargetSet.initOne(.mips)
6054 .attributes = .{ .@"const" = true }
6055
6056__builtin_msa_srar_h
6057 .param_str = "V8sV8sV8s"
6058 .target_set = TargetSet.initOne(.mips)
6059 .attributes = .{ .@"const" = true }
6060
6061__builtin_msa_srar_w
6062 .param_str = "V4iV4iV4i"
6063 .target_set = TargetSet.initOne(.mips)
6064 .attributes = .{ .@"const" = true }
6065
6066__builtin_msa_srari_b
6067 .param_str = "V16cV16cIUi"
6068 .target_set = TargetSet.initOne(.mips)
6069 .attributes = .{ .@"const" = true }
6070
6071__builtin_msa_srari_d
6072 .param_str = "V2LLiV2LLiIUi"
6073 .target_set = TargetSet.initOne(.mips)
6074 .attributes = .{ .@"const" = true }
6075
6076__builtin_msa_srari_h
6077 .param_str = "V8sV8sIUi"
6078 .target_set = TargetSet.initOne(.mips)
6079 .attributes = .{ .@"const" = true }
6080
6081__builtin_msa_srari_w
6082 .param_str = "V4iV4iIUi"
6083 .target_set = TargetSet.initOne(.mips)
6084 .attributes = .{ .@"const" = true }
6085
6086__builtin_msa_srl_b
6087 .param_str = "V16cV16cV16c"
6088 .target_set = TargetSet.initOne(.mips)
6089 .attributes = .{ .@"const" = true }
6090
6091__builtin_msa_srl_d
6092 .param_str = "V2LLiV2LLiV2LLi"
6093 .target_set = TargetSet.initOne(.mips)
6094 .attributes = .{ .@"const" = true }
6095
6096__builtin_msa_srl_h
6097 .param_str = "V8sV8sV8s"
6098 .target_set = TargetSet.initOne(.mips)
6099 .attributes = .{ .@"const" = true }
6100
6101__builtin_msa_srl_w
6102 .param_str = "V4iV4iV4i"
6103 .target_set = TargetSet.initOne(.mips)
6104 .attributes = .{ .@"const" = true }
6105
6106__builtin_msa_srli_b
6107 .param_str = "V16cV16cIUi"
6108 .target_set = TargetSet.initOne(.mips)
6109 .attributes = .{ .@"const" = true }
6110
6111__builtin_msa_srli_d
6112 .param_str = "V2LLiV2LLiIUi"
6113 .target_set = TargetSet.initOne(.mips)
6114 .attributes = .{ .@"const" = true }
6115
6116__builtin_msa_srli_h
6117 .param_str = "V8sV8sIUi"
6118 .target_set = TargetSet.initOne(.mips)
6119 .attributes = .{ .@"const" = true }
6120
6121__builtin_msa_srli_w
6122 .param_str = "V4iV4iIUi"
6123 .target_set = TargetSet.initOne(.mips)
6124 .attributes = .{ .@"const" = true }
6125
6126__builtin_msa_srlr_b
6127 .param_str = "V16cV16cV16c"
6128 .target_set = TargetSet.initOne(.mips)
6129 .attributes = .{ .@"const" = true }
6130
6131__builtin_msa_srlr_d
6132 .param_str = "V2LLiV2LLiV2LLi"
6133 .target_set = TargetSet.initOne(.mips)
6134 .attributes = .{ .@"const" = true }
6135
6136__builtin_msa_srlr_h
6137 .param_str = "V8sV8sV8s"
6138 .target_set = TargetSet.initOne(.mips)
6139 .attributes = .{ .@"const" = true }
6140
6141__builtin_msa_srlr_w
6142 .param_str = "V4iV4iV4i"
6143 .target_set = TargetSet.initOne(.mips)
6144 .attributes = .{ .@"const" = true }
6145
6146__builtin_msa_srlri_b
6147 .param_str = "V16cV16cIUi"
6148 .target_set = TargetSet.initOne(.mips)
6149 .attributes = .{ .@"const" = true }
6150
6151__builtin_msa_srlri_d
6152 .param_str = "V2LLiV2LLiIUi"
6153 .target_set = TargetSet.initOne(.mips)
6154 .attributes = .{ .@"const" = true }
6155
6156__builtin_msa_srlri_h
6157 .param_str = "V8sV8sIUi"
6158 .target_set = TargetSet.initOne(.mips)
6159 .attributes = .{ .@"const" = true }
6160
6161__builtin_msa_srlri_w
6162 .param_str = "V4iV4iIUi"
6163 .target_set = TargetSet.initOne(.mips)
6164 .attributes = .{ .@"const" = true }
6165
6166__builtin_msa_st_b
6167 .param_str = "vV16Scv*Ii"
6168 .target_set = TargetSet.initOne(.mips)
6169 .attributes = .{ .@"const" = true }
6170
6171__builtin_msa_st_d
6172 .param_str = "vV2SLLiv*Ii"
6173 .target_set = TargetSet.initOne(.mips)
6174 .attributes = .{ .@"const" = true }
6175
6176__builtin_msa_st_h
6177 .param_str = "vV8Ssv*Ii"
6178 .target_set = TargetSet.initOne(.mips)
6179 .attributes = .{ .@"const" = true }
6180
6181__builtin_msa_st_w
6182 .param_str = "vV4Siv*Ii"
6183 .target_set = TargetSet.initOne(.mips)
6184 .attributes = .{ .@"const" = true }
6185
6186__builtin_msa_str_d
6187 .param_str = "vV2SLLiv*Ii"
6188 .target_set = TargetSet.initOne(.mips)
6189 .attributes = .{ .@"const" = true }
6190
6191__builtin_msa_str_w
6192 .param_str = "vV4Siv*Ii"
6193 .target_set = TargetSet.initOne(.mips)
6194 .attributes = .{ .@"const" = true }
6195
6196__builtin_msa_subs_s_b
6197 .param_str = "V16ScV16ScV16Sc"
6198 .target_set = TargetSet.initOne(.mips)
6199 .attributes = .{ .@"const" = true }
6200
6201__builtin_msa_subs_s_d
6202 .param_str = "V2SLLiV2SLLiV2SLLi"
6203 .target_set = TargetSet.initOne(.mips)
6204 .attributes = .{ .@"const" = true }
6205
6206__builtin_msa_subs_s_h
6207 .param_str = "V8SsV8SsV8Ss"
6208 .target_set = TargetSet.initOne(.mips)
6209 .attributes = .{ .@"const" = true }
6210
6211__builtin_msa_subs_s_w
6212 .param_str = "V4SiV4SiV4Si"
6213 .target_set = TargetSet.initOne(.mips)
6214 .attributes = .{ .@"const" = true }
6215
6216__builtin_msa_subs_u_b
6217 .param_str = "V16UcV16UcV16Uc"
6218 .target_set = TargetSet.initOne(.mips)
6219 .attributes = .{ .@"const" = true }
6220
6221__builtin_msa_subs_u_d
6222 .param_str = "V2ULLiV2ULLiV2ULLi"
6223 .target_set = TargetSet.initOne(.mips)
6224 .attributes = .{ .@"const" = true }
6225
6226__builtin_msa_subs_u_h
6227 .param_str = "V8UsV8UsV8Us"
6228 .target_set = TargetSet.initOne(.mips)
6229 .attributes = .{ .@"const" = true }
6230
6231__builtin_msa_subs_u_w
6232 .param_str = "V4UiV4UiV4Ui"
6233 .target_set = TargetSet.initOne(.mips)
6234 .attributes = .{ .@"const" = true }
6235
6236__builtin_msa_subsus_u_b
6237 .param_str = "V16UcV16UcV16Sc"
6238 .target_set = TargetSet.initOne(.mips)
6239 .attributes = .{ .@"const" = true }
6240
6241__builtin_msa_subsus_u_d
6242 .param_str = "V2ULLiV2ULLiV2SLLi"
6243 .target_set = TargetSet.initOne(.mips)
6244 .attributes = .{ .@"const" = true }
6245
6246__builtin_msa_subsus_u_h
6247 .param_str = "V8UsV8UsV8Ss"
6248 .target_set = TargetSet.initOne(.mips)
6249 .attributes = .{ .@"const" = true }
6250
6251__builtin_msa_subsus_u_w
6252 .param_str = "V4UiV4UiV4Si"
6253 .target_set = TargetSet.initOne(.mips)
6254 .attributes = .{ .@"const" = true }
6255
6256__builtin_msa_subsuu_s_b
6257 .param_str = "V16ScV16UcV16Uc"
6258 .target_set = TargetSet.initOne(.mips)
6259 .attributes = .{ .@"const" = true }
6260
6261__builtin_msa_subsuu_s_d
6262 .param_str = "V2SLLiV2ULLiV2ULLi"
6263 .target_set = TargetSet.initOne(.mips)
6264 .attributes = .{ .@"const" = true }
6265
6266__builtin_msa_subsuu_s_h
6267 .param_str = "V8SsV8UsV8Us"
6268 .target_set = TargetSet.initOne(.mips)
6269 .attributes = .{ .@"const" = true }
6270
6271__builtin_msa_subsuu_s_w
6272 .param_str = "V4SiV4UiV4Ui"
6273 .target_set = TargetSet.initOne(.mips)
6274 .attributes = .{ .@"const" = true }
6275
6276__builtin_msa_subv_b
6277 .param_str = "V16cV16cV16c"
6278 .target_set = TargetSet.initOne(.mips)
6279 .attributes = .{ .@"const" = true }
6280
6281__builtin_msa_subv_d
6282 .param_str = "V2LLiV2LLiV2LLi"
6283 .target_set = TargetSet.initOne(.mips)
6284 .attributes = .{ .@"const" = true }
6285
6286__builtin_msa_subv_h
6287 .param_str = "V8sV8sV8s"
6288 .target_set = TargetSet.initOne(.mips)
6289 .attributes = .{ .@"const" = true }
6290
6291__builtin_msa_subv_w
6292 .param_str = "V4iV4iV4i"
6293 .target_set = TargetSet.initOne(.mips)
6294 .attributes = .{ .@"const" = true }
6295
6296__builtin_msa_subvi_b
6297 .param_str = "V16cV16cIUi"
6298 .target_set = TargetSet.initOne(.mips)
6299 .attributes = .{ .@"const" = true }
6300
6301__builtin_msa_subvi_d
6302 .param_str = "V2LLiV2LLiIUi"
6303 .target_set = TargetSet.initOne(.mips)
6304 .attributes = .{ .@"const" = true }
6305
6306__builtin_msa_subvi_h
6307 .param_str = "V8sV8sIUi"
6308 .target_set = TargetSet.initOne(.mips)
6309 .attributes = .{ .@"const" = true }
6310
6311__builtin_msa_subvi_w
6312 .param_str = "V4iV4iIUi"
6313 .target_set = TargetSet.initOne(.mips)
6314 .attributes = .{ .@"const" = true }
6315
6316__builtin_msa_vshf_b
6317 .param_str = "V16cV16cV16cV16c"
6318 .target_set = TargetSet.initOne(.mips)
6319 .attributes = .{ .@"const" = true }
6320
6321__builtin_msa_vshf_d
6322 .param_str = "V2LLiV2LLiV2LLiV2LLi"
6323 .target_set = TargetSet.initOne(.mips)
6324 .attributes = .{ .@"const" = true }
6325
6326__builtin_msa_vshf_h
6327 .param_str = "V8sV8sV8sV8s"
6328 .target_set = TargetSet.initOne(.mips)
6329 .attributes = .{ .@"const" = true }
6330
6331__builtin_msa_vshf_w
6332 .param_str = "V4iV4iV4iV4i"
6333 .target_set = TargetSet.initOne(.mips)
6334 .attributes = .{ .@"const" = true }
6335
6336__builtin_msa_xor_v
6337 .param_str = "V16cV16cV16c"
6338 .target_set = TargetSet.initOne(.mips)
6339 .attributes = .{ .@"const" = true }
6340
6341__builtin_msa_xori_b
6342 .param_str = "V16cV16cIUi"
6343 .target_set = TargetSet.initOne(.mips)
6344 .attributes = .{ .@"const" = true }
6345
6346__builtin_mul_overflow
6347 .param_str = "b."
6348 .attributes = .{ .custom_typecheck = true, .const_evaluable = true }
6349
6350__builtin_nan
6351 .param_str = "dcC*"
6352 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6353
6354__builtin_nanf
6355 .param_str = "fcC*"
6356 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6357
6358__builtin_nanf128
6359 .param_str = "LLdcC*"
6360 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6361
6362__builtin_nanf16
6363 .param_str = "xcC*"
6364 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6365
6366__builtin_nanl
6367 .param_str = "LdcC*"
6368 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6369
6370__builtin_nans
6371 .param_str = "dcC*"
6372 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6373
6374__builtin_nansf
6375 .param_str = "fcC*"
6376 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6377
6378__builtin_nansf128
6379 .param_str = "LLdcC*"
6380 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6381
6382__builtin_nansf16
6383 .param_str = "xcC*"
6384 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6385
6386__builtin_nansl
6387 .param_str = "LdcC*"
6388 .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true }
6389
6390__builtin_nearbyint
6391 .param_str = "dd"
6392 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
6393
6394__builtin_nearbyintf
6395 .param_str = "ff"
6396 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
6397
6398__builtin_nearbyintf128
6399 .param_str = "LLdLLd"
6400 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
6401
6402__builtin_nearbyintl
6403 .param_str = "LdLd"
6404 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
6405
6406__builtin_nextafter
6407 .param_str = "ddd"
6408 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6409
6410__builtin_nextafterf
6411 .param_str = "fff"
6412 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6413
6414__builtin_nextafterf128
6415 .param_str = "LLdLLdLLd"
6416 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6417
6418__builtin_nextafterl
6419 .param_str = "LdLdLd"
6420 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6421
6422__builtin_nexttoward
6423 .param_str = "ddLd"
6424 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6425
6426__builtin_nexttowardf
6427 .param_str = "ffLd"
6428 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6429
6430__builtin_nexttowardf128
6431 .param_str = "LLdLLdLLd"
6432 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6433
6434__builtin_nexttowardl
6435 .param_str = "LdLdLd"
6436 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6437
6438__builtin_nondeterministic_value
6439 .param_str = "v."
6440 .attributes = .{ .custom_typecheck = true }
6441
6442__builtin_nontemporal_load
6443 .param_str = "v."
6444 .attributes = .{ .custom_typecheck = true }
6445
6446__builtin_nontemporal_store
6447 .param_str = "v."
6448 .attributes = .{ .custom_typecheck = true }
6449
6450__builtin_objc_memmove_collectable
6451 .param_str = "v*v*vC*z"
6452 .attributes = .{ .lib_function_with_builtin_prefix = true }
6453
6454__builtin_object_size
6455 .param_str = "zvC*i"
6456 .attributes = .{ .eval_args = false, .const_evaluable = true }
6457
6458__builtin_operator_delete
6459 .param_str = "vv*"
6460 .attributes = .{ .custom_typecheck = true, .const_evaluable = true }
6461
6462__builtin_operator_new
6463 .param_str = "v*z"
6464 .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true }
6465
6466__builtin_os_log_format
6467 .param_str = "v*v*cC*."
6468 .attributes = .{ .custom_typecheck = true, .format_kind = .printf }
6469
6470__builtin_os_log_format_buffer_size
6471 .param_str = "zcC*."
6472 .attributes = .{ .custom_typecheck = true, .format_kind = .printf, .eval_args = false, .const_evaluable = true }
6473
6474__builtin_pack_longdouble
6475 .param_str = "Lddd"
6476 .target_set = TargetSet.initOne(.ppc)
6477
6478__builtin_parity
6479 .param_str = "iUi"
6480 .attributes = .{ .@"const" = true, .const_evaluable = true }
6481
6482__builtin_parityl
6483 .param_str = "iULi"
6484 .attributes = .{ .@"const" = true, .const_evaluable = true }
6485
6486__builtin_parityll
6487 .param_str = "iULLi"
6488 .attributes = .{ .@"const" = true, .const_evaluable = true }
6489
6490__builtin_popcount
6491 .param_str = "iUi"
6492 .attributes = .{ .@"const" = true, .const_evaluable = true }
6493
6494__builtin_popcountl
6495 .param_str = "iULi"
6496 .attributes = .{ .@"const" = true, .const_evaluable = true }
6497
6498__builtin_popcountll
6499 .param_str = "iULLi"
6500 .attributes = .{ .@"const" = true, .const_evaluable = true }
6501
6502__builtin_pow
6503 .param_str = "ddd"
6504 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6505
6506__builtin_powf
6507 .param_str = "fff"
6508 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6509
6510__builtin_powf128
6511 .param_str = "LLdLLdLLd"
6512 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6513
6514__builtin_powf16
6515 .param_str = "hhh"
6516 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6517
6518__builtin_powi
6519 .param_str = "ddi"
6520 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
6521
6522__builtin_powif
6523 .param_str = "ffi"
6524 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
6525
6526__builtin_powil
6527 .param_str = "LdLdi"
6528 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
6529
6530__builtin_powl
6531 .param_str = "LdLdLd"
6532 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
6533
6534__builtin_ppc_alignx
6535 .param_str = "vIivC*"
6536 .target_set = TargetSet.initOne(.ppc)
6537 .attributes = .{ .@"const" = true }
6538
6539__builtin_ppc_cmpb
6540 .param_str = "LLiLLiLLi"
6541 .target_set = TargetSet.initOne(.ppc)
6542
6543__builtin_ppc_compare_and_swap
6544 .param_str = "iiD*i*i"
6545 .target_set = TargetSet.initOne(.ppc)
6546
6547__builtin_ppc_compare_and_swaplp
6548 .param_str = "iLiD*Li*Li"
6549 .target_set = TargetSet.initOne(.ppc)
6550
6551__builtin_ppc_dcbfl
6552 .param_str = "vvC*"
6553 .target_set = TargetSet.initOne(.ppc)
6554
6555__builtin_ppc_dcbflp
6556 .param_str = "vvC*"
6557 .target_set = TargetSet.initOne(.ppc)
6558
6559__builtin_ppc_dcbst
6560 .param_str = "vvC*"
6561 .target_set = TargetSet.initOne(.ppc)
6562
6563__builtin_ppc_dcbt
6564 .param_str = "vv*"
6565 .target_set = TargetSet.initOne(.ppc)
6566
6567__builtin_ppc_dcbtst
6568 .param_str = "vv*"
6569 .target_set = TargetSet.initOne(.ppc)
6570
6571__builtin_ppc_dcbtstt
6572 .param_str = "vv*"
6573 .target_set = TargetSet.initOne(.ppc)
6574
6575__builtin_ppc_dcbtt
6576 .param_str = "vv*"
6577 .target_set = TargetSet.initOne(.ppc)
6578
6579__builtin_ppc_dcbz
6580 .param_str = "vv*"
6581 .target_set = TargetSet.initOne(.ppc)
6582
6583__builtin_ppc_eieio
6584 .param_str = "v"
6585 .target_set = TargetSet.initOne(.ppc)
6586
6587__builtin_ppc_fcfid
6588 .param_str = "dd"
6589 .target_set = TargetSet.initOne(.ppc)
6590
6591__builtin_ppc_fcfud
6592 .param_str = "dd"
6593 .target_set = TargetSet.initOne(.ppc)
6594
6595__builtin_ppc_fctid
6596 .param_str = "dd"
6597 .target_set = TargetSet.initOne(.ppc)
6598
6599__builtin_ppc_fctidz
6600 .param_str = "dd"
6601 .target_set = TargetSet.initOne(.ppc)
6602
6603__builtin_ppc_fctiw
6604 .param_str = "dd"
6605 .target_set = TargetSet.initOne(.ppc)
6606
6607__builtin_ppc_fctiwz
6608 .param_str = "dd"
6609 .target_set = TargetSet.initOne(.ppc)
6610
6611__builtin_ppc_fctudz
6612 .param_str = "dd"
6613 .target_set = TargetSet.initOne(.ppc)
6614
6615__builtin_ppc_fctuwz
6616 .param_str = "dd"
6617 .target_set = TargetSet.initOne(.ppc)
6618
6619__builtin_ppc_fetch_and_add
6620 .param_str = "iiD*i"
6621 .target_set = TargetSet.initOne(.ppc)
6622
6623__builtin_ppc_fetch_and_addlp
6624 .param_str = "LiLiD*Li"
6625 .target_set = TargetSet.initOne(.ppc)
6626
6627__builtin_ppc_fetch_and_and
6628 .param_str = "UiUiD*Ui"
6629 .target_set = TargetSet.initOne(.ppc)
6630
6631__builtin_ppc_fetch_and_andlp
6632 .param_str = "ULiULiD*ULi"
6633 .target_set = TargetSet.initOne(.ppc)
6634
6635__builtin_ppc_fetch_and_or
6636 .param_str = "UiUiD*Ui"
6637 .target_set = TargetSet.initOne(.ppc)
6638
6639__builtin_ppc_fetch_and_orlp
6640 .param_str = "ULiULiD*ULi"
6641 .target_set = TargetSet.initOne(.ppc)
6642
6643__builtin_ppc_fetch_and_swap
6644 .param_str = "UiUiD*Ui"
6645 .target_set = TargetSet.initOne(.ppc)
6646
6647__builtin_ppc_fetch_and_swaplp
6648 .param_str = "ULiULiD*ULi"
6649 .target_set = TargetSet.initOne(.ppc)
6650
6651__builtin_ppc_fmsub
6652 .param_str = "dddd"
6653 .target_set = TargetSet.initOne(.ppc)
6654
6655__builtin_ppc_fmsubs
6656 .param_str = "ffff"
6657 .target_set = TargetSet.initOne(.ppc)
6658
6659__builtin_ppc_fnabs
6660 .param_str = "dd"
6661 .target_set = TargetSet.initOne(.ppc)
6662
6663__builtin_ppc_fnabss
6664 .param_str = "ff"
6665 .target_set = TargetSet.initOne(.ppc)
6666
6667__builtin_ppc_fnmadd
6668 .param_str = "dddd"
6669 .target_set = TargetSet.initOne(.ppc)
6670
6671__builtin_ppc_fnmadds
6672 .param_str = "ffff"
6673 .target_set = TargetSet.initOne(.ppc)
6674
6675__builtin_ppc_fnmsub
6676 .param_str = "dddd"
6677 .target_set = TargetSet.initOne(.ppc)
6678
6679__builtin_ppc_fnmsubs
6680 .param_str = "ffff"
6681 .target_set = TargetSet.initOne(.ppc)
6682
6683__builtin_ppc_fre
6684 .param_str = "dd"
6685 .target_set = TargetSet.initOne(.ppc)
6686
6687__builtin_ppc_fres
6688 .param_str = "ff"
6689 .target_set = TargetSet.initOne(.ppc)
6690
6691__builtin_ppc_fric
6692 .param_str = "dd"
6693 .target_set = TargetSet.initOne(.ppc)
6694
6695__builtin_ppc_frim
6696 .param_str = "dd"
6697 .target_set = TargetSet.initOne(.ppc)
6698
6699__builtin_ppc_frims
6700 .param_str = "ff"
6701 .target_set = TargetSet.initOne(.ppc)
6702
6703__builtin_ppc_frin
6704 .param_str = "dd"
6705 .target_set = TargetSet.initOne(.ppc)
6706
6707__builtin_ppc_frins
6708 .param_str = "ff"
6709 .target_set = TargetSet.initOne(.ppc)
6710
6711__builtin_ppc_frip
6712 .param_str = "dd"
6713 .target_set = TargetSet.initOne(.ppc)
6714
6715__builtin_ppc_frips
6716 .param_str = "ff"
6717 .target_set = TargetSet.initOne(.ppc)
6718
6719__builtin_ppc_friz
6720 .param_str = "dd"
6721 .target_set = TargetSet.initOne(.ppc)
6722
6723__builtin_ppc_frizs
6724 .param_str = "ff"
6725 .target_set = TargetSet.initOne(.ppc)
6726
6727__builtin_ppc_frsqrte
6728 .param_str = "dd"
6729 .target_set = TargetSet.initOne(.ppc)
6730
6731__builtin_ppc_frsqrtes
6732 .param_str = "ff"
6733 .target_set = TargetSet.initOne(.ppc)
6734
6735__builtin_ppc_fsel
6736 .param_str = "dddd"
6737 .target_set = TargetSet.initOne(.ppc)
6738
6739__builtin_ppc_fsels
6740 .param_str = "ffff"
6741 .target_set = TargetSet.initOne(.ppc)
6742
6743__builtin_ppc_fsqrt
6744 .param_str = "dd"
6745 .target_set = TargetSet.initOne(.ppc)
6746
6747__builtin_ppc_fsqrts
6748 .param_str = "ff"
6749 .target_set = TargetSet.initOne(.ppc)
6750
6751__builtin_ppc_get_timebase
6752 .param_str = "ULLi"
6753 .target_set = TargetSet.initOne(.ppc)
6754
6755__builtin_ppc_iospace_eieio
6756 .param_str = "v"
6757 .target_set = TargetSet.initOne(.ppc)
6758
6759__builtin_ppc_iospace_lwsync
6760 .param_str = "v"
6761 .target_set = TargetSet.initOne(.ppc)
6762
6763__builtin_ppc_iospace_sync
6764 .param_str = "v"
6765 .target_set = TargetSet.initOne(.ppc)
6766
6767__builtin_ppc_isync
6768 .param_str = "v"
6769 .target_set = TargetSet.initOne(.ppc)
6770
6771__builtin_ppc_ldarx
6772 .param_str = "LiLiD*"
6773 .target_set = TargetSet.initOne(.ppc)
6774
6775__builtin_ppc_load2r
6776 .param_str = "UsUs*"
6777 .target_set = TargetSet.initOne(.ppc)
6778
6779__builtin_ppc_load4r
6780 .param_str = "UiUi*"
6781 .target_set = TargetSet.initOne(.ppc)
6782
6783__builtin_ppc_lwarx
6784 .param_str = "iiD*"
6785 .target_set = TargetSet.initOne(.ppc)
6786
6787__builtin_ppc_lwsync
6788 .param_str = "v"
6789 .target_set = TargetSet.initOne(.ppc)
6790
6791__builtin_ppc_maxfe
6792 .param_str = "LdLdLdLd."
6793 .target_set = TargetSet.initOne(.ppc)
6794 .attributes = .{ .custom_typecheck = true }
6795
6796__builtin_ppc_maxfl
6797 .param_str = "dddd."
6798 .target_set = TargetSet.initOne(.ppc)
6799 .attributes = .{ .custom_typecheck = true }
6800
6801__builtin_ppc_maxfs
6802 .param_str = "ffff."
6803 .target_set = TargetSet.initOne(.ppc)
6804 .attributes = .{ .custom_typecheck = true }
6805
6806__builtin_ppc_mfmsr
6807 .param_str = "Ui"
6808 .target_set = TargetSet.initOne(.ppc)
6809
6810__builtin_ppc_mfspr
6811 .param_str = "ULiIi"
6812 .target_set = TargetSet.initOne(.ppc)
6813
6814__builtin_ppc_mftbu
6815 .param_str = "Ui"
6816 .target_set = TargetSet.initOne(.ppc)
6817
6818__builtin_ppc_minfe
6819 .param_str = "LdLdLdLd."
6820 .target_set = TargetSet.initOne(.ppc)
6821 .attributes = .{ .custom_typecheck = true }
6822
6823__builtin_ppc_minfl
6824 .param_str = "dddd."
6825 .target_set = TargetSet.initOne(.ppc)
6826 .attributes = .{ .custom_typecheck = true }
6827
6828__builtin_ppc_minfs
6829 .param_str = "ffff."
6830 .target_set = TargetSet.initOne(.ppc)
6831 .attributes = .{ .custom_typecheck = true }
6832
6833__builtin_ppc_mtfsb0
6834 .param_str = "vUIi"
6835 .target_set = TargetSet.initOne(.ppc)
6836
6837__builtin_ppc_mtfsb1
6838 .param_str = "vUIi"
6839 .target_set = TargetSet.initOne(.ppc)
6840
6841__builtin_ppc_mtfsf
6842 .param_str = "vUIiUi"
6843 .target_set = TargetSet.initOne(.ppc)
6844
6845__builtin_ppc_mtfsfi
6846 .param_str = "vUIiUIi"
6847 .target_set = TargetSet.initOne(.ppc)
6848
6849__builtin_ppc_mtmsr
6850 .param_str = "vUi"
6851 .target_set = TargetSet.initOne(.ppc)
6852
6853__builtin_ppc_mtspr
6854 .param_str = "vIiULi"
6855 .target_set = TargetSet.initOne(.ppc)
6856
6857__builtin_ppc_mulhd
6858 .param_str = "LLiLiLi"
6859 .target_set = TargetSet.initOne(.ppc)
6860
6861__builtin_ppc_mulhdu
6862 .param_str = "ULLiULiULi"
6863 .target_set = TargetSet.initOne(.ppc)
6864
6865__builtin_ppc_mulhw
6866 .param_str = "iii"
6867 .target_set = TargetSet.initOne(.ppc)
6868
6869__builtin_ppc_mulhwu
6870 .param_str = "UiUiUi"
6871 .target_set = TargetSet.initOne(.ppc)
6872
6873__builtin_ppc_popcntb
6874 .param_str = "ULiULi"
6875 .target_set = TargetSet.initOne(.ppc)
6876
6877__builtin_ppc_poppar4
6878 .param_str = "iUi"
6879 .target_set = TargetSet.initOne(.ppc)
6880
6881__builtin_ppc_poppar8
6882 .param_str = "iULLi"
6883 .target_set = TargetSet.initOne(.ppc)
6884
6885__builtin_ppc_rdlam
6886 .param_str = "UWiUWiUWiUWIi"
6887 .target_set = TargetSet.initOne(.ppc)
6888 .attributes = .{ .@"const" = true }
6889
6890__builtin_ppc_recipdivd
6891 .param_str = "V2dV2dV2d"
6892 .target_set = TargetSet.initOne(.ppc)
6893
6894__builtin_ppc_recipdivf
6895 .param_str = "V4fV4fV4f"
6896 .target_set = TargetSet.initOne(.ppc)
6897
6898__builtin_ppc_rldimi
6899 .param_str = "ULLiULLiULLiIUiIULLi"
6900 .target_set = TargetSet.initOne(.ppc)
6901
6902__builtin_ppc_rlwimi
6903 .param_str = "UiUiUiIUiIUi"
6904 .target_set = TargetSet.initOne(.ppc)
6905
6906__builtin_ppc_rlwnm
6907 .param_str = "UiUiUiIUi"
6908 .target_set = TargetSet.initOne(.ppc)
6909
6910__builtin_ppc_rsqrtd
6911 .param_str = "V2dV2d"
6912 .target_set = TargetSet.initOne(.ppc)
6913
6914__builtin_ppc_rsqrtf
6915 .param_str = "V4fV4f"
6916 .target_set = TargetSet.initOne(.ppc)
6917
6918__builtin_ppc_stdcx
6919 .param_str = "iLiD*Li"
6920 .target_set = TargetSet.initOne(.ppc)
6921
6922__builtin_ppc_stfiw
6923 .param_str = "viC*d"
6924 .target_set = TargetSet.initOne(.ppc)
6925
6926__builtin_ppc_store2r
6927 .param_str = "vUiUs*"
6928 .target_set = TargetSet.initOne(.ppc)
6929
6930__builtin_ppc_store4r
6931 .param_str = "vUiUi*"
6932 .target_set = TargetSet.initOne(.ppc)
6933
6934__builtin_ppc_stwcx
6935 .param_str = "iiD*i"
6936 .target_set = TargetSet.initOne(.ppc)
6937
6938__builtin_ppc_swdiv
6939 .param_str = "ddd"
6940 .target_set = TargetSet.initOne(.ppc)
6941
6942__builtin_ppc_swdiv_nochk
6943 .param_str = "ddd"
6944 .target_set = TargetSet.initOne(.ppc)
6945
6946__builtin_ppc_swdivs
6947 .param_str = "fff"
6948 .target_set = TargetSet.initOne(.ppc)
6949
6950__builtin_ppc_swdivs_nochk
6951 .param_str = "fff"
6952 .target_set = TargetSet.initOne(.ppc)
6953
6954__builtin_ppc_sync
6955 .param_str = "v"
6956 .target_set = TargetSet.initOne(.ppc)
6957
6958__builtin_ppc_tdw
6959 .param_str = "vLLiLLiIUi"
6960 .target_set = TargetSet.initOne(.ppc)
6961
6962__builtin_ppc_trap
6963 .param_str = "vi"
6964 .target_set = TargetSet.initOne(.ppc)
6965
6966__builtin_ppc_trapd
6967 .param_str = "vLi"
6968 .target_set = TargetSet.initOne(.ppc)
6969
6970__builtin_ppc_tw
6971 .param_str = "viiIUi"
6972 .target_set = TargetSet.initOne(.ppc)
6973
6974__builtin_prefetch
6975 .param_str = "vvC*."
6976 .attributes = .{ .@"const" = true }
6977
6978__builtin_preserve_access_index
6979 .param_str = "v."
6980 .attributes = .{ .custom_typecheck = true }
6981
6982__builtin_printf
6983 .param_str = "icC*R."
6984 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf }
6985
6986__builtin_ptx_get_image_channel_data_typei_
6987 .param_str = "ii"
6988 .target_set = TargetSet.initOne(.nvptx)
6989
6990__builtin_ptx_get_image_channel_orderi_
6991 .param_str = "ii"
6992 .target_set = TargetSet.initOne(.nvptx)
6993
6994__builtin_ptx_get_image_depthi_
6995 .param_str = "ii"
6996 .target_set = TargetSet.initOne(.nvptx)
6997
6998__builtin_ptx_get_image_heighti_
6999 .param_str = "ii"
7000 .target_set = TargetSet.initOne(.nvptx)
7001
7002__builtin_ptx_get_image_widthi_
7003 .param_str = "ii"
7004 .target_set = TargetSet.initOne(.nvptx)
7005
7006__builtin_ptx_read_image2Dff_
7007 .param_str = "V4fiiff"
7008 .target_set = TargetSet.initOne(.nvptx)
7009
7010__builtin_ptx_read_image2Dfi_
7011 .param_str = "V4fiiii"
7012 .target_set = TargetSet.initOne(.nvptx)
7013
7014__builtin_ptx_read_image2Dif_
7015 .param_str = "V4iiiff"
7016 .target_set = TargetSet.initOne(.nvptx)
7017
7018__builtin_ptx_read_image2Dii_
7019 .param_str = "V4iiiii"
7020 .target_set = TargetSet.initOne(.nvptx)
7021
7022__builtin_ptx_read_image3Dff_
7023 .param_str = "V4fiiffff"
7024 .target_set = TargetSet.initOne(.nvptx)
7025
7026__builtin_ptx_read_image3Dfi_
7027 .param_str = "V4fiiiiii"
7028 .target_set = TargetSet.initOne(.nvptx)
7029
7030__builtin_ptx_read_image3Dif_
7031 .param_str = "V4iiiffff"
7032 .target_set = TargetSet.initOne(.nvptx)
7033
7034__builtin_ptx_read_image3Dii_
7035 .param_str = "V4iiiiiii"
7036 .target_set = TargetSet.initOne(.nvptx)
7037
7038__builtin_ptx_write_image2Df_
7039 .param_str = "viiiffff"
7040 .target_set = TargetSet.initOne(.nvptx)
7041
7042__builtin_ptx_write_image2Di_
7043 .param_str = "viiiiiii"
7044 .target_set = TargetSet.initOne(.nvptx)
7045
7046__builtin_ptx_write_image2Dui_
7047 .param_str = "viiiUiUiUiUi"
7048 .target_set = TargetSet.initOne(.nvptx)
7049
7050__builtin_r600_implicitarg_ptr
7051 .param_str = "Uc*7"
7052 .target_set = TargetSet.initOne(.amdgpu)
7053 .attributes = .{ .@"const" = true }
7054
7055__builtin_r600_read_tgid_x
7056 .param_str = "Ui"
7057 .target_set = TargetSet.initOne(.amdgpu)
7058 .attributes = .{ .@"const" = true }
7059
7060__builtin_r600_read_tgid_y
7061 .param_str = "Ui"
7062 .target_set = TargetSet.initOne(.amdgpu)
7063 .attributes = .{ .@"const" = true }
7064
7065__builtin_r600_read_tgid_z
7066 .param_str = "Ui"
7067 .target_set = TargetSet.initOne(.amdgpu)
7068 .attributes = .{ .@"const" = true }
7069
7070__builtin_r600_read_tidig_x
7071 .param_str = "Ui"
7072 .target_set = TargetSet.initOne(.amdgpu)
7073 .attributes = .{ .@"const" = true }
7074
7075__builtin_r600_read_tidig_y
7076 .param_str = "Ui"
7077 .target_set = TargetSet.initOne(.amdgpu)
7078 .attributes = .{ .@"const" = true }
7079
7080__builtin_r600_read_tidig_z
7081 .param_str = "Ui"
7082 .target_set = TargetSet.initOne(.amdgpu)
7083 .attributes = .{ .@"const" = true }
7084
7085__builtin_r600_recipsqrt_ieee
7086 .param_str = "dd"
7087 .target_set = TargetSet.initOne(.amdgpu)
7088 .attributes = .{ .@"const" = true }
7089
7090__builtin_r600_recipsqrt_ieeef
7091 .param_str = "ff"
7092 .target_set = TargetSet.initOne(.amdgpu)
7093 .attributes = .{ .@"const" = true }
7094
7095__builtin_readcyclecounter
7096 .param_str = "ULLi"
7097
7098__builtin_readflm
7099 .param_str = "d"
7100 .target_set = TargetSet.initOne(.ppc)
7101
7102__builtin_realloc
7103 .param_str = "v*v*z"
7104 .attributes = .{ .lib_function_with_builtin_prefix = true }
7105
7106__builtin_reduce_add
7107 .param_str = "v."
7108 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7109
7110__builtin_reduce_and
7111 .param_str = "v."
7112 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7113
7114__builtin_reduce_max
7115 .param_str = "v."
7116 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7117
7118__builtin_reduce_min
7119 .param_str = "v."
7120 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7121
7122__builtin_reduce_mul
7123 .param_str = "v."
7124 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7125
7126__builtin_reduce_or
7127 .param_str = "v."
7128 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7129
7130__builtin_reduce_xor
7131 .param_str = "v."
7132 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7133
7134__builtin_remainder
7135 .param_str = "ddd"
7136 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7137
7138__builtin_remainderf
7139 .param_str = "fff"
7140 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7141
7142__builtin_remainderf128
7143 .param_str = "LLdLLdLLd"
7144 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7145
7146__builtin_remainderl
7147 .param_str = "LdLdLd"
7148 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7149
7150__builtin_remquo
7151 .param_str = "dddi*"
7152 .attributes = .{ .lib_function_with_builtin_prefix = true }
7153
7154__builtin_remquof
7155 .param_str = "fffi*"
7156 .attributes = .{ .lib_function_with_builtin_prefix = true }
7157
7158__builtin_remquof128
7159 .param_str = "LLdLLdLLdi*"
7160 .attributes = .{ .lib_function_with_builtin_prefix = true }
7161
7162__builtin_remquol
7163 .param_str = "LdLdLdi*"
7164 .attributes = .{ .lib_function_with_builtin_prefix = true }
7165
7166__builtin_return_address
7167 .param_str = "v*IUi"
7168
7169__builtin_rindex
7170 .param_str = "c*cC*i"
7171 .attributes = .{ .lib_function_with_builtin_prefix = true }
7172
7173__builtin_rint
7174 .param_str = "dd"
7175 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7176
7177__builtin_rintf
7178 .param_str = "ff"
7179 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7180
7181__builtin_rintf128
7182 .param_str = "LLdLLd"
7183 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7184
7185__builtin_rintf16
7186 .param_str = "hh"
7187 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7188
7189__builtin_rintl
7190 .param_str = "LdLd"
7191 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7192
7193__builtin_rotateleft16
7194 .param_str = "UsUsUs"
7195 .attributes = .{ .@"const" = true, .const_evaluable = true }
7196
7197__builtin_rotateleft32
7198 .param_str = "UZiUZiUZi"
7199 .attributes = .{ .@"const" = true, .const_evaluable = true }
7200
7201__builtin_rotateleft64
7202 .param_str = "UWiUWiUWi"
7203 .attributes = .{ .@"const" = true, .const_evaluable = true }
7204
7205__builtin_rotateleft8
7206 .param_str = "UcUcUc"
7207 .attributes = .{ .@"const" = true, .const_evaluable = true }
7208
7209__builtin_rotateright16
7210 .param_str = "UsUsUs"
7211 .attributes = .{ .@"const" = true, .const_evaluable = true }
7212
7213__builtin_rotateright32
7214 .param_str = "UZiUZiUZi"
7215 .attributes = .{ .@"const" = true, .const_evaluable = true }
7216
7217__builtin_rotateright64
7218 .param_str = "UWiUWiUWi"
7219 .attributes = .{ .@"const" = true, .const_evaluable = true }
7220
7221__builtin_rotateright8
7222 .param_str = "UcUcUc"
7223 .attributes = .{ .@"const" = true, .const_evaluable = true }
7224
7225__builtin_round
7226 .param_str = "dd"
7227 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7228
7229__builtin_roundeven
7230 .param_str = "dd"
7231 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7232
7233__builtin_roundevenf
7234 .param_str = "ff"
7235 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7236
7237__builtin_roundevenf128
7238 .param_str = "LLdLLd"
7239 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7240
7241__builtin_roundevenf16
7242 .param_str = "hh"
7243 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7244
7245__builtin_roundevenl
7246 .param_str = "LdLd"
7247 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7248
7249__builtin_roundf
7250 .param_str = "ff"
7251 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7252
7253__builtin_roundf128
7254 .param_str = "LLdLLd"
7255 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7256
7257__builtin_roundf16
7258 .param_str = "hh"
7259 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7260
7261__builtin_roundl
7262 .param_str = "LdLd"
7263 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7264
7265__builtin_sadd_overflow
7266 .param_str = "bSiCSiCSi*"
7267 .attributes = .{ .const_evaluable = true }
7268
7269__builtin_saddl_overflow
7270 .param_str = "bSLiCSLiCSLi*"
7271 .attributes = .{ .const_evaluable = true }
7272
7273__builtin_saddll_overflow
7274 .param_str = "bSLLiCSLLiCSLLi*"
7275 .attributes = .{ .const_evaluable = true }
7276
7277__builtin_scalbln
7278 .param_str = "ddLi"
7279 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7280
7281__builtin_scalblnf
7282 .param_str = "ffLi"
7283 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7284
7285__builtin_scalblnf128
7286 .param_str = "LLdLLdLi"
7287 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7288
7289__builtin_scalblnl
7290 .param_str = "LdLdLi"
7291 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7292
7293__builtin_scalbn
7294 .param_str = "ddi"
7295 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7296
7297__builtin_scalbnf
7298 .param_str = "ffi"
7299 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7300
7301__builtin_scalbnf128
7302 .param_str = "LLdLLdi"
7303 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7304
7305__builtin_scalbnl
7306 .param_str = "LdLdi"
7307 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7308
7309__builtin_scanf
7310 .param_str = "icC*R."
7311 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf }
7312
7313__builtin_set_flt_rounds
7314 .param_str = "vi"
7315
7316__builtin_setflm
7317 .param_str = "dd"
7318 .target_set = TargetSet.initOne(.ppc)
7319
7320__builtin_setjmp
7321 .param_str = "iv**"
7322 .attributes = .{ .returns_twice = true }
7323
7324__builtin_setps
7325 .param_str = "vUiUi"
7326 .target_set = TargetSet.initOne(.xcore)
7327
7328__builtin_setrnd
7329 .param_str = "di"
7330 .target_set = TargetSet.initOne(.ppc)
7331
7332__builtin_shufflevector
7333 .param_str = "v."
7334 .attributes = .{ .@"const" = true, .custom_typecheck = true }
7335
7336__builtin_signbit
7337 .param_str = "i."
7338 .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true }
7339
7340__builtin_signbitf
7341 .param_str = "if"
7342 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7343
7344__builtin_signbitl
7345 .param_str = "iLd"
7346 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7347
7348__builtin_sin
7349 .param_str = "dd"
7350 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7351
7352__builtin_sinf
7353 .param_str = "ff"
7354 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7355
7356__builtin_sinf128
7357 .param_str = "LLdLLd"
7358 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7359
7360__builtin_sinf16
7361 .param_str = "hh"
7362 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7363
7364__builtin_sinh
7365 .param_str = "dd"
7366 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7367
7368__builtin_sinhf
7369 .param_str = "ff"
7370 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7371
7372__builtin_sinhf128
7373 .param_str = "LLdLLd"
7374 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7375
7376__builtin_sinhl
7377 .param_str = "LdLd"
7378 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7379
7380__builtin_sinl
7381 .param_str = "LdLd"
7382 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7383
7384__builtin_smul_overflow
7385 .param_str = "bSiCSiCSi*"
7386 .attributes = .{ .const_evaluable = true }
7387
7388__builtin_smull_overflow
7389 .param_str = "bSLiCSLiCSLi*"
7390 .attributes = .{ .const_evaluable = true }
7391
7392__builtin_smulll_overflow
7393 .param_str = "bSLLiCSLLiCSLLi*"
7394 .attributes = .{ .const_evaluable = true }
7395
7396__builtin_snprintf
7397 .param_str = "ic*RzcC*R."
7398 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 2 }
7399
7400__builtin_sponentry
7401 .param_str = "v*"
7402 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
7403 .attributes = .{ .@"const" = true }
7404
7405__builtin_sprintf
7406 .param_str = "ic*RcC*R."
7407 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 }
7408
7409__builtin_sqrt
7410 .param_str = "dd"
7411 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7412
7413__builtin_sqrtf
7414 .param_str = "ff"
7415 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7416
7417__builtin_sqrtf128
7418 .param_str = "LLdLLd"
7419 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7420
7421__builtin_sqrtf16
7422 .param_str = "hh"
7423 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7424
7425__builtin_sqrtl
7426 .param_str = "LdLd"
7427 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7428
7429__builtin_sscanf
7430 .param_str = "icC*RcC*R."
7431 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf, .format_string_position = 1 }
7432
7433__builtin_ssub_overflow
7434 .param_str = "bSiCSiCSi*"
7435 .attributes = .{ .const_evaluable = true }
7436
7437__builtin_ssubl_overflow
7438 .param_str = "bSLiCSLiCSLi*"
7439 .attributes = .{ .const_evaluable = true }
7440
7441__builtin_ssubll_overflow
7442 .param_str = "bSLLiCSLLiCSLLi*"
7443 .attributes = .{ .const_evaluable = true }
7444
7445__builtin_stdarg_start
7446 .param_str = "vA."
7447 .attributes = .{ .custom_typecheck = true }
7448
7449__builtin_stpcpy
7450 .param_str = "c*c*cC*"
7451 .attributes = .{ .lib_function_with_builtin_prefix = true }
7452
7453__builtin_stpncpy
7454 .param_str = "c*c*cC*z"
7455 .attributes = .{ .lib_function_with_builtin_prefix = true }
7456
7457__builtin_strcasecmp
7458 .param_str = "icC*cC*"
7459 .attributes = .{ .lib_function_with_builtin_prefix = true }
7460
7461__builtin_strcat
7462 .param_str = "c*c*cC*"
7463 .attributes = .{ .lib_function_with_builtin_prefix = true }
7464
7465__builtin_strchr
7466 .param_str = "c*cC*i"
7467 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
7468
7469__builtin_strcmp
7470 .param_str = "icC*cC*"
7471 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
7472
7473__builtin_strcpy
7474 .param_str = "c*c*cC*"
7475 .attributes = .{ .lib_function_with_builtin_prefix = true }
7476
7477__builtin_strcspn
7478 .param_str = "zcC*cC*"
7479 .attributes = .{ .lib_function_with_builtin_prefix = true }
7480
7481__builtin_strdup
7482 .param_str = "c*cC*"
7483 .attributes = .{ .lib_function_with_builtin_prefix = true }
7484
7485__builtin_strlen
7486 .param_str = "zcC*"
7487 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
7488
7489__builtin_strncasecmp
7490 .param_str = "icC*cC*z"
7491 .attributes = .{ .lib_function_with_builtin_prefix = true }
7492
7493__builtin_strncat
7494 .param_str = "c*c*cC*z"
7495 .attributes = .{ .lib_function_with_builtin_prefix = true }
7496
7497__builtin_strncmp
7498 .param_str = "icC*cC*z"
7499 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
7500
7501__builtin_strncpy
7502 .param_str = "c*c*cC*z"
7503 .attributes = .{ .lib_function_with_builtin_prefix = true }
7504
7505__builtin_strndup
7506 .param_str = "c*cC*z"
7507 .attributes = .{ .lib_function_with_builtin_prefix = true }
7508
7509__builtin_strpbrk
7510 .param_str = "c*cC*cC*"
7511 .attributes = .{ .lib_function_with_builtin_prefix = true }
7512
7513__builtin_strrchr
7514 .param_str = "c*cC*i"
7515 .attributes = .{ .lib_function_with_builtin_prefix = true }
7516
7517__builtin_strspn
7518 .param_str = "zcC*cC*"
7519 .attributes = .{ .lib_function_with_builtin_prefix = true }
7520
7521__builtin_strstr
7522 .param_str = "c*cC*cC*"
7523 .attributes = .{ .lib_function_with_builtin_prefix = true }
7524
7525__builtin_sub_overflow
7526 .param_str = "b."
7527 .attributes = .{ .custom_typecheck = true, .const_evaluable = true }
7528
7529__builtin_subc
7530 .param_str = "UiUiCUiCUiCUi*"
7531
7532__builtin_subcb
7533 .param_str = "UcUcCUcCUcCUc*"
7534
7535__builtin_subcl
7536 .param_str = "ULiULiCULiCULiCULi*"
7537
7538__builtin_subcll
7539 .param_str = "ULLiULLiCULLiCULLiCULLi*"
7540
7541__builtin_subcs
7542 .param_str = "UsUsCUsCUsCUs*"
7543
7544__builtin_tan
7545 .param_str = "dd"
7546 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7547
7548__builtin_tanf
7549 .param_str = "ff"
7550 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7551
7552__builtin_tanf128
7553 .param_str = "LLdLLd"
7554 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7555
7556__builtin_tanh
7557 .param_str = "dd"
7558 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7559
7560__builtin_tanhf
7561 .param_str = "ff"
7562 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7563
7564__builtin_tanhf128
7565 .param_str = "LLdLLd"
7566 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7567
7568__builtin_tanhl
7569 .param_str = "LdLd"
7570 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7571
7572__builtin_tanl
7573 .param_str = "LdLd"
7574 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7575
7576__builtin_tgamma
7577 .param_str = "dd"
7578 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7579
7580__builtin_tgammaf
7581 .param_str = "ff"
7582 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7583
7584__builtin_tgammaf128
7585 .param_str = "LLdLLd"
7586 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7587
7588__builtin_tgammal
7589 .param_str = "LdLd"
7590 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true }
7591
7592__builtin_thread_pointer
7593 .param_str = "v*"
7594 .attributes = .{ .@"const" = true }
7595
7596__builtin_trap
7597 .param_str = "v"
7598 .attributes = .{ .noreturn = true }
7599
7600__builtin_trunc
7601 .param_str = "dd"
7602 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7603
7604__builtin_truncf
7605 .param_str = "ff"
7606 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7607
7608__builtin_truncf128
7609 .param_str = "LLdLLd"
7610 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7611
7612__builtin_truncf16
7613 .param_str = "hh"
7614 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7615
7616__builtin_truncl
7617 .param_str = "LdLd"
7618 .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true }
7619
7620__builtin_uadd_overflow
7621 .param_str = "bUiCUiCUi*"
7622 .attributes = .{ .const_evaluable = true }
7623
7624__builtin_uaddl_overflow
7625 .param_str = "bULiCULiCULi*"
7626 .attributes = .{ .const_evaluable = true }
7627
7628__builtin_uaddll_overflow
7629 .param_str = "bULLiCULLiCULLi*"
7630 .attributes = .{ .const_evaluable = true }
7631
7632__builtin_umul_overflow
7633 .param_str = "bUiCUiCUi*"
7634 .attributes = .{ .const_evaluable = true }
7635
7636__builtin_umull_overflow
7637 .param_str = "bULiCULiCULi*"
7638 .attributes = .{ .const_evaluable = true }
7639
7640__builtin_umulll_overflow
7641 .param_str = "bULLiCULLiCULLi*"
7642 .attributes = .{ .const_evaluable = true }
7643
7644__builtin_unpack_longdouble
7645 .param_str = "dLdIi"
7646 .target_set = TargetSet.initOne(.ppc)
7647
7648__builtin_unpredictable
7649 .param_str = "LiLi"
7650 .attributes = .{ .@"const" = true }
7651
7652__builtin_unreachable
7653 .param_str = "v"
7654 .attributes = .{ .noreturn = true }
7655
7656__builtin_unwind_init
7657 .param_str = "v"
7658
7659__builtin_usub_overflow
7660 .param_str = "bUiCUiCUi*"
7661 .attributes = .{ .const_evaluable = true }
7662
7663__builtin_usubl_overflow
7664 .param_str = "bULiCULiCULi*"
7665 .attributes = .{ .const_evaluable = true }
7666
7667__builtin_usubll_overflow
7668 .param_str = "bULLiCULLiCULLi*"
7669 .attributes = .{ .const_evaluable = true }
7670
7671__builtin_va_copy
7672 .param_str = "vAA"
7673
7674__builtin_va_end
7675 .param_str = "vA"
7676
7677__builtin_va_start
7678 .param_str = "vA."
7679 .attributes = .{ .custom_typecheck = true }
7680
7681__builtin_ve_vl_andm_MMM
7682 .param_str = "V512bV512bV512b"
7683 .target_set = TargetSet.initOne(.vevl_gen)
7684
7685__builtin_ve_vl_andm_mmm
7686 .param_str = "V256bV256bV256b"
7687 .target_set = TargetSet.initOne(.vevl_gen)
7688
7689__builtin_ve_vl_eqvm_MMM
7690 .param_str = "V512bV512bV512b"
7691 .target_set = TargetSet.initOne(.vevl_gen)
7692
7693__builtin_ve_vl_eqvm_mmm
7694 .param_str = "V256bV256bV256b"
7695 .target_set = TargetSet.initOne(.vevl_gen)
7696
7697__builtin_ve_vl_extract_vm512l
7698 .param_str = "V256bV512b"
7699 .target_set = TargetSet.initOne(.ve)
7700
7701__builtin_ve_vl_extract_vm512u
7702 .param_str = "V256bV512b"
7703 .target_set = TargetSet.initOne(.ve)
7704
7705__builtin_ve_vl_fencec_s
7706 .param_str = "vUi"
7707 .target_set = TargetSet.initOne(.vevl_gen)
7708
7709__builtin_ve_vl_fencei
7710 .param_str = "v"
7711 .target_set = TargetSet.initOne(.vevl_gen)
7712
7713__builtin_ve_vl_fencem_s
7714 .param_str = "vUi"
7715 .target_set = TargetSet.initOne(.vevl_gen)
7716
7717__builtin_ve_vl_fidcr_sss
7718 .param_str = "LUiLUiUi"
7719 .target_set = TargetSet.initOne(.vevl_gen)
7720
7721__builtin_ve_vl_insert_vm512l
7722 .param_str = "V512bV512bV256b"
7723 .target_set = TargetSet.initOne(.ve)
7724
7725__builtin_ve_vl_insert_vm512u
7726 .param_str = "V512bV512bV256b"
7727 .target_set = TargetSet.initOne(.ve)
7728
7729__builtin_ve_vl_lcr_sss
7730 .param_str = "LUiLUiLUi"
7731 .target_set = TargetSet.initOne(.vevl_gen)
7732
7733__builtin_ve_vl_lsv_vvss
7734 .param_str = "V256dV256dUiLUi"
7735 .target_set = TargetSet.initOne(.vevl_gen)
7736
7737__builtin_ve_vl_lvm_MMss
7738 .param_str = "V512bV512bLUiLUi"
7739 .target_set = TargetSet.initOne(.vevl_gen)
7740
7741__builtin_ve_vl_lvm_mmss
7742 .param_str = "V256bV256bLUiLUi"
7743 .target_set = TargetSet.initOne(.vevl_gen)
7744
7745__builtin_ve_vl_lvsd_svs
7746 .param_str = "dV256dUi"
7747 .target_set = TargetSet.initOne(.vevl_gen)
7748
7749__builtin_ve_vl_lvsl_svs
7750 .param_str = "LUiV256dUi"
7751 .target_set = TargetSet.initOne(.vevl_gen)
7752
7753__builtin_ve_vl_lvss_svs
7754 .param_str = "fV256dUi"
7755 .target_set = TargetSet.initOne(.vevl_gen)
7756
7757__builtin_ve_vl_lzvm_sml
7758 .param_str = "LUiV256bUi"
7759 .target_set = TargetSet.initOne(.vevl_gen)
7760
7761__builtin_ve_vl_negm_MM
7762 .param_str = "V512bV512b"
7763 .target_set = TargetSet.initOne(.vevl_gen)
7764
7765__builtin_ve_vl_negm_mm
7766 .param_str = "V256bV256b"
7767 .target_set = TargetSet.initOne(.vevl_gen)
7768
7769__builtin_ve_vl_nndm_MMM
7770 .param_str = "V512bV512bV512b"
7771 .target_set = TargetSet.initOne(.vevl_gen)
7772
7773__builtin_ve_vl_nndm_mmm
7774 .param_str = "V256bV256bV256b"
7775 .target_set = TargetSet.initOne(.vevl_gen)
7776
7777__builtin_ve_vl_orm_MMM
7778 .param_str = "V512bV512bV512b"
7779 .target_set = TargetSet.initOne(.vevl_gen)
7780
7781__builtin_ve_vl_orm_mmm
7782 .param_str = "V256bV256bV256b"
7783 .target_set = TargetSet.initOne(.vevl_gen)
7784
7785__builtin_ve_vl_pack_f32a
7786 .param_str = "ULifC*"
7787 .target_set = TargetSet.initOne(.ve)
7788
7789__builtin_ve_vl_pack_f32p
7790 .param_str = "ULifC*fC*"
7791 .target_set = TargetSet.initOne(.ve)
7792
7793__builtin_ve_vl_pcvm_sml
7794 .param_str = "LUiV256bUi"
7795 .target_set = TargetSet.initOne(.vevl_gen)
7796
7797__builtin_ve_vl_pfchv_ssl
7798 .param_str = "vLivC*Ui"
7799 .target_set = TargetSet.initOne(.vevl_gen)
7800
7801__builtin_ve_vl_pfchvnc_ssl
7802 .param_str = "vLivC*Ui"
7803 .target_set = TargetSet.initOne(.vevl_gen)
7804
7805__builtin_ve_vl_pvadds_vsvMvl
7806 .param_str = "V256dLUiV256dV512bV256dUi"
7807 .target_set = TargetSet.initOne(.vevl_gen)
7808
7809__builtin_ve_vl_pvadds_vsvl
7810 .param_str = "V256dLUiV256dUi"
7811 .target_set = TargetSet.initOne(.vevl_gen)
7812
7813__builtin_ve_vl_pvadds_vsvvl
7814 .param_str = "V256dLUiV256dV256dUi"
7815 .target_set = TargetSet.initOne(.vevl_gen)
7816
7817__builtin_ve_vl_pvadds_vvvMvl
7818 .param_str = "V256dV256dV256dV512bV256dUi"
7819 .target_set = TargetSet.initOne(.vevl_gen)
7820
7821__builtin_ve_vl_pvadds_vvvl
7822 .param_str = "V256dV256dV256dUi"
7823 .target_set = TargetSet.initOne(.vevl_gen)
7824
7825__builtin_ve_vl_pvadds_vvvvl
7826 .param_str = "V256dV256dV256dV256dUi"
7827 .target_set = TargetSet.initOne(.vevl_gen)
7828
7829__builtin_ve_vl_pvaddu_vsvMvl
7830 .param_str = "V256dLUiV256dV512bV256dUi"
7831 .target_set = TargetSet.initOne(.vevl_gen)
7832
7833__builtin_ve_vl_pvaddu_vsvl
7834 .param_str = "V256dLUiV256dUi"
7835 .target_set = TargetSet.initOne(.vevl_gen)
7836
7837__builtin_ve_vl_pvaddu_vsvvl
7838 .param_str = "V256dLUiV256dV256dUi"
7839 .target_set = TargetSet.initOne(.vevl_gen)
7840
7841__builtin_ve_vl_pvaddu_vvvMvl
7842 .param_str = "V256dV256dV256dV512bV256dUi"
7843 .target_set = TargetSet.initOne(.vevl_gen)
7844
7845__builtin_ve_vl_pvaddu_vvvl
7846 .param_str = "V256dV256dV256dUi"
7847 .target_set = TargetSet.initOne(.vevl_gen)
7848
7849__builtin_ve_vl_pvaddu_vvvvl
7850 .param_str = "V256dV256dV256dV256dUi"
7851 .target_set = TargetSet.initOne(.vevl_gen)
7852
7853__builtin_ve_vl_pvand_vsvMvl
7854 .param_str = "V256dLUiV256dV512bV256dUi"
7855 .target_set = TargetSet.initOne(.vevl_gen)
7856
7857__builtin_ve_vl_pvand_vsvl
7858 .param_str = "V256dLUiV256dUi"
7859 .target_set = TargetSet.initOne(.vevl_gen)
7860
7861__builtin_ve_vl_pvand_vsvvl
7862 .param_str = "V256dLUiV256dV256dUi"
7863 .target_set = TargetSet.initOne(.vevl_gen)
7864
7865__builtin_ve_vl_pvand_vvvMvl
7866 .param_str = "V256dV256dV256dV512bV256dUi"
7867 .target_set = TargetSet.initOne(.vevl_gen)
7868
7869__builtin_ve_vl_pvand_vvvl
7870 .param_str = "V256dV256dV256dUi"
7871 .target_set = TargetSet.initOne(.vevl_gen)
7872
7873__builtin_ve_vl_pvand_vvvvl
7874 .param_str = "V256dV256dV256dV256dUi"
7875 .target_set = TargetSet.initOne(.vevl_gen)
7876
7877__builtin_ve_vl_pvbrd_vsMvl
7878 .param_str = "V256dLUiV512bV256dUi"
7879 .target_set = TargetSet.initOne(.vevl_gen)
7880
7881__builtin_ve_vl_pvbrd_vsl
7882 .param_str = "V256dLUiUi"
7883 .target_set = TargetSet.initOne(.vevl_gen)
7884
7885__builtin_ve_vl_pvbrd_vsvl
7886 .param_str = "V256dLUiV256dUi"
7887 .target_set = TargetSet.initOne(.vevl_gen)
7888
7889__builtin_ve_vl_pvbrv_vvMvl
7890 .param_str = "V256dV256dV512bV256dUi"
7891 .target_set = TargetSet.initOne(.vevl_gen)
7892
7893__builtin_ve_vl_pvbrv_vvl
7894 .param_str = "V256dV256dUi"
7895 .target_set = TargetSet.initOne(.vevl_gen)
7896
7897__builtin_ve_vl_pvbrv_vvvl
7898 .param_str = "V256dV256dV256dUi"
7899 .target_set = TargetSet.initOne(.vevl_gen)
7900
7901__builtin_ve_vl_pvbrvlo_vvl
7902 .param_str = "V256dV256dUi"
7903 .target_set = TargetSet.initOne(.vevl_gen)
7904
7905__builtin_ve_vl_pvbrvlo_vvmvl
7906 .param_str = "V256dV256dV256bV256dUi"
7907 .target_set = TargetSet.initOne(.vevl_gen)
7908
7909__builtin_ve_vl_pvbrvlo_vvvl
7910 .param_str = "V256dV256dV256dUi"
7911 .target_set = TargetSet.initOne(.vevl_gen)
7912
7913__builtin_ve_vl_pvbrvup_vvl
7914 .param_str = "V256dV256dUi"
7915 .target_set = TargetSet.initOne(.vevl_gen)
7916
7917__builtin_ve_vl_pvbrvup_vvmvl
7918 .param_str = "V256dV256dV256bV256dUi"
7919 .target_set = TargetSet.initOne(.vevl_gen)
7920
7921__builtin_ve_vl_pvbrvup_vvvl
7922 .param_str = "V256dV256dV256dUi"
7923 .target_set = TargetSet.initOne(.vevl_gen)
7924
7925__builtin_ve_vl_pvcmps_vsvMvl
7926 .param_str = "V256dLUiV256dV512bV256dUi"
7927 .target_set = TargetSet.initOne(.vevl_gen)
7928
7929__builtin_ve_vl_pvcmps_vsvl
7930 .param_str = "V256dLUiV256dUi"
7931 .target_set = TargetSet.initOne(.vevl_gen)
7932
7933__builtin_ve_vl_pvcmps_vsvvl
7934 .param_str = "V256dLUiV256dV256dUi"
7935 .target_set = TargetSet.initOne(.vevl_gen)
7936
7937__builtin_ve_vl_pvcmps_vvvMvl
7938 .param_str = "V256dV256dV256dV512bV256dUi"
7939 .target_set = TargetSet.initOne(.vevl_gen)
7940
7941__builtin_ve_vl_pvcmps_vvvl
7942 .param_str = "V256dV256dV256dUi"
7943 .target_set = TargetSet.initOne(.vevl_gen)
7944
7945__builtin_ve_vl_pvcmps_vvvvl
7946 .param_str = "V256dV256dV256dV256dUi"
7947 .target_set = TargetSet.initOne(.vevl_gen)
7948
7949__builtin_ve_vl_pvcmpu_vsvMvl
7950 .param_str = "V256dLUiV256dV512bV256dUi"
7951 .target_set = TargetSet.initOne(.vevl_gen)
7952
7953__builtin_ve_vl_pvcmpu_vsvl
7954 .param_str = "V256dLUiV256dUi"
7955 .target_set = TargetSet.initOne(.vevl_gen)
7956
7957__builtin_ve_vl_pvcmpu_vsvvl
7958 .param_str = "V256dLUiV256dV256dUi"
7959 .target_set = TargetSet.initOne(.vevl_gen)
7960
7961__builtin_ve_vl_pvcmpu_vvvMvl
7962 .param_str = "V256dV256dV256dV512bV256dUi"
7963 .target_set = TargetSet.initOne(.vevl_gen)
7964
7965__builtin_ve_vl_pvcmpu_vvvl
7966 .param_str = "V256dV256dV256dUi"
7967 .target_set = TargetSet.initOne(.vevl_gen)
7968
7969__builtin_ve_vl_pvcmpu_vvvvl
7970 .param_str = "V256dV256dV256dV256dUi"
7971 .target_set = TargetSet.initOne(.vevl_gen)
7972
7973__builtin_ve_vl_pvcvtsw_vvl
7974 .param_str = "V256dV256dUi"
7975 .target_set = TargetSet.initOne(.vevl_gen)
7976
7977__builtin_ve_vl_pvcvtsw_vvvl
7978 .param_str = "V256dV256dV256dUi"
7979 .target_set = TargetSet.initOne(.vevl_gen)
7980
7981__builtin_ve_vl_pvcvtws_vvMvl
7982 .param_str = "V256dV256dV512bV256dUi"
7983 .target_set = TargetSet.initOne(.vevl_gen)
7984
7985__builtin_ve_vl_pvcvtws_vvl
7986 .param_str = "V256dV256dUi"
7987 .target_set = TargetSet.initOne(.vevl_gen)
7988
7989__builtin_ve_vl_pvcvtws_vvvl
7990 .param_str = "V256dV256dV256dUi"
7991 .target_set = TargetSet.initOne(.vevl_gen)
7992
7993__builtin_ve_vl_pvcvtwsrz_vvMvl
7994 .param_str = "V256dV256dV512bV256dUi"
7995 .target_set = TargetSet.initOne(.vevl_gen)
7996
7997__builtin_ve_vl_pvcvtwsrz_vvl
7998 .param_str = "V256dV256dUi"
7999 .target_set = TargetSet.initOne(.vevl_gen)
8000
8001__builtin_ve_vl_pvcvtwsrz_vvvl
8002 .param_str = "V256dV256dV256dUi"
8003 .target_set = TargetSet.initOne(.vevl_gen)
8004
8005__builtin_ve_vl_pveqv_vsvMvl
8006 .param_str = "V256dLUiV256dV512bV256dUi"
8007 .target_set = TargetSet.initOne(.vevl_gen)
8008
8009__builtin_ve_vl_pveqv_vsvl
8010 .param_str = "V256dLUiV256dUi"
8011 .target_set = TargetSet.initOne(.vevl_gen)
8012
8013__builtin_ve_vl_pveqv_vsvvl
8014 .param_str = "V256dLUiV256dV256dUi"
8015 .target_set = TargetSet.initOne(.vevl_gen)
8016
8017__builtin_ve_vl_pveqv_vvvMvl
8018 .param_str = "V256dV256dV256dV512bV256dUi"
8019 .target_set = TargetSet.initOne(.vevl_gen)
8020
8021__builtin_ve_vl_pveqv_vvvl
8022 .param_str = "V256dV256dV256dUi"
8023 .target_set = TargetSet.initOne(.vevl_gen)
8024
8025__builtin_ve_vl_pveqv_vvvvl
8026 .param_str = "V256dV256dV256dV256dUi"
8027 .target_set = TargetSet.initOne(.vevl_gen)
8028
8029__builtin_ve_vl_pvfadd_vsvMvl
8030 .param_str = "V256dLUiV256dV512bV256dUi"
8031 .target_set = TargetSet.initOne(.vevl_gen)
8032
8033__builtin_ve_vl_pvfadd_vsvl
8034 .param_str = "V256dLUiV256dUi"
8035 .target_set = TargetSet.initOne(.vevl_gen)
8036
8037__builtin_ve_vl_pvfadd_vsvvl
8038 .param_str = "V256dLUiV256dV256dUi"
8039 .target_set = TargetSet.initOne(.vevl_gen)
8040
8041__builtin_ve_vl_pvfadd_vvvMvl
8042 .param_str = "V256dV256dV256dV512bV256dUi"
8043 .target_set = TargetSet.initOne(.vevl_gen)
8044
8045__builtin_ve_vl_pvfadd_vvvl
8046 .param_str = "V256dV256dV256dUi"
8047 .target_set = TargetSet.initOne(.vevl_gen)
8048
8049__builtin_ve_vl_pvfadd_vvvvl
8050 .param_str = "V256dV256dV256dV256dUi"
8051 .target_set = TargetSet.initOne(.vevl_gen)
8052
8053__builtin_ve_vl_pvfcmp_vsvMvl
8054 .param_str = "V256dLUiV256dV512bV256dUi"
8055 .target_set = TargetSet.initOne(.vevl_gen)
8056
8057__builtin_ve_vl_pvfcmp_vsvl
8058 .param_str = "V256dLUiV256dUi"
8059 .target_set = TargetSet.initOne(.vevl_gen)
8060
8061__builtin_ve_vl_pvfcmp_vsvvl
8062 .param_str = "V256dLUiV256dV256dUi"
8063 .target_set = TargetSet.initOne(.vevl_gen)
8064
8065__builtin_ve_vl_pvfcmp_vvvMvl
8066 .param_str = "V256dV256dV256dV512bV256dUi"
8067 .target_set = TargetSet.initOne(.vevl_gen)
8068
8069__builtin_ve_vl_pvfcmp_vvvl
8070 .param_str = "V256dV256dV256dUi"
8071 .target_set = TargetSet.initOne(.vevl_gen)
8072
8073__builtin_ve_vl_pvfcmp_vvvvl
8074 .param_str = "V256dV256dV256dV256dUi"
8075 .target_set = TargetSet.initOne(.vevl_gen)
8076
8077__builtin_ve_vl_pvfmad_vsvvMvl
8078 .param_str = "V256dLUiV256dV256dV512bV256dUi"
8079 .target_set = TargetSet.initOne(.vevl_gen)
8080
8081__builtin_ve_vl_pvfmad_vsvvl
8082 .param_str = "V256dLUiV256dV256dUi"
8083 .target_set = TargetSet.initOne(.vevl_gen)
8084
8085__builtin_ve_vl_pvfmad_vsvvvl
8086 .param_str = "V256dLUiV256dV256dV256dUi"
8087 .target_set = TargetSet.initOne(.vevl_gen)
8088
8089__builtin_ve_vl_pvfmad_vvsvMvl
8090 .param_str = "V256dV256dLUiV256dV512bV256dUi"
8091 .target_set = TargetSet.initOne(.vevl_gen)
8092
8093__builtin_ve_vl_pvfmad_vvsvl
8094 .param_str = "V256dV256dLUiV256dUi"
8095 .target_set = TargetSet.initOne(.vevl_gen)
8096
8097__builtin_ve_vl_pvfmad_vvsvvl
8098 .param_str = "V256dV256dLUiV256dV256dUi"
8099 .target_set = TargetSet.initOne(.vevl_gen)
8100
8101__builtin_ve_vl_pvfmad_vvvvMvl
8102 .param_str = "V256dV256dV256dV256dV512bV256dUi"
8103 .target_set = TargetSet.initOne(.vevl_gen)
8104
8105__builtin_ve_vl_pvfmad_vvvvl
8106 .param_str = "V256dV256dV256dV256dUi"
8107 .target_set = TargetSet.initOne(.vevl_gen)
8108
8109__builtin_ve_vl_pvfmad_vvvvvl
8110 .param_str = "V256dV256dV256dV256dV256dUi"
8111 .target_set = TargetSet.initOne(.vevl_gen)
8112
8113__builtin_ve_vl_pvfmax_vsvMvl
8114 .param_str = "V256dLUiV256dV512bV256dUi"
8115 .target_set = TargetSet.initOne(.vevl_gen)
8116
8117__builtin_ve_vl_pvfmax_vsvl
8118 .param_str = "V256dLUiV256dUi"
8119 .target_set = TargetSet.initOne(.vevl_gen)
8120
8121__builtin_ve_vl_pvfmax_vsvvl
8122 .param_str = "V256dLUiV256dV256dUi"
8123 .target_set = TargetSet.initOne(.vevl_gen)
8124
8125__builtin_ve_vl_pvfmax_vvvMvl
8126 .param_str = "V256dV256dV256dV512bV256dUi"
8127 .target_set = TargetSet.initOne(.vevl_gen)
8128
8129__builtin_ve_vl_pvfmax_vvvl
8130 .param_str = "V256dV256dV256dUi"
8131 .target_set = TargetSet.initOne(.vevl_gen)
8132
8133__builtin_ve_vl_pvfmax_vvvvl
8134 .param_str = "V256dV256dV256dV256dUi"
8135 .target_set = TargetSet.initOne(.vevl_gen)
8136
8137__builtin_ve_vl_pvfmin_vsvMvl
8138 .param_str = "V256dLUiV256dV512bV256dUi"
8139 .target_set = TargetSet.initOne(.vevl_gen)
8140
8141__builtin_ve_vl_pvfmin_vsvl
8142 .param_str = "V256dLUiV256dUi"
8143 .target_set = TargetSet.initOne(.vevl_gen)
8144
8145__builtin_ve_vl_pvfmin_vsvvl
8146 .param_str = "V256dLUiV256dV256dUi"
8147 .target_set = TargetSet.initOne(.vevl_gen)
8148
8149__builtin_ve_vl_pvfmin_vvvMvl
8150 .param_str = "V256dV256dV256dV512bV256dUi"
8151 .target_set = TargetSet.initOne(.vevl_gen)
8152
8153__builtin_ve_vl_pvfmin_vvvl
8154 .param_str = "V256dV256dV256dUi"
8155 .target_set = TargetSet.initOne(.vevl_gen)
8156
8157__builtin_ve_vl_pvfmin_vvvvl
8158 .param_str = "V256dV256dV256dV256dUi"
8159 .target_set = TargetSet.initOne(.vevl_gen)
8160
8161__builtin_ve_vl_pvfmkaf_Ml
8162 .param_str = "V512bUi"
8163 .target_set = TargetSet.initOne(.vevl_gen)
8164
8165__builtin_ve_vl_pvfmkat_Ml
8166 .param_str = "V512bUi"
8167 .target_set = TargetSet.initOne(.vevl_gen)
8168
8169__builtin_ve_vl_pvfmkseq_MvMl
8170 .param_str = "V512bV256dV512bUi"
8171 .target_set = TargetSet.initOne(.vevl_gen)
8172
8173__builtin_ve_vl_pvfmkseq_Mvl
8174 .param_str = "V512bV256dUi"
8175 .target_set = TargetSet.initOne(.vevl_gen)
8176
8177__builtin_ve_vl_pvfmkseqnan_MvMl
8178 .param_str = "V512bV256dV512bUi"
8179 .target_set = TargetSet.initOne(.vevl_gen)
8180
8181__builtin_ve_vl_pvfmkseqnan_Mvl
8182 .param_str = "V512bV256dUi"
8183 .target_set = TargetSet.initOne(.vevl_gen)
8184
8185__builtin_ve_vl_pvfmksge_MvMl
8186 .param_str = "V512bV256dV512bUi"
8187 .target_set = TargetSet.initOne(.vevl_gen)
8188
8189__builtin_ve_vl_pvfmksge_Mvl
8190 .param_str = "V512bV256dUi"
8191 .target_set = TargetSet.initOne(.vevl_gen)
8192
8193__builtin_ve_vl_pvfmksgenan_MvMl
8194 .param_str = "V512bV256dV512bUi"
8195 .target_set = TargetSet.initOne(.vevl_gen)
8196
8197__builtin_ve_vl_pvfmksgenan_Mvl
8198 .param_str = "V512bV256dUi"
8199 .target_set = TargetSet.initOne(.vevl_gen)
8200
8201__builtin_ve_vl_pvfmksgt_MvMl
8202 .param_str = "V512bV256dV512bUi"
8203 .target_set = TargetSet.initOne(.vevl_gen)
8204
8205__builtin_ve_vl_pvfmksgt_Mvl
8206 .param_str = "V512bV256dUi"
8207 .target_set = TargetSet.initOne(.vevl_gen)
8208
8209__builtin_ve_vl_pvfmksgtnan_MvMl
8210 .param_str = "V512bV256dV512bUi"
8211 .target_set = TargetSet.initOne(.vevl_gen)
8212
8213__builtin_ve_vl_pvfmksgtnan_Mvl
8214 .param_str = "V512bV256dUi"
8215 .target_set = TargetSet.initOne(.vevl_gen)
8216
8217__builtin_ve_vl_pvfmksle_MvMl
8218 .param_str = "V512bV256dV512bUi"
8219 .target_set = TargetSet.initOne(.vevl_gen)
8220
8221__builtin_ve_vl_pvfmksle_Mvl
8222 .param_str = "V512bV256dUi"
8223 .target_set = TargetSet.initOne(.vevl_gen)
8224
8225__builtin_ve_vl_pvfmkslenan_MvMl
8226 .param_str = "V512bV256dV512bUi"
8227 .target_set = TargetSet.initOne(.vevl_gen)
8228
8229__builtin_ve_vl_pvfmkslenan_Mvl
8230 .param_str = "V512bV256dUi"
8231 .target_set = TargetSet.initOne(.vevl_gen)
8232
8233__builtin_ve_vl_pvfmksloeq_mvl
8234 .param_str = "V256bV256dUi"
8235 .target_set = TargetSet.initOne(.vevl_gen)
8236
8237__builtin_ve_vl_pvfmksloeq_mvml
8238 .param_str = "V256bV256dV256bUi"
8239 .target_set = TargetSet.initOne(.vevl_gen)
8240
8241__builtin_ve_vl_pvfmksloeqnan_mvl
8242 .param_str = "V256bV256dUi"
8243 .target_set = TargetSet.initOne(.vevl_gen)
8244
8245__builtin_ve_vl_pvfmksloeqnan_mvml
8246 .param_str = "V256bV256dV256bUi"
8247 .target_set = TargetSet.initOne(.vevl_gen)
8248
8249__builtin_ve_vl_pvfmksloge_mvl
8250 .param_str = "V256bV256dUi"
8251 .target_set = TargetSet.initOne(.vevl_gen)
8252
8253__builtin_ve_vl_pvfmksloge_mvml
8254 .param_str = "V256bV256dV256bUi"
8255 .target_set = TargetSet.initOne(.vevl_gen)
8256
8257__builtin_ve_vl_pvfmkslogenan_mvl
8258 .param_str = "V256bV256dUi"
8259 .target_set = TargetSet.initOne(.vevl_gen)
8260
8261__builtin_ve_vl_pvfmkslogenan_mvml
8262 .param_str = "V256bV256dV256bUi"
8263 .target_set = TargetSet.initOne(.vevl_gen)
8264
8265__builtin_ve_vl_pvfmkslogt_mvl
8266 .param_str = "V256bV256dUi"
8267 .target_set = TargetSet.initOne(.vevl_gen)
8268
8269__builtin_ve_vl_pvfmkslogt_mvml
8270 .param_str = "V256bV256dV256bUi"
8271 .target_set = TargetSet.initOne(.vevl_gen)
8272
8273__builtin_ve_vl_pvfmkslogtnan_mvl
8274 .param_str = "V256bV256dUi"
8275 .target_set = TargetSet.initOne(.vevl_gen)
8276
8277__builtin_ve_vl_pvfmkslogtnan_mvml
8278 .param_str = "V256bV256dV256bUi"
8279 .target_set = TargetSet.initOne(.vevl_gen)
8280
8281__builtin_ve_vl_pvfmkslole_mvl
8282 .param_str = "V256bV256dUi"
8283 .target_set = TargetSet.initOne(.vevl_gen)
8284
8285__builtin_ve_vl_pvfmkslole_mvml
8286 .param_str = "V256bV256dV256bUi"
8287 .target_set = TargetSet.initOne(.vevl_gen)
8288
8289__builtin_ve_vl_pvfmkslolenan_mvl
8290 .param_str = "V256bV256dUi"
8291 .target_set = TargetSet.initOne(.vevl_gen)
8292
8293__builtin_ve_vl_pvfmkslolenan_mvml
8294 .param_str = "V256bV256dV256bUi"
8295 .target_set = TargetSet.initOne(.vevl_gen)
8296
8297__builtin_ve_vl_pvfmkslolt_mvl
8298 .param_str = "V256bV256dUi"
8299 .target_set = TargetSet.initOne(.vevl_gen)
8300
8301__builtin_ve_vl_pvfmkslolt_mvml
8302 .param_str = "V256bV256dV256bUi"
8303 .target_set = TargetSet.initOne(.vevl_gen)
8304
8305__builtin_ve_vl_pvfmksloltnan_mvl
8306 .param_str = "V256bV256dUi"
8307 .target_set = TargetSet.initOne(.vevl_gen)
8308
8309__builtin_ve_vl_pvfmksloltnan_mvml
8310 .param_str = "V256bV256dV256bUi"
8311 .target_set = TargetSet.initOne(.vevl_gen)
8312
8313__builtin_ve_vl_pvfmkslonan_mvl
8314 .param_str = "V256bV256dUi"
8315 .target_set = TargetSet.initOne(.vevl_gen)
8316
8317__builtin_ve_vl_pvfmkslonan_mvml
8318 .param_str = "V256bV256dV256bUi"
8319 .target_set = TargetSet.initOne(.vevl_gen)
8320
8321__builtin_ve_vl_pvfmkslone_mvl
8322 .param_str = "V256bV256dUi"
8323 .target_set = TargetSet.initOne(.vevl_gen)
8324
8325__builtin_ve_vl_pvfmkslone_mvml
8326 .param_str = "V256bV256dV256bUi"
8327 .target_set = TargetSet.initOne(.vevl_gen)
8328
8329__builtin_ve_vl_pvfmkslonenan_mvl
8330 .param_str = "V256bV256dUi"
8331 .target_set = TargetSet.initOne(.vevl_gen)
8332
8333__builtin_ve_vl_pvfmkslonenan_mvml
8334 .param_str = "V256bV256dV256bUi"
8335 .target_set = TargetSet.initOne(.vevl_gen)
8336
8337__builtin_ve_vl_pvfmkslonum_mvl
8338 .param_str = "V256bV256dUi"
8339 .target_set = TargetSet.initOne(.vevl_gen)
8340
8341__builtin_ve_vl_pvfmkslonum_mvml
8342 .param_str = "V256bV256dV256bUi"
8343 .target_set = TargetSet.initOne(.vevl_gen)
8344
8345__builtin_ve_vl_pvfmkslt_MvMl
8346 .param_str = "V512bV256dV512bUi"
8347 .target_set = TargetSet.initOne(.vevl_gen)
8348
8349__builtin_ve_vl_pvfmkslt_Mvl
8350 .param_str = "V512bV256dUi"
8351 .target_set = TargetSet.initOne(.vevl_gen)
8352
8353__builtin_ve_vl_pvfmksltnan_MvMl
8354 .param_str = "V512bV256dV512bUi"
8355 .target_set = TargetSet.initOne(.vevl_gen)
8356
8357__builtin_ve_vl_pvfmksltnan_Mvl
8358 .param_str = "V512bV256dUi"
8359 .target_set = TargetSet.initOne(.vevl_gen)
8360
8361__builtin_ve_vl_pvfmksnan_MvMl
8362 .param_str = "V512bV256dV512bUi"
8363 .target_set = TargetSet.initOne(.vevl_gen)
8364
8365__builtin_ve_vl_pvfmksnan_Mvl
8366 .param_str = "V512bV256dUi"
8367 .target_set = TargetSet.initOne(.vevl_gen)
8368
8369__builtin_ve_vl_pvfmksne_MvMl
8370 .param_str = "V512bV256dV512bUi"
8371 .target_set = TargetSet.initOne(.vevl_gen)
8372
8373__builtin_ve_vl_pvfmksne_Mvl
8374 .param_str = "V512bV256dUi"
8375 .target_set = TargetSet.initOne(.vevl_gen)
8376
8377__builtin_ve_vl_pvfmksnenan_MvMl
8378 .param_str = "V512bV256dV512bUi"
8379 .target_set = TargetSet.initOne(.vevl_gen)
8380
8381__builtin_ve_vl_pvfmksnenan_Mvl
8382 .param_str = "V512bV256dUi"
8383 .target_set = TargetSet.initOne(.vevl_gen)
8384
8385__builtin_ve_vl_pvfmksnum_MvMl
8386 .param_str = "V512bV256dV512bUi"
8387 .target_set = TargetSet.initOne(.vevl_gen)
8388
8389__builtin_ve_vl_pvfmksnum_Mvl
8390 .param_str = "V512bV256dUi"
8391 .target_set = TargetSet.initOne(.vevl_gen)
8392
8393__builtin_ve_vl_pvfmksupeq_mvl
8394 .param_str = "V256bV256dUi"
8395 .target_set = TargetSet.initOne(.vevl_gen)
8396
8397__builtin_ve_vl_pvfmksupeq_mvml
8398 .param_str = "V256bV256dV256bUi"
8399 .target_set = TargetSet.initOne(.vevl_gen)
8400
8401__builtin_ve_vl_pvfmksupeqnan_mvl
8402 .param_str = "V256bV256dUi"
8403 .target_set = TargetSet.initOne(.vevl_gen)
8404
8405__builtin_ve_vl_pvfmksupeqnan_mvml
8406 .param_str = "V256bV256dV256bUi"
8407 .target_set = TargetSet.initOne(.vevl_gen)
8408
8409__builtin_ve_vl_pvfmksupge_mvl
8410 .param_str = "V256bV256dUi"
8411 .target_set = TargetSet.initOne(.vevl_gen)
8412
8413__builtin_ve_vl_pvfmksupge_mvml
8414 .param_str = "V256bV256dV256bUi"
8415 .target_set = TargetSet.initOne(.vevl_gen)
8416
8417__builtin_ve_vl_pvfmksupgenan_mvl
8418 .param_str = "V256bV256dUi"
8419 .target_set = TargetSet.initOne(.vevl_gen)
8420
8421__builtin_ve_vl_pvfmksupgenan_mvml
8422 .param_str = "V256bV256dV256bUi"
8423 .target_set = TargetSet.initOne(.vevl_gen)
8424
8425__builtin_ve_vl_pvfmksupgt_mvl
8426 .param_str = "V256bV256dUi"
8427 .target_set = TargetSet.initOne(.vevl_gen)
8428
8429__builtin_ve_vl_pvfmksupgt_mvml
8430 .param_str = "V256bV256dV256bUi"
8431 .target_set = TargetSet.initOne(.vevl_gen)
8432
8433__builtin_ve_vl_pvfmksupgtnan_mvl
8434 .param_str = "V256bV256dUi"
8435 .target_set = TargetSet.initOne(.vevl_gen)
8436
8437__builtin_ve_vl_pvfmksupgtnan_mvml
8438 .param_str = "V256bV256dV256bUi"
8439 .target_set = TargetSet.initOne(.vevl_gen)
8440
8441__builtin_ve_vl_pvfmksuple_mvl
8442 .param_str = "V256bV256dUi"
8443 .target_set = TargetSet.initOne(.vevl_gen)
8444
8445__builtin_ve_vl_pvfmksuple_mvml
8446 .param_str = "V256bV256dV256bUi"
8447 .target_set = TargetSet.initOne(.vevl_gen)
8448
8449__builtin_ve_vl_pvfmksuplenan_mvl
8450 .param_str = "V256bV256dUi"
8451 .target_set = TargetSet.initOne(.vevl_gen)
8452
8453__builtin_ve_vl_pvfmksuplenan_mvml
8454 .param_str = "V256bV256dV256bUi"
8455 .target_set = TargetSet.initOne(.vevl_gen)
8456
8457__builtin_ve_vl_pvfmksuplt_mvl
8458 .param_str = "V256bV256dUi"
8459 .target_set = TargetSet.initOne(.vevl_gen)
8460
8461__builtin_ve_vl_pvfmksuplt_mvml
8462 .param_str = "V256bV256dV256bUi"
8463 .target_set = TargetSet.initOne(.vevl_gen)
8464
8465__builtin_ve_vl_pvfmksupltnan_mvl
8466 .param_str = "V256bV256dUi"
8467 .target_set = TargetSet.initOne(.vevl_gen)
8468
8469__builtin_ve_vl_pvfmksupltnan_mvml
8470 .param_str = "V256bV256dV256bUi"
8471 .target_set = TargetSet.initOne(.vevl_gen)
8472
8473__builtin_ve_vl_pvfmksupnan_mvl
8474 .param_str = "V256bV256dUi"
8475 .target_set = TargetSet.initOne(.vevl_gen)
8476
8477__builtin_ve_vl_pvfmksupnan_mvml
8478 .param_str = "V256bV256dV256bUi"
8479 .target_set = TargetSet.initOne(.vevl_gen)
8480
8481__builtin_ve_vl_pvfmksupne_mvl
8482 .param_str = "V256bV256dUi"
8483 .target_set = TargetSet.initOne(.vevl_gen)
8484
8485__builtin_ve_vl_pvfmksupne_mvml
8486 .param_str = "V256bV256dV256bUi"
8487 .target_set = TargetSet.initOne(.vevl_gen)
8488
8489__builtin_ve_vl_pvfmksupnenan_mvl
8490 .param_str = "V256bV256dUi"
8491 .target_set = TargetSet.initOne(.vevl_gen)
8492
8493__builtin_ve_vl_pvfmksupnenan_mvml
8494 .param_str = "V256bV256dV256bUi"
8495 .target_set = TargetSet.initOne(.vevl_gen)
8496
8497__builtin_ve_vl_pvfmksupnum_mvl
8498 .param_str = "V256bV256dUi"
8499 .target_set = TargetSet.initOne(.vevl_gen)
8500
8501__builtin_ve_vl_pvfmksupnum_mvml
8502 .param_str = "V256bV256dV256bUi"
8503 .target_set = TargetSet.initOne(.vevl_gen)
8504
8505__builtin_ve_vl_pvfmkweq_MvMl
8506 .param_str = "V512bV256dV512bUi"
8507 .target_set = TargetSet.initOne(.vevl_gen)
8508
8509__builtin_ve_vl_pvfmkweq_Mvl
8510 .param_str = "V512bV256dUi"
8511 .target_set = TargetSet.initOne(.vevl_gen)
8512
8513__builtin_ve_vl_pvfmkweqnan_MvMl
8514 .param_str = "V512bV256dV512bUi"
8515 .target_set = TargetSet.initOne(.vevl_gen)
8516
8517__builtin_ve_vl_pvfmkweqnan_Mvl
8518 .param_str = "V512bV256dUi"
8519 .target_set = TargetSet.initOne(.vevl_gen)
8520
8521__builtin_ve_vl_pvfmkwge_MvMl
8522 .param_str = "V512bV256dV512bUi"
8523 .target_set = TargetSet.initOne(.vevl_gen)
8524
8525__builtin_ve_vl_pvfmkwge_Mvl
8526 .param_str = "V512bV256dUi"
8527 .target_set = TargetSet.initOne(.vevl_gen)
8528
8529__builtin_ve_vl_pvfmkwgenan_MvMl
8530 .param_str = "V512bV256dV512bUi"
8531 .target_set = TargetSet.initOne(.vevl_gen)
8532
8533__builtin_ve_vl_pvfmkwgenan_Mvl
8534 .param_str = "V512bV256dUi"
8535 .target_set = TargetSet.initOne(.vevl_gen)
8536
8537__builtin_ve_vl_pvfmkwgt_MvMl
8538 .param_str = "V512bV256dV512bUi"
8539 .target_set = TargetSet.initOne(.vevl_gen)
8540
8541__builtin_ve_vl_pvfmkwgt_Mvl
8542 .param_str = "V512bV256dUi"
8543 .target_set = TargetSet.initOne(.vevl_gen)
8544
8545__builtin_ve_vl_pvfmkwgtnan_MvMl
8546 .param_str = "V512bV256dV512bUi"
8547 .target_set = TargetSet.initOne(.vevl_gen)
8548
8549__builtin_ve_vl_pvfmkwgtnan_Mvl
8550 .param_str = "V512bV256dUi"
8551 .target_set = TargetSet.initOne(.vevl_gen)
8552
8553__builtin_ve_vl_pvfmkwle_MvMl
8554 .param_str = "V512bV256dV512bUi"
8555 .target_set = TargetSet.initOne(.vevl_gen)
8556
8557__builtin_ve_vl_pvfmkwle_Mvl
8558 .param_str = "V512bV256dUi"
8559 .target_set = TargetSet.initOne(.vevl_gen)
8560
8561__builtin_ve_vl_pvfmkwlenan_MvMl
8562 .param_str = "V512bV256dV512bUi"
8563 .target_set = TargetSet.initOne(.vevl_gen)
8564
8565__builtin_ve_vl_pvfmkwlenan_Mvl
8566 .param_str = "V512bV256dUi"
8567 .target_set = TargetSet.initOne(.vevl_gen)
8568
8569__builtin_ve_vl_pvfmkwloeq_mvl
8570 .param_str = "V256bV256dUi"
8571 .target_set = TargetSet.initOne(.vevl_gen)
8572
8573__builtin_ve_vl_pvfmkwloeq_mvml
8574 .param_str = "V256bV256dV256bUi"
8575 .target_set = TargetSet.initOne(.vevl_gen)
8576
8577__builtin_ve_vl_pvfmkwloeqnan_mvl
8578 .param_str = "V256bV256dUi"
8579 .target_set = TargetSet.initOne(.vevl_gen)
8580
8581__builtin_ve_vl_pvfmkwloeqnan_mvml
8582 .param_str = "V256bV256dV256bUi"
8583 .target_set = TargetSet.initOne(.vevl_gen)
8584
8585__builtin_ve_vl_pvfmkwloge_mvl
8586 .param_str = "V256bV256dUi"
8587 .target_set = TargetSet.initOne(.vevl_gen)
8588
8589__builtin_ve_vl_pvfmkwloge_mvml
8590 .param_str = "V256bV256dV256bUi"
8591 .target_set = TargetSet.initOne(.vevl_gen)
8592
8593__builtin_ve_vl_pvfmkwlogenan_mvl
8594 .param_str = "V256bV256dUi"
8595 .target_set = TargetSet.initOne(.vevl_gen)
8596
8597__builtin_ve_vl_pvfmkwlogenan_mvml
8598 .param_str = "V256bV256dV256bUi"
8599 .target_set = TargetSet.initOne(.vevl_gen)
8600
8601__builtin_ve_vl_pvfmkwlogt_mvl
8602 .param_str = "V256bV256dUi"
8603 .target_set = TargetSet.initOne(.vevl_gen)
8604
8605__builtin_ve_vl_pvfmkwlogt_mvml
8606 .param_str = "V256bV256dV256bUi"
8607 .target_set = TargetSet.initOne(.vevl_gen)
8608
8609__builtin_ve_vl_pvfmkwlogtnan_mvl
8610 .param_str = "V256bV256dUi"
8611 .target_set = TargetSet.initOne(.vevl_gen)
8612
8613__builtin_ve_vl_pvfmkwlogtnan_mvml
8614 .param_str = "V256bV256dV256bUi"
8615 .target_set = TargetSet.initOne(.vevl_gen)
8616
8617__builtin_ve_vl_pvfmkwlole_mvl
8618 .param_str = "V256bV256dUi"
8619 .target_set = TargetSet.initOne(.vevl_gen)
8620
8621__builtin_ve_vl_pvfmkwlole_mvml
8622 .param_str = "V256bV256dV256bUi"
8623 .target_set = TargetSet.initOne(.vevl_gen)
8624
8625__builtin_ve_vl_pvfmkwlolenan_mvl
8626 .param_str = "V256bV256dUi"
8627 .target_set = TargetSet.initOne(.vevl_gen)
8628
8629__builtin_ve_vl_pvfmkwlolenan_mvml
8630 .param_str = "V256bV256dV256bUi"
8631 .target_set = TargetSet.initOne(.vevl_gen)
8632
8633__builtin_ve_vl_pvfmkwlolt_mvl
8634 .param_str = "V256bV256dUi"
8635 .target_set = TargetSet.initOne(.vevl_gen)
8636
8637__builtin_ve_vl_pvfmkwlolt_mvml
8638 .param_str = "V256bV256dV256bUi"
8639 .target_set = TargetSet.initOne(.vevl_gen)
8640
8641__builtin_ve_vl_pvfmkwloltnan_mvl
8642 .param_str = "V256bV256dUi"
8643 .target_set = TargetSet.initOne(.vevl_gen)
8644
8645__builtin_ve_vl_pvfmkwloltnan_mvml
8646 .param_str = "V256bV256dV256bUi"
8647 .target_set = TargetSet.initOne(.vevl_gen)
8648
8649__builtin_ve_vl_pvfmkwlonan_mvl
8650 .param_str = "V256bV256dUi"
8651 .target_set = TargetSet.initOne(.vevl_gen)
8652
8653__builtin_ve_vl_pvfmkwlonan_mvml
8654 .param_str = "V256bV256dV256bUi"
8655 .target_set = TargetSet.initOne(.vevl_gen)
8656
8657__builtin_ve_vl_pvfmkwlone_mvl
8658 .param_str = "V256bV256dUi"
8659 .target_set = TargetSet.initOne(.vevl_gen)
8660
8661__builtin_ve_vl_pvfmkwlone_mvml
8662 .param_str = "V256bV256dV256bUi"
8663 .target_set = TargetSet.initOne(.vevl_gen)
8664
8665__builtin_ve_vl_pvfmkwlonenan_mvl
8666 .param_str = "V256bV256dUi"
8667 .target_set = TargetSet.initOne(.vevl_gen)
8668
8669__builtin_ve_vl_pvfmkwlonenan_mvml
8670 .param_str = "V256bV256dV256bUi"
8671 .target_set = TargetSet.initOne(.vevl_gen)
8672
8673__builtin_ve_vl_pvfmkwlonum_mvl
8674 .param_str = "V256bV256dUi"
8675 .target_set = TargetSet.initOne(.vevl_gen)
8676
8677__builtin_ve_vl_pvfmkwlonum_mvml
8678 .param_str = "V256bV256dV256bUi"
8679 .target_set = TargetSet.initOne(.vevl_gen)
8680
8681__builtin_ve_vl_pvfmkwlt_MvMl
8682 .param_str = "V512bV256dV512bUi"
8683 .target_set = TargetSet.initOne(.vevl_gen)
8684
8685__builtin_ve_vl_pvfmkwlt_Mvl
8686 .param_str = "V512bV256dUi"
8687 .target_set = TargetSet.initOne(.vevl_gen)
8688
8689__builtin_ve_vl_pvfmkwltnan_MvMl
8690 .param_str = "V512bV256dV512bUi"
8691 .target_set = TargetSet.initOne(.vevl_gen)
8692
8693__builtin_ve_vl_pvfmkwltnan_Mvl
8694 .param_str = "V512bV256dUi"
8695 .target_set = TargetSet.initOne(.vevl_gen)
8696
8697__builtin_ve_vl_pvfmkwnan_MvMl
8698 .param_str = "V512bV256dV512bUi"
8699 .target_set = TargetSet.initOne(.vevl_gen)
8700
8701__builtin_ve_vl_pvfmkwnan_Mvl
8702 .param_str = "V512bV256dUi"
8703 .target_set = TargetSet.initOne(.vevl_gen)
8704
8705__builtin_ve_vl_pvfmkwne_MvMl
8706 .param_str = "V512bV256dV512bUi"
8707 .target_set = TargetSet.initOne(.vevl_gen)
8708
8709__builtin_ve_vl_pvfmkwne_Mvl
8710 .param_str = "V512bV256dUi"
8711 .target_set = TargetSet.initOne(.vevl_gen)
8712
8713__builtin_ve_vl_pvfmkwnenan_MvMl
8714 .param_str = "V512bV256dV512bUi"
8715 .target_set = TargetSet.initOne(.vevl_gen)
8716
8717__builtin_ve_vl_pvfmkwnenan_Mvl
8718 .param_str = "V512bV256dUi"
8719 .target_set = TargetSet.initOne(.vevl_gen)
8720
8721__builtin_ve_vl_pvfmkwnum_MvMl
8722 .param_str = "V512bV256dV512bUi"
8723 .target_set = TargetSet.initOne(.vevl_gen)
8724
8725__builtin_ve_vl_pvfmkwnum_Mvl
8726 .param_str = "V512bV256dUi"
8727 .target_set = TargetSet.initOne(.vevl_gen)
8728
8729__builtin_ve_vl_pvfmkwupeq_mvl
8730 .param_str = "V256bV256dUi"
8731 .target_set = TargetSet.initOne(.vevl_gen)
8732
8733__builtin_ve_vl_pvfmkwupeq_mvml
8734 .param_str = "V256bV256dV256bUi"
8735 .target_set = TargetSet.initOne(.vevl_gen)
8736
8737__builtin_ve_vl_pvfmkwupeqnan_mvl
8738 .param_str = "V256bV256dUi"
8739 .target_set = TargetSet.initOne(.vevl_gen)
8740
8741__builtin_ve_vl_pvfmkwupeqnan_mvml
8742 .param_str = "V256bV256dV256bUi"
8743 .target_set = TargetSet.initOne(.vevl_gen)
8744
8745__builtin_ve_vl_pvfmkwupge_mvl
8746 .param_str = "V256bV256dUi"
8747 .target_set = TargetSet.initOne(.vevl_gen)
8748
8749__builtin_ve_vl_pvfmkwupge_mvml
8750 .param_str = "V256bV256dV256bUi"
8751 .target_set = TargetSet.initOne(.vevl_gen)
8752
8753__builtin_ve_vl_pvfmkwupgenan_mvl
8754 .param_str = "V256bV256dUi"
8755 .target_set = TargetSet.initOne(.vevl_gen)
8756
8757__builtin_ve_vl_pvfmkwupgenan_mvml
8758 .param_str = "V256bV256dV256bUi"
8759 .target_set = TargetSet.initOne(.vevl_gen)
8760
8761__builtin_ve_vl_pvfmkwupgt_mvl
8762 .param_str = "V256bV256dUi"
8763 .target_set = TargetSet.initOne(.vevl_gen)
8764
8765__builtin_ve_vl_pvfmkwupgt_mvml
8766 .param_str = "V256bV256dV256bUi"
8767 .target_set = TargetSet.initOne(.vevl_gen)
8768
8769__builtin_ve_vl_pvfmkwupgtnan_mvl
8770 .param_str = "V256bV256dUi"
8771 .target_set = TargetSet.initOne(.vevl_gen)
8772
8773__builtin_ve_vl_pvfmkwupgtnan_mvml
8774 .param_str = "V256bV256dV256bUi"
8775 .target_set = TargetSet.initOne(.vevl_gen)
8776
8777__builtin_ve_vl_pvfmkwuple_mvl
8778 .param_str = "V256bV256dUi"
8779 .target_set = TargetSet.initOne(.vevl_gen)
8780
8781__builtin_ve_vl_pvfmkwuple_mvml
8782 .param_str = "V256bV256dV256bUi"
8783 .target_set = TargetSet.initOne(.vevl_gen)
8784
8785__builtin_ve_vl_pvfmkwuplenan_mvl
8786 .param_str = "V256bV256dUi"
8787 .target_set = TargetSet.initOne(.vevl_gen)
8788
8789__builtin_ve_vl_pvfmkwuplenan_mvml
8790 .param_str = "V256bV256dV256bUi"
8791 .target_set = TargetSet.initOne(.vevl_gen)
8792
8793__builtin_ve_vl_pvfmkwuplt_mvl
8794 .param_str = "V256bV256dUi"
8795 .target_set = TargetSet.initOne(.vevl_gen)
8796
8797__builtin_ve_vl_pvfmkwuplt_mvml
8798 .param_str = "V256bV256dV256bUi"
8799 .target_set = TargetSet.initOne(.vevl_gen)
8800
8801__builtin_ve_vl_pvfmkwupltnan_mvl
8802 .param_str = "V256bV256dUi"
8803 .target_set = TargetSet.initOne(.vevl_gen)
8804
8805__builtin_ve_vl_pvfmkwupltnan_mvml
8806 .param_str = "V256bV256dV256bUi"
8807 .target_set = TargetSet.initOne(.vevl_gen)
8808
8809__builtin_ve_vl_pvfmkwupnan_mvl
8810 .param_str = "V256bV256dUi"
8811 .target_set = TargetSet.initOne(.vevl_gen)
8812
8813__builtin_ve_vl_pvfmkwupnan_mvml
8814 .param_str = "V256bV256dV256bUi"
8815 .target_set = TargetSet.initOne(.vevl_gen)
8816
8817__builtin_ve_vl_pvfmkwupne_mvl
8818 .param_str = "V256bV256dUi"
8819 .target_set = TargetSet.initOne(.vevl_gen)
8820
8821__builtin_ve_vl_pvfmkwupne_mvml
8822 .param_str = "V256bV256dV256bUi"
8823 .target_set = TargetSet.initOne(.vevl_gen)
8824
8825__builtin_ve_vl_pvfmkwupnenan_mvl
8826 .param_str = "V256bV256dUi"
8827 .target_set = TargetSet.initOne(.vevl_gen)
8828
8829__builtin_ve_vl_pvfmkwupnenan_mvml
8830 .param_str = "V256bV256dV256bUi"
8831 .target_set = TargetSet.initOne(.vevl_gen)
8832
8833__builtin_ve_vl_pvfmkwupnum_mvl
8834 .param_str = "V256bV256dUi"
8835 .target_set = TargetSet.initOne(.vevl_gen)
8836
8837__builtin_ve_vl_pvfmkwupnum_mvml
8838 .param_str = "V256bV256dV256bUi"
8839 .target_set = TargetSet.initOne(.vevl_gen)
8840
8841__builtin_ve_vl_pvfmsb_vsvvMvl
8842 .param_str = "V256dLUiV256dV256dV512bV256dUi"
8843 .target_set = TargetSet.initOne(.vevl_gen)
8844
8845__builtin_ve_vl_pvfmsb_vsvvl
8846 .param_str = "V256dLUiV256dV256dUi"
8847 .target_set = TargetSet.initOne(.vevl_gen)
8848
8849__builtin_ve_vl_pvfmsb_vsvvvl
8850 .param_str = "V256dLUiV256dV256dV256dUi"
8851 .target_set = TargetSet.initOne(.vevl_gen)
8852
8853__builtin_ve_vl_pvfmsb_vvsvMvl
8854 .param_str = "V256dV256dLUiV256dV512bV256dUi"
8855 .target_set = TargetSet.initOne(.vevl_gen)
8856
8857__builtin_ve_vl_pvfmsb_vvsvl
8858 .param_str = "V256dV256dLUiV256dUi"
8859 .target_set = TargetSet.initOne(.vevl_gen)
8860
8861__builtin_ve_vl_pvfmsb_vvsvvl
8862 .param_str = "V256dV256dLUiV256dV256dUi"
8863 .target_set = TargetSet.initOne(.vevl_gen)
8864
8865__builtin_ve_vl_pvfmsb_vvvvMvl
8866 .param_str = "V256dV256dV256dV256dV512bV256dUi"
8867 .target_set = TargetSet.initOne(.vevl_gen)
8868
8869__builtin_ve_vl_pvfmsb_vvvvl
8870 .param_str = "V256dV256dV256dV256dUi"
8871 .target_set = TargetSet.initOne(.vevl_gen)
8872
8873__builtin_ve_vl_pvfmsb_vvvvvl
8874 .param_str = "V256dV256dV256dV256dV256dUi"
8875 .target_set = TargetSet.initOne(.vevl_gen)
8876
8877__builtin_ve_vl_pvfmul_vsvMvl
8878 .param_str = "V256dLUiV256dV512bV256dUi"
8879 .target_set = TargetSet.initOne(.vevl_gen)
8880
8881__builtin_ve_vl_pvfmul_vsvl
8882 .param_str = "V256dLUiV256dUi"
8883 .target_set = TargetSet.initOne(.vevl_gen)
8884
8885__builtin_ve_vl_pvfmul_vsvvl
8886 .param_str = "V256dLUiV256dV256dUi"
8887 .target_set = TargetSet.initOne(.vevl_gen)
8888
8889__builtin_ve_vl_pvfmul_vvvMvl
8890 .param_str = "V256dV256dV256dV512bV256dUi"
8891 .target_set = TargetSet.initOne(.vevl_gen)
8892
8893__builtin_ve_vl_pvfmul_vvvl
8894 .param_str = "V256dV256dV256dUi"
8895 .target_set = TargetSet.initOne(.vevl_gen)
8896
8897__builtin_ve_vl_pvfmul_vvvvl
8898 .param_str = "V256dV256dV256dV256dUi"
8899 .target_set = TargetSet.initOne(.vevl_gen)
8900
8901__builtin_ve_vl_pvfnmad_vsvvMvl
8902 .param_str = "V256dLUiV256dV256dV512bV256dUi"
8903 .target_set = TargetSet.initOne(.vevl_gen)
8904
8905__builtin_ve_vl_pvfnmad_vsvvl
8906 .param_str = "V256dLUiV256dV256dUi"
8907 .target_set = TargetSet.initOne(.vevl_gen)
8908
8909__builtin_ve_vl_pvfnmad_vsvvvl
8910 .param_str = "V256dLUiV256dV256dV256dUi"
8911 .target_set = TargetSet.initOne(.vevl_gen)
8912
8913__builtin_ve_vl_pvfnmad_vvsvMvl
8914 .param_str = "V256dV256dLUiV256dV512bV256dUi"
8915 .target_set = TargetSet.initOne(.vevl_gen)
8916
8917__builtin_ve_vl_pvfnmad_vvsvl
8918 .param_str = "V256dV256dLUiV256dUi"
8919 .target_set = TargetSet.initOne(.vevl_gen)
8920
8921__builtin_ve_vl_pvfnmad_vvsvvl
8922 .param_str = "V256dV256dLUiV256dV256dUi"
8923 .target_set = TargetSet.initOne(.vevl_gen)
8924
8925__builtin_ve_vl_pvfnmad_vvvvMvl
8926 .param_str = "V256dV256dV256dV256dV512bV256dUi"
8927 .target_set = TargetSet.initOne(.vevl_gen)
8928
8929__builtin_ve_vl_pvfnmad_vvvvl
8930 .param_str = "V256dV256dV256dV256dUi"
8931 .target_set = TargetSet.initOne(.vevl_gen)
8932
8933__builtin_ve_vl_pvfnmad_vvvvvl
8934 .param_str = "V256dV256dV256dV256dV256dUi"
8935 .target_set = TargetSet.initOne(.vevl_gen)
8936
8937__builtin_ve_vl_pvfnmsb_vsvvMvl
8938 .param_str = "V256dLUiV256dV256dV512bV256dUi"
8939 .target_set = TargetSet.initOne(.vevl_gen)
8940
8941__builtin_ve_vl_pvfnmsb_vsvvl
8942 .param_str = "V256dLUiV256dV256dUi"
8943 .target_set = TargetSet.initOne(.vevl_gen)
8944
8945__builtin_ve_vl_pvfnmsb_vsvvvl
8946 .param_str = "V256dLUiV256dV256dV256dUi"
8947 .target_set = TargetSet.initOne(.vevl_gen)
8948
8949__builtin_ve_vl_pvfnmsb_vvsvMvl
8950 .param_str = "V256dV256dLUiV256dV512bV256dUi"
8951 .target_set = TargetSet.initOne(.vevl_gen)
8952
8953__builtin_ve_vl_pvfnmsb_vvsvl
8954 .param_str = "V256dV256dLUiV256dUi"
8955 .target_set = TargetSet.initOne(.vevl_gen)
8956
8957__builtin_ve_vl_pvfnmsb_vvsvvl
8958 .param_str = "V256dV256dLUiV256dV256dUi"
8959 .target_set = TargetSet.initOne(.vevl_gen)
8960
8961__builtin_ve_vl_pvfnmsb_vvvvMvl
8962 .param_str = "V256dV256dV256dV256dV512bV256dUi"
8963 .target_set = TargetSet.initOne(.vevl_gen)
8964
8965__builtin_ve_vl_pvfnmsb_vvvvl
8966 .param_str = "V256dV256dV256dV256dUi"
8967 .target_set = TargetSet.initOne(.vevl_gen)
8968
8969__builtin_ve_vl_pvfnmsb_vvvvvl
8970 .param_str = "V256dV256dV256dV256dV256dUi"
8971 .target_set = TargetSet.initOne(.vevl_gen)
8972
8973__builtin_ve_vl_pvfsub_vsvMvl
8974 .param_str = "V256dLUiV256dV512bV256dUi"
8975 .target_set = TargetSet.initOne(.vevl_gen)
8976
8977__builtin_ve_vl_pvfsub_vsvl
8978 .param_str = "V256dLUiV256dUi"
8979 .target_set = TargetSet.initOne(.vevl_gen)
8980
8981__builtin_ve_vl_pvfsub_vsvvl
8982 .param_str = "V256dLUiV256dV256dUi"
8983 .target_set = TargetSet.initOne(.vevl_gen)
8984
8985__builtin_ve_vl_pvfsub_vvvMvl
8986 .param_str = "V256dV256dV256dV512bV256dUi"
8987 .target_set = TargetSet.initOne(.vevl_gen)
8988
8989__builtin_ve_vl_pvfsub_vvvl
8990 .param_str = "V256dV256dV256dUi"
8991 .target_set = TargetSet.initOne(.vevl_gen)
8992
8993__builtin_ve_vl_pvfsub_vvvvl
8994 .param_str = "V256dV256dV256dV256dUi"
8995 .target_set = TargetSet.initOne(.vevl_gen)
8996
8997__builtin_ve_vl_pvldz_vvMvl
8998 .param_str = "V256dV256dV512bV256dUi"
8999 .target_set = TargetSet.initOne(.vevl_gen)
9000
9001__builtin_ve_vl_pvldz_vvl
9002 .param_str = "V256dV256dUi"
9003 .target_set = TargetSet.initOne(.vevl_gen)
9004
9005__builtin_ve_vl_pvldz_vvvl
9006 .param_str = "V256dV256dV256dUi"
9007 .target_set = TargetSet.initOne(.vevl_gen)
9008
9009__builtin_ve_vl_pvldzlo_vvl
9010 .param_str = "V256dV256dUi"
9011 .target_set = TargetSet.initOne(.vevl_gen)
9012
9013__builtin_ve_vl_pvldzlo_vvmvl
9014 .param_str = "V256dV256dV256bV256dUi"
9015 .target_set = TargetSet.initOne(.vevl_gen)
9016
9017__builtin_ve_vl_pvldzlo_vvvl
9018 .param_str = "V256dV256dV256dUi"
9019 .target_set = TargetSet.initOne(.vevl_gen)
9020
9021__builtin_ve_vl_pvldzup_vvl
9022 .param_str = "V256dV256dUi"
9023 .target_set = TargetSet.initOne(.vevl_gen)
9024
9025__builtin_ve_vl_pvldzup_vvmvl
9026 .param_str = "V256dV256dV256bV256dUi"
9027 .target_set = TargetSet.initOne(.vevl_gen)
9028
9029__builtin_ve_vl_pvldzup_vvvl
9030 .param_str = "V256dV256dV256dUi"
9031 .target_set = TargetSet.initOne(.vevl_gen)
9032
9033__builtin_ve_vl_pvmaxs_vsvMvl
9034 .param_str = "V256dLUiV256dV512bV256dUi"
9035 .target_set = TargetSet.initOne(.vevl_gen)
9036
9037__builtin_ve_vl_pvmaxs_vsvl
9038 .param_str = "V256dLUiV256dUi"
9039 .target_set = TargetSet.initOne(.vevl_gen)
9040
9041__builtin_ve_vl_pvmaxs_vsvvl
9042 .param_str = "V256dLUiV256dV256dUi"
9043 .target_set = TargetSet.initOne(.vevl_gen)
9044
9045__builtin_ve_vl_pvmaxs_vvvMvl
9046 .param_str = "V256dV256dV256dV512bV256dUi"
9047 .target_set = TargetSet.initOne(.vevl_gen)
9048
9049__builtin_ve_vl_pvmaxs_vvvl
9050 .param_str = "V256dV256dV256dUi"
9051 .target_set = TargetSet.initOne(.vevl_gen)
9052
9053__builtin_ve_vl_pvmaxs_vvvvl
9054 .param_str = "V256dV256dV256dV256dUi"
9055 .target_set = TargetSet.initOne(.vevl_gen)
9056
9057__builtin_ve_vl_pvmins_vsvMvl
9058 .param_str = "V256dLUiV256dV512bV256dUi"
9059 .target_set = TargetSet.initOne(.vevl_gen)
9060
9061__builtin_ve_vl_pvmins_vsvl
9062 .param_str = "V256dLUiV256dUi"
9063 .target_set = TargetSet.initOne(.vevl_gen)
9064
9065__builtin_ve_vl_pvmins_vsvvl
9066 .param_str = "V256dLUiV256dV256dUi"
9067 .target_set = TargetSet.initOne(.vevl_gen)
9068
9069__builtin_ve_vl_pvmins_vvvMvl
9070 .param_str = "V256dV256dV256dV512bV256dUi"
9071 .target_set = TargetSet.initOne(.vevl_gen)
9072
9073__builtin_ve_vl_pvmins_vvvl
9074 .param_str = "V256dV256dV256dUi"
9075 .target_set = TargetSet.initOne(.vevl_gen)
9076
9077__builtin_ve_vl_pvmins_vvvvl
9078 .param_str = "V256dV256dV256dV256dUi"
9079 .target_set = TargetSet.initOne(.vevl_gen)
9080
9081__builtin_ve_vl_pvor_vsvMvl
9082 .param_str = "V256dLUiV256dV512bV256dUi"
9083 .target_set = TargetSet.initOne(.vevl_gen)
9084
9085__builtin_ve_vl_pvor_vsvl
9086 .param_str = "V256dLUiV256dUi"
9087 .target_set = TargetSet.initOne(.vevl_gen)
9088
9089__builtin_ve_vl_pvor_vsvvl
9090 .param_str = "V256dLUiV256dV256dUi"
9091 .target_set = TargetSet.initOne(.vevl_gen)
9092
9093__builtin_ve_vl_pvor_vvvMvl
9094 .param_str = "V256dV256dV256dV512bV256dUi"
9095 .target_set = TargetSet.initOne(.vevl_gen)
9096
9097__builtin_ve_vl_pvor_vvvl
9098 .param_str = "V256dV256dV256dUi"
9099 .target_set = TargetSet.initOne(.vevl_gen)
9100
9101__builtin_ve_vl_pvor_vvvvl
9102 .param_str = "V256dV256dV256dV256dUi"
9103 .target_set = TargetSet.initOne(.vevl_gen)
9104
9105__builtin_ve_vl_pvpcnt_vvMvl
9106 .param_str = "V256dV256dV512bV256dUi"
9107 .target_set = TargetSet.initOne(.vevl_gen)
9108
9109__builtin_ve_vl_pvpcnt_vvl
9110 .param_str = "V256dV256dUi"
9111 .target_set = TargetSet.initOne(.vevl_gen)
9112
9113__builtin_ve_vl_pvpcnt_vvvl
9114 .param_str = "V256dV256dV256dUi"
9115 .target_set = TargetSet.initOne(.vevl_gen)
9116
9117__builtin_ve_vl_pvpcntlo_vvl
9118 .param_str = "V256dV256dUi"
9119 .target_set = TargetSet.initOne(.vevl_gen)
9120
9121__builtin_ve_vl_pvpcntlo_vvmvl
9122 .param_str = "V256dV256dV256bV256dUi"
9123 .target_set = TargetSet.initOne(.vevl_gen)
9124
9125__builtin_ve_vl_pvpcntlo_vvvl
9126 .param_str = "V256dV256dV256dUi"
9127 .target_set = TargetSet.initOne(.vevl_gen)
9128
9129__builtin_ve_vl_pvpcntup_vvl
9130 .param_str = "V256dV256dUi"
9131 .target_set = TargetSet.initOne(.vevl_gen)
9132
9133__builtin_ve_vl_pvpcntup_vvmvl
9134 .param_str = "V256dV256dV256bV256dUi"
9135 .target_set = TargetSet.initOne(.vevl_gen)
9136
9137__builtin_ve_vl_pvpcntup_vvvl
9138 .param_str = "V256dV256dV256dUi"
9139 .target_set = TargetSet.initOne(.vevl_gen)
9140
9141__builtin_ve_vl_pvrcp_vvl
9142 .param_str = "V256dV256dUi"
9143 .target_set = TargetSet.initOne(.vevl_gen)
9144
9145__builtin_ve_vl_pvrcp_vvvl
9146 .param_str = "V256dV256dV256dUi"
9147 .target_set = TargetSet.initOne(.vevl_gen)
9148
9149__builtin_ve_vl_pvrsqrt_vvl
9150 .param_str = "V256dV256dUi"
9151 .target_set = TargetSet.initOne(.vevl_gen)
9152
9153__builtin_ve_vl_pvrsqrt_vvvl
9154 .param_str = "V256dV256dV256dUi"
9155 .target_set = TargetSet.initOne(.vevl_gen)
9156
9157__builtin_ve_vl_pvrsqrtnex_vvl
9158 .param_str = "V256dV256dUi"
9159 .target_set = TargetSet.initOne(.vevl_gen)
9160
9161__builtin_ve_vl_pvrsqrtnex_vvvl
9162 .param_str = "V256dV256dV256dUi"
9163 .target_set = TargetSet.initOne(.vevl_gen)
9164
9165__builtin_ve_vl_pvseq_vl
9166 .param_str = "V256dUi"
9167 .target_set = TargetSet.initOne(.vevl_gen)
9168
9169__builtin_ve_vl_pvseq_vvl
9170 .param_str = "V256dV256dUi"
9171 .target_set = TargetSet.initOne(.vevl_gen)
9172
9173__builtin_ve_vl_pvseqlo_vl
9174 .param_str = "V256dUi"
9175 .target_set = TargetSet.initOne(.vevl_gen)
9176
9177__builtin_ve_vl_pvseqlo_vvl
9178 .param_str = "V256dV256dUi"
9179 .target_set = TargetSet.initOne(.vevl_gen)
9180
9181__builtin_ve_vl_pvsequp_vl
9182 .param_str = "V256dUi"
9183 .target_set = TargetSet.initOne(.vevl_gen)
9184
9185__builtin_ve_vl_pvsequp_vvl
9186 .param_str = "V256dV256dUi"
9187 .target_set = TargetSet.initOne(.vevl_gen)
9188
9189__builtin_ve_vl_pvsla_vvsMvl
9190 .param_str = "V256dV256dLUiV512bV256dUi"
9191 .target_set = TargetSet.initOne(.vevl_gen)
9192
9193__builtin_ve_vl_pvsla_vvsl
9194 .param_str = "V256dV256dLUiUi"
9195 .target_set = TargetSet.initOne(.vevl_gen)
9196
9197__builtin_ve_vl_pvsla_vvsvl
9198 .param_str = "V256dV256dLUiV256dUi"
9199 .target_set = TargetSet.initOne(.vevl_gen)
9200
9201__builtin_ve_vl_pvsla_vvvMvl
9202 .param_str = "V256dV256dV256dV512bV256dUi"
9203 .target_set = TargetSet.initOne(.vevl_gen)
9204
9205__builtin_ve_vl_pvsla_vvvl
9206 .param_str = "V256dV256dV256dUi"
9207 .target_set = TargetSet.initOne(.vevl_gen)
9208
9209__builtin_ve_vl_pvsla_vvvvl
9210 .param_str = "V256dV256dV256dV256dUi"
9211 .target_set = TargetSet.initOne(.vevl_gen)
9212
9213__builtin_ve_vl_pvsll_vvsMvl
9214 .param_str = "V256dV256dLUiV512bV256dUi"
9215 .target_set = TargetSet.initOne(.vevl_gen)
9216
9217__builtin_ve_vl_pvsll_vvsl
9218 .param_str = "V256dV256dLUiUi"
9219 .target_set = TargetSet.initOne(.vevl_gen)
9220
9221__builtin_ve_vl_pvsll_vvsvl
9222 .param_str = "V256dV256dLUiV256dUi"
9223 .target_set = TargetSet.initOne(.vevl_gen)
9224
9225__builtin_ve_vl_pvsll_vvvMvl
9226 .param_str = "V256dV256dV256dV512bV256dUi"
9227 .target_set = TargetSet.initOne(.vevl_gen)
9228
9229__builtin_ve_vl_pvsll_vvvl
9230 .param_str = "V256dV256dV256dUi"
9231 .target_set = TargetSet.initOne(.vevl_gen)
9232
9233__builtin_ve_vl_pvsll_vvvvl
9234 .param_str = "V256dV256dV256dV256dUi"
9235 .target_set = TargetSet.initOne(.vevl_gen)
9236
9237__builtin_ve_vl_pvsra_vvsMvl
9238 .param_str = "V256dV256dLUiV512bV256dUi"
9239 .target_set = TargetSet.initOne(.vevl_gen)
9240
9241__builtin_ve_vl_pvsra_vvsl
9242 .param_str = "V256dV256dLUiUi"
9243 .target_set = TargetSet.initOne(.vevl_gen)
9244
9245__builtin_ve_vl_pvsra_vvsvl
9246 .param_str = "V256dV256dLUiV256dUi"
9247 .target_set = TargetSet.initOne(.vevl_gen)
9248
9249__builtin_ve_vl_pvsra_vvvMvl
9250 .param_str = "V256dV256dV256dV512bV256dUi"
9251 .target_set = TargetSet.initOne(.vevl_gen)
9252
9253__builtin_ve_vl_pvsra_vvvl
9254 .param_str = "V256dV256dV256dUi"
9255 .target_set = TargetSet.initOne(.vevl_gen)
9256
9257__builtin_ve_vl_pvsra_vvvvl
9258 .param_str = "V256dV256dV256dV256dUi"
9259 .target_set = TargetSet.initOne(.vevl_gen)
9260
9261__builtin_ve_vl_pvsrl_vvsMvl
9262 .param_str = "V256dV256dLUiV512bV256dUi"
9263 .target_set = TargetSet.initOne(.vevl_gen)
9264
9265__builtin_ve_vl_pvsrl_vvsl
9266 .param_str = "V256dV256dLUiUi"
9267 .target_set = TargetSet.initOne(.vevl_gen)
9268
9269__builtin_ve_vl_pvsrl_vvsvl
9270 .param_str = "V256dV256dLUiV256dUi"
9271 .target_set = TargetSet.initOne(.vevl_gen)
9272
9273__builtin_ve_vl_pvsrl_vvvMvl
9274 .param_str = "V256dV256dV256dV512bV256dUi"
9275 .target_set = TargetSet.initOne(.vevl_gen)
9276
9277__builtin_ve_vl_pvsrl_vvvl
9278 .param_str = "V256dV256dV256dUi"
9279 .target_set = TargetSet.initOne(.vevl_gen)
9280
9281__builtin_ve_vl_pvsrl_vvvvl
9282 .param_str = "V256dV256dV256dV256dUi"
9283 .target_set = TargetSet.initOne(.vevl_gen)
9284
9285__builtin_ve_vl_pvsubs_vsvMvl
9286 .param_str = "V256dLUiV256dV512bV256dUi"
9287 .target_set = TargetSet.initOne(.vevl_gen)
9288
9289__builtin_ve_vl_pvsubs_vsvl
9290 .param_str = "V256dLUiV256dUi"
9291 .target_set = TargetSet.initOne(.vevl_gen)
9292
9293__builtin_ve_vl_pvsubs_vsvvl
9294 .param_str = "V256dLUiV256dV256dUi"
9295 .target_set = TargetSet.initOne(.vevl_gen)
9296
9297__builtin_ve_vl_pvsubs_vvvMvl
9298 .param_str = "V256dV256dV256dV512bV256dUi"
9299 .target_set = TargetSet.initOne(.vevl_gen)
9300
9301__builtin_ve_vl_pvsubs_vvvl
9302 .param_str = "V256dV256dV256dUi"
9303 .target_set = TargetSet.initOne(.vevl_gen)
9304
9305__builtin_ve_vl_pvsubs_vvvvl
9306 .param_str = "V256dV256dV256dV256dUi"
9307 .target_set = TargetSet.initOne(.vevl_gen)
9308
9309__builtin_ve_vl_pvsubu_vsvMvl
9310 .param_str = "V256dLUiV256dV512bV256dUi"
9311 .target_set = TargetSet.initOne(.vevl_gen)
9312
9313__builtin_ve_vl_pvsubu_vsvl
9314 .param_str = "V256dLUiV256dUi"
9315 .target_set = TargetSet.initOne(.vevl_gen)
9316
9317__builtin_ve_vl_pvsubu_vsvvl
9318 .param_str = "V256dLUiV256dV256dUi"
9319 .target_set = TargetSet.initOne(.vevl_gen)
9320
9321__builtin_ve_vl_pvsubu_vvvMvl
9322 .param_str = "V256dV256dV256dV512bV256dUi"
9323 .target_set = TargetSet.initOne(.vevl_gen)
9324
9325__builtin_ve_vl_pvsubu_vvvl
9326 .param_str = "V256dV256dV256dUi"
9327 .target_set = TargetSet.initOne(.vevl_gen)
9328
9329__builtin_ve_vl_pvsubu_vvvvl
9330 .param_str = "V256dV256dV256dV256dUi"
9331 .target_set = TargetSet.initOne(.vevl_gen)
9332
9333__builtin_ve_vl_pvxor_vsvMvl
9334 .param_str = "V256dLUiV256dV512bV256dUi"
9335 .target_set = TargetSet.initOne(.vevl_gen)
9336
9337__builtin_ve_vl_pvxor_vsvl
9338 .param_str = "V256dLUiV256dUi"
9339 .target_set = TargetSet.initOne(.vevl_gen)
9340
9341__builtin_ve_vl_pvxor_vsvvl
9342 .param_str = "V256dLUiV256dV256dUi"
9343 .target_set = TargetSet.initOne(.vevl_gen)
9344
9345__builtin_ve_vl_pvxor_vvvMvl
9346 .param_str = "V256dV256dV256dV512bV256dUi"
9347 .target_set = TargetSet.initOne(.vevl_gen)
9348
9349__builtin_ve_vl_pvxor_vvvl
9350 .param_str = "V256dV256dV256dUi"
9351 .target_set = TargetSet.initOne(.vevl_gen)
9352
9353__builtin_ve_vl_pvxor_vvvvl
9354 .param_str = "V256dV256dV256dV256dUi"
9355 .target_set = TargetSet.initOne(.vevl_gen)
9356
9357__builtin_ve_vl_scr_sss
9358 .param_str = "vLUiLUiLUi"
9359 .target_set = TargetSet.initOne(.vevl_gen)
9360
9361__builtin_ve_vl_svm_sMs
9362 .param_str = "LUiV512bLUi"
9363 .target_set = TargetSet.initOne(.vevl_gen)
9364
9365__builtin_ve_vl_svm_sms
9366 .param_str = "LUiV256bLUi"
9367 .target_set = TargetSet.initOne(.vevl_gen)
9368
9369__builtin_ve_vl_svob
9370 .param_str = "v"
9371 .target_set = TargetSet.initOne(.vevl_gen)
9372
9373__builtin_ve_vl_tovm_sml
9374 .param_str = "LUiV256bUi"
9375 .target_set = TargetSet.initOne(.vevl_gen)
9376
9377__builtin_ve_vl_tscr_ssss
9378 .param_str = "LUiLUiLUiLUi"
9379 .target_set = TargetSet.initOne(.vevl_gen)
9380
9381__builtin_ve_vl_vaddsl_vsvl
9382 .param_str = "V256dLiV256dUi"
9383 .target_set = TargetSet.initOne(.vevl_gen)
9384
9385__builtin_ve_vl_vaddsl_vsvmvl
9386 .param_str = "V256dLiV256dV256bV256dUi"
9387 .target_set = TargetSet.initOne(.vevl_gen)
9388
9389__builtin_ve_vl_vaddsl_vsvvl
9390 .param_str = "V256dLiV256dV256dUi"
9391 .target_set = TargetSet.initOne(.vevl_gen)
9392
9393__builtin_ve_vl_vaddsl_vvvl
9394 .param_str = "V256dV256dV256dUi"
9395 .target_set = TargetSet.initOne(.vevl_gen)
9396
9397__builtin_ve_vl_vaddsl_vvvmvl
9398 .param_str = "V256dV256dV256dV256bV256dUi"
9399 .target_set = TargetSet.initOne(.vevl_gen)
9400
9401__builtin_ve_vl_vaddsl_vvvvl
9402 .param_str = "V256dV256dV256dV256dUi"
9403 .target_set = TargetSet.initOne(.vevl_gen)
9404
9405__builtin_ve_vl_vaddswsx_vsvl
9406 .param_str = "V256diV256dUi"
9407 .target_set = TargetSet.initOne(.vevl_gen)
9408
9409__builtin_ve_vl_vaddswsx_vsvmvl
9410 .param_str = "V256diV256dV256bV256dUi"
9411 .target_set = TargetSet.initOne(.vevl_gen)
9412
9413__builtin_ve_vl_vaddswsx_vsvvl
9414 .param_str = "V256diV256dV256dUi"
9415 .target_set = TargetSet.initOne(.vevl_gen)
9416
9417__builtin_ve_vl_vaddswsx_vvvl
9418 .param_str = "V256dV256dV256dUi"
9419 .target_set = TargetSet.initOne(.vevl_gen)
9420
9421__builtin_ve_vl_vaddswsx_vvvmvl
9422 .param_str = "V256dV256dV256dV256bV256dUi"
9423 .target_set = TargetSet.initOne(.vevl_gen)
9424
9425__builtin_ve_vl_vaddswsx_vvvvl
9426 .param_str = "V256dV256dV256dV256dUi"
9427 .target_set = TargetSet.initOne(.vevl_gen)
9428
9429__builtin_ve_vl_vaddswzx_vsvl
9430 .param_str = "V256diV256dUi"
9431 .target_set = TargetSet.initOne(.vevl_gen)
9432
9433__builtin_ve_vl_vaddswzx_vsvmvl
9434 .param_str = "V256diV256dV256bV256dUi"
9435 .target_set = TargetSet.initOne(.vevl_gen)
9436
9437__builtin_ve_vl_vaddswzx_vsvvl
9438 .param_str = "V256diV256dV256dUi"
9439 .target_set = TargetSet.initOne(.vevl_gen)
9440
9441__builtin_ve_vl_vaddswzx_vvvl
9442 .param_str = "V256dV256dV256dUi"
9443 .target_set = TargetSet.initOne(.vevl_gen)
9444
9445__builtin_ve_vl_vaddswzx_vvvmvl
9446 .param_str = "V256dV256dV256dV256bV256dUi"
9447 .target_set = TargetSet.initOne(.vevl_gen)
9448
9449__builtin_ve_vl_vaddswzx_vvvvl
9450 .param_str = "V256dV256dV256dV256dUi"
9451 .target_set = TargetSet.initOne(.vevl_gen)
9452
9453__builtin_ve_vl_vaddul_vsvl
9454 .param_str = "V256dLUiV256dUi"
9455 .target_set = TargetSet.initOne(.vevl_gen)
9456
9457__builtin_ve_vl_vaddul_vsvmvl
9458 .param_str = "V256dLUiV256dV256bV256dUi"
9459 .target_set = TargetSet.initOne(.vevl_gen)
9460
9461__builtin_ve_vl_vaddul_vsvvl
9462 .param_str = "V256dLUiV256dV256dUi"
9463 .target_set = TargetSet.initOne(.vevl_gen)
9464
9465__builtin_ve_vl_vaddul_vvvl
9466 .param_str = "V256dV256dV256dUi"
9467 .target_set = TargetSet.initOne(.vevl_gen)
9468
9469__builtin_ve_vl_vaddul_vvvmvl
9470 .param_str = "V256dV256dV256dV256bV256dUi"
9471 .target_set = TargetSet.initOne(.vevl_gen)
9472
9473__builtin_ve_vl_vaddul_vvvvl
9474 .param_str = "V256dV256dV256dV256dUi"
9475 .target_set = TargetSet.initOne(.vevl_gen)
9476
9477__builtin_ve_vl_vadduw_vsvl
9478 .param_str = "V256dUiV256dUi"
9479 .target_set = TargetSet.initOne(.vevl_gen)
9480
9481__builtin_ve_vl_vadduw_vsvmvl
9482 .param_str = "V256dUiV256dV256bV256dUi"
9483 .target_set = TargetSet.initOne(.vevl_gen)
9484
9485__builtin_ve_vl_vadduw_vsvvl
9486 .param_str = "V256dUiV256dV256dUi"
9487 .target_set = TargetSet.initOne(.vevl_gen)
9488
9489__builtin_ve_vl_vadduw_vvvl
9490 .param_str = "V256dV256dV256dUi"
9491 .target_set = TargetSet.initOne(.vevl_gen)
9492
9493__builtin_ve_vl_vadduw_vvvmvl
9494 .param_str = "V256dV256dV256dV256bV256dUi"
9495 .target_set = TargetSet.initOne(.vevl_gen)
9496
9497__builtin_ve_vl_vadduw_vvvvl
9498 .param_str = "V256dV256dV256dV256dUi"
9499 .target_set = TargetSet.initOne(.vevl_gen)
9500
9501__builtin_ve_vl_vand_vsvl
9502 .param_str = "V256dLUiV256dUi"
9503 .target_set = TargetSet.initOne(.vevl_gen)
9504
9505__builtin_ve_vl_vand_vsvmvl
9506 .param_str = "V256dLUiV256dV256bV256dUi"
9507 .target_set = TargetSet.initOne(.vevl_gen)
9508
9509__builtin_ve_vl_vand_vsvvl
9510 .param_str = "V256dLUiV256dV256dUi"
9511 .target_set = TargetSet.initOne(.vevl_gen)
9512
9513__builtin_ve_vl_vand_vvvl
9514 .param_str = "V256dV256dV256dUi"
9515 .target_set = TargetSet.initOne(.vevl_gen)
9516
9517__builtin_ve_vl_vand_vvvmvl
9518 .param_str = "V256dV256dV256dV256bV256dUi"
9519 .target_set = TargetSet.initOne(.vevl_gen)
9520
9521__builtin_ve_vl_vand_vvvvl
9522 .param_str = "V256dV256dV256dV256dUi"
9523 .target_set = TargetSet.initOne(.vevl_gen)
9524
9525__builtin_ve_vl_vbrdd_vsl
9526 .param_str = "V256ddUi"
9527 .target_set = TargetSet.initOne(.vevl_gen)
9528
9529__builtin_ve_vl_vbrdd_vsmvl
9530 .param_str = "V256ddV256bV256dUi"
9531 .target_set = TargetSet.initOne(.vevl_gen)
9532
9533__builtin_ve_vl_vbrdd_vsvl
9534 .param_str = "V256ddV256dUi"
9535 .target_set = TargetSet.initOne(.vevl_gen)
9536
9537__builtin_ve_vl_vbrdl_vsl
9538 .param_str = "V256dLiUi"
9539 .target_set = TargetSet.initOne(.vevl_gen)
9540
9541__builtin_ve_vl_vbrdl_vsmvl
9542 .param_str = "V256dLiV256bV256dUi"
9543 .target_set = TargetSet.initOne(.vevl_gen)
9544
9545__builtin_ve_vl_vbrdl_vsvl
9546 .param_str = "V256dLiV256dUi"
9547 .target_set = TargetSet.initOne(.vevl_gen)
9548
9549__builtin_ve_vl_vbrds_vsl
9550 .param_str = "V256dfUi"
9551 .target_set = TargetSet.initOne(.vevl_gen)
9552
9553__builtin_ve_vl_vbrds_vsmvl
9554 .param_str = "V256dfV256bV256dUi"
9555 .target_set = TargetSet.initOne(.vevl_gen)
9556
9557__builtin_ve_vl_vbrds_vsvl
9558 .param_str = "V256dfV256dUi"
9559 .target_set = TargetSet.initOne(.vevl_gen)
9560
9561__builtin_ve_vl_vbrdw_vsl
9562 .param_str = "V256diUi"
9563 .target_set = TargetSet.initOne(.vevl_gen)
9564
9565__builtin_ve_vl_vbrdw_vsmvl
9566 .param_str = "V256diV256bV256dUi"
9567 .target_set = TargetSet.initOne(.vevl_gen)
9568
9569__builtin_ve_vl_vbrdw_vsvl
9570 .param_str = "V256diV256dUi"
9571 .target_set = TargetSet.initOne(.vevl_gen)
9572
9573__builtin_ve_vl_vbrv_vvl
9574 .param_str = "V256dV256dUi"
9575 .target_set = TargetSet.initOne(.vevl_gen)
9576
9577__builtin_ve_vl_vbrv_vvmvl
9578 .param_str = "V256dV256dV256bV256dUi"
9579 .target_set = TargetSet.initOne(.vevl_gen)
9580
9581__builtin_ve_vl_vbrv_vvvl
9582 .param_str = "V256dV256dV256dUi"
9583 .target_set = TargetSet.initOne(.vevl_gen)
9584
9585__builtin_ve_vl_vcmpsl_vsvl
9586 .param_str = "V256dLiV256dUi"
9587 .target_set = TargetSet.initOne(.vevl_gen)
9588
9589__builtin_ve_vl_vcmpsl_vsvmvl
9590 .param_str = "V256dLiV256dV256bV256dUi"
9591 .target_set = TargetSet.initOne(.vevl_gen)
9592
9593__builtin_ve_vl_vcmpsl_vsvvl
9594 .param_str = "V256dLiV256dV256dUi"
9595 .target_set = TargetSet.initOne(.vevl_gen)
9596
9597__builtin_ve_vl_vcmpsl_vvvl
9598 .param_str = "V256dV256dV256dUi"
9599 .target_set = TargetSet.initOne(.vevl_gen)
9600
9601__builtin_ve_vl_vcmpsl_vvvmvl
9602 .param_str = "V256dV256dV256dV256bV256dUi"
9603 .target_set = TargetSet.initOne(.vevl_gen)
9604
9605__builtin_ve_vl_vcmpsl_vvvvl
9606 .param_str = "V256dV256dV256dV256dUi"
9607 .target_set = TargetSet.initOne(.vevl_gen)
9608
9609__builtin_ve_vl_vcmpswsx_vsvl
9610 .param_str = "V256diV256dUi"
9611 .target_set = TargetSet.initOne(.vevl_gen)
9612
9613__builtin_ve_vl_vcmpswsx_vsvmvl
9614 .param_str = "V256diV256dV256bV256dUi"
9615 .target_set = TargetSet.initOne(.vevl_gen)
9616
9617__builtin_ve_vl_vcmpswsx_vsvvl
9618 .param_str = "V256diV256dV256dUi"
9619 .target_set = TargetSet.initOne(.vevl_gen)
9620
9621__builtin_ve_vl_vcmpswsx_vvvl
9622 .param_str = "V256dV256dV256dUi"
9623 .target_set = TargetSet.initOne(.vevl_gen)
9624
9625__builtin_ve_vl_vcmpswsx_vvvmvl
9626 .param_str = "V256dV256dV256dV256bV256dUi"
9627 .target_set = TargetSet.initOne(.vevl_gen)
9628
9629__builtin_ve_vl_vcmpswsx_vvvvl
9630 .param_str = "V256dV256dV256dV256dUi"
9631 .target_set = TargetSet.initOne(.vevl_gen)
9632
9633__builtin_ve_vl_vcmpswzx_vsvl
9634 .param_str = "V256diV256dUi"
9635 .target_set = TargetSet.initOne(.vevl_gen)
9636
9637__builtin_ve_vl_vcmpswzx_vsvmvl
9638 .param_str = "V256diV256dV256bV256dUi"
9639 .target_set = TargetSet.initOne(.vevl_gen)
9640
9641__builtin_ve_vl_vcmpswzx_vsvvl
9642 .param_str = "V256diV256dV256dUi"
9643 .target_set = TargetSet.initOne(.vevl_gen)
9644
9645__builtin_ve_vl_vcmpswzx_vvvl
9646 .param_str = "V256dV256dV256dUi"
9647 .target_set = TargetSet.initOne(.vevl_gen)
9648
9649__builtin_ve_vl_vcmpswzx_vvvmvl
9650 .param_str = "V256dV256dV256dV256bV256dUi"
9651 .target_set = TargetSet.initOne(.vevl_gen)
9652
9653__builtin_ve_vl_vcmpswzx_vvvvl
9654 .param_str = "V256dV256dV256dV256dUi"
9655 .target_set = TargetSet.initOne(.vevl_gen)
9656
9657__builtin_ve_vl_vcmpul_vsvl
9658 .param_str = "V256dLUiV256dUi"
9659 .target_set = TargetSet.initOne(.vevl_gen)
9660
9661__builtin_ve_vl_vcmpul_vsvmvl
9662 .param_str = "V256dLUiV256dV256bV256dUi"
9663 .target_set = TargetSet.initOne(.vevl_gen)
9664
9665__builtin_ve_vl_vcmpul_vsvvl
9666 .param_str = "V256dLUiV256dV256dUi"
9667 .target_set = TargetSet.initOne(.vevl_gen)
9668
9669__builtin_ve_vl_vcmpul_vvvl
9670 .param_str = "V256dV256dV256dUi"
9671 .target_set = TargetSet.initOne(.vevl_gen)
9672
9673__builtin_ve_vl_vcmpul_vvvmvl
9674 .param_str = "V256dV256dV256dV256bV256dUi"
9675 .target_set = TargetSet.initOne(.vevl_gen)
9676
9677__builtin_ve_vl_vcmpul_vvvvl
9678 .param_str = "V256dV256dV256dV256dUi"
9679 .target_set = TargetSet.initOne(.vevl_gen)
9680
9681__builtin_ve_vl_vcmpuw_vsvl
9682 .param_str = "V256dUiV256dUi"
9683 .target_set = TargetSet.initOne(.vevl_gen)
9684
9685__builtin_ve_vl_vcmpuw_vsvmvl
9686 .param_str = "V256dUiV256dV256bV256dUi"
9687 .target_set = TargetSet.initOne(.vevl_gen)
9688
9689__builtin_ve_vl_vcmpuw_vsvvl
9690 .param_str = "V256dUiV256dV256dUi"
9691 .target_set = TargetSet.initOne(.vevl_gen)
9692
9693__builtin_ve_vl_vcmpuw_vvvl
9694 .param_str = "V256dV256dV256dUi"
9695 .target_set = TargetSet.initOne(.vevl_gen)
9696
9697__builtin_ve_vl_vcmpuw_vvvmvl
9698 .param_str = "V256dV256dV256dV256bV256dUi"
9699 .target_set = TargetSet.initOne(.vevl_gen)
9700
9701__builtin_ve_vl_vcmpuw_vvvvl
9702 .param_str = "V256dV256dV256dV256dUi"
9703 .target_set = TargetSet.initOne(.vevl_gen)
9704
9705__builtin_ve_vl_vcp_vvmvl
9706 .param_str = "V256dV256dV256bV256dUi"
9707 .target_set = TargetSet.initOne(.vevl_gen)
9708
9709__builtin_ve_vl_vcvtdl_vvl
9710 .param_str = "V256dV256dUi"
9711 .target_set = TargetSet.initOne(.vevl_gen)
9712
9713__builtin_ve_vl_vcvtdl_vvvl
9714 .param_str = "V256dV256dV256dUi"
9715 .target_set = TargetSet.initOne(.vevl_gen)
9716
9717__builtin_ve_vl_vcvtds_vvl
9718 .param_str = "V256dV256dUi"
9719 .target_set = TargetSet.initOne(.vevl_gen)
9720
9721__builtin_ve_vl_vcvtds_vvvl
9722 .param_str = "V256dV256dV256dUi"
9723 .target_set = TargetSet.initOne(.vevl_gen)
9724
9725__builtin_ve_vl_vcvtdw_vvl
9726 .param_str = "V256dV256dUi"
9727 .target_set = TargetSet.initOne(.vevl_gen)
9728
9729__builtin_ve_vl_vcvtdw_vvvl
9730 .param_str = "V256dV256dV256dUi"
9731 .target_set = TargetSet.initOne(.vevl_gen)
9732
9733__builtin_ve_vl_vcvtld_vvl
9734 .param_str = "V256dV256dUi"
9735 .target_set = TargetSet.initOne(.vevl_gen)
9736
9737__builtin_ve_vl_vcvtld_vvmvl
9738 .param_str = "V256dV256dV256bV256dUi"
9739 .target_set = TargetSet.initOne(.vevl_gen)
9740
9741__builtin_ve_vl_vcvtld_vvvl
9742 .param_str = "V256dV256dV256dUi"
9743 .target_set = TargetSet.initOne(.vevl_gen)
9744
9745__builtin_ve_vl_vcvtldrz_vvl
9746 .param_str = "V256dV256dUi"
9747 .target_set = TargetSet.initOne(.vevl_gen)
9748
9749__builtin_ve_vl_vcvtldrz_vvmvl
9750 .param_str = "V256dV256dV256bV256dUi"
9751 .target_set = TargetSet.initOne(.vevl_gen)
9752
9753__builtin_ve_vl_vcvtldrz_vvvl
9754 .param_str = "V256dV256dV256dUi"
9755 .target_set = TargetSet.initOne(.vevl_gen)
9756
9757__builtin_ve_vl_vcvtsd_vvl
9758 .param_str = "V256dV256dUi"
9759 .target_set = TargetSet.initOne(.vevl_gen)
9760
9761__builtin_ve_vl_vcvtsd_vvvl
9762 .param_str = "V256dV256dV256dUi"
9763 .target_set = TargetSet.initOne(.vevl_gen)
9764
9765__builtin_ve_vl_vcvtsw_vvl
9766 .param_str = "V256dV256dUi"
9767 .target_set = TargetSet.initOne(.vevl_gen)
9768
9769__builtin_ve_vl_vcvtsw_vvvl
9770 .param_str = "V256dV256dV256dUi"
9771 .target_set = TargetSet.initOne(.vevl_gen)
9772
9773__builtin_ve_vl_vcvtwdsx_vvl
9774 .param_str = "V256dV256dUi"
9775 .target_set = TargetSet.initOne(.vevl_gen)
9776
9777__builtin_ve_vl_vcvtwdsx_vvmvl
9778 .param_str = "V256dV256dV256bV256dUi"
9779 .target_set = TargetSet.initOne(.vevl_gen)
9780
9781__builtin_ve_vl_vcvtwdsx_vvvl
9782 .param_str = "V256dV256dV256dUi"
9783 .target_set = TargetSet.initOne(.vevl_gen)
9784
9785__builtin_ve_vl_vcvtwdsxrz_vvl
9786 .param_str = "V256dV256dUi"
9787 .target_set = TargetSet.initOne(.vevl_gen)
9788
9789__builtin_ve_vl_vcvtwdsxrz_vvmvl
9790 .param_str = "V256dV256dV256bV256dUi"
9791 .target_set = TargetSet.initOne(.vevl_gen)
9792
9793__builtin_ve_vl_vcvtwdsxrz_vvvl
9794 .param_str = "V256dV256dV256dUi"
9795 .target_set = TargetSet.initOne(.vevl_gen)
9796
9797__builtin_ve_vl_vcvtwdzx_vvl
9798 .param_str = "V256dV256dUi"
9799 .target_set = TargetSet.initOne(.vevl_gen)
9800
9801__builtin_ve_vl_vcvtwdzx_vvmvl
9802 .param_str = "V256dV256dV256bV256dUi"
9803 .target_set = TargetSet.initOne(.vevl_gen)
9804
9805__builtin_ve_vl_vcvtwdzx_vvvl
9806 .param_str = "V256dV256dV256dUi"
9807 .target_set = TargetSet.initOne(.vevl_gen)
9808
9809__builtin_ve_vl_vcvtwdzxrz_vvl
9810 .param_str = "V256dV256dUi"
9811 .target_set = TargetSet.initOne(.vevl_gen)
9812
9813__builtin_ve_vl_vcvtwdzxrz_vvmvl
9814 .param_str = "V256dV256dV256bV256dUi"
9815 .target_set = TargetSet.initOne(.vevl_gen)
9816
9817__builtin_ve_vl_vcvtwdzxrz_vvvl
9818 .param_str = "V256dV256dV256dUi"
9819 .target_set = TargetSet.initOne(.vevl_gen)
9820
9821__builtin_ve_vl_vcvtwssx_vvl
9822 .param_str = "V256dV256dUi"
9823 .target_set = TargetSet.initOne(.vevl_gen)
9824
9825__builtin_ve_vl_vcvtwssx_vvmvl
9826 .param_str = "V256dV256dV256bV256dUi"
9827 .target_set = TargetSet.initOne(.vevl_gen)
9828
9829__builtin_ve_vl_vcvtwssx_vvvl
9830 .param_str = "V256dV256dV256dUi"
9831 .target_set = TargetSet.initOne(.vevl_gen)
9832
9833__builtin_ve_vl_vcvtwssxrz_vvl
9834 .param_str = "V256dV256dUi"
9835 .target_set = TargetSet.initOne(.vevl_gen)
9836
9837__builtin_ve_vl_vcvtwssxrz_vvmvl
9838 .param_str = "V256dV256dV256bV256dUi"
9839 .target_set = TargetSet.initOne(.vevl_gen)
9840
9841__builtin_ve_vl_vcvtwssxrz_vvvl
9842 .param_str = "V256dV256dV256dUi"
9843 .target_set = TargetSet.initOne(.vevl_gen)
9844
9845__builtin_ve_vl_vcvtwszx_vvl
9846 .param_str = "V256dV256dUi"
9847 .target_set = TargetSet.initOne(.vevl_gen)
9848
9849__builtin_ve_vl_vcvtwszx_vvmvl
9850 .param_str = "V256dV256dV256bV256dUi"
9851 .target_set = TargetSet.initOne(.vevl_gen)
9852
9853__builtin_ve_vl_vcvtwszx_vvvl
9854 .param_str = "V256dV256dV256dUi"
9855 .target_set = TargetSet.initOne(.vevl_gen)
9856
9857__builtin_ve_vl_vcvtwszxrz_vvl
9858 .param_str = "V256dV256dUi"
9859 .target_set = TargetSet.initOne(.vevl_gen)
9860
9861__builtin_ve_vl_vcvtwszxrz_vvmvl
9862 .param_str = "V256dV256dV256bV256dUi"
9863 .target_set = TargetSet.initOne(.vevl_gen)
9864
9865__builtin_ve_vl_vcvtwszxrz_vvvl
9866 .param_str = "V256dV256dV256dUi"
9867 .target_set = TargetSet.initOne(.vevl_gen)
9868
9869__builtin_ve_vl_vdivsl_vsvl
9870 .param_str = "V256dLiV256dUi"
9871 .target_set = TargetSet.initOne(.vevl_gen)
9872
9873__builtin_ve_vl_vdivsl_vsvmvl
9874 .param_str = "V256dLiV256dV256bV256dUi"
9875 .target_set = TargetSet.initOne(.vevl_gen)
9876
9877__builtin_ve_vl_vdivsl_vsvvl
9878 .param_str = "V256dLiV256dV256dUi"
9879 .target_set = TargetSet.initOne(.vevl_gen)
9880
9881__builtin_ve_vl_vdivsl_vvsl
9882 .param_str = "V256dV256dLiUi"
9883 .target_set = TargetSet.initOne(.vevl_gen)
9884
9885__builtin_ve_vl_vdivsl_vvsmvl
9886 .param_str = "V256dV256dLiV256bV256dUi"
9887 .target_set = TargetSet.initOne(.vevl_gen)
9888
9889__builtin_ve_vl_vdivsl_vvsvl
9890 .param_str = "V256dV256dLiV256dUi"
9891 .target_set = TargetSet.initOne(.vevl_gen)
9892
9893__builtin_ve_vl_vdivsl_vvvl
9894 .param_str = "V256dV256dV256dUi"
9895 .target_set = TargetSet.initOne(.vevl_gen)
9896
9897__builtin_ve_vl_vdivsl_vvvmvl
9898 .param_str = "V256dV256dV256dV256bV256dUi"
9899 .target_set = TargetSet.initOne(.vevl_gen)
9900
9901__builtin_ve_vl_vdivsl_vvvvl
9902 .param_str = "V256dV256dV256dV256dUi"
9903 .target_set = TargetSet.initOne(.vevl_gen)
9904
9905__builtin_ve_vl_vdivswsx_vsvl
9906 .param_str = "V256diV256dUi"
9907 .target_set = TargetSet.initOne(.vevl_gen)
9908
9909__builtin_ve_vl_vdivswsx_vsvmvl
9910 .param_str = "V256diV256dV256bV256dUi"
9911 .target_set = TargetSet.initOne(.vevl_gen)
9912
9913__builtin_ve_vl_vdivswsx_vsvvl
9914 .param_str = "V256diV256dV256dUi"
9915 .target_set = TargetSet.initOne(.vevl_gen)
9916
9917__builtin_ve_vl_vdivswsx_vvsl
9918 .param_str = "V256dV256diUi"
9919 .target_set = TargetSet.initOne(.vevl_gen)
9920
9921__builtin_ve_vl_vdivswsx_vvsmvl
9922 .param_str = "V256dV256diV256bV256dUi"
9923 .target_set = TargetSet.initOne(.vevl_gen)
9924
9925__builtin_ve_vl_vdivswsx_vvsvl
9926 .param_str = "V256dV256diV256dUi"
9927 .target_set = TargetSet.initOne(.vevl_gen)
9928
9929__builtin_ve_vl_vdivswsx_vvvl
9930 .param_str = "V256dV256dV256dUi"
9931 .target_set = TargetSet.initOne(.vevl_gen)
9932
9933__builtin_ve_vl_vdivswsx_vvvmvl
9934 .param_str = "V256dV256dV256dV256bV256dUi"
9935 .target_set = TargetSet.initOne(.vevl_gen)
9936
9937__builtin_ve_vl_vdivswsx_vvvvl
9938 .param_str = "V256dV256dV256dV256dUi"
9939 .target_set = TargetSet.initOne(.vevl_gen)
9940
9941__builtin_ve_vl_vdivswzx_vsvl
9942 .param_str = "V256diV256dUi"
9943 .target_set = TargetSet.initOne(.vevl_gen)
9944
9945__builtin_ve_vl_vdivswzx_vsvmvl
9946 .param_str = "V256diV256dV256bV256dUi"
9947 .target_set = TargetSet.initOne(.vevl_gen)
9948
9949__builtin_ve_vl_vdivswzx_vsvvl
9950 .param_str = "V256diV256dV256dUi"
9951 .target_set = TargetSet.initOne(.vevl_gen)
9952
9953__builtin_ve_vl_vdivswzx_vvsl
9954 .param_str = "V256dV256diUi"
9955 .target_set = TargetSet.initOne(.vevl_gen)
9956
9957__builtin_ve_vl_vdivswzx_vvsmvl
9958 .param_str = "V256dV256diV256bV256dUi"
9959 .target_set = TargetSet.initOne(.vevl_gen)
9960
9961__builtin_ve_vl_vdivswzx_vvsvl
9962 .param_str = "V256dV256diV256dUi"
9963 .target_set = TargetSet.initOne(.vevl_gen)
9964
9965__builtin_ve_vl_vdivswzx_vvvl
9966 .param_str = "V256dV256dV256dUi"
9967 .target_set = TargetSet.initOne(.vevl_gen)
9968
9969__builtin_ve_vl_vdivswzx_vvvmvl
9970 .param_str = "V256dV256dV256dV256bV256dUi"
9971 .target_set = TargetSet.initOne(.vevl_gen)
9972
9973__builtin_ve_vl_vdivswzx_vvvvl
9974 .param_str = "V256dV256dV256dV256dUi"
9975 .target_set = TargetSet.initOne(.vevl_gen)
9976
9977__builtin_ve_vl_vdivul_vsvl
9978 .param_str = "V256dLUiV256dUi"
9979 .target_set = TargetSet.initOne(.vevl_gen)
9980
9981__builtin_ve_vl_vdivul_vsvmvl
9982 .param_str = "V256dLUiV256dV256bV256dUi"
9983 .target_set = TargetSet.initOne(.vevl_gen)
9984
9985__builtin_ve_vl_vdivul_vsvvl
9986 .param_str = "V256dLUiV256dV256dUi"
9987 .target_set = TargetSet.initOne(.vevl_gen)
9988
9989__builtin_ve_vl_vdivul_vvsl
9990 .param_str = "V256dV256dLUiUi"
9991 .target_set = TargetSet.initOne(.vevl_gen)
9992
9993__builtin_ve_vl_vdivul_vvsmvl
9994 .param_str = "V256dV256dLUiV256bV256dUi"
9995 .target_set = TargetSet.initOne(.vevl_gen)
9996
9997__builtin_ve_vl_vdivul_vvsvl
9998 .param_str = "V256dV256dLUiV256dUi"
9999 .target_set = TargetSet.initOne(.vevl_gen)
10000
10001__builtin_ve_vl_vdivul_vvvl
10002 .param_str = "V256dV256dV256dUi"
10003 .target_set = TargetSet.initOne(.vevl_gen)
10004
10005__builtin_ve_vl_vdivul_vvvmvl
10006 .param_str = "V256dV256dV256dV256bV256dUi"
10007 .target_set = TargetSet.initOne(.vevl_gen)
10008
10009__builtin_ve_vl_vdivul_vvvvl
10010 .param_str = "V256dV256dV256dV256dUi"
10011 .target_set = TargetSet.initOne(.vevl_gen)
10012
10013__builtin_ve_vl_vdivuw_vsvl
10014 .param_str = "V256dUiV256dUi"
10015 .target_set = TargetSet.initOne(.vevl_gen)
10016
10017__builtin_ve_vl_vdivuw_vsvmvl
10018 .param_str = "V256dUiV256dV256bV256dUi"
10019 .target_set = TargetSet.initOne(.vevl_gen)
10020
10021__builtin_ve_vl_vdivuw_vsvvl
10022 .param_str = "V256dUiV256dV256dUi"
10023 .target_set = TargetSet.initOne(.vevl_gen)
10024
10025__builtin_ve_vl_vdivuw_vvsl
10026 .param_str = "V256dV256dUiUi"
10027 .target_set = TargetSet.initOne(.vevl_gen)
10028
10029__builtin_ve_vl_vdivuw_vvsmvl
10030 .param_str = "V256dV256dUiV256bV256dUi"
10031 .target_set = TargetSet.initOne(.vevl_gen)
10032
10033__builtin_ve_vl_vdivuw_vvsvl
10034 .param_str = "V256dV256dUiV256dUi"
10035 .target_set = TargetSet.initOne(.vevl_gen)
10036
10037__builtin_ve_vl_vdivuw_vvvl
10038 .param_str = "V256dV256dV256dUi"
10039 .target_set = TargetSet.initOne(.vevl_gen)
10040
10041__builtin_ve_vl_vdivuw_vvvmvl
10042 .param_str = "V256dV256dV256dV256bV256dUi"
10043 .target_set = TargetSet.initOne(.vevl_gen)
10044
10045__builtin_ve_vl_vdivuw_vvvvl
10046 .param_str = "V256dV256dV256dV256dUi"
10047 .target_set = TargetSet.initOne(.vevl_gen)
10048
10049__builtin_ve_vl_veqv_vsvl
10050 .param_str = "V256dLUiV256dUi"
10051 .target_set = TargetSet.initOne(.vevl_gen)
10052
10053__builtin_ve_vl_veqv_vsvmvl
10054 .param_str = "V256dLUiV256dV256bV256dUi"
10055 .target_set = TargetSet.initOne(.vevl_gen)
10056
10057__builtin_ve_vl_veqv_vsvvl
10058 .param_str = "V256dLUiV256dV256dUi"
10059 .target_set = TargetSet.initOne(.vevl_gen)
10060
10061__builtin_ve_vl_veqv_vvvl
10062 .param_str = "V256dV256dV256dUi"
10063 .target_set = TargetSet.initOne(.vevl_gen)
10064
10065__builtin_ve_vl_veqv_vvvmvl
10066 .param_str = "V256dV256dV256dV256bV256dUi"
10067 .target_set = TargetSet.initOne(.vevl_gen)
10068
10069__builtin_ve_vl_veqv_vvvvl
10070 .param_str = "V256dV256dV256dV256dUi"
10071 .target_set = TargetSet.initOne(.vevl_gen)
10072
10073__builtin_ve_vl_vex_vvmvl
10074 .param_str = "V256dV256dV256bV256dUi"
10075 .target_set = TargetSet.initOne(.vevl_gen)
10076
10077__builtin_ve_vl_vfaddd_vsvl
10078 .param_str = "V256ddV256dUi"
10079 .target_set = TargetSet.initOne(.vevl_gen)
10080
10081__builtin_ve_vl_vfaddd_vsvmvl
10082 .param_str = "V256ddV256dV256bV256dUi"
10083 .target_set = TargetSet.initOne(.vevl_gen)
10084
10085__builtin_ve_vl_vfaddd_vsvvl
10086 .param_str = "V256ddV256dV256dUi"
10087 .target_set = TargetSet.initOne(.vevl_gen)
10088
10089__builtin_ve_vl_vfaddd_vvvl
10090 .param_str = "V256dV256dV256dUi"
10091 .target_set = TargetSet.initOne(.vevl_gen)
10092
10093__builtin_ve_vl_vfaddd_vvvmvl
10094 .param_str = "V256dV256dV256dV256bV256dUi"
10095 .target_set = TargetSet.initOne(.vevl_gen)
10096
10097__builtin_ve_vl_vfaddd_vvvvl
10098 .param_str = "V256dV256dV256dV256dUi"
10099 .target_set = TargetSet.initOne(.vevl_gen)
10100
10101__builtin_ve_vl_vfadds_vsvl
10102 .param_str = "V256dfV256dUi"
10103 .target_set = TargetSet.initOne(.vevl_gen)
10104
10105__builtin_ve_vl_vfadds_vsvmvl
10106 .param_str = "V256dfV256dV256bV256dUi"
10107 .target_set = TargetSet.initOne(.vevl_gen)
10108
10109__builtin_ve_vl_vfadds_vsvvl
10110 .param_str = "V256dfV256dV256dUi"
10111 .target_set = TargetSet.initOne(.vevl_gen)
10112
10113__builtin_ve_vl_vfadds_vvvl
10114 .param_str = "V256dV256dV256dUi"
10115 .target_set = TargetSet.initOne(.vevl_gen)
10116
10117__builtin_ve_vl_vfadds_vvvmvl
10118 .param_str = "V256dV256dV256dV256bV256dUi"
10119 .target_set = TargetSet.initOne(.vevl_gen)
10120
10121__builtin_ve_vl_vfadds_vvvvl
10122 .param_str = "V256dV256dV256dV256dUi"
10123 .target_set = TargetSet.initOne(.vevl_gen)
10124
10125__builtin_ve_vl_vfcmpd_vsvl
10126 .param_str = "V256ddV256dUi"
10127 .target_set = TargetSet.initOne(.vevl_gen)
10128
10129__builtin_ve_vl_vfcmpd_vsvmvl
10130 .param_str = "V256ddV256dV256bV256dUi"
10131 .target_set = TargetSet.initOne(.vevl_gen)
10132
10133__builtin_ve_vl_vfcmpd_vsvvl
10134 .param_str = "V256ddV256dV256dUi"
10135 .target_set = TargetSet.initOne(.vevl_gen)
10136
10137__builtin_ve_vl_vfcmpd_vvvl
10138 .param_str = "V256dV256dV256dUi"
10139 .target_set = TargetSet.initOne(.vevl_gen)
10140
10141__builtin_ve_vl_vfcmpd_vvvmvl
10142 .param_str = "V256dV256dV256dV256bV256dUi"
10143 .target_set = TargetSet.initOne(.vevl_gen)
10144
10145__builtin_ve_vl_vfcmpd_vvvvl
10146 .param_str = "V256dV256dV256dV256dUi"
10147 .target_set = TargetSet.initOne(.vevl_gen)
10148
10149__builtin_ve_vl_vfcmps_vsvl
10150 .param_str = "V256dfV256dUi"
10151 .target_set = TargetSet.initOne(.vevl_gen)
10152
10153__builtin_ve_vl_vfcmps_vsvmvl
10154 .param_str = "V256dfV256dV256bV256dUi"
10155 .target_set = TargetSet.initOne(.vevl_gen)
10156
10157__builtin_ve_vl_vfcmps_vsvvl
10158 .param_str = "V256dfV256dV256dUi"
10159 .target_set = TargetSet.initOne(.vevl_gen)
10160
10161__builtin_ve_vl_vfcmps_vvvl
10162 .param_str = "V256dV256dV256dUi"
10163 .target_set = TargetSet.initOne(.vevl_gen)
10164
10165__builtin_ve_vl_vfcmps_vvvmvl
10166 .param_str = "V256dV256dV256dV256bV256dUi"
10167 .target_set = TargetSet.initOne(.vevl_gen)
10168
10169__builtin_ve_vl_vfcmps_vvvvl
10170 .param_str = "V256dV256dV256dV256dUi"
10171 .target_set = TargetSet.initOne(.vevl_gen)
10172
10173__builtin_ve_vl_vfdivd_vsvl
10174 .param_str = "V256ddV256dUi"
10175 .target_set = TargetSet.initOne(.vevl_gen)
10176
10177__builtin_ve_vl_vfdivd_vsvmvl
10178 .param_str = "V256ddV256dV256bV256dUi"
10179 .target_set = TargetSet.initOne(.vevl_gen)
10180
10181__builtin_ve_vl_vfdivd_vsvvl
10182 .param_str = "V256ddV256dV256dUi"
10183 .target_set = TargetSet.initOne(.vevl_gen)
10184
10185__builtin_ve_vl_vfdivd_vvvl
10186 .param_str = "V256dV256dV256dUi"
10187 .target_set = TargetSet.initOne(.vevl_gen)
10188
10189__builtin_ve_vl_vfdivd_vvvmvl
10190 .param_str = "V256dV256dV256dV256bV256dUi"
10191 .target_set = TargetSet.initOne(.vevl_gen)
10192
10193__builtin_ve_vl_vfdivd_vvvvl
10194 .param_str = "V256dV256dV256dV256dUi"
10195 .target_set = TargetSet.initOne(.vevl_gen)
10196
10197__builtin_ve_vl_vfdivs_vsvl
10198 .param_str = "V256dfV256dUi"
10199 .target_set = TargetSet.initOne(.vevl_gen)
10200
10201__builtin_ve_vl_vfdivs_vsvmvl
10202 .param_str = "V256dfV256dV256bV256dUi"
10203 .target_set = TargetSet.initOne(.vevl_gen)
10204
10205__builtin_ve_vl_vfdivs_vsvvl
10206 .param_str = "V256dfV256dV256dUi"
10207 .target_set = TargetSet.initOne(.vevl_gen)
10208
10209__builtin_ve_vl_vfdivs_vvvl
10210 .param_str = "V256dV256dV256dUi"
10211 .target_set = TargetSet.initOne(.vevl_gen)
10212
10213__builtin_ve_vl_vfdivs_vvvmvl
10214 .param_str = "V256dV256dV256dV256bV256dUi"
10215 .target_set = TargetSet.initOne(.vevl_gen)
10216
10217__builtin_ve_vl_vfdivs_vvvvl
10218 .param_str = "V256dV256dV256dV256dUi"
10219 .target_set = TargetSet.initOne(.vevl_gen)
10220
10221__builtin_ve_vl_vfmadd_vsvvl
10222 .param_str = "V256ddV256dV256dUi"
10223 .target_set = TargetSet.initOne(.vevl_gen)
10224
10225__builtin_ve_vl_vfmadd_vsvvmvl
10226 .param_str = "V256ddV256dV256dV256bV256dUi"
10227 .target_set = TargetSet.initOne(.vevl_gen)
10228
10229__builtin_ve_vl_vfmadd_vsvvvl
10230 .param_str = "V256ddV256dV256dV256dUi"
10231 .target_set = TargetSet.initOne(.vevl_gen)
10232
10233__builtin_ve_vl_vfmadd_vvsvl
10234 .param_str = "V256dV256ddV256dUi"
10235 .target_set = TargetSet.initOne(.vevl_gen)
10236
10237__builtin_ve_vl_vfmadd_vvsvmvl
10238 .param_str = "V256dV256ddV256dV256bV256dUi"
10239 .target_set = TargetSet.initOne(.vevl_gen)
10240
10241__builtin_ve_vl_vfmadd_vvsvvl
10242 .param_str = "V256dV256ddV256dV256dUi"
10243 .target_set = TargetSet.initOne(.vevl_gen)
10244
10245__builtin_ve_vl_vfmadd_vvvvl
10246 .param_str = "V256dV256dV256dV256dUi"
10247 .target_set = TargetSet.initOne(.vevl_gen)
10248
10249__builtin_ve_vl_vfmadd_vvvvmvl
10250 .param_str = "V256dV256dV256dV256dV256bV256dUi"
10251 .target_set = TargetSet.initOne(.vevl_gen)
10252
10253__builtin_ve_vl_vfmadd_vvvvvl
10254 .param_str = "V256dV256dV256dV256dV256dUi"
10255 .target_set = TargetSet.initOne(.vevl_gen)
10256
10257__builtin_ve_vl_vfmads_vsvvl
10258 .param_str = "V256dfV256dV256dUi"
10259 .target_set = TargetSet.initOne(.vevl_gen)
10260
10261__builtin_ve_vl_vfmads_vsvvmvl
10262 .param_str = "V256dfV256dV256dV256bV256dUi"
10263 .target_set = TargetSet.initOne(.vevl_gen)
10264
10265__builtin_ve_vl_vfmads_vsvvvl
10266 .param_str = "V256dfV256dV256dV256dUi"
10267 .target_set = TargetSet.initOne(.vevl_gen)
10268
10269__builtin_ve_vl_vfmads_vvsvl
10270 .param_str = "V256dV256dfV256dUi"
10271 .target_set = TargetSet.initOne(.vevl_gen)
10272
10273__builtin_ve_vl_vfmads_vvsvmvl
10274 .param_str = "V256dV256dfV256dV256bV256dUi"
10275 .target_set = TargetSet.initOne(.vevl_gen)
10276
10277__builtin_ve_vl_vfmads_vvsvvl
10278 .param_str = "V256dV256dfV256dV256dUi"
10279 .target_set = TargetSet.initOne(.vevl_gen)
10280
10281__builtin_ve_vl_vfmads_vvvvl
10282 .param_str = "V256dV256dV256dV256dUi"
10283 .target_set = TargetSet.initOne(.vevl_gen)
10284
10285__builtin_ve_vl_vfmads_vvvvmvl
10286 .param_str = "V256dV256dV256dV256dV256bV256dUi"
10287 .target_set = TargetSet.initOne(.vevl_gen)
10288
10289__builtin_ve_vl_vfmads_vvvvvl
10290 .param_str = "V256dV256dV256dV256dV256dUi"
10291 .target_set = TargetSet.initOne(.vevl_gen)
10292
10293__builtin_ve_vl_vfmaxd_vsvl
10294 .param_str = "V256ddV256dUi"
10295 .target_set = TargetSet.initOne(.vevl_gen)
10296
10297__builtin_ve_vl_vfmaxd_vsvmvl
10298 .param_str = "V256ddV256dV256bV256dUi"
10299 .target_set = TargetSet.initOne(.vevl_gen)
10300
10301__builtin_ve_vl_vfmaxd_vsvvl
10302 .param_str = "V256ddV256dV256dUi"
10303 .target_set = TargetSet.initOne(.vevl_gen)
10304
10305__builtin_ve_vl_vfmaxd_vvvl
10306 .param_str = "V256dV256dV256dUi"
10307 .target_set = TargetSet.initOne(.vevl_gen)
10308
10309__builtin_ve_vl_vfmaxd_vvvmvl
10310 .param_str = "V256dV256dV256dV256bV256dUi"
10311 .target_set = TargetSet.initOne(.vevl_gen)
10312
10313__builtin_ve_vl_vfmaxd_vvvvl
10314 .param_str = "V256dV256dV256dV256dUi"
10315 .target_set = TargetSet.initOne(.vevl_gen)
10316
10317__builtin_ve_vl_vfmaxs_vsvl
10318 .param_str = "V256dfV256dUi"
10319 .target_set = TargetSet.initOne(.vevl_gen)
10320
10321__builtin_ve_vl_vfmaxs_vsvmvl
10322 .param_str = "V256dfV256dV256bV256dUi"
10323 .target_set = TargetSet.initOne(.vevl_gen)
10324
10325__builtin_ve_vl_vfmaxs_vsvvl
10326 .param_str = "V256dfV256dV256dUi"
10327 .target_set = TargetSet.initOne(.vevl_gen)
10328
10329__builtin_ve_vl_vfmaxs_vvvl
10330 .param_str = "V256dV256dV256dUi"
10331 .target_set = TargetSet.initOne(.vevl_gen)
10332
10333__builtin_ve_vl_vfmaxs_vvvmvl
10334 .param_str = "V256dV256dV256dV256bV256dUi"
10335 .target_set = TargetSet.initOne(.vevl_gen)
10336
10337__builtin_ve_vl_vfmaxs_vvvvl
10338 .param_str = "V256dV256dV256dV256dUi"
10339 .target_set = TargetSet.initOne(.vevl_gen)
10340
10341__builtin_ve_vl_vfmind_vsvl
10342 .param_str = "V256ddV256dUi"
10343 .target_set = TargetSet.initOne(.vevl_gen)
10344
10345__builtin_ve_vl_vfmind_vsvmvl
10346 .param_str = "V256ddV256dV256bV256dUi"
10347 .target_set = TargetSet.initOne(.vevl_gen)
10348
10349__builtin_ve_vl_vfmind_vsvvl
10350 .param_str = "V256ddV256dV256dUi"
10351 .target_set = TargetSet.initOne(.vevl_gen)
10352
10353__builtin_ve_vl_vfmind_vvvl
10354 .param_str = "V256dV256dV256dUi"
10355 .target_set = TargetSet.initOne(.vevl_gen)
10356
10357__builtin_ve_vl_vfmind_vvvmvl
10358 .param_str = "V256dV256dV256dV256bV256dUi"
10359 .target_set = TargetSet.initOne(.vevl_gen)
10360
10361__builtin_ve_vl_vfmind_vvvvl
10362 .param_str = "V256dV256dV256dV256dUi"
10363 .target_set = TargetSet.initOne(.vevl_gen)
10364
10365__builtin_ve_vl_vfmins_vsvl
10366 .param_str = "V256dfV256dUi"
10367 .target_set = TargetSet.initOne(.vevl_gen)
10368
10369__builtin_ve_vl_vfmins_vsvmvl
10370 .param_str = "V256dfV256dV256bV256dUi"
10371 .target_set = TargetSet.initOne(.vevl_gen)
10372
10373__builtin_ve_vl_vfmins_vsvvl
10374 .param_str = "V256dfV256dV256dUi"
10375 .target_set = TargetSet.initOne(.vevl_gen)
10376
10377__builtin_ve_vl_vfmins_vvvl
10378 .param_str = "V256dV256dV256dUi"
10379 .target_set = TargetSet.initOne(.vevl_gen)
10380
10381__builtin_ve_vl_vfmins_vvvmvl
10382 .param_str = "V256dV256dV256dV256bV256dUi"
10383 .target_set = TargetSet.initOne(.vevl_gen)
10384
10385__builtin_ve_vl_vfmins_vvvvl
10386 .param_str = "V256dV256dV256dV256dUi"
10387 .target_set = TargetSet.initOne(.vevl_gen)
10388
10389__builtin_ve_vl_vfmkdeq_mvl
10390 .param_str = "V256bV256dUi"
10391 .target_set = TargetSet.initOne(.vevl_gen)
10392
10393__builtin_ve_vl_vfmkdeq_mvml
10394 .param_str = "V256bV256dV256bUi"
10395 .target_set = TargetSet.initOne(.vevl_gen)
10396
10397__builtin_ve_vl_vfmkdeqnan_mvl
10398 .param_str = "V256bV256dUi"
10399 .target_set = TargetSet.initOne(.vevl_gen)
10400
10401__builtin_ve_vl_vfmkdeqnan_mvml
10402 .param_str = "V256bV256dV256bUi"
10403 .target_set = TargetSet.initOne(.vevl_gen)
10404
10405__builtin_ve_vl_vfmkdge_mvl
10406 .param_str = "V256bV256dUi"
10407 .target_set = TargetSet.initOne(.vevl_gen)
10408
10409__builtin_ve_vl_vfmkdge_mvml
10410 .param_str = "V256bV256dV256bUi"
10411 .target_set = TargetSet.initOne(.vevl_gen)
10412
10413__builtin_ve_vl_vfmkdgenan_mvl
10414 .param_str = "V256bV256dUi"
10415 .target_set = TargetSet.initOne(.vevl_gen)
10416
10417__builtin_ve_vl_vfmkdgenan_mvml
10418 .param_str = "V256bV256dV256bUi"
10419 .target_set = TargetSet.initOne(.vevl_gen)
10420
10421__builtin_ve_vl_vfmkdgt_mvl
10422 .param_str = "V256bV256dUi"
10423 .target_set = TargetSet.initOne(.vevl_gen)
10424
10425__builtin_ve_vl_vfmkdgt_mvml
10426 .param_str = "V256bV256dV256bUi"
10427 .target_set = TargetSet.initOne(.vevl_gen)
10428
10429__builtin_ve_vl_vfmkdgtnan_mvl
10430 .param_str = "V256bV256dUi"
10431 .target_set = TargetSet.initOne(.vevl_gen)
10432
10433__builtin_ve_vl_vfmkdgtnan_mvml
10434 .param_str = "V256bV256dV256bUi"
10435 .target_set = TargetSet.initOne(.vevl_gen)
10436
10437__builtin_ve_vl_vfmkdle_mvl
10438 .param_str = "V256bV256dUi"
10439 .target_set = TargetSet.initOne(.vevl_gen)
10440
10441__builtin_ve_vl_vfmkdle_mvml
10442 .param_str = "V256bV256dV256bUi"
10443 .target_set = TargetSet.initOne(.vevl_gen)
10444
10445__builtin_ve_vl_vfmkdlenan_mvl
10446 .param_str = "V256bV256dUi"
10447 .target_set = TargetSet.initOne(.vevl_gen)
10448
10449__builtin_ve_vl_vfmkdlenan_mvml
10450 .param_str = "V256bV256dV256bUi"
10451 .target_set = TargetSet.initOne(.vevl_gen)
10452
10453__builtin_ve_vl_vfmkdlt_mvl
10454 .param_str = "V256bV256dUi"
10455 .target_set = TargetSet.initOne(.vevl_gen)
10456
10457__builtin_ve_vl_vfmkdlt_mvml
10458 .param_str = "V256bV256dV256bUi"
10459 .target_set = TargetSet.initOne(.vevl_gen)
10460
10461__builtin_ve_vl_vfmkdltnan_mvl
10462 .param_str = "V256bV256dUi"
10463 .target_set = TargetSet.initOne(.vevl_gen)
10464
10465__builtin_ve_vl_vfmkdltnan_mvml
10466 .param_str = "V256bV256dV256bUi"
10467 .target_set = TargetSet.initOne(.vevl_gen)
10468
10469__builtin_ve_vl_vfmkdnan_mvl
10470 .param_str = "V256bV256dUi"
10471 .target_set = TargetSet.initOne(.vevl_gen)
10472
10473__builtin_ve_vl_vfmkdnan_mvml
10474 .param_str = "V256bV256dV256bUi"
10475 .target_set = TargetSet.initOne(.vevl_gen)
10476
10477__builtin_ve_vl_vfmkdne_mvl
10478 .param_str = "V256bV256dUi"
10479 .target_set = TargetSet.initOne(.vevl_gen)
10480
10481__builtin_ve_vl_vfmkdne_mvml
10482 .param_str = "V256bV256dV256bUi"
10483 .target_set = TargetSet.initOne(.vevl_gen)
10484
10485__builtin_ve_vl_vfmkdnenan_mvl
10486 .param_str = "V256bV256dUi"
10487 .target_set = TargetSet.initOne(.vevl_gen)
10488
10489__builtin_ve_vl_vfmkdnenan_mvml
10490 .param_str = "V256bV256dV256bUi"
10491 .target_set = TargetSet.initOne(.vevl_gen)
10492
10493__builtin_ve_vl_vfmkdnum_mvl
10494 .param_str = "V256bV256dUi"
10495 .target_set = TargetSet.initOne(.vevl_gen)
10496
10497__builtin_ve_vl_vfmkdnum_mvml
10498 .param_str = "V256bV256dV256bUi"
10499 .target_set = TargetSet.initOne(.vevl_gen)
10500
10501__builtin_ve_vl_vfmklaf_ml
10502 .param_str = "V256bUi"
10503 .target_set = TargetSet.initOne(.vevl_gen)
10504
10505__builtin_ve_vl_vfmklat_ml
10506 .param_str = "V256bUi"
10507 .target_set = TargetSet.initOne(.vevl_gen)
10508
10509__builtin_ve_vl_vfmkleq_mvl
10510 .param_str = "V256bV256dUi"
10511 .target_set = TargetSet.initOne(.vevl_gen)
10512
10513__builtin_ve_vl_vfmkleq_mvml
10514 .param_str = "V256bV256dV256bUi"
10515 .target_set = TargetSet.initOne(.vevl_gen)
10516
10517__builtin_ve_vl_vfmkleqnan_mvl
10518 .param_str = "V256bV256dUi"
10519 .target_set = TargetSet.initOne(.vevl_gen)
10520
10521__builtin_ve_vl_vfmkleqnan_mvml
10522 .param_str = "V256bV256dV256bUi"
10523 .target_set = TargetSet.initOne(.vevl_gen)
10524
10525__builtin_ve_vl_vfmklge_mvl
10526 .param_str = "V256bV256dUi"
10527 .target_set = TargetSet.initOne(.vevl_gen)
10528
10529__builtin_ve_vl_vfmklge_mvml
10530 .param_str = "V256bV256dV256bUi"
10531 .target_set = TargetSet.initOne(.vevl_gen)
10532
10533__builtin_ve_vl_vfmklgenan_mvl
10534 .param_str = "V256bV256dUi"
10535 .target_set = TargetSet.initOne(.vevl_gen)
10536
10537__builtin_ve_vl_vfmklgenan_mvml
10538 .param_str = "V256bV256dV256bUi"
10539 .target_set = TargetSet.initOne(.vevl_gen)
10540
10541__builtin_ve_vl_vfmklgt_mvl
10542 .param_str = "V256bV256dUi"
10543 .target_set = TargetSet.initOne(.vevl_gen)
10544
10545__builtin_ve_vl_vfmklgt_mvml
10546 .param_str = "V256bV256dV256bUi"
10547 .target_set = TargetSet.initOne(.vevl_gen)
10548
10549__builtin_ve_vl_vfmklgtnan_mvl
10550 .param_str = "V256bV256dUi"
10551 .target_set = TargetSet.initOne(.vevl_gen)
10552
10553__builtin_ve_vl_vfmklgtnan_mvml
10554 .param_str = "V256bV256dV256bUi"
10555 .target_set = TargetSet.initOne(.vevl_gen)
10556
10557__builtin_ve_vl_vfmklle_mvl
10558 .param_str = "V256bV256dUi"
10559 .target_set = TargetSet.initOne(.vevl_gen)
10560
10561__builtin_ve_vl_vfmklle_mvml
10562 .param_str = "V256bV256dV256bUi"
10563 .target_set = TargetSet.initOne(.vevl_gen)
10564
10565__builtin_ve_vl_vfmkllenan_mvl
10566 .param_str = "V256bV256dUi"
10567 .target_set = TargetSet.initOne(.vevl_gen)
10568
10569__builtin_ve_vl_vfmkllenan_mvml
10570 .param_str = "V256bV256dV256bUi"
10571 .target_set = TargetSet.initOne(.vevl_gen)
10572
10573__builtin_ve_vl_vfmkllt_mvl
10574 .param_str = "V256bV256dUi"
10575 .target_set = TargetSet.initOne(.vevl_gen)
10576
10577__builtin_ve_vl_vfmkllt_mvml
10578 .param_str = "V256bV256dV256bUi"
10579 .target_set = TargetSet.initOne(.vevl_gen)
10580
10581__builtin_ve_vl_vfmklltnan_mvl
10582 .param_str = "V256bV256dUi"
10583 .target_set = TargetSet.initOne(.vevl_gen)
10584
10585__builtin_ve_vl_vfmklltnan_mvml
10586 .param_str = "V256bV256dV256bUi"
10587 .target_set = TargetSet.initOne(.vevl_gen)
10588
10589__builtin_ve_vl_vfmklnan_mvl
10590 .param_str = "V256bV256dUi"
10591 .target_set = TargetSet.initOne(.vevl_gen)
10592
10593__builtin_ve_vl_vfmklnan_mvml
10594 .param_str = "V256bV256dV256bUi"
10595 .target_set = TargetSet.initOne(.vevl_gen)
10596
10597__builtin_ve_vl_vfmklne_mvl
10598 .param_str = "V256bV256dUi"
10599 .target_set = TargetSet.initOne(.vevl_gen)
10600
10601__builtin_ve_vl_vfmklne_mvml
10602 .param_str = "V256bV256dV256bUi"
10603 .target_set = TargetSet.initOne(.vevl_gen)
10604
10605__builtin_ve_vl_vfmklnenan_mvl
10606 .param_str = "V256bV256dUi"
10607 .target_set = TargetSet.initOne(.vevl_gen)
10608
10609__builtin_ve_vl_vfmklnenan_mvml
10610 .param_str = "V256bV256dV256bUi"
10611 .target_set = TargetSet.initOne(.vevl_gen)
10612
10613__builtin_ve_vl_vfmklnum_mvl
10614 .param_str = "V256bV256dUi"
10615 .target_set = TargetSet.initOne(.vevl_gen)
10616
10617__builtin_ve_vl_vfmklnum_mvml
10618 .param_str = "V256bV256dV256bUi"
10619 .target_set = TargetSet.initOne(.vevl_gen)
10620
10621__builtin_ve_vl_vfmkseq_mvl
10622 .param_str = "V256bV256dUi"
10623 .target_set = TargetSet.initOne(.vevl_gen)
10624
10625__builtin_ve_vl_vfmkseq_mvml
10626 .param_str = "V256bV256dV256bUi"
10627 .target_set = TargetSet.initOne(.vevl_gen)
10628
10629__builtin_ve_vl_vfmkseqnan_mvl
10630 .param_str = "V256bV256dUi"
10631 .target_set = TargetSet.initOne(.vevl_gen)
10632
10633__builtin_ve_vl_vfmkseqnan_mvml
10634 .param_str = "V256bV256dV256bUi"
10635 .target_set = TargetSet.initOne(.vevl_gen)
10636
10637__builtin_ve_vl_vfmksge_mvl
10638 .param_str = "V256bV256dUi"
10639 .target_set = TargetSet.initOne(.vevl_gen)
10640
10641__builtin_ve_vl_vfmksge_mvml
10642 .param_str = "V256bV256dV256bUi"
10643 .target_set = TargetSet.initOne(.vevl_gen)
10644
10645__builtin_ve_vl_vfmksgenan_mvl
10646 .param_str = "V256bV256dUi"
10647 .target_set = TargetSet.initOne(.vevl_gen)
10648
10649__builtin_ve_vl_vfmksgenan_mvml
10650 .param_str = "V256bV256dV256bUi"
10651 .target_set = TargetSet.initOne(.vevl_gen)
10652
10653__builtin_ve_vl_vfmksgt_mvl
10654 .param_str = "V256bV256dUi"
10655 .target_set = TargetSet.initOne(.vevl_gen)
10656
10657__builtin_ve_vl_vfmksgt_mvml
10658 .param_str = "V256bV256dV256bUi"
10659 .target_set = TargetSet.initOne(.vevl_gen)
10660
10661__builtin_ve_vl_vfmksgtnan_mvl
10662 .param_str = "V256bV256dUi"
10663 .target_set = TargetSet.initOne(.vevl_gen)
10664
10665__builtin_ve_vl_vfmksgtnan_mvml
10666 .param_str = "V256bV256dV256bUi"
10667 .target_set = TargetSet.initOne(.vevl_gen)
10668
10669__builtin_ve_vl_vfmksle_mvl
10670 .param_str = "V256bV256dUi"
10671 .target_set = TargetSet.initOne(.vevl_gen)
10672
10673__builtin_ve_vl_vfmksle_mvml
10674 .param_str = "V256bV256dV256bUi"
10675 .target_set = TargetSet.initOne(.vevl_gen)
10676
10677__builtin_ve_vl_vfmkslenan_mvl
10678 .param_str = "V256bV256dUi"
10679 .target_set = TargetSet.initOne(.vevl_gen)
10680
10681__builtin_ve_vl_vfmkslenan_mvml
10682 .param_str = "V256bV256dV256bUi"
10683 .target_set = TargetSet.initOne(.vevl_gen)
10684
10685__builtin_ve_vl_vfmkslt_mvl
10686 .param_str = "V256bV256dUi"
10687 .target_set = TargetSet.initOne(.vevl_gen)
10688
10689__builtin_ve_vl_vfmkslt_mvml
10690 .param_str = "V256bV256dV256bUi"
10691 .target_set = TargetSet.initOne(.vevl_gen)
10692
10693__builtin_ve_vl_vfmksltnan_mvl
10694 .param_str = "V256bV256dUi"
10695 .target_set = TargetSet.initOne(.vevl_gen)
10696
10697__builtin_ve_vl_vfmksltnan_mvml
10698 .param_str = "V256bV256dV256bUi"
10699 .target_set = TargetSet.initOne(.vevl_gen)
10700
10701__builtin_ve_vl_vfmksnan_mvl
10702 .param_str = "V256bV256dUi"
10703 .target_set = TargetSet.initOne(.vevl_gen)
10704
10705__builtin_ve_vl_vfmksnan_mvml
10706 .param_str = "V256bV256dV256bUi"
10707 .target_set = TargetSet.initOne(.vevl_gen)
10708
10709__builtin_ve_vl_vfmksne_mvl
10710 .param_str = "V256bV256dUi"
10711 .target_set = TargetSet.initOne(.vevl_gen)
10712
10713__builtin_ve_vl_vfmksne_mvml
10714 .param_str = "V256bV256dV256bUi"
10715 .target_set = TargetSet.initOne(.vevl_gen)
10716
10717__builtin_ve_vl_vfmksnenan_mvl
10718 .param_str = "V256bV256dUi"
10719 .target_set = TargetSet.initOne(.vevl_gen)
10720
10721__builtin_ve_vl_vfmksnenan_mvml
10722 .param_str = "V256bV256dV256bUi"
10723 .target_set = TargetSet.initOne(.vevl_gen)
10724
10725__builtin_ve_vl_vfmksnum_mvl
10726 .param_str = "V256bV256dUi"
10727 .target_set = TargetSet.initOne(.vevl_gen)
10728
10729__builtin_ve_vl_vfmksnum_mvml
10730 .param_str = "V256bV256dV256bUi"
10731 .target_set = TargetSet.initOne(.vevl_gen)
10732
10733__builtin_ve_vl_vfmkweq_mvl
10734 .param_str = "V256bV256dUi"
10735 .target_set = TargetSet.initOne(.vevl_gen)
10736
10737__builtin_ve_vl_vfmkweq_mvml
10738 .param_str = "V256bV256dV256bUi"
10739 .target_set = TargetSet.initOne(.vevl_gen)
10740
10741__builtin_ve_vl_vfmkweqnan_mvl
10742 .param_str = "V256bV256dUi"
10743 .target_set = TargetSet.initOne(.vevl_gen)
10744
10745__builtin_ve_vl_vfmkweqnan_mvml
10746 .param_str = "V256bV256dV256bUi"
10747 .target_set = TargetSet.initOne(.vevl_gen)
10748
10749__builtin_ve_vl_vfmkwge_mvl
10750 .param_str = "V256bV256dUi"
10751 .target_set = TargetSet.initOne(.vevl_gen)
10752
10753__builtin_ve_vl_vfmkwge_mvml
10754 .param_str = "V256bV256dV256bUi"
10755 .target_set = TargetSet.initOne(.vevl_gen)
10756
10757__builtin_ve_vl_vfmkwgenan_mvl
10758 .param_str = "V256bV256dUi"
10759 .target_set = TargetSet.initOne(.vevl_gen)
10760
10761__builtin_ve_vl_vfmkwgenan_mvml
10762 .param_str = "V256bV256dV256bUi"
10763 .target_set = TargetSet.initOne(.vevl_gen)
10764
10765__builtin_ve_vl_vfmkwgt_mvl
10766 .param_str = "V256bV256dUi"
10767 .target_set = TargetSet.initOne(.vevl_gen)
10768
10769__builtin_ve_vl_vfmkwgt_mvml
10770 .param_str = "V256bV256dV256bUi"
10771 .target_set = TargetSet.initOne(.vevl_gen)
10772
10773__builtin_ve_vl_vfmkwgtnan_mvl
10774 .param_str = "V256bV256dUi"
10775 .target_set = TargetSet.initOne(.vevl_gen)
10776
10777__builtin_ve_vl_vfmkwgtnan_mvml
10778 .param_str = "V256bV256dV256bUi"
10779 .target_set = TargetSet.initOne(.vevl_gen)
10780
10781__builtin_ve_vl_vfmkwle_mvl
10782 .param_str = "V256bV256dUi"
10783 .target_set = TargetSet.initOne(.vevl_gen)
10784
10785__builtin_ve_vl_vfmkwle_mvml
10786 .param_str = "V256bV256dV256bUi"
10787 .target_set = TargetSet.initOne(.vevl_gen)
10788
10789__builtin_ve_vl_vfmkwlenan_mvl
10790 .param_str = "V256bV256dUi"
10791 .target_set = TargetSet.initOne(.vevl_gen)
10792
10793__builtin_ve_vl_vfmkwlenan_mvml
10794 .param_str = "V256bV256dV256bUi"
10795 .target_set = TargetSet.initOne(.vevl_gen)
10796
10797__builtin_ve_vl_vfmkwlt_mvl
10798 .param_str = "V256bV256dUi"
10799 .target_set = TargetSet.initOne(.vevl_gen)
10800
10801__builtin_ve_vl_vfmkwlt_mvml
10802 .param_str = "V256bV256dV256bUi"
10803 .target_set = TargetSet.initOne(.vevl_gen)
10804
10805__builtin_ve_vl_vfmkwltnan_mvl
10806 .param_str = "V256bV256dUi"
10807 .target_set = TargetSet.initOne(.vevl_gen)
10808
10809__builtin_ve_vl_vfmkwltnan_mvml
10810 .param_str = "V256bV256dV256bUi"
10811 .target_set = TargetSet.initOne(.vevl_gen)
10812
10813__builtin_ve_vl_vfmkwnan_mvl
10814 .param_str = "V256bV256dUi"
10815 .target_set = TargetSet.initOne(.vevl_gen)
10816
10817__builtin_ve_vl_vfmkwnan_mvml
10818 .param_str = "V256bV256dV256bUi"
10819 .target_set = TargetSet.initOne(.vevl_gen)
10820
10821__builtin_ve_vl_vfmkwne_mvl
10822 .param_str = "V256bV256dUi"
10823 .target_set = TargetSet.initOne(.vevl_gen)
10824
10825__builtin_ve_vl_vfmkwne_mvml
10826 .param_str = "V256bV256dV256bUi"
10827 .target_set = TargetSet.initOne(.vevl_gen)
10828
10829__builtin_ve_vl_vfmkwnenan_mvl
10830 .param_str = "V256bV256dUi"
10831 .target_set = TargetSet.initOne(.vevl_gen)
10832
10833__builtin_ve_vl_vfmkwnenan_mvml
10834 .param_str = "V256bV256dV256bUi"
10835 .target_set = TargetSet.initOne(.vevl_gen)
10836
10837__builtin_ve_vl_vfmkwnum_mvl
10838 .param_str = "V256bV256dUi"
10839 .target_set = TargetSet.initOne(.vevl_gen)
10840
10841__builtin_ve_vl_vfmkwnum_mvml
10842 .param_str = "V256bV256dV256bUi"
10843 .target_set = TargetSet.initOne(.vevl_gen)
10844
10845__builtin_ve_vl_vfmsbd_vsvvl
10846 .param_str = "V256ddV256dV256dUi"
10847 .target_set = TargetSet.initOne(.vevl_gen)
10848
10849__builtin_ve_vl_vfmsbd_vsvvmvl
10850 .param_str = "V256ddV256dV256dV256bV256dUi"
10851 .target_set = TargetSet.initOne(.vevl_gen)
10852
10853__builtin_ve_vl_vfmsbd_vsvvvl
10854 .param_str = "V256ddV256dV256dV256dUi"
10855 .target_set = TargetSet.initOne(.vevl_gen)
10856
10857__builtin_ve_vl_vfmsbd_vvsvl
10858 .param_str = "V256dV256ddV256dUi"
10859 .target_set = TargetSet.initOne(.vevl_gen)
10860
10861__builtin_ve_vl_vfmsbd_vvsvmvl
10862 .param_str = "V256dV256ddV256dV256bV256dUi"
10863 .target_set = TargetSet.initOne(.vevl_gen)
10864
10865__builtin_ve_vl_vfmsbd_vvsvvl
10866 .param_str = "V256dV256ddV256dV256dUi"
10867 .target_set = TargetSet.initOne(.vevl_gen)
10868
10869__builtin_ve_vl_vfmsbd_vvvvl
10870 .param_str = "V256dV256dV256dV256dUi"
10871 .target_set = TargetSet.initOne(.vevl_gen)
10872
10873__builtin_ve_vl_vfmsbd_vvvvmvl
10874 .param_str = "V256dV256dV256dV256dV256bV256dUi"
10875 .target_set = TargetSet.initOne(.vevl_gen)
10876
10877__builtin_ve_vl_vfmsbd_vvvvvl
10878 .param_str = "V256dV256dV256dV256dV256dUi"
10879 .target_set = TargetSet.initOne(.vevl_gen)
10880
10881__builtin_ve_vl_vfmsbs_vsvvl
10882 .param_str = "V256dfV256dV256dUi"
10883 .target_set = TargetSet.initOne(.vevl_gen)
10884
10885__builtin_ve_vl_vfmsbs_vsvvmvl
10886 .param_str = "V256dfV256dV256dV256bV256dUi"
10887 .target_set = TargetSet.initOne(.vevl_gen)
10888
10889__builtin_ve_vl_vfmsbs_vsvvvl
10890 .param_str = "V256dfV256dV256dV256dUi"
10891 .target_set = TargetSet.initOne(.vevl_gen)
10892
10893__builtin_ve_vl_vfmsbs_vvsvl
10894 .param_str = "V256dV256dfV256dUi"
10895 .target_set = TargetSet.initOne(.vevl_gen)
10896
10897__builtin_ve_vl_vfmsbs_vvsvmvl
10898 .param_str = "V256dV256dfV256dV256bV256dUi"
10899 .target_set = TargetSet.initOne(.vevl_gen)
10900
10901__builtin_ve_vl_vfmsbs_vvsvvl
10902 .param_str = "V256dV256dfV256dV256dUi"
10903 .target_set = TargetSet.initOne(.vevl_gen)
10904
10905__builtin_ve_vl_vfmsbs_vvvvl
10906 .param_str = "V256dV256dV256dV256dUi"
10907 .target_set = TargetSet.initOne(.vevl_gen)
10908
10909__builtin_ve_vl_vfmsbs_vvvvmvl
10910 .param_str = "V256dV256dV256dV256dV256bV256dUi"
10911 .target_set = TargetSet.initOne(.vevl_gen)
10912
10913__builtin_ve_vl_vfmsbs_vvvvvl
10914 .param_str = "V256dV256dV256dV256dV256dUi"
10915 .target_set = TargetSet.initOne(.vevl_gen)
10916
10917__builtin_ve_vl_vfmuld_vsvl
10918 .param_str = "V256ddV256dUi"
10919 .target_set = TargetSet.initOne(.vevl_gen)
10920
10921__builtin_ve_vl_vfmuld_vsvmvl
10922 .param_str = "V256ddV256dV256bV256dUi"
10923 .target_set = TargetSet.initOne(.vevl_gen)
10924
10925__builtin_ve_vl_vfmuld_vsvvl
10926 .param_str = "V256ddV256dV256dUi"
10927 .target_set = TargetSet.initOne(.vevl_gen)
10928
10929__builtin_ve_vl_vfmuld_vvvl
10930 .param_str = "V256dV256dV256dUi"
10931 .target_set = TargetSet.initOne(.vevl_gen)
10932
10933__builtin_ve_vl_vfmuld_vvvmvl
10934 .param_str = "V256dV256dV256dV256bV256dUi"
10935 .target_set = TargetSet.initOne(.vevl_gen)
10936
10937__builtin_ve_vl_vfmuld_vvvvl
10938 .param_str = "V256dV256dV256dV256dUi"
10939 .target_set = TargetSet.initOne(.vevl_gen)
10940
10941__builtin_ve_vl_vfmuls_vsvl
10942 .param_str = "V256dfV256dUi"
10943 .target_set = TargetSet.initOne(.vevl_gen)
10944
10945__builtin_ve_vl_vfmuls_vsvmvl
10946 .param_str = "V256dfV256dV256bV256dUi"
10947 .target_set = TargetSet.initOne(.vevl_gen)
10948
10949__builtin_ve_vl_vfmuls_vsvvl
10950 .param_str = "V256dfV256dV256dUi"
10951 .target_set = TargetSet.initOne(.vevl_gen)
10952
10953__builtin_ve_vl_vfmuls_vvvl
10954 .param_str = "V256dV256dV256dUi"
10955 .target_set = TargetSet.initOne(.vevl_gen)
10956
10957__builtin_ve_vl_vfmuls_vvvmvl
10958 .param_str = "V256dV256dV256dV256bV256dUi"
10959 .target_set = TargetSet.initOne(.vevl_gen)
10960
10961__builtin_ve_vl_vfmuls_vvvvl
10962 .param_str = "V256dV256dV256dV256dUi"
10963 .target_set = TargetSet.initOne(.vevl_gen)
10964
10965__builtin_ve_vl_vfnmadd_vsvvl
10966 .param_str = "V256ddV256dV256dUi"
10967 .target_set = TargetSet.initOne(.vevl_gen)
10968
10969__builtin_ve_vl_vfnmadd_vsvvmvl
10970 .param_str = "V256ddV256dV256dV256bV256dUi"
10971 .target_set = TargetSet.initOne(.vevl_gen)
10972
10973__builtin_ve_vl_vfnmadd_vsvvvl
10974 .param_str = "V256ddV256dV256dV256dUi"
10975 .target_set = TargetSet.initOne(.vevl_gen)
10976
10977__builtin_ve_vl_vfnmadd_vvsvl
10978 .param_str = "V256dV256ddV256dUi"
10979 .target_set = TargetSet.initOne(.vevl_gen)
10980
10981__builtin_ve_vl_vfnmadd_vvsvmvl
10982 .param_str = "V256dV256ddV256dV256bV256dUi"
10983 .target_set = TargetSet.initOne(.vevl_gen)
10984
10985__builtin_ve_vl_vfnmadd_vvsvvl
10986 .param_str = "V256dV256ddV256dV256dUi"
10987 .target_set = TargetSet.initOne(.vevl_gen)
10988
10989__builtin_ve_vl_vfnmadd_vvvvl
10990 .param_str = "V256dV256dV256dV256dUi"
10991 .target_set = TargetSet.initOne(.vevl_gen)
10992
10993__builtin_ve_vl_vfnmadd_vvvvmvl
10994 .param_str = "V256dV256dV256dV256dV256bV256dUi"
10995 .target_set = TargetSet.initOne(.vevl_gen)
10996
10997__builtin_ve_vl_vfnmadd_vvvvvl
10998 .param_str = "V256dV256dV256dV256dV256dUi"
10999 .target_set = TargetSet.initOne(.vevl_gen)
11000
11001__builtin_ve_vl_vfnmads_vsvvl
11002 .param_str = "V256dfV256dV256dUi"
11003 .target_set = TargetSet.initOne(.vevl_gen)
11004
11005__builtin_ve_vl_vfnmads_vsvvmvl
11006 .param_str = "V256dfV256dV256dV256bV256dUi"
11007 .target_set = TargetSet.initOne(.vevl_gen)
11008
11009__builtin_ve_vl_vfnmads_vsvvvl
11010 .param_str = "V256dfV256dV256dV256dUi"
11011 .target_set = TargetSet.initOne(.vevl_gen)
11012
11013__builtin_ve_vl_vfnmads_vvsvl
11014 .param_str = "V256dV256dfV256dUi"
11015 .target_set = TargetSet.initOne(.vevl_gen)
11016
11017__builtin_ve_vl_vfnmads_vvsvmvl
11018 .param_str = "V256dV256dfV256dV256bV256dUi"
11019 .target_set = TargetSet.initOne(.vevl_gen)
11020
11021__builtin_ve_vl_vfnmads_vvsvvl
11022 .param_str = "V256dV256dfV256dV256dUi"
11023 .target_set = TargetSet.initOne(.vevl_gen)
11024
11025__builtin_ve_vl_vfnmads_vvvvl
11026 .param_str = "V256dV256dV256dV256dUi"
11027 .target_set = TargetSet.initOne(.vevl_gen)
11028
11029__builtin_ve_vl_vfnmads_vvvvmvl
11030 .param_str = "V256dV256dV256dV256dV256bV256dUi"
11031 .target_set = TargetSet.initOne(.vevl_gen)
11032
11033__builtin_ve_vl_vfnmads_vvvvvl
11034 .param_str = "V256dV256dV256dV256dV256dUi"
11035 .target_set = TargetSet.initOne(.vevl_gen)
11036
11037__builtin_ve_vl_vfnmsbd_vsvvl
11038 .param_str = "V256ddV256dV256dUi"
11039 .target_set = TargetSet.initOne(.vevl_gen)
11040
11041__builtin_ve_vl_vfnmsbd_vsvvmvl
11042 .param_str = "V256ddV256dV256dV256bV256dUi"
11043 .target_set = TargetSet.initOne(.vevl_gen)
11044
11045__builtin_ve_vl_vfnmsbd_vsvvvl
11046 .param_str = "V256ddV256dV256dV256dUi"
11047 .target_set = TargetSet.initOne(.vevl_gen)
11048
11049__builtin_ve_vl_vfnmsbd_vvsvl
11050 .param_str = "V256dV256ddV256dUi"
11051 .target_set = TargetSet.initOne(.vevl_gen)
11052
11053__builtin_ve_vl_vfnmsbd_vvsvmvl
11054 .param_str = "V256dV256ddV256dV256bV256dUi"
11055 .target_set = TargetSet.initOne(.vevl_gen)
11056
11057__builtin_ve_vl_vfnmsbd_vvsvvl
11058 .param_str = "V256dV256ddV256dV256dUi"
11059 .target_set = TargetSet.initOne(.vevl_gen)
11060
11061__builtin_ve_vl_vfnmsbd_vvvvl
11062 .param_str = "V256dV256dV256dV256dUi"
11063 .target_set = TargetSet.initOne(.vevl_gen)
11064
11065__builtin_ve_vl_vfnmsbd_vvvvmvl
11066 .param_str = "V256dV256dV256dV256dV256bV256dUi"
11067 .target_set = TargetSet.initOne(.vevl_gen)
11068
11069__builtin_ve_vl_vfnmsbd_vvvvvl
11070 .param_str = "V256dV256dV256dV256dV256dUi"
11071 .target_set = TargetSet.initOne(.vevl_gen)
11072
11073__builtin_ve_vl_vfnmsbs_vsvvl
11074 .param_str = "V256dfV256dV256dUi"
11075 .target_set = TargetSet.initOne(.vevl_gen)
11076
11077__builtin_ve_vl_vfnmsbs_vsvvmvl
11078 .param_str = "V256dfV256dV256dV256bV256dUi"
11079 .target_set = TargetSet.initOne(.vevl_gen)
11080
11081__builtin_ve_vl_vfnmsbs_vsvvvl
11082 .param_str = "V256dfV256dV256dV256dUi"
11083 .target_set = TargetSet.initOne(.vevl_gen)
11084
11085__builtin_ve_vl_vfnmsbs_vvsvl
11086 .param_str = "V256dV256dfV256dUi"
11087 .target_set = TargetSet.initOne(.vevl_gen)
11088
11089__builtin_ve_vl_vfnmsbs_vvsvmvl
11090 .param_str = "V256dV256dfV256dV256bV256dUi"
11091 .target_set = TargetSet.initOne(.vevl_gen)
11092
11093__builtin_ve_vl_vfnmsbs_vvsvvl
11094 .param_str = "V256dV256dfV256dV256dUi"
11095 .target_set = TargetSet.initOne(.vevl_gen)
11096
11097__builtin_ve_vl_vfnmsbs_vvvvl
11098 .param_str = "V256dV256dV256dV256dUi"
11099 .target_set = TargetSet.initOne(.vevl_gen)
11100
11101__builtin_ve_vl_vfnmsbs_vvvvmvl
11102 .param_str = "V256dV256dV256dV256dV256bV256dUi"
11103 .target_set = TargetSet.initOne(.vevl_gen)
11104
11105__builtin_ve_vl_vfnmsbs_vvvvvl
11106 .param_str = "V256dV256dV256dV256dV256dUi"
11107 .target_set = TargetSet.initOne(.vevl_gen)
11108
11109__builtin_ve_vl_vfrmaxdfst_vvl
11110 .param_str = "V256dV256dUi"
11111 .target_set = TargetSet.initOne(.vevl_gen)
11112
11113__builtin_ve_vl_vfrmaxdfst_vvvl
11114 .param_str = "V256dV256dV256dUi"
11115 .target_set = TargetSet.initOne(.vevl_gen)
11116
11117__builtin_ve_vl_vfrmaxdlst_vvl
11118 .param_str = "V256dV256dUi"
11119 .target_set = TargetSet.initOne(.vevl_gen)
11120
11121__builtin_ve_vl_vfrmaxdlst_vvvl
11122 .param_str = "V256dV256dV256dUi"
11123 .target_set = TargetSet.initOne(.vevl_gen)
11124
11125__builtin_ve_vl_vfrmaxsfst_vvl
11126 .param_str = "V256dV256dUi"
11127 .target_set = TargetSet.initOne(.vevl_gen)
11128
11129__builtin_ve_vl_vfrmaxsfst_vvvl
11130 .param_str = "V256dV256dV256dUi"
11131 .target_set = TargetSet.initOne(.vevl_gen)
11132
11133__builtin_ve_vl_vfrmaxslst_vvl
11134 .param_str = "V256dV256dUi"
11135 .target_set = TargetSet.initOne(.vevl_gen)
11136
11137__builtin_ve_vl_vfrmaxslst_vvvl
11138 .param_str = "V256dV256dV256dUi"
11139 .target_set = TargetSet.initOne(.vevl_gen)
11140
11141__builtin_ve_vl_vfrmindfst_vvl
11142 .param_str = "V256dV256dUi"
11143 .target_set = TargetSet.initOne(.vevl_gen)
11144
11145__builtin_ve_vl_vfrmindfst_vvvl
11146 .param_str = "V256dV256dV256dUi"
11147 .target_set = TargetSet.initOne(.vevl_gen)
11148
11149__builtin_ve_vl_vfrmindlst_vvl
11150 .param_str = "V256dV256dUi"
11151 .target_set = TargetSet.initOne(.vevl_gen)
11152
11153__builtin_ve_vl_vfrmindlst_vvvl
11154 .param_str = "V256dV256dV256dUi"
11155 .target_set = TargetSet.initOne(.vevl_gen)
11156
11157__builtin_ve_vl_vfrminsfst_vvl
11158 .param_str = "V256dV256dUi"
11159 .target_set = TargetSet.initOne(.vevl_gen)
11160
11161__builtin_ve_vl_vfrminsfst_vvvl
11162 .param_str = "V256dV256dV256dUi"
11163 .target_set = TargetSet.initOne(.vevl_gen)
11164
11165__builtin_ve_vl_vfrminslst_vvl
11166 .param_str = "V256dV256dUi"
11167 .target_set = TargetSet.initOne(.vevl_gen)
11168
11169__builtin_ve_vl_vfrminslst_vvvl
11170 .param_str = "V256dV256dV256dUi"
11171 .target_set = TargetSet.initOne(.vevl_gen)
11172
11173__builtin_ve_vl_vfsqrtd_vvl
11174 .param_str = "V256dV256dUi"
11175 .target_set = TargetSet.initOne(.vevl_gen)
11176
11177__builtin_ve_vl_vfsqrtd_vvvl
11178 .param_str = "V256dV256dV256dUi"
11179 .target_set = TargetSet.initOne(.vevl_gen)
11180
11181__builtin_ve_vl_vfsqrts_vvl
11182 .param_str = "V256dV256dUi"
11183 .target_set = TargetSet.initOne(.vevl_gen)
11184
11185__builtin_ve_vl_vfsqrts_vvvl
11186 .param_str = "V256dV256dV256dUi"
11187 .target_set = TargetSet.initOne(.vevl_gen)
11188
11189__builtin_ve_vl_vfsubd_vsvl
11190 .param_str = "V256ddV256dUi"
11191 .target_set = TargetSet.initOne(.vevl_gen)
11192
11193__builtin_ve_vl_vfsubd_vsvmvl
11194 .param_str = "V256ddV256dV256bV256dUi"
11195 .target_set = TargetSet.initOne(.vevl_gen)
11196
11197__builtin_ve_vl_vfsubd_vsvvl
11198 .param_str = "V256ddV256dV256dUi"
11199 .target_set = TargetSet.initOne(.vevl_gen)
11200
11201__builtin_ve_vl_vfsubd_vvvl
11202 .param_str = "V256dV256dV256dUi"
11203 .target_set = TargetSet.initOne(.vevl_gen)
11204
11205__builtin_ve_vl_vfsubd_vvvmvl
11206 .param_str = "V256dV256dV256dV256bV256dUi"
11207 .target_set = TargetSet.initOne(.vevl_gen)
11208
11209__builtin_ve_vl_vfsubd_vvvvl
11210 .param_str = "V256dV256dV256dV256dUi"
11211 .target_set = TargetSet.initOne(.vevl_gen)
11212
11213__builtin_ve_vl_vfsubs_vsvl
11214 .param_str = "V256dfV256dUi"
11215 .target_set = TargetSet.initOne(.vevl_gen)
11216
11217__builtin_ve_vl_vfsubs_vsvmvl
11218 .param_str = "V256dfV256dV256bV256dUi"
11219 .target_set = TargetSet.initOne(.vevl_gen)
11220
11221__builtin_ve_vl_vfsubs_vsvvl
11222 .param_str = "V256dfV256dV256dUi"
11223 .target_set = TargetSet.initOne(.vevl_gen)
11224
11225__builtin_ve_vl_vfsubs_vvvl
11226 .param_str = "V256dV256dV256dUi"
11227 .target_set = TargetSet.initOne(.vevl_gen)
11228
11229__builtin_ve_vl_vfsubs_vvvmvl
11230 .param_str = "V256dV256dV256dV256bV256dUi"
11231 .target_set = TargetSet.initOne(.vevl_gen)
11232
11233__builtin_ve_vl_vfsubs_vvvvl
11234 .param_str = "V256dV256dV256dV256dUi"
11235 .target_set = TargetSet.initOne(.vevl_gen)
11236
11237__builtin_ve_vl_vfsumd_vvl
11238 .param_str = "V256dV256dUi"
11239 .target_set = TargetSet.initOne(.vevl_gen)
11240
11241__builtin_ve_vl_vfsumd_vvml
11242 .param_str = "V256dV256dV256bUi"
11243 .target_set = TargetSet.initOne(.vevl_gen)
11244
11245__builtin_ve_vl_vfsums_vvl
11246 .param_str = "V256dV256dUi"
11247 .target_set = TargetSet.initOne(.vevl_gen)
11248
11249__builtin_ve_vl_vfsums_vvml
11250 .param_str = "V256dV256dV256bUi"
11251 .target_set = TargetSet.initOne(.vevl_gen)
11252
11253__builtin_ve_vl_vgt_vvssl
11254 .param_str = "V256dV256dLUiLUiUi"
11255 .target_set = TargetSet.initOne(.vevl_gen)
11256
11257__builtin_ve_vl_vgt_vvssml
11258 .param_str = "V256dV256dLUiLUiV256bUi"
11259 .target_set = TargetSet.initOne(.vevl_gen)
11260
11261__builtin_ve_vl_vgt_vvssmvl
11262 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11263 .target_set = TargetSet.initOne(.vevl_gen)
11264
11265__builtin_ve_vl_vgt_vvssvl
11266 .param_str = "V256dV256dLUiLUiV256dUi"
11267 .target_set = TargetSet.initOne(.vevl_gen)
11268
11269__builtin_ve_vl_vgtlsx_vvssl
11270 .param_str = "V256dV256dLUiLUiUi"
11271 .target_set = TargetSet.initOne(.vevl_gen)
11272
11273__builtin_ve_vl_vgtlsx_vvssml
11274 .param_str = "V256dV256dLUiLUiV256bUi"
11275 .target_set = TargetSet.initOne(.vevl_gen)
11276
11277__builtin_ve_vl_vgtlsx_vvssmvl
11278 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11279 .target_set = TargetSet.initOne(.vevl_gen)
11280
11281__builtin_ve_vl_vgtlsx_vvssvl
11282 .param_str = "V256dV256dLUiLUiV256dUi"
11283 .target_set = TargetSet.initOne(.vevl_gen)
11284
11285__builtin_ve_vl_vgtlsxnc_vvssl
11286 .param_str = "V256dV256dLUiLUiUi"
11287 .target_set = TargetSet.initOne(.vevl_gen)
11288
11289__builtin_ve_vl_vgtlsxnc_vvssml
11290 .param_str = "V256dV256dLUiLUiV256bUi"
11291 .target_set = TargetSet.initOne(.vevl_gen)
11292
11293__builtin_ve_vl_vgtlsxnc_vvssmvl
11294 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11295 .target_set = TargetSet.initOne(.vevl_gen)
11296
11297__builtin_ve_vl_vgtlsxnc_vvssvl
11298 .param_str = "V256dV256dLUiLUiV256dUi"
11299 .target_set = TargetSet.initOne(.vevl_gen)
11300
11301__builtin_ve_vl_vgtlzx_vvssl
11302 .param_str = "V256dV256dLUiLUiUi"
11303 .target_set = TargetSet.initOne(.vevl_gen)
11304
11305__builtin_ve_vl_vgtlzx_vvssml
11306 .param_str = "V256dV256dLUiLUiV256bUi"
11307 .target_set = TargetSet.initOne(.vevl_gen)
11308
11309__builtin_ve_vl_vgtlzx_vvssmvl
11310 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11311 .target_set = TargetSet.initOne(.vevl_gen)
11312
11313__builtin_ve_vl_vgtlzx_vvssvl
11314 .param_str = "V256dV256dLUiLUiV256dUi"
11315 .target_set = TargetSet.initOne(.vevl_gen)
11316
11317__builtin_ve_vl_vgtlzxnc_vvssl
11318 .param_str = "V256dV256dLUiLUiUi"
11319 .target_set = TargetSet.initOne(.vevl_gen)
11320
11321__builtin_ve_vl_vgtlzxnc_vvssml
11322 .param_str = "V256dV256dLUiLUiV256bUi"
11323 .target_set = TargetSet.initOne(.vevl_gen)
11324
11325__builtin_ve_vl_vgtlzxnc_vvssmvl
11326 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11327 .target_set = TargetSet.initOne(.vevl_gen)
11328
11329__builtin_ve_vl_vgtlzxnc_vvssvl
11330 .param_str = "V256dV256dLUiLUiV256dUi"
11331 .target_set = TargetSet.initOne(.vevl_gen)
11332
11333__builtin_ve_vl_vgtnc_vvssl
11334 .param_str = "V256dV256dLUiLUiUi"
11335 .target_set = TargetSet.initOne(.vevl_gen)
11336
11337__builtin_ve_vl_vgtnc_vvssml
11338 .param_str = "V256dV256dLUiLUiV256bUi"
11339 .target_set = TargetSet.initOne(.vevl_gen)
11340
11341__builtin_ve_vl_vgtnc_vvssmvl
11342 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11343 .target_set = TargetSet.initOne(.vevl_gen)
11344
11345__builtin_ve_vl_vgtnc_vvssvl
11346 .param_str = "V256dV256dLUiLUiV256dUi"
11347 .target_set = TargetSet.initOne(.vevl_gen)
11348
11349__builtin_ve_vl_vgtu_vvssl
11350 .param_str = "V256dV256dLUiLUiUi"
11351 .target_set = TargetSet.initOne(.vevl_gen)
11352
11353__builtin_ve_vl_vgtu_vvssml
11354 .param_str = "V256dV256dLUiLUiV256bUi"
11355 .target_set = TargetSet.initOne(.vevl_gen)
11356
11357__builtin_ve_vl_vgtu_vvssmvl
11358 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11359 .target_set = TargetSet.initOne(.vevl_gen)
11360
11361__builtin_ve_vl_vgtu_vvssvl
11362 .param_str = "V256dV256dLUiLUiV256dUi"
11363 .target_set = TargetSet.initOne(.vevl_gen)
11364
11365__builtin_ve_vl_vgtunc_vvssl
11366 .param_str = "V256dV256dLUiLUiUi"
11367 .target_set = TargetSet.initOne(.vevl_gen)
11368
11369__builtin_ve_vl_vgtunc_vvssml
11370 .param_str = "V256dV256dLUiLUiV256bUi"
11371 .target_set = TargetSet.initOne(.vevl_gen)
11372
11373__builtin_ve_vl_vgtunc_vvssmvl
11374 .param_str = "V256dV256dLUiLUiV256bV256dUi"
11375 .target_set = TargetSet.initOne(.vevl_gen)
11376
11377__builtin_ve_vl_vgtunc_vvssvl
11378 .param_str = "V256dV256dLUiLUiV256dUi"
11379 .target_set = TargetSet.initOne(.vevl_gen)
11380
11381__builtin_ve_vl_vld2d_vssl
11382 .param_str = "V256dLUivC*Ui"
11383 .target_set = TargetSet.initOne(.vevl_gen)
11384
11385__builtin_ve_vl_vld2d_vssvl
11386 .param_str = "V256dLUivC*V256dUi"
11387 .target_set = TargetSet.initOne(.vevl_gen)
11388
11389__builtin_ve_vl_vld2dnc_vssl
11390 .param_str = "V256dLUivC*Ui"
11391 .target_set = TargetSet.initOne(.vevl_gen)
11392
11393__builtin_ve_vl_vld2dnc_vssvl
11394 .param_str = "V256dLUivC*V256dUi"
11395 .target_set = TargetSet.initOne(.vevl_gen)
11396
11397__builtin_ve_vl_vld_vssl
11398 .param_str = "V256dLUivC*Ui"
11399 .target_set = TargetSet.initOne(.vevl_gen)
11400
11401__builtin_ve_vl_vld_vssvl
11402 .param_str = "V256dLUivC*V256dUi"
11403 .target_set = TargetSet.initOne(.vevl_gen)
11404
11405__builtin_ve_vl_vldl2dsx_vssl
11406 .param_str = "V256dLUivC*Ui"
11407 .target_set = TargetSet.initOne(.vevl_gen)
11408
11409__builtin_ve_vl_vldl2dsx_vssvl
11410 .param_str = "V256dLUivC*V256dUi"
11411 .target_set = TargetSet.initOne(.vevl_gen)
11412
11413__builtin_ve_vl_vldl2dsxnc_vssl
11414 .param_str = "V256dLUivC*Ui"
11415 .target_set = TargetSet.initOne(.vevl_gen)
11416
11417__builtin_ve_vl_vldl2dsxnc_vssvl
11418 .param_str = "V256dLUivC*V256dUi"
11419 .target_set = TargetSet.initOne(.vevl_gen)
11420
11421__builtin_ve_vl_vldl2dzx_vssl
11422 .param_str = "V256dLUivC*Ui"
11423 .target_set = TargetSet.initOne(.vevl_gen)
11424
11425__builtin_ve_vl_vldl2dzx_vssvl
11426 .param_str = "V256dLUivC*V256dUi"
11427 .target_set = TargetSet.initOne(.vevl_gen)
11428
11429__builtin_ve_vl_vldl2dzxnc_vssl
11430 .param_str = "V256dLUivC*Ui"
11431 .target_set = TargetSet.initOne(.vevl_gen)
11432
11433__builtin_ve_vl_vldl2dzxnc_vssvl
11434 .param_str = "V256dLUivC*V256dUi"
11435 .target_set = TargetSet.initOne(.vevl_gen)
11436
11437__builtin_ve_vl_vldlsx_vssl
11438 .param_str = "V256dLUivC*Ui"
11439 .target_set = TargetSet.initOne(.vevl_gen)
11440
11441__builtin_ve_vl_vldlsx_vssvl
11442 .param_str = "V256dLUivC*V256dUi"
11443 .target_set = TargetSet.initOne(.vevl_gen)
11444
11445__builtin_ve_vl_vldlsxnc_vssl
11446 .param_str = "V256dLUivC*Ui"
11447 .target_set = TargetSet.initOne(.vevl_gen)
11448
11449__builtin_ve_vl_vldlsxnc_vssvl
11450 .param_str = "V256dLUivC*V256dUi"
11451 .target_set = TargetSet.initOne(.vevl_gen)
11452
11453__builtin_ve_vl_vldlzx_vssl
11454 .param_str = "V256dLUivC*Ui"
11455 .target_set = TargetSet.initOne(.vevl_gen)
11456
11457__builtin_ve_vl_vldlzx_vssvl
11458 .param_str = "V256dLUivC*V256dUi"
11459 .target_set = TargetSet.initOne(.vevl_gen)
11460
11461__builtin_ve_vl_vldlzxnc_vssl
11462 .param_str = "V256dLUivC*Ui"
11463 .target_set = TargetSet.initOne(.vevl_gen)
11464
11465__builtin_ve_vl_vldlzxnc_vssvl
11466 .param_str = "V256dLUivC*V256dUi"
11467 .target_set = TargetSet.initOne(.vevl_gen)
11468
11469__builtin_ve_vl_vldnc_vssl
11470 .param_str = "V256dLUivC*Ui"
11471 .target_set = TargetSet.initOne(.vevl_gen)
11472
11473__builtin_ve_vl_vldnc_vssvl
11474 .param_str = "V256dLUivC*V256dUi"
11475 .target_set = TargetSet.initOne(.vevl_gen)
11476
11477__builtin_ve_vl_vldu2d_vssl
11478 .param_str = "V256dLUivC*Ui"
11479 .target_set = TargetSet.initOne(.vevl_gen)
11480
11481__builtin_ve_vl_vldu2d_vssvl
11482 .param_str = "V256dLUivC*V256dUi"
11483 .target_set = TargetSet.initOne(.vevl_gen)
11484
11485__builtin_ve_vl_vldu2dnc_vssl
11486 .param_str = "V256dLUivC*Ui"
11487 .target_set = TargetSet.initOne(.vevl_gen)
11488
11489__builtin_ve_vl_vldu2dnc_vssvl
11490 .param_str = "V256dLUivC*V256dUi"
11491 .target_set = TargetSet.initOne(.vevl_gen)
11492
11493__builtin_ve_vl_vldu_vssl
11494 .param_str = "V256dLUivC*Ui"
11495 .target_set = TargetSet.initOne(.vevl_gen)
11496
11497__builtin_ve_vl_vldu_vssvl
11498 .param_str = "V256dLUivC*V256dUi"
11499 .target_set = TargetSet.initOne(.vevl_gen)
11500
11501__builtin_ve_vl_vldunc_vssl
11502 .param_str = "V256dLUivC*Ui"
11503 .target_set = TargetSet.initOne(.vevl_gen)
11504
11505__builtin_ve_vl_vldunc_vssvl
11506 .param_str = "V256dLUivC*V256dUi"
11507 .target_set = TargetSet.initOne(.vevl_gen)
11508
11509__builtin_ve_vl_vldz_vvl
11510 .param_str = "V256dV256dUi"
11511 .target_set = TargetSet.initOne(.vevl_gen)
11512
11513__builtin_ve_vl_vldz_vvmvl
11514 .param_str = "V256dV256dV256bV256dUi"
11515 .target_set = TargetSet.initOne(.vevl_gen)
11516
11517__builtin_ve_vl_vldz_vvvl
11518 .param_str = "V256dV256dV256dUi"
11519 .target_set = TargetSet.initOne(.vevl_gen)
11520
11521__builtin_ve_vl_vmaxsl_vsvl
11522 .param_str = "V256dLiV256dUi"
11523 .target_set = TargetSet.initOne(.vevl_gen)
11524
11525__builtin_ve_vl_vmaxsl_vsvmvl
11526 .param_str = "V256dLiV256dV256bV256dUi"
11527 .target_set = TargetSet.initOne(.vevl_gen)
11528
11529__builtin_ve_vl_vmaxsl_vsvvl
11530 .param_str = "V256dLiV256dV256dUi"
11531 .target_set = TargetSet.initOne(.vevl_gen)
11532
11533__builtin_ve_vl_vmaxsl_vvvl
11534 .param_str = "V256dV256dV256dUi"
11535 .target_set = TargetSet.initOne(.vevl_gen)
11536
11537__builtin_ve_vl_vmaxsl_vvvmvl
11538 .param_str = "V256dV256dV256dV256bV256dUi"
11539 .target_set = TargetSet.initOne(.vevl_gen)
11540
11541__builtin_ve_vl_vmaxsl_vvvvl
11542 .param_str = "V256dV256dV256dV256dUi"
11543 .target_set = TargetSet.initOne(.vevl_gen)
11544
11545__builtin_ve_vl_vmaxswsx_vsvl
11546 .param_str = "V256diV256dUi"
11547 .target_set = TargetSet.initOne(.vevl_gen)
11548
11549__builtin_ve_vl_vmaxswsx_vsvmvl
11550 .param_str = "V256diV256dV256bV256dUi"
11551 .target_set = TargetSet.initOne(.vevl_gen)
11552
11553__builtin_ve_vl_vmaxswsx_vsvvl
11554 .param_str = "V256diV256dV256dUi"
11555 .target_set = TargetSet.initOne(.vevl_gen)
11556
11557__builtin_ve_vl_vmaxswsx_vvvl
11558 .param_str = "V256dV256dV256dUi"
11559 .target_set = TargetSet.initOne(.vevl_gen)
11560
11561__builtin_ve_vl_vmaxswsx_vvvmvl
11562 .param_str = "V256dV256dV256dV256bV256dUi"
11563 .target_set = TargetSet.initOne(.vevl_gen)
11564
11565__builtin_ve_vl_vmaxswsx_vvvvl
11566 .param_str = "V256dV256dV256dV256dUi"
11567 .target_set = TargetSet.initOne(.vevl_gen)
11568
11569__builtin_ve_vl_vmaxswzx_vsvl
11570 .param_str = "V256diV256dUi"
11571 .target_set = TargetSet.initOne(.vevl_gen)
11572
11573__builtin_ve_vl_vmaxswzx_vsvmvl
11574 .param_str = "V256diV256dV256bV256dUi"
11575 .target_set = TargetSet.initOne(.vevl_gen)
11576
11577__builtin_ve_vl_vmaxswzx_vsvvl
11578 .param_str = "V256diV256dV256dUi"
11579 .target_set = TargetSet.initOne(.vevl_gen)
11580
11581__builtin_ve_vl_vmaxswzx_vvvl
11582 .param_str = "V256dV256dV256dUi"
11583 .target_set = TargetSet.initOne(.vevl_gen)
11584
11585__builtin_ve_vl_vmaxswzx_vvvmvl
11586 .param_str = "V256dV256dV256dV256bV256dUi"
11587 .target_set = TargetSet.initOne(.vevl_gen)
11588
11589__builtin_ve_vl_vmaxswzx_vvvvl
11590 .param_str = "V256dV256dV256dV256dUi"
11591 .target_set = TargetSet.initOne(.vevl_gen)
11592
11593__builtin_ve_vl_vminsl_vsvl
11594 .param_str = "V256dLiV256dUi"
11595 .target_set = TargetSet.initOne(.vevl_gen)
11596
11597__builtin_ve_vl_vminsl_vsvmvl
11598 .param_str = "V256dLiV256dV256bV256dUi"
11599 .target_set = TargetSet.initOne(.vevl_gen)
11600
11601__builtin_ve_vl_vminsl_vsvvl
11602 .param_str = "V256dLiV256dV256dUi"
11603 .target_set = TargetSet.initOne(.vevl_gen)
11604
11605__builtin_ve_vl_vminsl_vvvl
11606 .param_str = "V256dV256dV256dUi"
11607 .target_set = TargetSet.initOne(.vevl_gen)
11608
11609__builtin_ve_vl_vminsl_vvvmvl
11610 .param_str = "V256dV256dV256dV256bV256dUi"
11611 .target_set = TargetSet.initOne(.vevl_gen)
11612
11613__builtin_ve_vl_vminsl_vvvvl
11614 .param_str = "V256dV256dV256dV256dUi"
11615 .target_set = TargetSet.initOne(.vevl_gen)
11616
11617__builtin_ve_vl_vminswsx_vsvl
11618 .param_str = "V256diV256dUi"
11619 .target_set = TargetSet.initOne(.vevl_gen)
11620
11621__builtin_ve_vl_vminswsx_vsvmvl
11622 .param_str = "V256diV256dV256bV256dUi"
11623 .target_set = TargetSet.initOne(.vevl_gen)
11624
11625__builtin_ve_vl_vminswsx_vsvvl
11626 .param_str = "V256diV256dV256dUi"
11627 .target_set = TargetSet.initOne(.vevl_gen)
11628
11629__builtin_ve_vl_vminswsx_vvvl
11630 .param_str = "V256dV256dV256dUi"
11631 .target_set = TargetSet.initOne(.vevl_gen)
11632
11633__builtin_ve_vl_vminswsx_vvvmvl
11634 .param_str = "V256dV256dV256dV256bV256dUi"
11635 .target_set = TargetSet.initOne(.vevl_gen)
11636
11637__builtin_ve_vl_vminswsx_vvvvl
11638 .param_str = "V256dV256dV256dV256dUi"
11639 .target_set = TargetSet.initOne(.vevl_gen)
11640
11641__builtin_ve_vl_vminswzx_vsvl
11642 .param_str = "V256diV256dUi"
11643 .target_set = TargetSet.initOne(.vevl_gen)
11644
11645__builtin_ve_vl_vminswzx_vsvmvl
11646 .param_str = "V256diV256dV256bV256dUi"
11647 .target_set = TargetSet.initOne(.vevl_gen)
11648
11649__builtin_ve_vl_vminswzx_vsvvl
11650 .param_str = "V256diV256dV256dUi"
11651 .target_set = TargetSet.initOne(.vevl_gen)
11652
11653__builtin_ve_vl_vminswzx_vvvl
11654 .param_str = "V256dV256dV256dUi"
11655 .target_set = TargetSet.initOne(.vevl_gen)
11656
11657__builtin_ve_vl_vminswzx_vvvmvl
11658 .param_str = "V256dV256dV256dV256bV256dUi"
11659 .target_set = TargetSet.initOne(.vevl_gen)
11660
11661__builtin_ve_vl_vminswzx_vvvvl
11662 .param_str = "V256dV256dV256dV256dUi"
11663 .target_set = TargetSet.initOne(.vevl_gen)
11664
11665__builtin_ve_vl_vmrg_vsvml
11666 .param_str = "V256dLUiV256dV256bUi"
11667 .target_set = TargetSet.initOne(.vevl_gen)
11668
11669__builtin_ve_vl_vmrg_vsvmvl
11670 .param_str = "V256dLUiV256dV256bV256dUi"
11671 .target_set = TargetSet.initOne(.vevl_gen)
11672
11673__builtin_ve_vl_vmrg_vvvml
11674 .param_str = "V256dV256dV256dV256bUi"
11675 .target_set = TargetSet.initOne(.vevl_gen)
11676
11677__builtin_ve_vl_vmrg_vvvmvl
11678 .param_str = "V256dV256dV256dV256bV256dUi"
11679 .target_set = TargetSet.initOne(.vevl_gen)
11680
11681__builtin_ve_vl_vmrgw_vsvMl
11682 .param_str = "V256dUiV256dV512bUi"
11683 .target_set = TargetSet.initOne(.vevl_gen)
11684
11685__builtin_ve_vl_vmrgw_vsvMvl
11686 .param_str = "V256dUiV256dV512bV256dUi"
11687 .target_set = TargetSet.initOne(.vevl_gen)
11688
11689__builtin_ve_vl_vmrgw_vvvMl
11690 .param_str = "V256dV256dV256dV512bUi"
11691 .target_set = TargetSet.initOne(.vevl_gen)
11692
11693__builtin_ve_vl_vmrgw_vvvMvl
11694 .param_str = "V256dV256dV256dV512bV256dUi"
11695 .target_set = TargetSet.initOne(.vevl_gen)
11696
11697__builtin_ve_vl_vmulsl_vsvl
11698 .param_str = "V256dLiV256dUi"
11699 .target_set = TargetSet.initOne(.vevl_gen)
11700
11701__builtin_ve_vl_vmulsl_vsvmvl
11702 .param_str = "V256dLiV256dV256bV256dUi"
11703 .target_set = TargetSet.initOne(.vevl_gen)
11704
11705__builtin_ve_vl_vmulsl_vsvvl
11706 .param_str = "V256dLiV256dV256dUi"
11707 .target_set = TargetSet.initOne(.vevl_gen)
11708
11709__builtin_ve_vl_vmulsl_vvvl
11710 .param_str = "V256dV256dV256dUi"
11711 .target_set = TargetSet.initOne(.vevl_gen)
11712
11713__builtin_ve_vl_vmulsl_vvvmvl
11714 .param_str = "V256dV256dV256dV256bV256dUi"
11715 .target_set = TargetSet.initOne(.vevl_gen)
11716
11717__builtin_ve_vl_vmulsl_vvvvl
11718 .param_str = "V256dV256dV256dV256dUi"
11719 .target_set = TargetSet.initOne(.vevl_gen)
11720
11721__builtin_ve_vl_vmulslw_vsvl
11722 .param_str = "V256diV256dUi"
11723 .target_set = TargetSet.initOne(.vevl_gen)
11724
11725__builtin_ve_vl_vmulslw_vsvvl
11726 .param_str = "V256diV256dV256dUi"
11727 .target_set = TargetSet.initOne(.vevl_gen)
11728
11729__builtin_ve_vl_vmulslw_vvvl
11730 .param_str = "V256dV256dV256dUi"
11731 .target_set = TargetSet.initOne(.vevl_gen)
11732
11733__builtin_ve_vl_vmulslw_vvvvl
11734 .param_str = "V256dV256dV256dV256dUi"
11735 .target_set = TargetSet.initOne(.vevl_gen)
11736
11737__builtin_ve_vl_vmulswsx_vsvl
11738 .param_str = "V256diV256dUi"
11739 .target_set = TargetSet.initOne(.vevl_gen)
11740
11741__builtin_ve_vl_vmulswsx_vsvmvl
11742 .param_str = "V256diV256dV256bV256dUi"
11743 .target_set = TargetSet.initOne(.vevl_gen)
11744
11745__builtin_ve_vl_vmulswsx_vsvvl
11746 .param_str = "V256diV256dV256dUi"
11747 .target_set = TargetSet.initOne(.vevl_gen)
11748
11749__builtin_ve_vl_vmulswsx_vvvl
11750 .param_str = "V256dV256dV256dUi"
11751 .target_set = TargetSet.initOne(.vevl_gen)
11752
11753__builtin_ve_vl_vmulswsx_vvvmvl
11754 .param_str = "V256dV256dV256dV256bV256dUi"
11755 .target_set = TargetSet.initOne(.vevl_gen)
11756
11757__builtin_ve_vl_vmulswsx_vvvvl
11758 .param_str = "V256dV256dV256dV256dUi"
11759 .target_set = TargetSet.initOne(.vevl_gen)
11760
11761__builtin_ve_vl_vmulswzx_vsvl
11762 .param_str = "V256diV256dUi"
11763 .target_set = TargetSet.initOne(.vevl_gen)
11764
11765__builtin_ve_vl_vmulswzx_vsvmvl
11766 .param_str = "V256diV256dV256bV256dUi"
11767 .target_set = TargetSet.initOne(.vevl_gen)
11768
11769__builtin_ve_vl_vmulswzx_vsvvl
11770 .param_str = "V256diV256dV256dUi"
11771 .target_set = TargetSet.initOne(.vevl_gen)
11772
11773__builtin_ve_vl_vmulswzx_vvvl
11774 .param_str = "V256dV256dV256dUi"
11775 .target_set = TargetSet.initOne(.vevl_gen)
11776
11777__builtin_ve_vl_vmulswzx_vvvmvl
11778 .param_str = "V256dV256dV256dV256bV256dUi"
11779 .target_set = TargetSet.initOne(.vevl_gen)
11780
11781__builtin_ve_vl_vmulswzx_vvvvl
11782 .param_str = "V256dV256dV256dV256dUi"
11783 .target_set = TargetSet.initOne(.vevl_gen)
11784
11785__builtin_ve_vl_vmulul_vsvl
11786 .param_str = "V256dLUiV256dUi"
11787 .target_set = TargetSet.initOne(.vevl_gen)
11788
11789__builtin_ve_vl_vmulul_vsvmvl
11790 .param_str = "V256dLUiV256dV256bV256dUi"
11791 .target_set = TargetSet.initOne(.vevl_gen)
11792
11793__builtin_ve_vl_vmulul_vsvvl
11794 .param_str = "V256dLUiV256dV256dUi"
11795 .target_set = TargetSet.initOne(.vevl_gen)
11796
11797__builtin_ve_vl_vmulul_vvvl
11798 .param_str = "V256dV256dV256dUi"
11799 .target_set = TargetSet.initOne(.vevl_gen)
11800
11801__builtin_ve_vl_vmulul_vvvmvl
11802 .param_str = "V256dV256dV256dV256bV256dUi"
11803 .target_set = TargetSet.initOne(.vevl_gen)
11804
11805__builtin_ve_vl_vmulul_vvvvl
11806 .param_str = "V256dV256dV256dV256dUi"
11807 .target_set = TargetSet.initOne(.vevl_gen)
11808
11809__builtin_ve_vl_vmuluw_vsvl
11810 .param_str = "V256dUiV256dUi"
11811 .target_set = TargetSet.initOne(.vevl_gen)
11812
11813__builtin_ve_vl_vmuluw_vsvmvl
11814 .param_str = "V256dUiV256dV256bV256dUi"
11815 .target_set = TargetSet.initOne(.vevl_gen)
11816
11817__builtin_ve_vl_vmuluw_vsvvl
11818 .param_str = "V256dUiV256dV256dUi"
11819 .target_set = TargetSet.initOne(.vevl_gen)
11820
11821__builtin_ve_vl_vmuluw_vvvl
11822 .param_str = "V256dV256dV256dUi"
11823 .target_set = TargetSet.initOne(.vevl_gen)
11824
11825__builtin_ve_vl_vmuluw_vvvmvl
11826 .param_str = "V256dV256dV256dV256bV256dUi"
11827 .target_set = TargetSet.initOne(.vevl_gen)
11828
11829__builtin_ve_vl_vmuluw_vvvvl
11830 .param_str = "V256dV256dV256dV256dUi"
11831 .target_set = TargetSet.initOne(.vevl_gen)
11832
11833__builtin_ve_vl_vmv_vsvl
11834 .param_str = "V256dUiV256dUi"
11835 .target_set = TargetSet.initOne(.vevl_gen)
11836
11837__builtin_ve_vl_vmv_vsvmvl
11838 .param_str = "V256dUiV256dV256bV256dUi"
11839 .target_set = TargetSet.initOne(.vevl_gen)
11840
11841__builtin_ve_vl_vmv_vsvvl
11842 .param_str = "V256dUiV256dV256dUi"
11843 .target_set = TargetSet.initOne(.vevl_gen)
11844
11845__builtin_ve_vl_vor_vsvl
11846 .param_str = "V256dLUiV256dUi"
11847 .target_set = TargetSet.initOne(.vevl_gen)
11848
11849__builtin_ve_vl_vor_vsvmvl
11850 .param_str = "V256dLUiV256dV256bV256dUi"
11851 .target_set = TargetSet.initOne(.vevl_gen)
11852
11853__builtin_ve_vl_vor_vsvvl
11854 .param_str = "V256dLUiV256dV256dUi"
11855 .target_set = TargetSet.initOne(.vevl_gen)
11856
11857__builtin_ve_vl_vor_vvvl
11858 .param_str = "V256dV256dV256dUi"
11859 .target_set = TargetSet.initOne(.vevl_gen)
11860
11861__builtin_ve_vl_vor_vvvmvl
11862 .param_str = "V256dV256dV256dV256bV256dUi"
11863 .target_set = TargetSet.initOne(.vevl_gen)
11864
11865__builtin_ve_vl_vor_vvvvl
11866 .param_str = "V256dV256dV256dV256dUi"
11867 .target_set = TargetSet.initOne(.vevl_gen)
11868
11869__builtin_ve_vl_vpcnt_vvl
11870 .param_str = "V256dV256dUi"
11871 .target_set = TargetSet.initOne(.vevl_gen)
11872
11873__builtin_ve_vl_vpcnt_vvmvl
11874 .param_str = "V256dV256dV256bV256dUi"
11875 .target_set = TargetSet.initOne(.vevl_gen)
11876
11877__builtin_ve_vl_vpcnt_vvvl
11878 .param_str = "V256dV256dV256dUi"
11879 .target_set = TargetSet.initOne(.vevl_gen)
11880
11881__builtin_ve_vl_vrand_vvl
11882 .param_str = "V256dV256dUi"
11883 .target_set = TargetSet.initOne(.vevl_gen)
11884
11885__builtin_ve_vl_vrand_vvml
11886 .param_str = "V256dV256dV256bUi"
11887 .target_set = TargetSet.initOne(.vevl_gen)
11888
11889__builtin_ve_vl_vrcpd_vvl
11890 .param_str = "V256dV256dUi"
11891 .target_set = TargetSet.initOne(.vevl_gen)
11892
11893__builtin_ve_vl_vrcpd_vvvl
11894 .param_str = "V256dV256dV256dUi"
11895 .target_set = TargetSet.initOne(.vevl_gen)
11896
11897__builtin_ve_vl_vrcps_vvl
11898 .param_str = "V256dV256dUi"
11899 .target_set = TargetSet.initOne(.vevl_gen)
11900
11901__builtin_ve_vl_vrcps_vvvl
11902 .param_str = "V256dV256dV256dUi"
11903 .target_set = TargetSet.initOne(.vevl_gen)
11904
11905__builtin_ve_vl_vrmaxslfst_vvl
11906 .param_str = "V256dV256dUi"
11907 .target_set = TargetSet.initOne(.vevl_gen)
11908
11909__builtin_ve_vl_vrmaxslfst_vvvl
11910 .param_str = "V256dV256dV256dUi"
11911 .target_set = TargetSet.initOne(.vevl_gen)
11912
11913__builtin_ve_vl_vrmaxsllst_vvl
11914 .param_str = "V256dV256dUi"
11915 .target_set = TargetSet.initOne(.vevl_gen)
11916
11917__builtin_ve_vl_vrmaxsllst_vvvl
11918 .param_str = "V256dV256dV256dUi"
11919 .target_set = TargetSet.initOne(.vevl_gen)
11920
11921__builtin_ve_vl_vrmaxswfstsx_vvl
11922 .param_str = "V256dV256dUi"
11923 .target_set = TargetSet.initOne(.vevl_gen)
11924
11925__builtin_ve_vl_vrmaxswfstsx_vvvl
11926 .param_str = "V256dV256dV256dUi"
11927 .target_set = TargetSet.initOne(.vevl_gen)
11928
11929__builtin_ve_vl_vrmaxswfstzx_vvl
11930 .param_str = "V256dV256dUi"
11931 .target_set = TargetSet.initOne(.vevl_gen)
11932
11933__builtin_ve_vl_vrmaxswfstzx_vvvl
11934 .param_str = "V256dV256dV256dUi"
11935 .target_set = TargetSet.initOne(.vevl_gen)
11936
11937__builtin_ve_vl_vrmaxswlstsx_vvl
11938 .param_str = "V256dV256dUi"
11939 .target_set = TargetSet.initOne(.vevl_gen)
11940
11941__builtin_ve_vl_vrmaxswlstsx_vvvl
11942 .param_str = "V256dV256dV256dUi"
11943 .target_set = TargetSet.initOne(.vevl_gen)
11944
11945__builtin_ve_vl_vrmaxswlstzx_vvl
11946 .param_str = "V256dV256dUi"
11947 .target_set = TargetSet.initOne(.vevl_gen)
11948
11949__builtin_ve_vl_vrmaxswlstzx_vvvl
11950 .param_str = "V256dV256dV256dUi"
11951 .target_set = TargetSet.initOne(.vevl_gen)
11952
11953__builtin_ve_vl_vrminslfst_vvl
11954 .param_str = "V256dV256dUi"
11955 .target_set = TargetSet.initOne(.vevl_gen)
11956
11957__builtin_ve_vl_vrminslfst_vvvl
11958 .param_str = "V256dV256dV256dUi"
11959 .target_set = TargetSet.initOne(.vevl_gen)
11960
11961__builtin_ve_vl_vrminsllst_vvl
11962 .param_str = "V256dV256dUi"
11963 .target_set = TargetSet.initOne(.vevl_gen)
11964
11965__builtin_ve_vl_vrminsllst_vvvl
11966 .param_str = "V256dV256dV256dUi"
11967 .target_set = TargetSet.initOne(.vevl_gen)
11968
11969__builtin_ve_vl_vrminswfstsx_vvl
11970 .param_str = "V256dV256dUi"
11971 .target_set = TargetSet.initOne(.vevl_gen)
11972
11973__builtin_ve_vl_vrminswfstsx_vvvl
11974 .param_str = "V256dV256dV256dUi"
11975 .target_set = TargetSet.initOne(.vevl_gen)
11976
11977__builtin_ve_vl_vrminswfstzx_vvl
11978 .param_str = "V256dV256dUi"
11979 .target_set = TargetSet.initOne(.vevl_gen)
11980
11981__builtin_ve_vl_vrminswfstzx_vvvl
11982 .param_str = "V256dV256dV256dUi"
11983 .target_set = TargetSet.initOne(.vevl_gen)
11984
11985__builtin_ve_vl_vrminswlstsx_vvl
11986 .param_str = "V256dV256dUi"
11987 .target_set = TargetSet.initOne(.vevl_gen)
11988
11989__builtin_ve_vl_vrminswlstsx_vvvl
11990 .param_str = "V256dV256dV256dUi"
11991 .target_set = TargetSet.initOne(.vevl_gen)
11992
11993__builtin_ve_vl_vrminswlstzx_vvl
11994 .param_str = "V256dV256dUi"
11995 .target_set = TargetSet.initOne(.vevl_gen)
11996
11997__builtin_ve_vl_vrminswlstzx_vvvl
11998 .param_str = "V256dV256dV256dUi"
11999 .target_set = TargetSet.initOne(.vevl_gen)
12000
12001__builtin_ve_vl_vror_vvl
12002 .param_str = "V256dV256dUi"
12003 .target_set = TargetSet.initOne(.vevl_gen)
12004
12005__builtin_ve_vl_vror_vvml
12006 .param_str = "V256dV256dV256bUi"
12007 .target_set = TargetSet.initOne(.vevl_gen)
12008
12009__builtin_ve_vl_vrsqrtd_vvl
12010 .param_str = "V256dV256dUi"
12011 .target_set = TargetSet.initOne(.vevl_gen)
12012
12013__builtin_ve_vl_vrsqrtd_vvvl
12014 .param_str = "V256dV256dV256dUi"
12015 .target_set = TargetSet.initOne(.vevl_gen)
12016
12017__builtin_ve_vl_vrsqrtdnex_vvl
12018 .param_str = "V256dV256dUi"
12019 .target_set = TargetSet.initOne(.vevl_gen)
12020
12021__builtin_ve_vl_vrsqrtdnex_vvvl
12022 .param_str = "V256dV256dV256dUi"
12023 .target_set = TargetSet.initOne(.vevl_gen)
12024
12025__builtin_ve_vl_vrsqrts_vvl
12026 .param_str = "V256dV256dUi"
12027 .target_set = TargetSet.initOne(.vevl_gen)
12028
12029__builtin_ve_vl_vrsqrts_vvvl
12030 .param_str = "V256dV256dV256dUi"
12031 .target_set = TargetSet.initOne(.vevl_gen)
12032
12033__builtin_ve_vl_vrsqrtsnex_vvl
12034 .param_str = "V256dV256dUi"
12035 .target_set = TargetSet.initOne(.vevl_gen)
12036
12037__builtin_ve_vl_vrsqrtsnex_vvvl
12038 .param_str = "V256dV256dV256dUi"
12039 .target_set = TargetSet.initOne(.vevl_gen)
12040
12041__builtin_ve_vl_vrxor_vvl
12042 .param_str = "V256dV256dUi"
12043 .target_set = TargetSet.initOne(.vevl_gen)
12044
12045__builtin_ve_vl_vrxor_vvml
12046 .param_str = "V256dV256dV256bUi"
12047 .target_set = TargetSet.initOne(.vevl_gen)
12048
12049__builtin_ve_vl_vsc_vvssl
12050 .param_str = "vV256dV256dLUiLUiUi"
12051 .target_set = TargetSet.initOne(.vevl_gen)
12052
12053__builtin_ve_vl_vsc_vvssml
12054 .param_str = "vV256dV256dLUiLUiV256bUi"
12055 .target_set = TargetSet.initOne(.vevl_gen)
12056
12057__builtin_ve_vl_vscl_vvssl
12058 .param_str = "vV256dV256dLUiLUiUi"
12059 .target_set = TargetSet.initOne(.vevl_gen)
12060
12061__builtin_ve_vl_vscl_vvssml
12062 .param_str = "vV256dV256dLUiLUiV256bUi"
12063 .target_set = TargetSet.initOne(.vevl_gen)
12064
12065__builtin_ve_vl_vsclnc_vvssl
12066 .param_str = "vV256dV256dLUiLUiUi"
12067 .target_set = TargetSet.initOne(.vevl_gen)
12068
12069__builtin_ve_vl_vsclnc_vvssml
12070 .param_str = "vV256dV256dLUiLUiV256bUi"
12071 .target_set = TargetSet.initOne(.vevl_gen)
12072
12073__builtin_ve_vl_vsclncot_vvssl
12074 .param_str = "vV256dV256dLUiLUiUi"
12075 .target_set = TargetSet.initOne(.vevl_gen)
12076
12077__builtin_ve_vl_vsclncot_vvssml
12078 .param_str = "vV256dV256dLUiLUiV256bUi"
12079 .target_set = TargetSet.initOne(.vevl_gen)
12080
12081__builtin_ve_vl_vsclot_vvssl
12082 .param_str = "vV256dV256dLUiLUiUi"
12083 .target_set = TargetSet.initOne(.vevl_gen)
12084
12085__builtin_ve_vl_vsclot_vvssml
12086 .param_str = "vV256dV256dLUiLUiV256bUi"
12087 .target_set = TargetSet.initOne(.vevl_gen)
12088
12089__builtin_ve_vl_vscnc_vvssl
12090 .param_str = "vV256dV256dLUiLUiUi"
12091 .target_set = TargetSet.initOne(.vevl_gen)
12092
12093__builtin_ve_vl_vscnc_vvssml
12094 .param_str = "vV256dV256dLUiLUiV256bUi"
12095 .target_set = TargetSet.initOne(.vevl_gen)
12096
12097__builtin_ve_vl_vscncot_vvssl
12098 .param_str = "vV256dV256dLUiLUiUi"
12099 .target_set = TargetSet.initOne(.vevl_gen)
12100
12101__builtin_ve_vl_vscncot_vvssml
12102 .param_str = "vV256dV256dLUiLUiV256bUi"
12103 .target_set = TargetSet.initOne(.vevl_gen)
12104
12105__builtin_ve_vl_vscot_vvssl
12106 .param_str = "vV256dV256dLUiLUiUi"
12107 .target_set = TargetSet.initOne(.vevl_gen)
12108
12109__builtin_ve_vl_vscot_vvssml
12110 .param_str = "vV256dV256dLUiLUiV256bUi"
12111 .target_set = TargetSet.initOne(.vevl_gen)
12112
12113__builtin_ve_vl_vscu_vvssl
12114 .param_str = "vV256dV256dLUiLUiUi"
12115 .target_set = TargetSet.initOne(.vevl_gen)
12116
12117__builtin_ve_vl_vscu_vvssml
12118 .param_str = "vV256dV256dLUiLUiV256bUi"
12119 .target_set = TargetSet.initOne(.vevl_gen)
12120
12121__builtin_ve_vl_vscunc_vvssl
12122 .param_str = "vV256dV256dLUiLUiUi"
12123 .target_set = TargetSet.initOne(.vevl_gen)
12124
12125__builtin_ve_vl_vscunc_vvssml
12126 .param_str = "vV256dV256dLUiLUiV256bUi"
12127 .target_set = TargetSet.initOne(.vevl_gen)
12128
12129__builtin_ve_vl_vscuncot_vvssl
12130 .param_str = "vV256dV256dLUiLUiUi"
12131 .target_set = TargetSet.initOne(.vevl_gen)
12132
12133__builtin_ve_vl_vscuncot_vvssml
12134 .param_str = "vV256dV256dLUiLUiV256bUi"
12135 .target_set = TargetSet.initOne(.vevl_gen)
12136
12137__builtin_ve_vl_vscuot_vvssl
12138 .param_str = "vV256dV256dLUiLUiUi"
12139 .target_set = TargetSet.initOne(.vevl_gen)
12140
12141__builtin_ve_vl_vscuot_vvssml
12142 .param_str = "vV256dV256dLUiLUiV256bUi"
12143 .target_set = TargetSet.initOne(.vevl_gen)
12144
12145__builtin_ve_vl_vseq_vl
12146 .param_str = "V256dUi"
12147 .target_set = TargetSet.initOne(.vevl_gen)
12148
12149__builtin_ve_vl_vseq_vvl
12150 .param_str = "V256dV256dUi"
12151 .target_set = TargetSet.initOne(.vevl_gen)
12152
12153__builtin_ve_vl_vsfa_vvssl
12154 .param_str = "V256dV256dLUiLUiUi"
12155 .target_set = TargetSet.initOne(.vevl_gen)
12156
12157__builtin_ve_vl_vsfa_vvssmvl
12158 .param_str = "V256dV256dLUiLUiV256bV256dUi"
12159 .target_set = TargetSet.initOne(.vevl_gen)
12160
12161__builtin_ve_vl_vsfa_vvssvl
12162 .param_str = "V256dV256dLUiLUiV256dUi"
12163 .target_set = TargetSet.initOne(.vevl_gen)
12164
12165__builtin_ve_vl_vshf_vvvsl
12166 .param_str = "V256dV256dV256dLUiUi"
12167 .target_set = TargetSet.initOne(.vevl_gen)
12168
12169__builtin_ve_vl_vshf_vvvsvl
12170 .param_str = "V256dV256dV256dLUiV256dUi"
12171 .target_set = TargetSet.initOne(.vevl_gen)
12172
12173__builtin_ve_vl_vslal_vvsl
12174 .param_str = "V256dV256dLiUi"
12175 .target_set = TargetSet.initOne(.vevl_gen)
12176
12177__builtin_ve_vl_vslal_vvsmvl
12178 .param_str = "V256dV256dLiV256bV256dUi"
12179 .target_set = TargetSet.initOne(.vevl_gen)
12180
12181__builtin_ve_vl_vslal_vvsvl
12182 .param_str = "V256dV256dLiV256dUi"
12183 .target_set = TargetSet.initOne(.vevl_gen)
12184
12185__builtin_ve_vl_vslal_vvvl
12186 .param_str = "V256dV256dV256dUi"
12187 .target_set = TargetSet.initOne(.vevl_gen)
12188
12189__builtin_ve_vl_vslal_vvvmvl
12190 .param_str = "V256dV256dV256dV256bV256dUi"
12191 .target_set = TargetSet.initOne(.vevl_gen)
12192
12193__builtin_ve_vl_vslal_vvvvl
12194 .param_str = "V256dV256dV256dV256dUi"
12195 .target_set = TargetSet.initOne(.vevl_gen)
12196
12197__builtin_ve_vl_vslawsx_vvsl
12198 .param_str = "V256dV256diUi"
12199 .target_set = TargetSet.initOne(.vevl_gen)
12200
12201__builtin_ve_vl_vslawsx_vvsmvl
12202 .param_str = "V256dV256diV256bV256dUi"
12203 .target_set = TargetSet.initOne(.vevl_gen)
12204
12205__builtin_ve_vl_vslawsx_vvsvl
12206 .param_str = "V256dV256diV256dUi"
12207 .target_set = TargetSet.initOne(.vevl_gen)
12208
12209__builtin_ve_vl_vslawsx_vvvl
12210 .param_str = "V256dV256dV256dUi"
12211 .target_set = TargetSet.initOne(.vevl_gen)
12212
12213__builtin_ve_vl_vslawsx_vvvmvl
12214 .param_str = "V256dV256dV256dV256bV256dUi"
12215 .target_set = TargetSet.initOne(.vevl_gen)
12216
12217__builtin_ve_vl_vslawsx_vvvvl
12218 .param_str = "V256dV256dV256dV256dUi"
12219 .target_set = TargetSet.initOne(.vevl_gen)
12220
12221__builtin_ve_vl_vslawzx_vvsl
12222 .param_str = "V256dV256diUi"
12223 .target_set = TargetSet.initOne(.vevl_gen)
12224
12225__builtin_ve_vl_vslawzx_vvsmvl
12226 .param_str = "V256dV256diV256bV256dUi"
12227 .target_set = TargetSet.initOne(.vevl_gen)
12228
12229__builtin_ve_vl_vslawzx_vvsvl
12230 .param_str = "V256dV256diV256dUi"
12231 .target_set = TargetSet.initOne(.vevl_gen)
12232
12233__builtin_ve_vl_vslawzx_vvvl
12234 .param_str = "V256dV256dV256dUi"
12235 .target_set = TargetSet.initOne(.vevl_gen)
12236
12237__builtin_ve_vl_vslawzx_vvvmvl
12238 .param_str = "V256dV256dV256dV256bV256dUi"
12239 .target_set = TargetSet.initOne(.vevl_gen)
12240
12241__builtin_ve_vl_vslawzx_vvvvl
12242 .param_str = "V256dV256dV256dV256dUi"
12243 .target_set = TargetSet.initOne(.vevl_gen)
12244
12245__builtin_ve_vl_vsll_vvsl
12246 .param_str = "V256dV256dLUiUi"
12247 .target_set = TargetSet.initOne(.vevl_gen)
12248
12249__builtin_ve_vl_vsll_vvsmvl
12250 .param_str = "V256dV256dLUiV256bV256dUi"
12251 .target_set = TargetSet.initOne(.vevl_gen)
12252
12253__builtin_ve_vl_vsll_vvsvl
12254 .param_str = "V256dV256dLUiV256dUi"
12255 .target_set = TargetSet.initOne(.vevl_gen)
12256
12257__builtin_ve_vl_vsll_vvvl
12258 .param_str = "V256dV256dV256dUi"
12259 .target_set = TargetSet.initOne(.vevl_gen)
12260
12261__builtin_ve_vl_vsll_vvvmvl
12262 .param_str = "V256dV256dV256dV256bV256dUi"
12263 .target_set = TargetSet.initOne(.vevl_gen)
12264
12265__builtin_ve_vl_vsll_vvvvl
12266 .param_str = "V256dV256dV256dV256dUi"
12267 .target_set = TargetSet.initOne(.vevl_gen)
12268
12269__builtin_ve_vl_vsral_vvsl
12270 .param_str = "V256dV256dLiUi"
12271 .target_set = TargetSet.initOne(.vevl_gen)
12272
12273__builtin_ve_vl_vsral_vvsmvl
12274 .param_str = "V256dV256dLiV256bV256dUi"
12275 .target_set = TargetSet.initOne(.vevl_gen)
12276
12277__builtin_ve_vl_vsral_vvsvl
12278 .param_str = "V256dV256dLiV256dUi"
12279 .target_set = TargetSet.initOne(.vevl_gen)
12280
12281__builtin_ve_vl_vsral_vvvl
12282 .param_str = "V256dV256dV256dUi"
12283 .target_set = TargetSet.initOne(.vevl_gen)
12284
12285__builtin_ve_vl_vsral_vvvmvl
12286 .param_str = "V256dV256dV256dV256bV256dUi"
12287 .target_set = TargetSet.initOne(.vevl_gen)
12288
12289__builtin_ve_vl_vsral_vvvvl
12290 .param_str = "V256dV256dV256dV256dUi"
12291 .target_set = TargetSet.initOne(.vevl_gen)
12292
12293__builtin_ve_vl_vsrawsx_vvsl
12294 .param_str = "V256dV256diUi"
12295 .target_set = TargetSet.initOne(.vevl_gen)
12296
12297__builtin_ve_vl_vsrawsx_vvsmvl
12298 .param_str = "V256dV256diV256bV256dUi"
12299 .target_set = TargetSet.initOne(.vevl_gen)
12300
12301__builtin_ve_vl_vsrawsx_vvsvl
12302 .param_str = "V256dV256diV256dUi"
12303 .target_set = TargetSet.initOne(.vevl_gen)
12304
12305__builtin_ve_vl_vsrawsx_vvvl
12306 .param_str = "V256dV256dV256dUi"
12307 .target_set = TargetSet.initOne(.vevl_gen)
12308
12309__builtin_ve_vl_vsrawsx_vvvmvl
12310 .param_str = "V256dV256dV256dV256bV256dUi"
12311 .target_set = TargetSet.initOne(.vevl_gen)
12312
12313__builtin_ve_vl_vsrawsx_vvvvl
12314 .param_str = "V256dV256dV256dV256dUi"
12315 .target_set = TargetSet.initOne(.vevl_gen)
12316
12317__builtin_ve_vl_vsrawzx_vvsl
12318 .param_str = "V256dV256diUi"
12319 .target_set = TargetSet.initOne(.vevl_gen)
12320
12321__builtin_ve_vl_vsrawzx_vvsmvl
12322 .param_str = "V256dV256diV256bV256dUi"
12323 .target_set = TargetSet.initOne(.vevl_gen)
12324
12325__builtin_ve_vl_vsrawzx_vvsvl
12326 .param_str = "V256dV256diV256dUi"
12327 .target_set = TargetSet.initOne(.vevl_gen)
12328
12329__builtin_ve_vl_vsrawzx_vvvl
12330 .param_str = "V256dV256dV256dUi"
12331 .target_set = TargetSet.initOne(.vevl_gen)
12332
12333__builtin_ve_vl_vsrawzx_vvvmvl
12334 .param_str = "V256dV256dV256dV256bV256dUi"
12335 .target_set = TargetSet.initOne(.vevl_gen)
12336
12337__builtin_ve_vl_vsrawzx_vvvvl
12338 .param_str = "V256dV256dV256dV256dUi"
12339 .target_set = TargetSet.initOne(.vevl_gen)
12340
12341__builtin_ve_vl_vsrl_vvsl
12342 .param_str = "V256dV256dLUiUi"
12343 .target_set = TargetSet.initOne(.vevl_gen)
12344
12345__builtin_ve_vl_vsrl_vvsmvl
12346 .param_str = "V256dV256dLUiV256bV256dUi"
12347 .target_set = TargetSet.initOne(.vevl_gen)
12348
12349__builtin_ve_vl_vsrl_vvsvl
12350 .param_str = "V256dV256dLUiV256dUi"
12351 .target_set = TargetSet.initOne(.vevl_gen)
12352
12353__builtin_ve_vl_vsrl_vvvl
12354 .param_str = "V256dV256dV256dUi"
12355 .target_set = TargetSet.initOne(.vevl_gen)
12356
12357__builtin_ve_vl_vsrl_vvvmvl
12358 .param_str = "V256dV256dV256dV256bV256dUi"
12359 .target_set = TargetSet.initOne(.vevl_gen)
12360
12361__builtin_ve_vl_vsrl_vvvvl
12362 .param_str = "V256dV256dV256dV256dUi"
12363 .target_set = TargetSet.initOne(.vevl_gen)
12364
12365__builtin_ve_vl_vst2d_vssl
12366 .param_str = "vV256dLUiv*Ui"
12367 .target_set = TargetSet.initOne(.vevl_gen)
12368
12369__builtin_ve_vl_vst2d_vssml
12370 .param_str = "vV256dLUiv*V256bUi"
12371 .target_set = TargetSet.initOne(.vevl_gen)
12372
12373__builtin_ve_vl_vst2dnc_vssl
12374 .param_str = "vV256dLUiv*Ui"
12375 .target_set = TargetSet.initOne(.vevl_gen)
12376
12377__builtin_ve_vl_vst2dnc_vssml
12378 .param_str = "vV256dLUiv*V256bUi"
12379 .target_set = TargetSet.initOne(.vevl_gen)
12380
12381__builtin_ve_vl_vst2dncot_vssl
12382 .param_str = "vV256dLUiv*Ui"
12383 .target_set = TargetSet.initOne(.vevl_gen)
12384
12385__builtin_ve_vl_vst2dncot_vssml
12386 .param_str = "vV256dLUiv*V256bUi"
12387 .target_set = TargetSet.initOne(.vevl_gen)
12388
12389__builtin_ve_vl_vst2dot_vssl
12390 .param_str = "vV256dLUiv*Ui"
12391 .target_set = TargetSet.initOne(.vevl_gen)
12392
12393__builtin_ve_vl_vst2dot_vssml
12394 .param_str = "vV256dLUiv*V256bUi"
12395 .target_set = TargetSet.initOne(.vevl_gen)
12396
12397__builtin_ve_vl_vst_vssl
12398 .param_str = "vV256dLUiv*Ui"
12399 .target_set = TargetSet.initOne(.vevl_gen)
12400
12401__builtin_ve_vl_vst_vssml
12402 .param_str = "vV256dLUiv*V256bUi"
12403 .target_set = TargetSet.initOne(.vevl_gen)
12404
12405__builtin_ve_vl_vstl2d_vssl
12406 .param_str = "vV256dLUiv*Ui"
12407 .target_set = TargetSet.initOne(.vevl_gen)
12408
12409__builtin_ve_vl_vstl2d_vssml
12410 .param_str = "vV256dLUiv*V256bUi"
12411 .target_set = TargetSet.initOne(.vevl_gen)
12412
12413__builtin_ve_vl_vstl2dnc_vssl
12414 .param_str = "vV256dLUiv*Ui"
12415 .target_set = TargetSet.initOne(.vevl_gen)
12416
12417__builtin_ve_vl_vstl2dnc_vssml
12418 .param_str = "vV256dLUiv*V256bUi"
12419 .target_set = TargetSet.initOne(.vevl_gen)
12420
12421__builtin_ve_vl_vstl2dncot_vssl
12422 .param_str = "vV256dLUiv*Ui"
12423 .target_set = TargetSet.initOne(.vevl_gen)
12424
12425__builtin_ve_vl_vstl2dncot_vssml
12426 .param_str = "vV256dLUiv*V256bUi"
12427 .target_set = TargetSet.initOne(.vevl_gen)
12428
12429__builtin_ve_vl_vstl2dot_vssl
12430 .param_str = "vV256dLUiv*Ui"
12431 .target_set = TargetSet.initOne(.vevl_gen)
12432
12433__builtin_ve_vl_vstl2dot_vssml
12434 .param_str = "vV256dLUiv*V256bUi"
12435 .target_set = TargetSet.initOne(.vevl_gen)
12436
12437__builtin_ve_vl_vstl_vssl
12438 .param_str = "vV256dLUiv*Ui"
12439 .target_set = TargetSet.initOne(.vevl_gen)
12440
12441__builtin_ve_vl_vstl_vssml
12442 .param_str = "vV256dLUiv*V256bUi"
12443 .target_set = TargetSet.initOne(.vevl_gen)
12444
12445__builtin_ve_vl_vstlnc_vssl
12446 .param_str = "vV256dLUiv*Ui"
12447 .target_set = TargetSet.initOne(.vevl_gen)
12448
12449__builtin_ve_vl_vstlnc_vssml
12450 .param_str = "vV256dLUiv*V256bUi"
12451 .target_set = TargetSet.initOne(.vevl_gen)
12452
12453__builtin_ve_vl_vstlncot_vssl
12454 .param_str = "vV256dLUiv*Ui"
12455 .target_set = TargetSet.initOne(.vevl_gen)
12456
12457__builtin_ve_vl_vstlncot_vssml
12458 .param_str = "vV256dLUiv*V256bUi"
12459 .target_set = TargetSet.initOne(.vevl_gen)
12460
12461__builtin_ve_vl_vstlot_vssl
12462 .param_str = "vV256dLUiv*Ui"
12463 .target_set = TargetSet.initOne(.vevl_gen)
12464
12465__builtin_ve_vl_vstlot_vssml
12466 .param_str = "vV256dLUiv*V256bUi"
12467 .target_set = TargetSet.initOne(.vevl_gen)
12468
12469__builtin_ve_vl_vstnc_vssl
12470 .param_str = "vV256dLUiv*Ui"
12471 .target_set = TargetSet.initOne(.vevl_gen)
12472
12473__builtin_ve_vl_vstnc_vssml
12474 .param_str = "vV256dLUiv*V256bUi"
12475 .target_set = TargetSet.initOne(.vevl_gen)
12476
12477__builtin_ve_vl_vstncot_vssl
12478 .param_str = "vV256dLUiv*Ui"
12479 .target_set = TargetSet.initOne(.vevl_gen)
12480
12481__builtin_ve_vl_vstncot_vssml
12482 .param_str = "vV256dLUiv*V256bUi"
12483 .target_set = TargetSet.initOne(.vevl_gen)
12484
12485__builtin_ve_vl_vstot_vssl
12486 .param_str = "vV256dLUiv*Ui"
12487 .target_set = TargetSet.initOne(.vevl_gen)
12488
12489__builtin_ve_vl_vstot_vssml
12490 .param_str = "vV256dLUiv*V256bUi"
12491 .target_set = TargetSet.initOne(.vevl_gen)
12492
12493__builtin_ve_vl_vstu2d_vssl
12494 .param_str = "vV256dLUiv*Ui"
12495 .target_set = TargetSet.initOne(.vevl_gen)
12496
12497__builtin_ve_vl_vstu2d_vssml
12498 .param_str = "vV256dLUiv*V256bUi"
12499 .target_set = TargetSet.initOne(.vevl_gen)
12500
12501__builtin_ve_vl_vstu2dnc_vssl
12502 .param_str = "vV256dLUiv*Ui"
12503 .target_set = TargetSet.initOne(.vevl_gen)
12504
12505__builtin_ve_vl_vstu2dnc_vssml
12506 .param_str = "vV256dLUiv*V256bUi"
12507 .target_set = TargetSet.initOne(.vevl_gen)
12508
12509__builtin_ve_vl_vstu2dncot_vssl
12510 .param_str = "vV256dLUiv*Ui"
12511 .target_set = TargetSet.initOne(.vevl_gen)
12512
12513__builtin_ve_vl_vstu2dncot_vssml
12514 .param_str = "vV256dLUiv*V256bUi"
12515 .target_set = TargetSet.initOne(.vevl_gen)
12516
12517__builtin_ve_vl_vstu2dot_vssl
12518 .param_str = "vV256dLUiv*Ui"
12519 .target_set = TargetSet.initOne(.vevl_gen)
12520
12521__builtin_ve_vl_vstu2dot_vssml
12522 .param_str = "vV256dLUiv*V256bUi"
12523 .target_set = TargetSet.initOne(.vevl_gen)
12524
12525__builtin_ve_vl_vstu_vssl
12526 .param_str = "vV256dLUiv*Ui"
12527 .target_set = TargetSet.initOne(.vevl_gen)
12528
12529__builtin_ve_vl_vstu_vssml
12530 .param_str = "vV256dLUiv*V256bUi"
12531 .target_set = TargetSet.initOne(.vevl_gen)
12532
12533__builtin_ve_vl_vstunc_vssl
12534 .param_str = "vV256dLUiv*Ui"
12535 .target_set = TargetSet.initOne(.vevl_gen)
12536
12537__builtin_ve_vl_vstunc_vssml
12538 .param_str = "vV256dLUiv*V256bUi"
12539 .target_set = TargetSet.initOne(.vevl_gen)
12540
12541__builtin_ve_vl_vstuncot_vssl
12542 .param_str = "vV256dLUiv*Ui"
12543 .target_set = TargetSet.initOne(.vevl_gen)
12544
12545__builtin_ve_vl_vstuncot_vssml
12546 .param_str = "vV256dLUiv*V256bUi"
12547 .target_set = TargetSet.initOne(.vevl_gen)
12548
12549__builtin_ve_vl_vstuot_vssl
12550 .param_str = "vV256dLUiv*Ui"
12551 .target_set = TargetSet.initOne(.vevl_gen)
12552
12553__builtin_ve_vl_vstuot_vssml
12554 .param_str = "vV256dLUiv*V256bUi"
12555 .target_set = TargetSet.initOne(.vevl_gen)
12556
12557__builtin_ve_vl_vsubsl_vsvl
12558 .param_str = "V256dLiV256dUi"
12559 .target_set = TargetSet.initOne(.vevl_gen)
12560
12561__builtin_ve_vl_vsubsl_vsvmvl
12562 .param_str = "V256dLiV256dV256bV256dUi"
12563 .target_set = TargetSet.initOne(.vevl_gen)
12564
12565__builtin_ve_vl_vsubsl_vsvvl
12566 .param_str = "V256dLiV256dV256dUi"
12567 .target_set = TargetSet.initOne(.vevl_gen)
12568
12569__builtin_ve_vl_vsubsl_vvvl
12570 .param_str = "V256dV256dV256dUi"
12571 .target_set = TargetSet.initOne(.vevl_gen)
12572
12573__builtin_ve_vl_vsubsl_vvvmvl
12574 .param_str = "V256dV256dV256dV256bV256dUi"
12575 .target_set = TargetSet.initOne(.vevl_gen)
12576
12577__builtin_ve_vl_vsubsl_vvvvl
12578 .param_str = "V256dV256dV256dV256dUi"
12579 .target_set = TargetSet.initOne(.vevl_gen)
12580
12581__builtin_ve_vl_vsubswsx_vsvl
12582 .param_str = "V256diV256dUi"
12583 .target_set = TargetSet.initOne(.vevl_gen)
12584
12585__builtin_ve_vl_vsubswsx_vsvmvl
12586 .param_str = "V256diV256dV256bV256dUi"
12587 .target_set = TargetSet.initOne(.vevl_gen)
12588
12589__builtin_ve_vl_vsubswsx_vsvvl
12590 .param_str = "V256diV256dV256dUi"
12591 .target_set = TargetSet.initOne(.vevl_gen)
12592
12593__builtin_ve_vl_vsubswsx_vvvl
12594 .param_str = "V256dV256dV256dUi"
12595 .target_set = TargetSet.initOne(.vevl_gen)
12596
12597__builtin_ve_vl_vsubswsx_vvvmvl
12598 .param_str = "V256dV256dV256dV256bV256dUi"
12599 .target_set = TargetSet.initOne(.vevl_gen)
12600
12601__builtin_ve_vl_vsubswsx_vvvvl
12602 .param_str = "V256dV256dV256dV256dUi"
12603 .target_set = TargetSet.initOne(.vevl_gen)
12604
12605__builtin_ve_vl_vsubswzx_vsvl
12606 .param_str = "V256diV256dUi"
12607 .target_set = TargetSet.initOne(.vevl_gen)
12608
12609__builtin_ve_vl_vsubswzx_vsvmvl
12610 .param_str = "V256diV256dV256bV256dUi"
12611 .target_set = TargetSet.initOne(.vevl_gen)
12612
12613__builtin_ve_vl_vsubswzx_vsvvl
12614 .param_str = "V256diV256dV256dUi"
12615 .target_set = TargetSet.initOne(.vevl_gen)
12616
12617__builtin_ve_vl_vsubswzx_vvvl
12618 .param_str = "V256dV256dV256dUi"
12619 .target_set = TargetSet.initOne(.vevl_gen)
12620
12621__builtin_ve_vl_vsubswzx_vvvmvl
12622 .param_str = "V256dV256dV256dV256bV256dUi"
12623 .target_set = TargetSet.initOne(.vevl_gen)
12624
12625__builtin_ve_vl_vsubswzx_vvvvl
12626 .param_str = "V256dV256dV256dV256dUi"
12627 .target_set = TargetSet.initOne(.vevl_gen)
12628
12629__builtin_ve_vl_vsubul_vsvl
12630 .param_str = "V256dLUiV256dUi"
12631 .target_set = TargetSet.initOne(.vevl_gen)
12632
12633__builtin_ve_vl_vsubul_vsvmvl
12634 .param_str = "V256dLUiV256dV256bV256dUi"
12635 .target_set = TargetSet.initOne(.vevl_gen)
12636
12637__builtin_ve_vl_vsubul_vsvvl
12638 .param_str = "V256dLUiV256dV256dUi"
12639 .target_set = TargetSet.initOne(.vevl_gen)
12640
12641__builtin_ve_vl_vsubul_vvvl
12642 .param_str = "V256dV256dV256dUi"
12643 .target_set = TargetSet.initOne(.vevl_gen)
12644
12645__builtin_ve_vl_vsubul_vvvmvl
12646 .param_str = "V256dV256dV256dV256bV256dUi"
12647 .target_set = TargetSet.initOne(.vevl_gen)
12648
12649__builtin_ve_vl_vsubul_vvvvl
12650 .param_str = "V256dV256dV256dV256dUi"
12651 .target_set = TargetSet.initOne(.vevl_gen)
12652
12653__builtin_ve_vl_vsubuw_vsvl
12654 .param_str = "V256dUiV256dUi"
12655 .target_set = TargetSet.initOne(.vevl_gen)
12656
12657__builtin_ve_vl_vsubuw_vsvmvl
12658 .param_str = "V256dUiV256dV256bV256dUi"
12659 .target_set = TargetSet.initOne(.vevl_gen)
12660
12661__builtin_ve_vl_vsubuw_vsvvl
12662 .param_str = "V256dUiV256dV256dUi"
12663 .target_set = TargetSet.initOne(.vevl_gen)
12664
12665__builtin_ve_vl_vsubuw_vvvl
12666 .param_str = "V256dV256dV256dUi"
12667 .target_set = TargetSet.initOne(.vevl_gen)
12668
12669__builtin_ve_vl_vsubuw_vvvmvl
12670 .param_str = "V256dV256dV256dV256bV256dUi"
12671 .target_set = TargetSet.initOne(.vevl_gen)
12672
12673__builtin_ve_vl_vsubuw_vvvvl
12674 .param_str = "V256dV256dV256dV256dUi"
12675 .target_set = TargetSet.initOne(.vevl_gen)
12676
12677__builtin_ve_vl_vsuml_vvl
12678 .param_str = "V256dV256dUi"
12679 .target_set = TargetSet.initOne(.vevl_gen)
12680
12681__builtin_ve_vl_vsuml_vvml
12682 .param_str = "V256dV256dV256bUi"
12683 .target_set = TargetSet.initOne(.vevl_gen)
12684
12685__builtin_ve_vl_vsumwsx_vvl
12686 .param_str = "V256dV256dUi"
12687 .target_set = TargetSet.initOne(.vevl_gen)
12688
12689__builtin_ve_vl_vsumwsx_vvml
12690 .param_str = "V256dV256dV256bUi"
12691 .target_set = TargetSet.initOne(.vevl_gen)
12692
12693__builtin_ve_vl_vsumwzx_vvl
12694 .param_str = "V256dV256dUi"
12695 .target_set = TargetSet.initOne(.vevl_gen)
12696
12697__builtin_ve_vl_vsumwzx_vvml
12698 .param_str = "V256dV256dV256bUi"
12699 .target_set = TargetSet.initOne(.vevl_gen)
12700
12701__builtin_ve_vl_vxor_vsvl
12702 .param_str = "V256dLUiV256dUi"
12703 .target_set = TargetSet.initOne(.vevl_gen)
12704
12705__builtin_ve_vl_vxor_vsvmvl
12706 .param_str = "V256dLUiV256dV256bV256dUi"
12707 .target_set = TargetSet.initOne(.vevl_gen)
12708
12709__builtin_ve_vl_vxor_vsvvl
12710 .param_str = "V256dLUiV256dV256dUi"
12711 .target_set = TargetSet.initOne(.vevl_gen)
12712
12713__builtin_ve_vl_vxor_vvvl
12714 .param_str = "V256dV256dV256dUi"
12715 .target_set = TargetSet.initOne(.vevl_gen)
12716
12717__builtin_ve_vl_vxor_vvvmvl
12718 .param_str = "V256dV256dV256dV256bV256dUi"
12719 .target_set = TargetSet.initOne(.vevl_gen)
12720
12721__builtin_ve_vl_vxor_vvvvl
12722 .param_str = "V256dV256dV256dV256dUi"
12723 .target_set = TargetSet.initOne(.vevl_gen)
12724
12725__builtin_ve_vl_xorm_MMM
12726 .param_str = "V512bV512bV512b"
12727 .target_set = TargetSet.initOne(.vevl_gen)
12728
12729__builtin_ve_vl_xorm_mmm
12730 .param_str = "V256bV256bV256b"
12731 .target_set = TargetSet.initOne(.vevl_gen)
12732
12733__builtin_vfprintf
12734 .param_str = "iP*RcC*Ra"
12735 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 }
12736
12737__builtin_vfscanf
12738 .param_str = "iP*RcC*Ra"
12739 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf, .format_string_position = 1 }
12740
12741__builtin_vprintf
12742 .param_str = "icC*Ra"
12743 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf }
12744
12745__builtin_vscanf
12746 .param_str = "icC*Ra"
12747 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf }
12748
12749__builtin_vsnprintf
12750 .param_str = "ic*RzcC*Ra"
12751 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 2 }
12752
12753__builtin_vsprintf
12754 .param_str = "ic*RcC*Ra"
12755 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 }
12756
12757__builtin_vsscanf
12758 .param_str = "icC*RcC*Ra"
12759 .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf, .format_string_position = 1 }
12760
12761__builtin_wasm_max_f32
12762 .param_str = "fff"
12763 .target_set = TargetSet.initOne(.webassembly)
12764 .attributes = .{ .@"const" = true }
12765
12766__builtin_wasm_max_f64
12767 .param_str = "ddd"
12768 .target_set = TargetSet.initOne(.webassembly)
12769 .attributes = .{ .@"const" = true }
12770
12771__builtin_wasm_memory_grow
12772 .param_str = "zIiz"
12773 .target_set = TargetSet.initOne(.webassembly)
12774
12775__builtin_wasm_memory_size
12776 .param_str = "zIi"
12777 .target_set = TargetSet.initOne(.webassembly)
12778
12779__builtin_wasm_min_f32
12780 .param_str = "fff"
12781 .target_set = TargetSet.initOne(.webassembly)
12782 .attributes = .{ .@"const" = true }
12783
12784__builtin_wasm_min_f64
12785 .param_str = "ddd"
12786 .target_set = TargetSet.initOne(.webassembly)
12787 .attributes = .{ .@"const" = true }
12788
12789__builtin_wasm_trunc_s_i32_f32
12790 .param_str = "if"
12791 .target_set = TargetSet.initOne(.webassembly)
12792 .attributes = .{ .@"const" = true }
12793
12794__builtin_wasm_trunc_s_i32_f64
12795 .param_str = "id"
12796 .target_set = TargetSet.initOne(.webassembly)
12797 .attributes = .{ .@"const" = true }
12798
12799__builtin_wasm_trunc_s_i64_f32
12800 .param_str = "LLif"
12801 .target_set = TargetSet.initOne(.webassembly)
12802 .attributes = .{ .@"const" = true }
12803
12804__builtin_wasm_trunc_s_i64_f64
12805 .param_str = "LLid"
12806 .target_set = TargetSet.initOne(.webassembly)
12807 .attributes = .{ .@"const" = true }
12808
12809__builtin_wasm_trunc_u_i32_f32
12810 .param_str = "if"
12811 .target_set = TargetSet.initOne(.webassembly)
12812 .attributes = .{ .@"const" = true }
12813
12814__builtin_wasm_trunc_u_i32_f64
12815 .param_str = "id"
12816 .target_set = TargetSet.initOne(.webassembly)
12817 .attributes = .{ .@"const" = true }
12818
12819__builtin_wasm_trunc_u_i64_f32
12820 .param_str = "LLif"
12821 .target_set = TargetSet.initOne(.webassembly)
12822 .attributes = .{ .@"const" = true }
12823
12824__builtin_wasm_trunc_u_i64_f64
12825 .param_str = "LLid"
12826 .target_set = TargetSet.initOne(.webassembly)
12827 .attributes = .{ .@"const" = true }
12828
12829__builtin_wcschr
12830 .param_str = "w*wC*w"
12831 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12832
12833__builtin_wcscmp
12834 .param_str = "iwC*wC*"
12835 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12836
12837__builtin_wcslen
12838 .param_str = "zwC*"
12839 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12840
12841__builtin_wcsncmp
12842 .param_str = "iwC*wC*z"
12843 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12844
12845__builtin_wmemchr
12846 .param_str = "w*wC*wz"
12847 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12848
12849__builtin_wmemcmp
12850 .param_str = "iwC*wC*z"
12851 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12852
12853__builtin_wmemcpy
12854 .param_str = "w*w*wC*z"
12855 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12856
12857__builtin_wmemmove
12858 .param_str = "w*w*wC*z"
12859 .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true }
12860
12861__c11_atomic_is_lock_free
12862 .param_str = "bz"
12863 .attributes = .{ .const_evaluable = true }
12864
12865__c11_atomic_signal_fence
12866 .param_str = "vi"
12867
12868__c11_atomic_thread_fence
12869 .param_str = "vi"
12870
12871__clear_cache
12872 .param_str = "vv*v*"
12873 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
12874
12875__cospi
12876 .param_str = "dd"
12877 .header = .math
12878 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
12879
12880__cospif
12881 .param_str = "ff"
12882 .header = .math
12883 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
12884
12885__debugbreak
12886 .param_str = "v"
12887 .language = .all_ms_languages
12888
12889__dmb
12890 .param_str = "vUi"
12891 .language = .all_ms_languages
12892 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
12893 .attributes = .{ .@"const" = true }
12894
12895__dsb
12896 .param_str = "vUi"
12897 .language = .all_ms_languages
12898 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
12899 .attributes = .{ .@"const" = true }
12900
12901__emit
12902 .param_str = "vIUiC"
12903 .language = .all_ms_languages
12904 .target_set = TargetSet.initOne(.arm)
12905
12906__exception_code
12907 .param_str = "UNi"
12908 .language = .all_ms_languages
12909
12910__exception_info
12911 .param_str = "v*"
12912 .language = .all_ms_languages
12913
12914__exp10
12915 .param_str = "dd"
12916 .header = .math
12917 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
12918
12919__exp10f
12920 .param_str = "ff"
12921 .header = .math
12922 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
12923
12924__fastfail
12925 .param_str = "vUi"
12926 .language = .all_ms_languages
12927 .attributes = .{ .noreturn = true }
12928
12929__finite
12930 .param_str = "id"
12931 .header = .math
12932 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
12933
12934__finitef
12935 .param_str = "if"
12936 .header = .math
12937 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
12938
12939__finitel
12940 .param_str = "iLd"
12941 .header = .math
12942 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
12943
12944__isb
12945 .param_str = "vUi"
12946 .language = .all_ms_languages
12947 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
12948 .attributes = .{ .@"const" = true }
12949
12950__iso_volatile_load16
12951 .param_str = "ssCD*"
12952 .language = .all_ms_languages
12953
12954__iso_volatile_load32
12955 .param_str = "iiCD*"
12956 .language = .all_ms_languages
12957
12958__iso_volatile_load64
12959 .param_str = "LLiLLiCD*"
12960 .language = .all_ms_languages
12961
12962__iso_volatile_load8
12963 .param_str = "ccCD*"
12964 .language = .all_ms_languages
12965
12966__iso_volatile_store16
12967 .param_str = "vsD*s"
12968 .language = .all_ms_languages
12969
12970__iso_volatile_store32
12971 .param_str = "viD*i"
12972 .language = .all_ms_languages
12973
12974__iso_volatile_store64
12975 .param_str = "vLLiD*LLi"
12976 .language = .all_ms_languages
12977
12978__iso_volatile_store8
12979 .param_str = "vcD*c"
12980 .language = .all_ms_languages
12981
12982__ldrexd
12983 .param_str = "WiWiCD*"
12984 .language = .all_ms_languages
12985 .target_set = TargetSet.initOne(.arm)
12986
12987__lzcnt
12988 .param_str = "UiUi"
12989 .language = .all_ms_languages
12990 .attributes = .{ .@"const" = true, .const_evaluable = true }
12991
12992__lzcnt16
12993 .param_str = "UsUs"
12994 .language = .all_ms_languages
12995 .attributes = .{ .@"const" = true, .const_evaluable = true }
12996
12997__lzcnt64
12998 .param_str = "UWiUWi"
12999 .language = .all_ms_languages
13000 .attributes = .{ .@"const" = true, .const_evaluable = true }
13001
13002__noop
13003 .param_str = "i."
13004 .language = .all_ms_languages
13005
13006__nvvm_add_rm_d
13007 .param_str = "ddd"
13008 .target_set = TargetSet.initOne(.nvptx)
13009
13010__nvvm_add_rm_f
13011 .param_str = "fff"
13012 .target_set = TargetSet.initOne(.nvptx)
13013
13014__nvvm_add_rm_ftz_f
13015 .param_str = "fff"
13016 .target_set = TargetSet.initOne(.nvptx)
13017
13018__nvvm_add_rn_d
13019 .param_str = "ddd"
13020 .target_set = TargetSet.initOne(.nvptx)
13021
13022__nvvm_add_rn_f
13023 .param_str = "fff"
13024 .target_set = TargetSet.initOne(.nvptx)
13025
13026__nvvm_add_rn_ftz_f
13027 .param_str = "fff"
13028 .target_set = TargetSet.initOne(.nvptx)
13029
13030__nvvm_add_rp_d
13031 .param_str = "ddd"
13032 .target_set = TargetSet.initOne(.nvptx)
13033
13034__nvvm_add_rp_f
13035 .param_str = "fff"
13036 .target_set = TargetSet.initOne(.nvptx)
13037
13038__nvvm_add_rp_ftz_f
13039 .param_str = "fff"
13040 .target_set = TargetSet.initOne(.nvptx)
13041
13042__nvvm_add_rz_d
13043 .param_str = "ddd"
13044 .target_set = TargetSet.initOne(.nvptx)
13045
13046__nvvm_add_rz_f
13047 .param_str = "fff"
13048 .target_set = TargetSet.initOne(.nvptx)
13049
13050__nvvm_add_rz_ftz_f
13051 .param_str = "fff"
13052 .target_set = TargetSet.initOne(.nvptx)
13053
13054__nvvm_atom_add_gen_f
13055 .param_str = "ffD*f"
13056 .target_set = TargetSet.initOne(.nvptx)
13057
13058__nvvm_atom_add_gen_i
13059 .param_str = "iiD*i"
13060 .target_set = TargetSet.initOne(.nvptx)
13061
13062__nvvm_atom_add_gen_l
13063 .param_str = "LiLiD*Li"
13064 .target_set = TargetSet.initOne(.nvptx)
13065
13066__nvvm_atom_add_gen_ll
13067 .param_str = "LLiLLiD*LLi"
13068 .target_set = TargetSet.initOne(.nvptx)
13069
13070__nvvm_atom_and_gen_i
13071 .param_str = "iiD*i"
13072 .target_set = TargetSet.initOne(.nvptx)
13073
13074__nvvm_atom_and_gen_l
13075 .param_str = "LiLiD*Li"
13076 .target_set = TargetSet.initOne(.nvptx)
13077
13078__nvvm_atom_and_gen_ll
13079 .param_str = "LLiLLiD*LLi"
13080 .target_set = TargetSet.initOne(.nvptx)
13081
13082__nvvm_atom_cas_gen_i
13083 .param_str = "iiD*ii"
13084 .target_set = TargetSet.initOne(.nvptx)
13085
13086__nvvm_atom_cas_gen_l
13087 .param_str = "LiLiD*LiLi"
13088 .target_set = TargetSet.initOne(.nvptx)
13089
13090__nvvm_atom_cas_gen_ll
13091 .param_str = "LLiLLiD*LLiLLi"
13092 .target_set = TargetSet.initOne(.nvptx)
13093
13094__nvvm_atom_dec_gen_ui
13095 .param_str = "UiUiD*Ui"
13096 .target_set = TargetSet.initOne(.nvptx)
13097
13098__nvvm_atom_inc_gen_ui
13099 .param_str = "UiUiD*Ui"
13100 .target_set = TargetSet.initOne(.nvptx)
13101
13102__nvvm_atom_max_gen_i
13103 .param_str = "iiD*i"
13104 .target_set = TargetSet.initOne(.nvptx)
13105
13106__nvvm_atom_max_gen_l
13107 .param_str = "LiLiD*Li"
13108 .target_set = TargetSet.initOne(.nvptx)
13109
13110__nvvm_atom_max_gen_ll
13111 .param_str = "LLiLLiD*LLi"
13112 .target_set = TargetSet.initOne(.nvptx)
13113
13114__nvvm_atom_max_gen_ui
13115 .param_str = "UiUiD*Ui"
13116 .target_set = TargetSet.initOne(.nvptx)
13117
13118__nvvm_atom_max_gen_ul
13119 .param_str = "ULiULiD*ULi"
13120 .target_set = TargetSet.initOne(.nvptx)
13121
13122__nvvm_atom_max_gen_ull
13123 .param_str = "ULLiULLiD*ULLi"
13124 .target_set = TargetSet.initOne(.nvptx)
13125
13126__nvvm_atom_min_gen_i
13127 .param_str = "iiD*i"
13128 .target_set = TargetSet.initOne(.nvptx)
13129
13130__nvvm_atom_min_gen_l
13131 .param_str = "LiLiD*Li"
13132 .target_set = TargetSet.initOne(.nvptx)
13133
13134__nvvm_atom_min_gen_ll
13135 .param_str = "LLiLLiD*LLi"
13136 .target_set = TargetSet.initOne(.nvptx)
13137
13138__nvvm_atom_min_gen_ui
13139 .param_str = "UiUiD*Ui"
13140 .target_set = TargetSet.initOne(.nvptx)
13141
13142__nvvm_atom_min_gen_ul
13143 .param_str = "ULiULiD*ULi"
13144 .target_set = TargetSet.initOne(.nvptx)
13145
13146__nvvm_atom_min_gen_ull
13147 .param_str = "ULLiULLiD*ULLi"
13148 .target_set = TargetSet.initOne(.nvptx)
13149
13150__nvvm_atom_or_gen_i
13151 .param_str = "iiD*i"
13152 .target_set = TargetSet.initOne(.nvptx)
13153
13154__nvvm_atom_or_gen_l
13155 .param_str = "LiLiD*Li"
13156 .target_set = TargetSet.initOne(.nvptx)
13157
13158__nvvm_atom_or_gen_ll
13159 .param_str = "LLiLLiD*LLi"
13160 .target_set = TargetSet.initOne(.nvptx)
13161
13162__nvvm_atom_sub_gen_i
13163 .param_str = "iiD*i"
13164 .target_set = TargetSet.initOne(.nvptx)
13165
13166__nvvm_atom_sub_gen_l
13167 .param_str = "LiLiD*Li"
13168 .target_set = TargetSet.initOne(.nvptx)
13169
13170__nvvm_atom_sub_gen_ll
13171 .param_str = "LLiLLiD*LLi"
13172 .target_set = TargetSet.initOne(.nvptx)
13173
13174__nvvm_atom_xchg_gen_i
13175 .param_str = "iiD*i"
13176 .target_set = TargetSet.initOne(.nvptx)
13177
13178__nvvm_atom_xchg_gen_l
13179 .param_str = "LiLiD*Li"
13180 .target_set = TargetSet.initOne(.nvptx)
13181
13182__nvvm_atom_xchg_gen_ll
13183 .param_str = "LLiLLiD*LLi"
13184 .target_set = TargetSet.initOne(.nvptx)
13185
13186__nvvm_atom_xor_gen_i
13187 .param_str = "iiD*i"
13188 .target_set = TargetSet.initOne(.nvptx)
13189
13190__nvvm_atom_xor_gen_l
13191 .param_str = "LiLiD*Li"
13192 .target_set = TargetSet.initOne(.nvptx)
13193
13194__nvvm_atom_xor_gen_ll
13195 .param_str = "LLiLLiD*LLi"
13196 .target_set = TargetSet.initOne(.nvptx)
13197
13198__nvvm_bar0_and
13199 .param_str = "ii"
13200 .target_set = TargetSet.initOne(.nvptx)
13201
13202__nvvm_bar0_or
13203 .param_str = "ii"
13204 .target_set = TargetSet.initOne(.nvptx)
13205
13206__nvvm_bar0_popc
13207 .param_str = "ii"
13208 .target_set = TargetSet.initOne(.nvptx)
13209
13210__nvvm_bar_sync
13211 .param_str = "vi"
13212 .target_set = TargetSet.initOne(.nvptx)
13213
13214__nvvm_bitcast_d2ll
13215 .param_str = "LLid"
13216 .target_set = TargetSet.initOne(.nvptx)
13217
13218__nvvm_bitcast_f2i
13219 .param_str = "if"
13220 .target_set = TargetSet.initOne(.nvptx)
13221
13222__nvvm_bitcast_i2f
13223 .param_str = "fi"
13224 .target_set = TargetSet.initOne(.nvptx)
13225
13226__nvvm_bitcast_ll2d
13227 .param_str = "dLLi"
13228 .target_set = TargetSet.initOne(.nvptx)
13229
13230__nvvm_ceil_d
13231 .param_str = "dd"
13232 .target_set = TargetSet.initOne(.nvptx)
13233
13234__nvvm_ceil_f
13235 .param_str = "ff"
13236 .target_set = TargetSet.initOne(.nvptx)
13237
13238__nvvm_ceil_ftz_f
13239 .param_str = "ff"
13240 .target_set = TargetSet.initOne(.nvptx)
13241
13242__nvvm_compiler_error
13243 .param_str = "vcC*4"
13244 .target_set = TargetSet.initOne(.nvptx)
13245
13246__nvvm_compiler_warn
13247 .param_str = "vcC*4"
13248 .target_set = TargetSet.initOne(.nvptx)
13249
13250__nvvm_cos_approx_f
13251 .param_str = "ff"
13252 .target_set = TargetSet.initOne(.nvptx)
13253
13254__nvvm_cos_approx_ftz_f
13255 .param_str = "ff"
13256 .target_set = TargetSet.initOne(.nvptx)
13257
13258__nvvm_d2f_rm
13259 .param_str = "fd"
13260 .target_set = TargetSet.initOne(.nvptx)
13261
13262__nvvm_d2f_rm_ftz
13263 .param_str = "fd"
13264 .target_set = TargetSet.initOne(.nvptx)
13265
13266__nvvm_d2f_rn
13267 .param_str = "fd"
13268 .target_set = TargetSet.initOne(.nvptx)
13269
13270__nvvm_d2f_rn_ftz
13271 .param_str = "fd"
13272 .target_set = TargetSet.initOne(.nvptx)
13273
13274__nvvm_d2f_rp
13275 .param_str = "fd"
13276 .target_set = TargetSet.initOne(.nvptx)
13277
13278__nvvm_d2f_rp_ftz
13279 .param_str = "fd"
13280 .target_set = TargetSet.initOne(.nvptx)
13281
13282__nvvm_d2f_rz
13283 .param_str = "fd"
13284 .target_set = TargetSet.initOne(.nvptx)
13285
13286__nvvm_d2f_rz_ftz
13287 .param_str = "fd"
13288 .target_set = TargetSet.initOne(.nvptx)
13289
13290__nvvm_d2i_hi
13291 .param_str = "id"
13292 .target_set = TargetSet.initOne(.nvptx)
13293
13294__nvvm_d2i_lo
13295 .param_str = "id"
13296 .target_set = TargetSet.initOne(.nvptx)
13297
13298__nvvm_d2i_rm
13299 .param_str = "id"
13300 .target_set = TargetSet.initOne(.nvptx)
13301
13302__nvvm_d2i_rn
13303 .param_str = "id"
13304 .target_set = TargetSet.initOne(.nvptx)
13305
13306__nvvm_d2i_rp
13307 .param_str = "id"
13308 .target_set = TargetSet.initOne(.nvptx)
13309
13310__nvvm_d2i_rz
13311 .param_str = "id"
13312 .target_set = TargetSet.initOne(.nvptx)
13313
13314__nvvm_d2ll_rm
13315 .param_str = "LLid"
13316 .target_set = TargetSet.initOne(.nvptx)
13317
13318__nvvm_d2ll_rn
13319 .param_str = "LLid"
13320 .target_set = TargetSet.initOne(.nvptx)
13321
13322__nvvm_d2ll_rp
13323 .param_str = "LLid"
13324 .target_set = TargetSet.initOne(.nvptx)
13325
13326__nvvm_d2ll_rz
13327 .param_str = "LLid"
13328 .target_set = TargetSet.initOne(.nvptx)
13329
13330__nvvm_d2ui_rm
13331 .param_str = "Uid"
13332 .target_set = TargetSet.initOne(.nvptx)
13333
13334__nvvm_d2ui_rn
13335 .param_str = "Uid"
13336 .target_set = TargetSet.initOne(.nvptx)
13337
13338__nvvm_d2ui_rp
13339 .param_str = "Uid"
13340 .target_set = TargetSet.initOne(.nvptx)
13341
13342__nvvm_d2ui_rz
13343 .param_str = "Uid"
13344 .target_set = TargetSet.initOne(.nvptx)
13345
13346__nvvm_d2ull_rm
13347 .param_str = "ULLid"
13348 .target_set = TargetSet.initOne(.nvptx)
13349
13350__nvvm_d2ull_rn
13351 .param_str = "ULLid"
13352 .target_set = TargetSet.initOne(.nvptx)
13353
13354__nvvm_d2ull_rp
13355 .param_str = "ULLid"
13356 .target_set = TargetSet.initOne(.nvptx)
13357
13358__nvvm_d2ull_rz
13359 .param_str = "ULLid"
13360 .target_set = TargetSet.initOne(.nvptx)
13361
13362__nvvm_div_approx_f
13363 .param_str = "fff"
13364 .target_set = TargetSet.initOne(.nvptx)
13365
13366__nvvm_div_approx_ftz_f
13367 .param_str = "fff"
13368 .target_set = TargetSet.initOne(.nvptx)
13369
13370__nvvm_div_rm_d
13371 .param_str = "ddd"
13372 .target_set = TargetSet.initOne(.nvptx)
13373
13374__nvvm_div_rm_f
13375 .param_str = "fff"
13376 .target_set = TargetSet.initOne(.nvptx)
13377
13378__nvvm_div_rm_ftz_f
13379 .param_str = "fff"
13380 .target_set = TargetSet.initOne(.nvptx)
13381
13382__nvvm_div_rn_d
13383 .param_str = "ddd"
13384 .target_set = TargetSet.initOne(.nvptx)
13385
13386__nvvm_div_rn_f
13387 .param_str = "fff"
13388 .target_set = TargetSet.initOne(.nvptx)
13389
13390__nvvm_div_rn_ftz_f
13391 .param_str = "fff"
13392 .target_set = TargetSet.initOne(.nvptx)
13393
13394__nvvm_div_rp_d
13395 .param_str = "ddd"
13396 .target_set = TargetSet.initOne(.nvptx)
13397
13398__nvvm_div_rp_f
13399 .param_str = "fff"
13400 .target_set = TargetSet.initOne(.nvptx)
13401
13402__nvvm_div_rp_ftz_f
13403 .param_str = "fff"
13404 .target_set = TargetSet.initOne(.nvptx)
13405
13406__nvvm_div_rz_d
13407 .param_str = "ddd"
13408 .target_set = TargetSet.initOne(.nvptx)
13409
13410__nvvm_div_rz_f
13411 .param_str = "fff"
13412 .target_set = TargetSet.initOne(.nvptx)
13413
13414__nvvm_div_rz_ftz_f
13415 .param_str = "fff"
13416 .target_set = TargetSet.initOne(.nvptx)
13417
13418__nvvm_ex2_approx_d
13419 .param_str = "dd"
13420 .target_set = TargetSet.initOne(.nvptx)
13421
13422__nvvm_ex2_approx_f
13423 .param_str = "ff"
13424 .target_set = TargetSet.initOne(.nvptx)
13425
13426__nvvm_ex2_approx_ftz_f
13427 .param_str = "ff"
13428 .target_set = TargetSet.initOne(.nvptx)
13429
13430__nvvm_f2h_rn
13431 .param_str = "Usf"
13432 .target_set = TargetSet.initOne(.nvptx)
13433
13434__nvvm_f2h_rn_ftz
13435 .param_str = "Usf"
13436 .target_set = TargetSet.initOne(.nvptx)
13437
13438__nvvm_f2i_rm
13439 .param_str = "if"
13440 .target_set = TargetSet.initOne(.nvptx)
13441
13442__nvvm_f2i_rm_ftz
13443 .param_str = "if"
13444 .target_set = TargetSet.initOne(.nvptx)
13445
13446__nvvm_f2i_rn
13447 .param_str = "if"
13448 .target_set = TargetSet.initOne(.nvptx)
13449
13450__nvvm_f2i_rn_ftz
13451 .param_str = "if"
13452 .target_set = TargetSet.initOne(.nvptx)
13453
13454__nvvm_f2i_rp
13455 .param_str = "if"
13456 .target_set = TargetSet.initOne(.nvptx)
13457
13458__nvvm_f2i_rp_ftz
13459 .param_str = "if"
13460 .target_set = TargetSet.initOne(.nvptx)
13461
13462__nvvm_f2i_rz
13463 .param_str = "if"
13464 .target_set = TargetSet.initOne(.nvptx)
13465
13466__nvvm_f2i_rz_ftz
13467 .param_str = "if"
13468 .target_set = TargetSet.initOne(.nvptx)
13469
13470__nvvm_f2ll_rm
13471 .param_str = "LLif"
13472 .target_set = TargetSet.initOne(.nvptx)
13473
13474__nvvm_f2ll_rm_ftz
13475 .param_str = "LLif"
13476 .target_set = TargetSet.initOne(.nvptx)
13477
13478__nvvm_f2ll_rn
13479 .param_str = "LLif"
13480 .target_set = TargetSet.initOne(.nvptx)
13481
13482__nvvm_f2ll_rn_ftz
13483 .param_str = "LLif"
13484 .target_set = TargetSet.initOne(.nvptx)
13485
13486__nvvm_f2ll_rp
13487 .param_str = "LLif"
13488 .target_set = TargetSet.initOne(.nvptx)
13489
13490__nvvm_f2ll_rp_ftz
13491 .param_str = "LLif"
13492 .target_set = TargetSet.initOne(.nvptx)
13493
13494__nvvm_f2ll_rz
13495 .param_str = "LLif"
13496 .target_set = TargetSet.initOne(.nvptx)
13497
13498__nvvm_f2ll_rz_ftz
13499 .param_str = "LLif"
13500 .target_set = TargetSet.initOne(.nvptx)
13501
13502__nvvm_f2ui_rm
13503 .param_str = "Uif"
13504 .target_set = TargetSet.initOne(.nvptx)
13505
13506__nvvm_f2ui_rm_ftz
13507 .param_str = "Uif"
13508 .target_set = TargetSet.initOne(.nvptx)
13509
13510__nvvm_f2ui_rn
13511 .param_str = "Uif"
13512 .target_set = TargetSet.initOne(.nvptx)
13513
13514__nvvm_f2ui_rn_ftz
13515 .param_str = "Uif"
13516 .target_set = TargetSet.initOne(.nvptx)
13517
13518__nvvm_f2ui_rp
13519 .param_str = "Uif"
13520 .target_set = TargetSet.initOne(.nvptx)
13521
13522__nvvm_f2ui_rp_ftz
13523 .param_str = "Uif"
13524 .target_set = TargetSet.initOne(.nvptx)
13525
13526__nvvm_f2ui_rz
13527 .param_str = "Uif"
13528 .target_set = TargetSet.initOne(.nvptx)
13529
13530__nvvm_f2ui_rz_ftz
13531 .param_str = "Uif"
13532 .target_set = TargetSet.initOne(.nvptx)
13533
13534__nvvm_f2ull_rm
13535 .param_str = "ULLif"
13536 .target_set = TargetSet.initOne(.nvptx)
13537
13538__nvvm_f2ull_rm_ftz
13539 .param_str = "ULLif"
13540 .target_set = TargetSet.initOne(.nvptx)
13541
13542__nvvm_f2ull_rn
13543 .param_str = "ULLif"
13544 .target_set = TargetSet.initOne(.nvptx)
13545
13546__nvvm_f2ull_rn_ftz
13547 .param_str = "ULLif"
13548 .target_set = TargetSet.initOne(.nvptx)
13549
13550__nvvm_f2ull_rp
13551 .param_str = "ULLif"
13552 .target_set = TargetSet.initOne(.nvptx)
13553
13554__nvvm_f2ull_rp_ftz
13555 .param_str = "ULLif"
13556 .target_set = TargetSet.initOne(.nvptx)
13557
13558__nvvm_f2ull_rz
13559 .param_str = "ULLif"
13560 .target_set = TargetSet.initOne(.nvptx)
13561
13562__nvvm_f2ull_rz_ftz
13563 .param_str = "ULLif"
13564 .target_set = TargetSet.initOne(.nvptx)
13565
13566__nvvm_fabs_d
13567 .param_str = "dd"
13568 .target_set = TargetSet.initOne(.nvptx)
13569
13570__nvvm_fabs_f
13571 .param_str = "ff"
13572 .target_set = TargetSet.initOne(.nvptx)
13573
13574__nvvm_fabs_ftz_f
13575 .param_str = "ff"
13576 .target_set = TargetSet.initOne(.nvptx)
13577
13578__nvvm_floor_d
13579 .param_str = "dd"
13580 .target_set = TargetSet.initOne(.nvptx)
13581
13582__nvvm_floor_f
13583 .param_str = "ff"
13584 .target_set = TargetSet.initOne(.nvptx)
13585
13586__nvvm_floor_ftz_f
13587 .param_str = "ff"
13588 .target_set = TargetSet.initOne(.nvptx)
13589
13590__nvvm_fma_rm_d
13591 .param_str = "dddd"
13592 .target_set = TargetSet.initOne(.nvptx)
13593
13594__nvvm_fma_rm_f
13595 .param_str = "ffff"
13596 .target_set = TargetSet.initOne(.nvptx)
13597
13598__nvvm_fma_rm_ftz_f
13599 .param_str = "ffff"
13600 .target_set = TargetSet.initOne(.nvptx)
13601
13602__nvvm_fma_rn_d
13603 .param_str = "dddd"
13604 .target_set = TargetSet.initOne(.nvptx)
13605
13606__nvvm_fma_rn_f
13607 .param_str = "ffff"
13608 .target_set = TargetSet.initOne(.nvptx)
13609
13610__nvvm_fma_rn_ftz_f
13611 .param_str = "ffff"
13612 .target_set = TargetSet.initOne(.nvptx)
13613
13614__nvvm_fma_rp_d
13615 .param_str = "dddd"
13616 .target_set = TargetSet.initOne(.nvptx)
13617
13618__nvvm_fma_rp_f
13619 .param_str = "ffff"
13620 .target_set = TargetSet.initOne(.nvptx)
13621
13622__nvvm_fma_rp_ftz_f
13623 .param_str = "ffff"
13624 .target_set = TargetSet.initOne(.nvptx)
13625
13626__nvvm_fma_rz_d
13627 .param_str = "dddd"
13628 .target_set = TargetSet.initOne(.nvptx)
13629
13630__nvvm_fma_rz_f
13631 .param_str = "ffff"
13632 .target_set = TargetSet.initOne(.nvptx)
13633
13634__nvvm_fma_rz_ftz_f
13635 .param_str = "ffff"
13636 .target_set = TargetSet.initOne(.nvptx)
13637
13638__nvvm_fmax_d
13639 .param_str = "ddd"
13640 .target_set = TargetSet.initOne(.nvptx)
13641
13642__nvvm_fmax_f
13643 .param_str = "fff"
13644 .target_set = TargetSet.initOne(.nvptx)
13645
13646__nvvm_fmax_ftz_f
13647 .param_str = "fff"
13648 .target_set = TargetSet.initOne(.nvptx)
13649
13650__nvvm_fmin_d
13651 .param_str = "ddd"
13652 .target_set = TargetSet.initOne(.nvptx)
13653
13654__nvvm_fmin_f
13655 .param_str = "fff"
13656 .target_set = TargetSet.initOne(.nvptx)
13657
13658__nvvm_fmin_ftz_f
13659 .param_str = "fff"
13660 .target_set = TargetSet.initOne(.nvptx)
13661
13662__nvvm_i2d_rm
13663 .param_str = "di"
13664 .target_set = TargetSet.initOne(.nvptx)
13665
13666__nvvm_i2d_rn
13667 .param_str = "di"
13668 .target_set = TargetSet.initOne(.nvptx)
13669
13670__nvvm_i2d_rp
13671 .param_str = "di"
13672 .target_set = TargetSet.initOne(.nvptx)
13673
13674__nvvm_i2d_rz
13675 .param_str = "di"
13676 .target_set = TargetSet.initOne(.nvptx)
13677
13678__nvvm_i2f_rm
13679 .param_str = "fi"
13680 .target_set = TargetSet.initOne(.nvptx)
13681
13682__nvvm_i2f_rn
13683 .param_str = "fi"
13684 .target_set = TargetSet.initOne(.nvptx)
13685
13686__nvvm_i2f_rp
13687 .param_str = "fi"
13688 .target_set = TargetSet.initOne(.nvptx)
13689
13690__nvvm_i2f_rz
13691 .param_str = "fi"
13692 .target_set = TargetSet.initOne(.nvptx)
13693
13694__nvvm_isspacep_const
13695 .param_str = "bvC*"
13696 .target_set = TargetSet.initOne(.nvptx)
13697 .attributes = .{ .@"const" = true }
13698
13699__nvvm_isspacep_global
13700 .param_str = "bvC*"
13701 .target_set = TargetSet.initOne(.nvptx)
13702 .attributes = .{ .@"const" = true }
13703
13704__nvvm_isspacep_local
13705 .param_str = "bvC*"
13706 .target_set = TargetSet.initOne(.nvptx)
13707 .attributes = .{ .@"const" = true }
13708
13709__nvvm_isspacep_shared
13710 .param_str = "bvC*"
13711 .target_set = TargetSet.initOne(.nvptx)
13712 .attributes = .{ .@"const" = true }
13713
13714__nvvm_ldg_c
13715 .param_str = "ccC*"
13716 .target_set = TargetSet.initOne(.nvptx)
13717
13718__nvvm_ldg_c2
13719 .param_str = "E2cE2cC*"
13720 .target_set = TargetSet.initOne(.nvptx)
13721
13722__nvvm_ldg_c4
13723 .param_str = "E4cE4cC*"
13724 .target_set = TargetSet.initOne(.nvptx)
13725
13726__nvvm_ldg_d
13727 .param_str = "ddC*"
13728 .target_set = TargetSet.initOne(.nvptx)
13729
13730__nvvm_ldg_d2
13731 .param_str = "E2dE2dC*"
13732 .target_set = TargetSet.initOne(.nvptx)
13733
13734__nvvm_ldg_f
13735 .param_str = "ffC*"
13736 .target_set = TargetSet.initOne(.nvptx)
13737
13738__nvvm_ldg_f2
13739 .param_str = "E2fE2fC*"
13740 .target_set = TargetSet.initOne(.nvptx)
13741
13742__nvvm_ldg_f4
13743 .param_str = "E4fE4fC*"
13744 .target_set = TargetSet.initOne(.nvptx)
13745
13746__nvvm_ldg_h
13747 .param_str = "hhC*"
13748 .target_set = TargetSet.initOne(.nvptx)
13749
13750__nvvm_ldg_h2
13751 .param_str = "E2hE2hC*"
13752 .target_set = TargetSet.initOne(.nvptx)
13753
13754__nvvm_ldg_i
13755 .param_str = "iiC*"
13756 .target_set = TargetSet.initOne(.nvptx)
13757
13758__nvvm_ldg_i2
13759 .param_str = "E2iE2iC*"
13760 .target_set = TargetSet.initOne(.nvptx)
13761
13762__nvvm_ldg_i4
13763 .param_str = "E4iE4iC*"
13764 .target_set = TargetSet.initOne(.nvptx)
13765
13766__nvvm_ldg_l
13767 .param_str = "LiLiC*"
13768 .target_set = TargetSet.initOne(.nvptx)
13769
13770__nvvm_ldg_l2
13771 .param_str = "E2LiE2LiC*"
13772 .target_set = TargetSet.initOne(.nvptx)
13773
13774__nvvm_ldg_ll
13775 .param_str = "LLiLLiC*"
13776 .target_set = TargetSet.initOne(.nvptx)
13777
13778__nvvm_ldg_ll2
13779 .param_str = "E2LLiE2LLiC*"
13780 .target_set = TargetSet.initOne(.nvptx)
13781
13782__nvvm_ldg_s
13783 .param_str = "ssC*"
13784 .target_set = TargetSet.initOne(.nvptx)
13785
13786__nvvm_ldg_s2
13787 .param_str = "E2sE2sC*"
13788 .target_set = TargetSet.initOne(.nvptx)
13789
13790__nvvm_ldg_s4
13791 .param_str = "E4sE4sC*"
13792 .target_set = TargetSet.initOne(.nvptx)
13793
13794__nvvm_ldg_sc
13795 .param_str = "ScScC*"
13796 .target_set = TargetSet.initOne(.nvptx)
13797
13798__nvvm_ldg_sc2
13799 .param_str = "E2ScE2ScC*"
13800 .target_set = TargetSet.initOne(.nvptx)
13801
13802__nvvm_ldg_sc4
13803 .param_str = "E4ScE4ScC*"
13804 .target_set = TargetSet.initOne(.nvptx)
13805
13806__nvvm_ldg_uc
13807 .param_str = "UcUcC*"
13808 .target_set = TargetSet.initOne(.nvptx)
13809
13810__nvvm_ldg_uc2
13811 .param_str = "E2UcE2UcC*"
13812 .target_set = TargetSet.initOne(.nvptx)
13813
13814__nvvm_ldg_uc4
13815 .param_str = "E4UcE4UcC*"
13816 .target_set = TargetSet.initOne(.nvptx)
13817
13818__nvvm_ldg_ui
13819 .param_str = "UiUiC*"
13820 .target_set = TargetSet.initOne(.nvptx)
13821
13822__nvvm_ldg_ui2
13823 .param_str = "E2UiE2UiC*"
13824 .target_set = TargetSet.initOne(.nvptx)
13825
13826__nvvm_ldg_ui4
13827 .param_str = "E4UiE4UiC*"
13828 .target_set = TargetSet.initOne(.nvptx)
13829
13830__nvvm_ldg_ul
13831 .param_str = "ULiULiC*"
13832 .target_set = TargetSet.initOne(.nvptx)
13833
13834__nvvm_ldg_ul2
13835 .param_str = "E2ULiE2ULiC*"
13836 .target_set = TargetSet.initOne(.nvptx)
13837
13838__nvvm_ldg_ull
13839 .param_str = "ULLiULLiC*"
13840 .target_set = TargetSet.initOne(.nvptx)
13841
13842__nvvm_ldg_ull2
13843 .param_str = "E2ULLiE2ULLiC*"
13844 .target_set = TargetSet.initOne(.nvptx)
13845
13846__nvvm_ldg_us
13847 .param_str = "UsUsC*"
13848 .target_set = TargetSet.initOne(.nvptx)
13849
13850__nvvm_ldg_us2
13851 .param_str = "E2UsE2UsC*"
13852 .target_set = TargetSet.initOne(.nvptx)
13853
13854__nvvm_ldg_us4
13855 .param_str = "E4UsE4UsC*"
13856 .target_set = TargetSet.initOne(.nvptx)
13857
13858__nvvm_ldu_c
13859 .param_str = "ccC*"
13860 .target_set = TargetSet.initOne(.nvptx)
13861
13862__nvvm_ldu_c2
13863 .param_str = "E2cE2cC*"
13864 .target_set = TargetSet.initOne(.nvptx)
13865
13866__nvvm_ldu_c4
13867 .param_str = "E4cE4cC*"
13868 .target_set = TargetSet.initOne(.nvptx)
13869
13870__nvvm_ldu_d
13871 .param_str = "ddC*"
13872 .target_set = TargetSet.initOne(.nvptx)
13873
13874__nvvm_ldu_d2
13875 .param_str = "E2dE2dC*"
13876 .target_set = TargetSet.initOne(.nvptx)
13877
13878__nvvm_ldu_f
13879 .param_str = "ffC*"
13880 .target_set = TargetSet.initOne(.nvptx)
13881
13882__nvvm_ldu_f2
13883 .param_str = "E2fE2fC*"
13884 .target_set = TargetSet.initOne(.nvptx)
13885
13886__nvvm_ldu_f4
13887 .param_str = "E4fE4fC*"
13888 .target_set = TargetSet.initOne(.nvptx)
13889
13890__nvvm_ldu_h
13891 .param_str = "hhC*"
13892 .target_set = TargetSet.initOne(.nvptx)
13893
13894__nvvm_ldu_h2
13895 .param_str = "E2hE2hC*"
13896 .target_set = TargetSet.initOne(.nvptx)
13897
13898__nvvm_ldu_i
13899 .param_str = "iiC*"
13900 .target_set = TargetSet.initOne(.nvptx)
13901
13902__nvvm_ldu_i2
13903 .param_str = "E2iE2iC*"
13904 .target_set = TargetSet.initOne(.nvptx)
13905
13906__nvvm_ldu_i4
13907 .param_str = "E4iE4iC*"
13908 .target_set = TargetSet.initOne(.nvptx)
13909
13910__nvvm_ldu_l
13911 .param_str = "LiLiC*"
13912 .target_set = TargetSet.initOne(.nvptx)
13913
13914__nvvm_ldu_l2
13915 .param_str = "E2LiE2LiC*"
13916 .target_set = TargetSet.initOne(.nvptx)
13917
13918__nvvm_ldu_ll
13919 .param_str = "LLiLLiC*"
13920 .target_set = TargetSet.initOne(.nvptx)
13921
13922__nvvm_ldu_ll2
13923 .param_str = "E2LLiE2LLiC*"
13924 .target_set = TargetSet.initOne(.nvptx)
13925
13926__nvvm_ldu_s
13927 .param_str = "ssC*"
13928 .target_set = TargetSet.initOne(.nvptx)
13929
13930__nvvm_ldu_s2
13931 .param_str = "E2sE2sC*"
13932 .target_set = TargetSet.initOne(.nvptx)
13933
13934__nvvm_ldu_s4
13935 .param_str = "E4sE4sC*"
13936 .target_set = TargetSet.initOne(.nvptx)
13937
13938__nvvm_ldu_sc
13939 .param_str = "ScScC*"
13940 .target_set = TargetSet.initOne(.nvptx)
13941
13942__nvvm_ldu_sc2
13943 .param_str = "E2ScE2ScC*"
13944 .target_set = TargetSet.initOne(.nvptx)
13945
13946__nvvm_ldu_sc4
13947 .param_str = "E4ScE4ScC*"
13948 .target_set = TargetSet.initOne(.nvptx)
13949
13950__nvvm_ldu_uc
13951 .param_str = "UcUcC*"
13952 .target_set = TargetSet.initOne(.nvptx)
13953
13954__nvvm_ldu_uc2
13955 .param_str = "E2UcE2UcC*"
13956 .target_set = TargetSet.initOne(.nvptx)
13957
13958__nvvm_ldu_uc4
13959 .param_str = "E4UcE4UcC*"
13960 .target_set = TargetSet.initOne(.nvptx)
13961
13962__nvvm_ldu_ui
13963 .param_str = "UiUiC*"
13964 .target_set = TargetSet.initOne(.nvptx)
13965
13966__nvvm_ldu_ui2
13967 .param_str = "E2UiE2UiC*"
13968 .target_set = TargetSet.initOne(.nvptx)
13969
13970__nvvm_ldu_ui4
13971 .param_str = "E4UiE4UiC*"
13972 .target_set = TargetSet.initOne(.nvptx)
13973
13974__nvvm_ldu_ul
13975 .param_str = "ULiULiC*"
13976 .target_set = TargetSet.initOne(.nvptx)
13977
13978__nvvm_ldu_ul2
13979 .param_str = "E2ULiE2ULiC*"
13980 .target_set = TargetSet.initOne(.nvptx)
13981
13982__nvvm_ldu_ull
13983 .param_str = "ULLiULLiC*"
13984 .target_set = TargetSet.initOne(.nvptx)
13985
13986__nvvm_ldu_ull2
13987 .param_str = "E2ULLiE2ULLiC*"
13988 .target_set = TargetSet.initOne(.nvptx)
13989
13990__nvvm_ldu_us
13991 .param_str = "UsUsC*"
13992 .target_set = TargetSet.initOne(.nvptx)
13993
13994__nvvm_ldu_us2
13995 .param_str = "E2UsE2UsC*"
13996 .target_set = TargetSet.initOne(.nvptx)
13997
13998__nvvm_ldu_us4
13999 .param_str = "E4UsE4UsC*"
14000 .target_set = TargetSet.initOne(.nvptx)
14001
14002__nvvm_lg2_approx_d
14003 .param_str = "dd"
14004 .target_set = TargetSet.initOne(.nvptx)
14005
14006__nvvm_lg2_approx_f
14007 .param_str = "ff"
14008 .target_set = TargetSet.initOne(.nvptx)
14009
14010__nvvm_lg2_approx_ftz_f
14011 .param_str = "ff"
14012 .target_set = TargetSet.initOne(.nvptx)
14013
14014__nvvm_ll2d_rm
14015 .param_str = "dLLi"
14016 .target_set = TargetSet.initOne(.nvptx)
14017
14018__nvvm_ll2d_rn
14019 .param_str = "dLLi"
14020 .target_set = TargetSet.initOne(.nvptx)
14021
14022__nvvm_ll2d_rp
14023 .param_str = "dLLi"
14024 .target_set = TargetSet.initOne(.nvptx)
14025
14026__nvvm_ll2d_rz
14027 .param_str = "dLLi"
14028 .target_set = TargetSet.initOne(.nvptx)
14029
14030__nvvm_ll2f_rm
14031 .param_str = "fLLi"
14032 .target_set = TargetSet.initOne(.nvptx)
14033
14034__nvvm_ll2f_rn
14035 .param_str = "fLLi"
14036 .target_set = TargetSet.initOne(.nvptx)
14037
14038__nvvm_ll2f_rp
14039 .param_str = "fLLi"
14040 .target_set = TargetSet.initOne(.nvptx)
14041
14042__nvvm_ll2f_rz
14043 .param_str = "fLLi"
14044 .target_set = TargetSet.initOne(.nvptx)
14045
14046__nvvm_lohi_i2d
14047 .param_str = "dii"
14048 .target_set = TargetSet.initOne(.nvptx)
14049
14050__nvvm_membar_cta
14051 .param_str = "v"
14052 .target_set = TargetSet.initOne(.nvptx)
14053
14054__nvvm_membar_gl
14055 .param_str = "v"
14056 .target_set = TargetSet.initOne(.nvptx)
14057
14058__nvvm_membar_sys
14059 .param_str = "v"
14060 .target_set = TargetSet.initOne(.nvptx)
14061
14062__nvvm_memcpy
14063 .param_str = "vUc*Uc*zi"
14064 .target_set = TargetSet.initOne(.nvptx)
14065
14066__nvvm_memset
14067 .param_str = "vUc*Uczi"
14068 .target_set = TargetSet.initOne(.nvptx)
14069
14070__nvvm_mul24_i
14071 .param_str = "iii"
14072 .target_set = TargetSet.initOne(.nvptx)
14073
14074__nvvm_mul24_ui
14075 .param_str = "UiUiUi"
14076 .target_set = TargetSet.initOne(.nvptx)
14077
14078__nvvm_mul_rm_d
14079 .param_str = "ddd"
14080 .target_set = TargetSet.initOne(.nvptx)
14081
14082__nvvm_mul_rm_f
14083 .param_str = "fff"
14084 .target_set = TargetSet.initOne(.nvptx)
14085
14086__nvvm_mul_rm_ftz_f
14087 .param_str = "fff"
14088 .target_set = TargetSet.initOne(.nvptx)
14089
14090__nvvm_mul_rn_d
14091 .param_str = "ddd"
14092 .target_set = TargetSet.initOne(.nvptx)
14093
14094__nvvm_mul_rn_f
14095 .param_str = "fff"
14096 .target_set = TargetSet.initOne(.nvptx)
14097
14098__nvvm_mul_rn_ftz_f
14099 .param_str = "fff"
14100 .target_set = TargetSet.initOne(.nvptx)
14101
14102__nvvm_mul_rp_d
14103 .param_str = "ddd"
14104 .target_set = TargetSet.initOne(.nvptx)
14105
14106__nvvm_mul_rp_f
14107 .param_str = "fff"
14108 .target_set = TargetSet.initOne(.nvptx)
14109
14110__nvvm_mul_rp_ftz_f
14111 .param_str = "fff"
14112 .target_set = TargetSet.initOne(.nvptx)
14113
14114__nvvm_mul_rz_d
14115 .param_str = "ddd"
14116 .target_set = TargetSet.initOne(.nvptx)
14117
14118__nvvm_mul_rz_f
14119 .param_str = "fff"
14120 .target_set = TargetSet.initOne(.nvptx)
14121
14122__nvvm_mul_rz_ftz_f
14123 .param_str = "fff"
14124 .target_set = TargetSet.initOne(.nvptx)
14125
14126__nvvm_mulhi_i
14127 .param_str = "iii"
14128 .target_set = TargetSet.initOne(.nvptx)
14129
14130__nvvm_mulhi_ll
14131 .param_str = "LLiLLiLLi"
14132 .target_set = TargetSet.initOne(.nvptx)
14133
14134__nvvm_mulhi_ui
14135 .param_str = "UiUiUi"
14136 .target_set = TargetSet.initOne(.nvptx)
14137
14138__nvvm_mulhi_ull
14139 .param_str = "ULLiULLiULLi"
14140 .target_set = TargetSet.initOne(.nvptx)
14141
14142__nvvm_prmt
14143 .param_str = "UiUiUiUi"
14144 .target_set = TargetSet.initOne(.nvptx)
14145
14146__nvvm_rcp_approx_ftz_d
14147 .param_str = "dd"
14148 .target_set = TargetSet.initOne(.nvptx)
14149
14150__nvvm_rcp_approx_ftz_f
14151 .param_str = "ff"
14152 .target_set = TargetSet.initOne(.nvptx)
14153
14154__nvvm_rcp_rm_d
14155 .param_str = "dd"
14156 .target_set = TargetSet.initOne(.nvptx)
14157
14158__nvvm_rcp_rm_f
14159 .param_str = "ff"
14160 .target_set = TargetSet.initOne(.nvptx)
14161
14162__nvvm_rcp_rm_ftz_f
14163 .param_str = "ff"
14164 .target_set = TargetSet.initOne(.nvptx)
14165
14166__nvvm_rcp_rn_d
14167 .param_str = "dd"
14168 .target_set = TargetSet.initOne(.nvptx)
14169
14170__nvvm_rcp_rn_f
14171 .param_str = "ff"
14172 .target_set = TargetSet.initOne(.nvptx)
14173
14174__nvvm_rcp_rn_ftz_f
14175 .param_str = "ff"
14176 .target_set = TargetSet.initOne(.nvptx)
14177
14178__nvvm_rcp_rp_d
14179 .param_str = "dd"
14180 .target_set = TargetSet.initOne(.nvptx)
14181
14182__nvvm_rcp_rp_f
14183 .param_str = "ff"
14184 .target_set = TargetSet.initOne(.nvptx)
14185
14186__nvvm_rcp_rp_ftz_f
14187 .param_str = "ff"
14188 .target_set = TargetSet.initOne(.nvptx)
14189
14190__nvvm_rcp_rz_d
14191 .param_str = "dd"
14192 .target_set = TargetSet.initOne(.nvptx)
14193
14194__nvvm_rcp_rz_f
14195 .param_str = "ff"
14196 .target_set = TargetSet.initOne(.nvptx)
14197
14198__nvvm_rcp_rz_ftz_f
14199 .param_str = "ff"
14200 .target_set = TargetSet.initOne(.nvptx)
14201
14202__nvvm_read_ptx_sreg_clock
14203 .param_str = "i"
14204 .target_set = TargetSet.initOne(.nvptx)
14205
14206__nvvm_read_ptx_sreg_clock64
14207 .param_str = "LLi"
14208 .target_set = TargetSet.initOne(.nvptx)
14209
14210__nvvm_read_ptx_sreg_ctaid_w
14211 .param_str = "i"
14212 .target_set = TargetSet.initOne(.nvptx)
14213 .attributes = .{ .@"const" = true }
14214
14215__nvvm_read_ptx_sreg_ctaid_x
14216 .param_str = "i"
14217 .target_set = TargetSet.initOne(.nvptx)
14218 .attributes = .{ .@"const" = true }
14219
14220__nvvm_read_ptx_sreg_ctaid_y
14221 .param_str = "i"
14222 .target_set = TargetSet.initOne(.nvptx)
14223 .attributes = .{ .@"const" = true }
14224
14225__nvvm_read_ptx_sreg_ctaid_z
14226 .param_str = "i"
14227 .target_set = TargetSet.initOne(.nvptx)
14228 .attributes = .{ .@"const" = true }
14229
14230__nvvm_read_ptx_sreg_gridid
14231 .param_str = "i"
14232 .target_set = TargetSet.initOne(.nvptx)
14233 .attributes = .{ .@"const" = true }
14234
14235__nvvm_read_ptx_sreg_laneid
14236 .param_str = "i"
14237 .target_set = TargetSet.initOne(.nvptx)
14238 .attributes = .{ .@"const" = true }
14239
14240__nvvm_read_ptx_sreg_lanemask_eq
14241 .param_str = "i"
14242 .target_set = TargetSet.initOne(.nvptx)
14243 .attributes = .{ .@"const" = true }
14244
14245__nvvm_read_ptx_sreg_lanemask_ge
14246 .param_str = "i"
14247 .target_set = TargetSet.initOne(.nvptx)
14248 .attributes = .{ .@"const" = true }
14249
14250__nvvm_read_ptx_sreg_lanemask_gt
14251 .param_str = "i"
14252 .target_set = TargetSet.initOne(.nvptx)
14253 .attributes = .{ .@"const" = true }
14254
14255__nvvm_read_ptx_sreg_lanemask_le
14256 .param_str = "i"
14257 .target_set = TargetSet.initOne(.nvptx)
14258 .attributes = .{ .@"const" = true }
14259
14260__nvvm_read_ptx_sreg_lanemask_lt
14261 .param_str = "i"
14262 .target_set = TargetSet.initOne(.nvptx)
14263 .attributes = .{ .@"const" = true }
14264
14265__nvvm_read_ptx_sreg_nctaid_w
14266 .param_str = "i"
14267 .target_set = TargetSet.initOne(.nvptx)
14268 .attributes = .{ .@"const" = true }
14269
14270__nvvm_read_ptx_sreg_nctaid_x
14271 .param_str = "i"
14272 .target_set = TargetSet.initOne(.nvptx)
14273 .attributes = .{ .@"const" = true }
14274
14275__nvvm_read_ptx_sreg_nctaid_y
14276 .param_str = "i"
14277 .target_set = TargetSet.initOne(.nvptx)
14278 .attributes = .{ .@"const" = true }
14279
14280__nvvm_read_ptx_sreg_nctaid_z
14281 .param_str = "i"
14282 .target_set = TargetSet.initOne(.nvptx)
14283 .attributes = .{ .@"const" = true }
14284
14285__nvvm_read_ptx_sreg_nsmid
14286 .param_str = "i"
14287 .target_set = TargetSet.initOne(.nvptx)
14288 .attributes = .{ .@"const" = true }
14289
14290__nvvm_read_ptx_sreg_ntid_w
14291 .param_str = "i"
14292 .target_set = TargetSet.initOne(.nvptx)
14293 .attributes = .{ .@"const" = true }
14294
14295__nvvm_read_ptx_sreg_ntid_x
14296 .param_str = "i"
14297 .target_set = TargetSet.initOne(.nvptx)
14298 .attributes = .{ .@"const" = true }
14299
14300__nvvm_read_ptx_sreg_ntid_y
14301 .param_str = "i"
14302 .target_set = TargetSet.initOne(.nvptx)
14303 .attributes = .{ .@"const" = true }
14304
14305__nvvm_read_ptx_sreg_ntid_z
14306 .param_str = "i"
14307 .target_set = TargetSet.initOne(.nvptx)
14308 .attributes = .{ .@"const" = true }
14309
14310__nvvm_read_ptx_sreg_nwarpid
14311 .param_str = "i"
14312 .target_set = TargetSet.initOne(.nvptx)
14313 .attributes = .{ .@"const" = true }
14314
14315__nvvm_read_ptx_sreg_pm0
14316 .param_str = "i"
14317 .target_set = TargetSet.initOne(.nvptx)
14318
14319__nvvm_read_ptx_sreg_pm1
14320 .param_str = "i"
14321 .target_set = TargetSet.initOne(.nvptx)
14322
14323__nvvm_read_ptx_sreg_pm2
14324 .param_str = "i"
14325 .target_set = TargetSet.initOne(.nvptx)
14326
14327__nvvm_read_ptx_sreg_pm3
14328 .param_str = "i"
14329 .target_set = TargetSet.initOne(.nvptx)
14330
14331__nvvm_read_ptx_sreg_smid
14332 .param_str = "i"
14333 .target_set = TargetSet.initOne(.nvptx)
14334 .attributes = .{ .@"const" = true }
14335
14336__nvvm_read_ptx_sreg_tid_w
14337 .param_str = "i"
14338 .target_set = TargetSet.initOne(.nvptx)
14339 .attributes = .{ .@"const" = true }
14340
14341__nvvm_read_ptx_sreg_tid_x
14342 .param_str = "i"
14343 .target_set = TargetSet.initOne(.nvptx)
14344 .attributes = .{ .@"const" = true }
14345
14346__nvvm_read_ptx_sreg_tid_y
14347 .param_str = "i"
14348 .target_set = TargetSet.initOne(.nvptx)
14349 .attributes = .{ .@"const" = true }
14350
14351__nvvm_read_ptx_sreg_tid_z
14352 .param_str = "i"
14353 .target_set = TargetSet.initOne(.nvptx)
14354 .attributes = .{ .@"const" = true }
14355
14356__nvvm_read_ptx_sreg_warpid
14357 .param_str = "i"
14358 .target_set = TargetSet.initOne(.nvptx)
14359 .attributes = .{ .@"const" = true }
14360
14361__nvvm_round_d
14362 .param_str = "dd"
14363 .target_set = TargetSet.initOne(.nvptx)
14364
14365__nvvm_round_f
14366 .param_str = "ff"
14367 .target_set = TargetSet.initOne(.nvptx)
14368
14369__nvvm_round_ftz_f
14370 .param_str = "ff"
14371 .target_set = TargetSet.initOne(.nvptx)
14372
14373__nvvm_rsqrt_approx_d
14374 .param_str = "dd"
14375 .target_set = TargetSet.initOne(.nvptx)
14376
14377__nvvm_rsqrt_approx_f
14378 .param_str = "ff"
14379 .target_set = TargetSet.initOne(.nvptx)
14380
14381__nvvm_rsqrt_approx_ftz_f
14382 .param_str = "ff"
14383 .target_set = TargetSet.initOne(.nvptx)
14384
14385__nvvm_sad_i
14386 .param_str = "iiii"
14387 .target_set = TargetSet.initOne(.nvptx)
14388
14389__nvvm_sad_ui
14390 .param_str = "UiUiUiUi"
14391 .target_set = TargetSet.initOne(.nvptx)
14392
14393__nvvm_saturate_d
14394 .param_str = "dd"
14395 .target_set = TargetSet.initOne(.nvptx)
14396
14397__nvvm_saturate_f
14398 .param_str = "ff"
14399 .target_set = TargetSet.initOne(.nvptx)
14400
14401__nvvm_saturate_ftz_f
14402 .param_str = "ff"
14403 .target_set = TargetSet.initOne(.nvptx)
14404
14405__nvvm_shfl_bfly_f32
14406 .param_str = "ffii"
14407 .target_set = TargetSet.initOne(.nvptx)
14408
14409__nvvm_shfl_bfly_i32
14410 .param_str = "iiii"
14411 .target_set = TargetSet.initOne(.nvptx)
14412
14413__nvvm_shfl_down_f32
14414 .param_str = "ffii"
14415 .target_set = TargetSet.initOne(.nvptx)
14416
14417__nvvm_shfl_down_i32
14418 .param_str = "iiii"
14419 .target_set = TargetSet.initOne(.nvptx)
14420
14421__nvvm_shfl_idx_f32
14422 .param_str = "ffii"
14423 .target_set = TargetSet.initOne(.nvptx)
14424
14425__nvvm_shfl_idx_i32
14426 .param_str = "iiii"
14427 .target_set = TargetSet.initOne(.nvptx)
14428
14429__nvvm_shfl_up_f32
14430 .param_str = "ffii"
14431 .target_set = TargetSet.initOne(.nvptx)
14432
14433__nvvm_shfl_up_i32
14434 .param_str = "iiii"
14435 .target_set = TargetSet.initOne(.nvptx)
14436
14437__nvvm_sin_approx_f
14438 .param_str = "ff"
14439 .target_set = TargetSet.initOne(.nvptx)
14440
14441__nvvm_sin_approx_ftz_f
14442 .param_str = "ff"
14443 .target_set = TargetSet.initOne(.nvptx)
14444
14445__nvvm_sqrt_approx_f
14446 .param_str = "ff"
14447 .target_set = TargetSet.initOne(.nvptx)
14448
14449__nvvm_sqrt_approx_ftz_f
14450 .param_str = "ff"
14451 .target_set = TargetSet.initOne(.nvptx)
14452
14453__nvvm_sqrt_rm_d
14454 .param_str = "dd"
14455 .target_set = TargetSet.initOne(.nvptx)
14456
14457__nvvm_sqrt_rm_f
14458 .param_str = "ff"
14459 .target_set = TargetSet.initOne(.nvptx)
14460
14461__nvvm_sqrt_rm_ftz_f
14462 .param_str = "ff"
14463 .target_set = TargetSet.initOne(.nvptx)
14464
14465__nvvm_sqrt_rn_d
14466 .param_str = "dd"
14467 .target_set = TargetSet.initOne(.nvptx)
14468
14469__nvvm_sqrt_rn_f
14470 .param_str = "ff"
14471 .target_set = TargetSet.initOne(.nvptx)
14472
14473__nvvm_sqrt_rn_ftz_f
14474 .param_str = "ff"
14475 .target_set = TargetSet.initOne(.nvptx)
14476
14477__nvvm_sqrt_rp_d
14478 .param_str = "dd"
14479 .target_set = TargetSet.initOne(.nvptx)
14480
14481__nvvm_sqrt_rp_f
14482 .param_str = "ff"
14483 .target_set = TargetSet.initOne(.nvptx)
14484
14485__nvvm_sqrt_rp_ftz_f
14486 .param_str = "ff"
14487 .target_set = TargetSet.initOne(.nvptx)
14488
14489__nvvm_sqrt_rz_d
14490 .param_str = "dd"
14491 .target_set = TargetSet.initOne(.nvptx)
14492
14493__nvvm_sqrt_rz_f
14494 .param_str = "ff"
14495 .target_set = TargetSet.initOne(.nvptx)
14496
14497__nvvm_sqrt_rz_ftz_f
14498 .param_str = "ff"
14499 .target_set = TargetSet.initOne(.nvptx)
14500
14501__nvvm_trunc_d
14502 .param_str = "dd"
14503 .target_set = TargetSet.initOne(.nvptx)
14504
14505__nvvm_trunc_f
14506 .param_str = "ff"
14507 .target_set = TargetSet.initOne(.nvptx)
14508
14509__nvvm_trunc_ftz_f
14510 .param_str = "ff"
14511 .target_set = TargetSet.initOne(.nvptx)
14512
14513__nvvm_ui2d_rm
14514 .param_str = "dUi"
14515 .target_set = TargetSet.initOne(.nvptx)
14516
14517__nvvm_ui2d_rn
14518 .param_str = "dUi"
14519 .target_set = TargetSet.initOne(.nvptx)
14520
14521__nvvm_ui2d_rp
14522 .param_str = "dUi"
14523 .target_set = TargetSet.initOne(.nvptx)
14524
14525__nvvm_ui2d_rz
14526 .param_str = "dUi"
14527 .target_set = TargetSet.initOne(.nvptx)
14528
14529__nvvm_ui2f_rm
14530 .param_str = "fUi"
14531 .target_set = TargetSet.initOne(.nvptx)
14532
14533__nvvm_ui2f_rn
14534 .param_str = "fUi"
14535 .target_set = TargetSet.initOne(.nvptx)
14536
14537__nvvm_ui2f_rp
14538 .param_str = "fUi"
14539 .target_set = TargetSet.initOne(.nvptx)
14540
14541__nvvm_ui2f_rz
14542 .param_str = "fUi"
14543 .target_set = TargetSet.initOne(.nvptx)
14544
14545__nvvm_ull2d_rm
14546 .param_str = "dULLi"
14547 .target_set = TargetSet.initOne(.nvptx)
14548
14549__nvvm_ull2d_rn
14550 .param_str = "dULLi"
14551 .target_set = TargetSet.initOne(.nvptx)
14552
14553__nvvm_ull2d_rp
14554 .param_str = "dULLi"
14555 .target_set = TargetSet.initOne(.nvptx)
14556
14557__nvvm_ull2d_rz
14558 .param_str = "dULLi"
14559 .target_set = TargetSet.initOne(.nvptx)
14560
14561__nvvm_ull2f_rm
14562 .param_str = "fULLi"
14563 .target_set = TargetSet.initOne(.nvptx)
14564
14565__nvvm_ull2f_rn
14566 .param_str = "fULLi"
14567 .target_set = TargetSet.initOne(.nvptx)
14568
14569__nvvm_ull2f_rp
14570 .param_str = "fULLi"
14571 .target_set = TargetSet.initOne(.nvptx)
14572
14573__nvvm_ull2f_rz
14574 .param_str = "fULLi"
14575 .target_set = TargetSet.initOne(.nvptx)
14576
14577__nvvm_vote_all
14578 .param_str = "bb"
14579 .target_set = TargetSet.initOne(.nvptx)
14580
14581__nvvm_vote_any
14582 .param_str = "bb"
14583 .target_set = TargetSet.initOne(.nvptx)
14584
14585__nvvm_vote_ballot
14586 .param_str = "Uib"
14587 .target_set = TargetSet.initOne(.nvptx)
14588
14589__nvvm_vote_uni
14590 .param_str = "bb"
14591 .target_set = TargetSet.initOne(.nvptx)
14592
14593__popcnt
14594 .param_str = "UiUi"
14595 .language = .all_ms_languages
14596 .attributes = .{ .@"const" = true, .const_evaluable = true }
14597
14598__popcnt16
14599 .param_str = "UsUs"
14600 .language = .all_ms_languages
14601 .attributes = .{ .@"const" = true, .const_evaluable = true }
14602
14603__popcnt64
14604 .param_str = "UWiUWi"
14605 .language = .all_ms_languages
14606 .attributes = .{ .@"const" = true, .const_evaluable = true }
14607
14608__rdtsc
14609 .param_str = "UOi"
14610 .target_set = TargetSet.initOne(.x86)
14611
14612__sev
14613 .param_str = "v"
14614 .language = .all_ms_languages
14615 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
14616
14617__sevl
14618 .param_str = "v"
14619 .language = .all_ms_languages
14620 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
14621
14622__sigsetjmp
14623 .param_str = "iSJi"
14624 .header = .setjmp
14625 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
14626
14627__sinpi
14628 .param_str = "dd"
14629 .header = .math
14630 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
14631
14632__sinpif
14633 .param_str = "ff"
14634 .header = .math
14635 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
14636
14637__sync_add_and_fetch
14638 .param_str = "v."
14639 .attributes = .{ .custom_typecheck = true }
14640
14641__sync_add_and_fetch_1
14642 .param_str = "ccD*c."
14643 .attributes = .{ .custom_typecheck = true }
14644
14645__sync_add_and_fetch_16
14646 .param_str = "LLLiLLLiD*LLLi."
14647 .attributes = .{ .custom_typecheck = true }
14648
14649__sync_add_and_fetch_2
14650 .param_str = "ssD*s."
14651 .attributes = .{ .custom_typecheck = true }
14652
14653__sync_add_and_fetch_4
14654 .param_str = "iiD*i."
14655 .attributes = .{ .custom_typecheck = true }
14656
14657__sync_add_and_fetch_8
14658 .param_str = "LLiLLiD*LLi."
14659 .attributes = .{ .custom_typecheck = true }
14660
14661__sync_and_and_fetch
14662 .param_str = "v."
14663 .attributes = .{ .custom_typecheck = true }
14664
14665__sync_and_and_fetch_1
14666 .param_str = "ccD*c."
14667 .attributes = .{ .custom_typecheck = true }
14668
14669__sync_and_and_fetch_16
14670 .param_str = "LLLiLLLiD*LLLi."
14671 .attributes = .{ .custom_typecheck = true }
14672
14673__sync_and_and_fetch_2
14674 .param_str = "ssD*s."
14675 .attributes = .{ .custom_typecheck = true }
14676
14677__sync_and_and_fetch_4
14678 .param_str = "iiD*i."
14679 .attributes = .{ .custom_typecheck = true }
14680
14681__sync_and_and_fetch_8
14682 .param_str = "LLiLLiD*LLi."
14683 .attributes = .{ .custom_typecheck = true }
14684
14685__sync_bool_compare_and_swap
14686 .param_str = "v."
14687 .attributes = .{ .custom_typecheck = true }
14688
14689__sync_bool_compare_and_swap_1
14690 .param_str = "bcD*cc."
14691 .attributes = .{ .custom_typecheck = true }
14692
14693__sync_bool_compare_and_swap_16
14694 .param_str = "bLLLiD*LLLiLLLi."
14695 .attributes = .{ .custom_typecheck = true }
14696
14697__sync_bool_compare_and_swap_2
14698 .param_str = "bsD*ss."
14699 .attributes = .{ .custom_typecheck = true }
14700
14701__sync_bool_compare_and_swap_4
14702 .param_str = "biD*ii."
14703 .attributes = .{ .custom_typecheck = true }
14704
14705__sync_bool_compare_and_swap_8
14706 .param_str = "bLLiD*LLiLLi."
14707 .attributes = .{ .custom_typecheck = true }
14708
14709__sync_fetch_and_add
14710 .param_str = "v."
14711 .attributes = .{ .custom_typecheck = true }
14712
14713__sync_fetch_and_add_1
14714 .param_str = "ccD*c."
14715 .attributes = .{ .custom_typecheck = true }
14716
14717__sync_fetch_and_add_16
14718 .param_str = "LLLiLLLiD*LLLi."
14719 .attributes = .{ .custom_typecheck = true }
14720
14721__sync_fetch_and_add_2
14722 .param_str = "ssD*s."
14723 .attributes = .{ .custom_typecheck = true }
14724
14725__sync_fetch_and_add_4
14726 .param_str = "iiD*i."
14727 .attributes = .{ .custom_typecheck = true }
14728
14729__sync_fetch_and_add_8
14730 .param_str = "LLiLLiD*LLi."
14731 .attributes = .{ .custom_typecheck = true }
14732
14733__sync_fetch_and_and
14734 .param_str = "v."
14735 .attributes = .{ .custom_typecheck = true }
14736
14737__sync_fetch_and_and_1
14738 .param_str = "ccD*c."
14739 .attributes = .{ .custom_typecheck = true }
14740
14741__sync_fetch_and_and_16
14742 .param_str = "LLLiLLLiD*LLLi."
14743 .attributes = .{ .custom_typecheck = true }
14744
14745__sync_fetch_and_and_2
14746 .param_str = "ssD*s."
14747 .attributes = .{ .custom_typecheck = true }
14748
14749__sync_fetch_and_and_4
14750 .param_str = "iiD*i."
14751 .attributes = .{ .custom_typecheck = true }
14752
14753__sync_fetch_and_and_8
14754 .param_str = "LLiLLiD*LLi."
14755 .attributes = .{ .custom_typecheck = true }
14756
14757__sync_fetch_and_max
14758 .param_str = "iiD*i"
14759
14760__sync_fetch_and_min
14761 .param_str = "iiD*i"
14762
14763__sync_fetch_and_nand
14764 .param_str = "v."
14765 .attributes = .{ .custom_typecheck = true }
14766
14767__sync_fetch_and_nand_1
14768 .param_str = "ccD*c."
14769 .attributes = .{ .custom_typecheck = true }
14770
14771__sync_fetch_and_nand_16
14772 .param_str = "LLLiLLLiD*LLLi."
14773 .attributes = .{ .custom_typecheck = true }
14774
14775__sync_fetch_and_nand_2
14776 .param_str = "ssD*s."
14777 .attributes = .{ .custom_typecheck = true }
14778
14779__sync_fetch_and_nand_4
14780 .param_str = "iiD*i."
14781 .attributes = .{ .custom_typecheck = true }
14782
14783__sync_fetch_and_nand_8
14784 .param_str = "LLiLLiD*LLi."
14785 .attributes = .{ .custom_typecheck = true }
14786
14787__sync_fetch_and_or
14788 .param_str = "v."
14789 .attributes = .{ .custom_typecheck = true }
14790
14791__sync_fetch_and_or_1
14792 .param_str = "ccD*c."
14793 .attributes = .{ .custom_typecheck = true }
14794
14795__sync_fetch_and_or_16
14796 .param_str = "LLLiLLLiD*LLLi."
14797 .attributes = .{ .custom_typecheck = true }
14798
14799__sync_fetch_and_or_2
14800 .param_str = "ssD*s."
14801 .attributes = .{ .custom_typecheck = true }
14802
14803__sync_fetch_and_or_4
14804 .param_str = "iiD*i."
14805 .attributes = .{ .custom_typecheck = true }
14806
14807__sync_fetch_and_or_8
14808 .param_str = "LLiLLiD*LLi."
14809 .attributes = .{ .custom_typecheck = true }
14810
14811__sync_fetch_and_sub
14812 .param_str = "v."
14813 .attributes = .{ .custom_typecheck = true }
14814
14815__sync_fetch_and_sub_1
14816 .param_str = "ccD*c."
14817 .attributes = .{ .custom_typecheck = true }
14818
14819__sync_fetch_and_sub_16
14820 .param_str = "LLLiLLLiD*LLLi."
14821 .attributes = .{ .custom_typecheck = true }
14822
14823__sync_fetch_and_sub_2
14824 .param_str = "ssD*s."
14825 .attributes = .{ .custom_typecheck = true }
14826
14827__sync_fetch_and_sub_4
14828 .param_str = "iiD*i."
14829 .attributes = .{ .custom_typecheck = true }
14830
14831__sync_fetch_and_sub_8
14832 .param_str = "LLiLLiD*LLi."
14833 .attributes = .{ .custom_typecheck = true }
14834
14835__sync_fetch_and_umax
14836 .param_str = "UiUiD*Ui"
14837
14838__sync_fetch_and_umin
14839 .param_str = "UiUiD*Ui"
14840
14841__sync_fetch_and_xor
14842 .param_str = "v."
14843 .attributes = .{ .custom_typecheck = true }
14844
14845__sync_fetch_and_xor_1
14846 .param_str = "ccD*c."
14847 .attributes = .{ .custom_typecheck = true }
14848
14849__sync_fetch_and_xor_16
14850 .param_str = "LLLiLLLiD*LLLi."
14851 .attributes = .{ .custom_typecheck = true }
14852
14853__sync_fetch_and_xor_2
14854 .param_str = "ssD*s."
14855 .attributes = .{ .custom_typecheck = true }
14856
14857__sync_fetch_and_xor_4
14858 .param_str = "iiD*i."
14859 .attributes = .{ .custom_typecheck = true }
14860
14861__sync_fetch_and_xor_8
14862 .param_str = "LLiLLiD*LLi."
14863 .attributes = .{ .custom_typecheck = true }
14864
14865__sync_lock_release
14866 .param_str = "v."
14867 .attributes = .{ .custom_typecheck = true }
14868
14869__sync_lock_release_1
14870 .param_str = "vcD*."
14871 .attributes = .{ .custom_typecheck = true }
14872
14873__sync_lock_release_16
14874 .param_str = "vLLLiD*."
14875 .attributes = .{ .custom_typecheck = true }
14876
14877__sync_lock_release_2
14878 .param_str = "vsD*."
14879 .attributes = .{ .custom_typecheck = true }
14880
14881__sync_lock_release_4
14882 .param_str = "viD*."
14883 .attributes = .{ .custom_typecheck = true }
14884
14885__sync_lock_release_8
14886 .param_str = "vLLiD*."
14887 .attributes = .{ .custom_typecheck = true }
14888
14889__sync_lock_test_and_set
14890 .param_str = "v."
14891 .attributes = .{ .custom_typecheck = true }
14892
14893__sync_lock_test_and_set_1
14894 .param_str = "ccD*c."
14895 .attributes = .{ .custom_typecheck = true }
14896
14897__sync_lock_test_and_set_16
14898 .param_str = "LLLiLLLiD*LLLi."
14899 .attributes = .{ .custom_typecheck = true }
14900
14901__sync_lock_test_and_set_2
14902 .param_str = "ssD*s."
14903 .attributes = .{ .custom_typecheck = true }
14904
14905__sync_lock_test_and_set_4
14906 .param_str = "iiD*i."
14907 .attributes = .{ .custom_typecheck = true }
14908
14909__sync_lock_test_and_set_8
14910 .param_str = "LLiLLiD*LLi."
14911 .attributes = .{ .custom_typecheck = true }
14912
14913__sync_nand_and_fetch
14914 .param_str = "v."
14915 .attributes = .{ .custom_typecheck = true }
14916
14917__sync_nand_and_fetch_1
14918 .param_str = "ccD*c."
14919 .attributes = .{ .custom_typecheck = true }
14920
14921__sync_nand_and_fetch_16
14922 .param_str = "LLLiLLLiD*LLLi."
14923 .attributes = .{ .custom_typecheck = true }
14924
14925__sync_nand_and_fetch_2
14926 .param_str = "ssD*s."
14927 .attributes = .{ .custom_typecheck = true }
14928
14929__sync_nand_and_fetch_4
14930 .param_str = "iiD*i."
14931 .attributes = .{ .custom_typecheck = true }
14932
14933__sync_nand_and_fetch_8
14934 .param_str = "LLiLLiD*LLi."
14935 .attributes = .{ .custom_typecheck = true }
14936
14937__sync_or_and_fetch
14938 .param_str = "v."
14939 .attributes = .{ .custom_typecheck = true }
14940
14941__sync_or_and_fetch_1
14942 .param_str = "ccD*c."
14943 .attributes = .{ .custom_typecheck = true }
14944
14945__sync_or_and_fetch_16
14946 .param_str = "LLLiLLLiD*LLLi."
14947 .attributes = .{ .custom_typecheck = true }
14948
14949__sync_or_and_fetch_2
14950 .param_str = "ssD*s."
14951 .attributes = .{ .custom_typecheck = true }
14952
14953__sync_or_and_fetch_4
14954 .param_str = "iiD*i."
14955 .attributes = .{ .custom_typecheck = true }
14956
14957__sync_or_and_fetch_8
14958 .param_str = "LLiLLiD*LLi."
14959 .attributes = .{ .custom_typecheck = true }
14960
14961__sync_sub_and_fetch
14962 .param_str = "v."
14963 .attributes = .{ .custom_typecheck = true }
14964
14965__sync_sub_and_fetch_1
14966 .param_str = "ccD*c."
14967 .attributes = .{ .custom_typecheck = true }
14968
14969__sync_sub_and_fetch_16
14970 .param_str = "LLLiLLLiD*LLLi."
14971 .attributes = .{ .custom_typecheck = true }
14972
14973__sync_sub_and_fetch_2
14974 .param_str = "ssD*s."
14975 .attributes = .{ .custom_typecheck = true }
14976
14977__sync_sub_and_fetch_4
14978 .param_str = "iiD*i."
14979 .attributes = .{ .custom_typecheck = true }
14980
14981__sync_sub_and_fetch_8
14982 .param_str = "LLiLLiD*LLi."
14983 .attributes = .{ .custom_typecheck = true }
14984
14985__sync_swap
14986 .param_str = "v."
14987 .attributes = .{ .custom_typecheck = true }
14988
14989__sync_swap_1
14990 .param_str = "ccD*c."
14991 .attributes = .{ .custom_typecheck = true }
14992
14993__sync_swap_16
14994 .param_str = "LLLiLLLiD*LLLi."
14995 .attributes = .{ .custom_typecheck = true }
14996
14997__sync_swap_2
14998 .param_str = "ssD*s."
14999 .attributes = .{ .custom_typecheck = true }
15000
15001__sync_swap_4
15002 .param_str = "iiD*i."
15003 .attributes = .{ .custom_typecheck = true }
15004
15005__sync_swap_8
15006 .param_str = "LLiLLiD*LLi."
15007 .attributes = .{ .custom_typecheck = true }
15008
15009__sync_synchronize
15010 .param_str = "v"
15011
15012__sync_val_compare_and_swap
15013 .param_str = "v."
15014 .attributes = .{ .custom_typecheck = true }
15015
15016__sync_val_compare_and_swap_1
15017 .param_str = "ccD*cc."
15018 .attributes = .{ .custom_typecheck = true }
15019
15020__sync_val_compare_and_swap_16
15021 .param_str = "LLLiLLLiD*LLLiLLLi."
15022 .attributes = .{ .custom_typecheck = true }
15023
15024__sync_val_compare_and_swap_2
15025 .param_str = "ssD*ss."
15026 .attributes = .{ .custom_typecheck = true }
15027
15028__sync_val_compare_and_swap_4
15029 .param_str = "iiD*ii."
15030 .attributes = .{ .custom_typecheck = true }
15031
15032__sync_val_compare_and_swap_8
15033 .param_str = "LLiLLiD*LLiLLi."
15034 .attributes = .{ .custom_typecheck = true }
15035
15036__sync_xor_and_fetch
15037 .param_str = "v."
15038 .attributes = .{ .custom_typecheck = true }
15039
15040__sync_xor_and_fetch_1
15041 .param_str = "ccD*c."
15042 .attributes = .{ .custom_typecheck = true }
15043
15044__sync_xor_and_fetch_16
15045 .param_str = "LLLiLLLiD*LLLi."
15046 .attributes = .{ .custom_typecheck = true }
15047
15048__sync_xor_and_fetch_2
15049 .param_str = "ssD*s."
15050 .attributes = .{ .custom_typecheck = true }
15051
15052__sync_xor_and_fetch_4
15053 .param_str = "iiD*i."
15054 .attributes = .{ .custom_typecheck = true }
15055
15056__sync_xor_and_fetch_8
15057 .param_str = "LLiLLiD*LLi."
15058 .attributes = .{ .custom_typecheck = true }
15059
15060__syncthreads
15061 .param_str = "v"
15062 .target_set = TargetSet.initOne(.nvptx)
15063
15064__tanpi
15065 .param_str = "dd"
15066 .header = .math
15067 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15068
15069__tanpif
15070 .param_str = "ff"
15071 .header = .math
15072 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15073
15074__va_start
15075 .param_str = "vc**."
15076 .language = .all_ms_languages
15077 .attributes = .{ .custom_typecheck = true }
15078
15079__warn_memset_zero_len
15080 .param_str = "v"
15081 .attributes = .{ .pure = true }
15082
15083__wfe
15084 .param_str = "v"
15085 .language = .all_ms_languages
15086 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
15087
15088__wfi
15089 .param_str = "v"
15090 .language = .all_ms_languages
15091 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
15092
15093__xray_customevent
15094 .param_str = "vcC*z"
15095
15096__xray_typedevent
15097 .param_str = "vzcC*z"
15098
15099__yield
15100 .param_str = "v"
15101 .language = .all_ms_languages
15102 .target_set = TargetSet.initMany(&.{ .aarch64, .arm })
15103
15104_abnormal_termination
15105 .param_str = "i"
15106 .language = .all_ms_languages
15107
15108_alloca
15109 .param_str = "v*z"
15110 .language = .all_ms_languages
15111
15112_bittest
15113 .param_str = "UcNiC*Ni"
15114 .language = .all_ms_languages
15115
15116_bittest64
15117 .param_str = "UcWiC*Wi"
15118 .language = .all_ms_languages
15119
15120_bittestandcomplement
15121 .param_str = "UcNi*Ni"
15122 .language = .all_ms_languages
15123
15124_bittestandcomplement64
15125 .param_str = "UcWi*Wi"
15126 .language = .all_ms_languages
15127
15128_bittestandreset
15129 .param_str = "UcNi*Ni"
15130 .language = .all_ms_languages
15131
15132_bittestandreset64
15133 .param_str = "UcWi*Wi"
15134 .language = .all_ms_languages
15135
15136_bittestandset
15137 .param_str = "UcNi*Ni"
15138 .language = .all_ms_languages
15139
15140_bittestandset64
15141 .param_str = "UcWi*Wi"
15142 .language = .all_ms_languages
15143
15144_byteswap_uint64
15145 .param_str = "ULLiULLi"
15146 .header = .stdlib, .language = .all_ms_languages
15147 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15148
15149_byteswap_ulong
15150 .param_str = "UNiUNi"
15151 .header = .stdlib, .language = .all_ms_languages
15152 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15153
15154_byteswap_ushort
15155 .param_str = "UsUs"
15156 .header = .stdlib, .language = .all_ms_languages
15157 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15158
15159_exception_code
15160 .param_str = "UNi"
15161 .language = .all_ms_languages
15162
15163_exception_info
15164 .param_str = "v*"
15165 .language = .all_ms_languages
15166
15167_exit
15168 .param_str = "vi"
15169 .header = .unistd, .language = .all_gnu_languages
15170 .attributes = .{ .noreturn = true, .lib_function_without_prefix = true }
15171
15172_interlockedbittestandreset
15173 .param_str = "UcNiD*Ni"
15174 .language = .all_ms_languages
15175
15176_interlockedbittestandreset64
15177 .param_str = "UcWiD*Wi"
15178 .language = .all_ms_languages
15179
15180_interlockedbittestandreset_acq
15181 .param_str = "UcNiD*Ni"
15182 .language = .all_ms_languages
15183
15184_interlockedbittestandreset_nf
15185 .param_str = "UcNiD*Ni"
15186 .language = .all_ms_languages
15187
15188_interlockedbittestandreset_rel
15189 .param_str = "UcNiD*Ni"
15190 .language = .all_ms_languages
15191
15192_interlockedbittestandset
15193 .param_str = "UcNiD*Ni"
15194 .language = .all_ms_languages
15195
15196_interlockedbittestandset64
15197 .param_str = "UcWiD*Wi"
15198 .language = .all_ms_languages
15199
15200_interlockedbittestandset_acq
15201 .param_str = "UcNiD*Ni"
15202 .language = .all_ms_languages
15203
15204_interlockedbittestandset_nf
15205 .param_str = "UcNiD*Ni"
15206 .language = .all_ms_languages
15207
15208_interlockedbittestandset_rel
15209 .param_str = "UcNiD*Ni"
15210 .language = .all_ms_languages
15211
15212_longjmp
15213 .param_str = "vJi"
15214 .header = .setjmp, .language = .all_gnu_languages
15215 .attributes = .{ .noreturn = true, .allow_type_mismatch = true, .lib_function_without_prefix = true }
15216
15217_lrotl
15218 .param_str = "ULiULii"
15219 .language = .all_ms_languages
15220 .attributes = .{ .const_evaluable = true }
15221
15222_lrotr
15223 .param_str = "ULiULii"
15224 .language = .all_ms_languages
15225 .attributes = .{ .const_evaluable = true }
15226
15227_rotl
15228 .param_str = "UiUii"
15229 .language = .all_ms_languages
15230 .attributes = .{ .const_evaluable = true }
15231
15232_rotl16
15233 .param_str = "UsUsUc"
15234 .language = .all_ms_languages
15235 .attributes = .{ .const_evaluable = true }
15236
15237_rotl64
15238 .param_str = "UWiUWii"
15239 .language = .all_ms_languages
15240 .attributes = .{ .const_evaluable = true }
15241
15242_rotl8
15243 .param_str = "UcUcUc"
15244 .language = .all_ms_languages
15245 .attributes = .{ .const_evaluable = true }
15246
15247_rotr
15248 .param_str = "UiUii"
15249 .language = .all_ms_languages
15250 .attributes = .{ .const_evaluable = true }
15251
15252_rotr16
15253 .param_str = "UsUsUc"
15254 .language = .all_ms_languages
15255 .attributes = .{ .const_evaluable = true }
15256
15257_rotr64
15258 .param_str = "UWiUWii"
15259 .language = .all_ms_languages
15260 .attributes = .{ .const_evaluable = true }
15261
15262_rotr8
15263 .param_str = "UcUcUc"
15264 .language = .all_ms_languages
15265 .attributes = .{ .const_evaluable = true }
15266
15267_setjmp
15268 .param_str = "iJ"
15269 .header = .setjmp
15270 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
15271
15272_setjmpex
15273 .param_str = "iJ"
15274 .header = .setjmpex, .language = .all_ms_languages
15275 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
15276
15277abort
15278 .param_str = "v"
15279 .header = .stdlib
15280 .attributes = .{ .noreturn = true, .lib_function_without_prefix = true }
15281
15282abs
15283 .param_str = "ii"
15284 .header = .stdlib
15285 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15286
15287acos
15288 .param_str = "dd"
15289 .header = .math
15290 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15291
15292acosf
15293 .param_str = "ff"
15294 .header = .math
15295 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15296
15297acosh
15298 .param_str = "dd"
15299 .header = .math
15300 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15301
15302acoshf
15303 .param_str = "ff"
15304 .header = .math
15305 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15306
15307acoshl
15308 .param_str = "LdLd"
15309 .header = .math
15310 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15311
15312acosl
15313 .param_str = "LdLd"
15314 .header = .math
15315 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15316
15317aligned_alloc
15318 .param_str = "v*zz"
15319 .header = .stdlib
15320 .attributes = .{ .lib_function_without_prefix = true }
15321
15322alloca
15323 .param_str = "v*z"
15324 .header = .stdlib, .language = .all_gnu_languages
15325 .attributes = .{ .lib_function_without_prefix = true }
15326
15327asin
15328 .param_str = "dd"
15329 .header = .math
15330 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15331
15332asinf
15333 .param_str = "ff"
15334 .header = .math
15335 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15336
15337asinh
15338 .param_str = "dd"
15339 .header = .math
15340 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15341
15342asinhf
15343 .param_str = "ff"
15344 .header = .math
15345 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15346
15347asinhl
15348 .param_str = "LdLd"
15349 .header = .math
15350 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15351
15352asinl
15353 .param_str = "LdLd"
15354 .header = .math
15355 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15356
15357atan
15358 .param_str = "dd"
15359 .header = .math
15360 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15361
15362atan2
15363 .param_str = "ddd"
15364 .header = .math
15365 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15366
15367atan2f
15368 .param_str = "fff"
15369 .header = .math
15370 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15371
15372atan2l
15373 .param_str = "LdLdLd"
15374 .header = .math
15375 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15376
15377atanf
15378 .param_str = "ff"
15379 .header = .math
15380 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15381
15382atanh
15383 .param_str = "dd"
15384 .header = .math
15385 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15386
15387atanhf
15388 .param_str = "ff"
15389 .header = .math
15390 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15391
15392atanhl
15393 .param_str = "LdLd"
15394 .header = .math
15395 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15396
15397atanl
15398 .param_str = "LdLd"
15399 .header = .math
15400 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15401
15402bcmp
15403 .param_str = "ivC*vC*z"
15404 .header = .strings, .language = .all_gnu_languages
15405 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
15406
15407bcopy
15408 .param_str = "vvC*v*z"
15409 .header = .strings, .language = .all_gnu_languages
15410 .attributes = .{ .lib_function_without_prefix = true }
15411
15412bzero
15413 .param_str = "vv*z"
15414 .header = .strings, .language = .all_gnu_languages
15415 .attributes = .{ .lib_function_without_prefix = true }
15416
15417cabs
15418 .param_str = "dXd"
15419 .header = .complex
15420 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15421
15422cabsf
15423 .param_str = "fXf"
15424 .header = .complex
15425 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15426
15427cabsl
15428 .param_str = "LdXLd"
15429 .header = .complex
15430 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15431
15432cacos
15433 .param_str = "XdXd"
15434 .header = .complex
15435 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15436
15437cacosf
15438 .param_str = "XfXf"
15439 .header = .complex
15440 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15441
15442cacosh
15443 .param_str = "XdXd"
15444 .header = .complex
15445 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15446
15447cacoshf
15448 .param_str = "XfXf"
15449 .header = .complex
15450 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15451
15452cacoshl
15453 .param_str = "XLdXLd"
15454 .header = .complex
15455 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15456
15457cacosl
15458 .param_str = "XLdXLd"
15459 .header = .complex
15460 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15461
15462calloc
15463 .param_str = "v*zz"
15464 .header = .stdlib
15465 .attributes = .{ .lib_function_without_prefix = true }
15466
15467carg
15468 .param_str = "dXd"
15469 .header = .complex
15470 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15471
15472cargf
15473 .param_str = "fXf"
15474 .header = .complex
15475 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15476
15477cargl
15478 .param_str = "LdXLd"
15479 .header = .complex
15480 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15481
15482casin
15483 .param_str = "XdXd"
15484 .header = .complex
15485 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15486
15487casinf
15488 .param_str = "XfXf"
15489 .header = .complex
15490 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15491
15492casinh
15493 .param_str = "XdXd"
15494 .header = .complex
15495 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15496
15497casinhf
15498 .param_str = "XfXf"
15499 .header = .complex
15500 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15501
15502casinhl
15503 .param_str = "XLdXLd"
15504 .header = .complex
15505 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15506
15507casinl
15508 .param_str = "XLdXLd"
15509 .header = .complex
15510 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15511
15512catan
15513 .param_str = "XdXd"
15514 .header = .complex
15515 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15516
15517catanf
15518 .param_str = "XfXf"
15519 .header = .complex
15520 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15521
15522catanh
15523 .param_str = "XdXd"
15524 .header = .complex
15525 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15526
15527catanhf
15528 .param_str = "XfXf"
15529 .header = .complex
15530 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15531
15532catanhl
15533 .param_str = "XLdXLd"
15534 .header = .complex
15535 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15536
15537catanl
15538 .param_str = "XLdXLd"
15539 .header = .complex
15540 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15541
15542cbrt
15543 .param_str = "dd"
15544 .header = .math
15545 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15546
15547cbrtf
15548 .param_str = "ff"
15549 .header = .math
15550 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15551
15552cbrtl
15553 .param_str = "LdLd"
15554 .header = .math
15555 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15556
15557ccos
15558 .param_str = "XdXd"
15559 .header = .complex
15560 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15561
15562ccosf
15563 .param_str = "XfXf"
15564 .header = .complex
15565 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15566
15567ccosh
15568 .param_str = "XdXd"
15569 .header = .complex
15570 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15571
15572ccoshf
15573 .param_str = "XfXf"
15574 .header = .complex
15575 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15576
15577ccoshl
15578 .param_str = "XLdXLd"
15579 .header = .complex
15580 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15581
15582ccosl
15583 .param_str = "XLdXLd"
15584 .header = .complex
15585 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15586
15587ceil
15588 .param_str = "dd"
15589 .header = .math
15590 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15591
15592ceilf
15593 .param_str = "ff"
15594 .header = .math
15595 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15596
15597ceill
15598 .param_str = "LdLd"
15599 .header = .math
15600 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15601
15602cexp
15603 .param_str = "XdXd"
15604 .header = .complex
15605 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15606
15607cexpf
15608 .param_str = "XfXf"
15609 .header = .complex
15610 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15611
15612cexpl
15613 .param_str = "XLdXLd"
15614 .header = .complex
15615 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15616
15617cimag
15618 .param_str = "dXd"
15619 .header = .complex
15620 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15621
15622cimagf
15623 .param_str = "fXf"
15624 .header = .complex
15625 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15626
15627cimagl
15628 .param_str = "LdXLd"
15629 .header = .complex
15630 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15631
15632clog
15633 .param_str = "XdXd"
15634 .header = .complex
15635 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15636
15637clogf
15638 .param_str = "XfXf"
15639 .header = .complex
15640 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15641
15642clogl
15643 .param_str = "XLdXLd"
15644 .header = .complex
15645 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15646
15647conj
15648 .param_str = "XdXd"
15649 .header = .complex
15650 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15651
15652conjf
15653 .param_str = "XfXf"
15654 .header = .complex
15655 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15656
15657conjl
15658 .param_str = "XLdXLd"
15659 .header = .complex
15660 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15661
15662copysign
15663 .param_str = "ddd"
15664 .header = .math
15665 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15666
15667copysignf
15668 .param_str = "fff"
15669 .header = .math
15670 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15671
15672copysignl
15673 .param_str = "LdLdLd"
15674 .header = .math
15675 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15676
15677cos
15678 .param_str = "dd"
15679 .header = .math
15680 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15681
15682cosf
15683 .param_str = "ff"
15684 .header = .math
15685 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15686
15687cosh
15688 .param_str = "dd"
15689 .header = .math
15690 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15691
15692coshf
15693 .param_str = "ff"
15694 .header = .math
15695 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15696
15697coshl
15698 .param_str = "LdLd"
15699 .header = .math
15700 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15701
15702cosl
15703 .param_str = "LdLd"
15704 .header = .math
15705 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15706
15707cpow
15708 .param_str = "XdXdXd"
15709 .header = .complex
15710 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15711
15712cpowf
15713 .param_str = "XfXfXf"
15714 .header = .complex
15715 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15716
15717cpowl
15718 .param_str = "XLdXLdXLd"
15719 .header = .complex
15720 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15721
15722cproj
15723 .param_str = "XdXd"
15724 .header = .complex
15725 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15726
15727cprojf
15728 .param_str = "XfXf"
15729 .header = .complex
15730 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15731
15732cprojl
15733 .param_str = "XLdXLd"
15734 .header = .complex
15735 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15736
15737creal
15738 .param_str = "dXd"
15739 .header = .complex
15740 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15741
15742crealf
15743 .param_str = "fXf"
15744 .header = .complex
15745 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15746
15747creall
15748 .param_str = "LdXLd"
15749 .header = .complex
15750 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15751
15752csin
15753 .param_str = "XdXd"
15754 .header = .complex
15755 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15756
15757csinf
15758 .param_str = "XfXf"
15759 .header = .complex
15760 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15761
15762csinh
15763 .param_str = "XdXd"
15764 .header = .complex
15765 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15766
15767csinhf
15768 .param_str = "XfXf"
15769 .header = .complex
15770 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15771
15772csinhl
15773 .param_str = "XLdXLd"
15774 .header = .complex
15775 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15776
15777csinl
15778 .param_str = "XLdXLd"
15779 .header = .complex
15780 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15781
15782csqrt
15783 .param_str = "XdXd"
15784 .header = .complex
15785 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15786
15787csqrtf
15788 .param_str = "XfXf"
15789 .header = .complex
15790 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15791
15792csqrtl
15793 .param_str = "XLdXLd"
15794 .header = .complex
15795 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15796
15797ctan
15798 .param_str = "XdXd"
15799 .header = .complex
15800 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15801
15802ctanf
15803 .param_str = "XfXf"
15804 .header = .complex
15805 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15806
15807ctanh
15808 .param_str = "XdXd"
15809 .header = .complex
15810 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15811
15812ctanhf
15813 .param_str = "XfXf"
15814 .header = .complex
15815 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15816
15817ctanhl
15818 .param_str = "XLdXLd"
15819 .header = .complex
15820 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15821
15822ctanl
15823 .param_str = "XLdXLd"
15824 .header = .complex
15825 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15826
15827erf
15828 .param_str = "dd"
15829 .header = .math
15830 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15831
15832erfc
15833 .param_str = "dd"
15834 .header = .math
15835 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15836
15837erfcf
15838 .param_str = "ff"
15839 .header = .math
15840 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15841
15842erfcl
15843 .param_str = "LdLd"
15844 .header = .math
15845 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15846
15847erff
15848 .param_str = "ff"
15849 .header = .math
15850 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15851
15852erfl
15853 .param_str = "LdLd"
15854 .header = .math
15855 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15856
15857exit
15858 .param_str = "vi"
15859 .header = .stdlib
15860 .attributes = .{ .noreturn = true, .lib_function_without_prefix = true }
15861
15862exp
15863 .param_str = "dd"
15864 .header = .math
15865 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15866
15867exp2
15868 .param_str = "dd"
15869 .header = .math
15870 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15871
15872exp2f
15873 .param_str = "ff"
15874 .header = .math
15875 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15876
15877exp2l
15878 .param_str = "LdLd"
15879 .header = .math
15880 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15881
15882expf
15883 .param_str = "ff"
15884 .header = .math
15885 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15886
15887expl
15888 .param_str = "LdLd"
15889 .header = .math
15890 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15891
15892expm1
15893 .param_str = "dd"
15894 .header = .math
15895 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15896
15897expm1f
15898 .param_str = "ff"
15899 .header = .math
15900 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15901
15902expm1l
15903 .param_str = "LdLd"
15904 .header = .math
15905 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15906
15907fabs
15908 .param_str = "dd"
15909 .header = .math
15910 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15911
15912fabsf
15913 .param_str = "ff"
15914 .header = .math
15915 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15916
15917fabsl
15918 .param_str = "LdLd"
15919 .header = .math
15920 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15921
15922fdim
15923 .param_str = "ddd"
15924 .header = .math
15925 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15926
15927fdimf
15928 .param_str = "fff"
15929 .header = .math
15930 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15931
15932fdiml
15933 .param_str = "LdLdLd"
15934 .header = .math
15935 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15936
15937finite
15938 .param_str = "id"
15939 .header = .math, .language = .gnu_lang
15940 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15941
15942finitef
15943 .param_str = "if"
15944 .header = .math, .language = .gnu_lang
15945 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15946
15947finitel
15948 .param_str = "iLd"
15949 .header = .math, .language = .gnu_lang
15950 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15951
15952floor
15953 .param_str = "dd"
15954 .header = .math
15955 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15956
15957floorf
15958 .param_str = "ff"
15959 .header = .math
15960 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15961
15962floorl
15963 .param_str = "LdLd"
15964 .header = .math
15965 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15966
15967fma
15968 .param_str = "dddd"
15969 .header = .math
15970 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15971
15972fmaf
15973 .param_str = "ffff"
15974 .header = .math
15975 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15976
15977fmal
15978 .param_str = "LdLdLdLd"
15979 .header = .math
15980 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
15981
15982fmax
15983 .param_str = "ddd"
15984 .header = .math
15985 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15986
15987fmaxf
15988 .param_str = "fff"
15989 .header = .math
15990 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15991
15992fmaxl
15993 .param_str = "LdLdLd"
15994 .header = .math
15995 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
15996
15997fmin
15998 .param_str = "ddd"
15999 .header = .math
16000 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16001
16002fminf
16003 .param_str = "fff"
16004 .header = .math
16005 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16006
16007fminl
16008 .param_str = "LdLdLd"
16009 .header = .math
16010 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16011
16012fmod
16013 .param_str = "ddd"
16014 .header = .math
16015 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16016
16017fmodf
16018 .param_str = "fff"
16019 .header = .math
16020 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16021
16022fmodl
16023 .param_str = "LdLdLd"
16024 .header = .math
16025 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16026
16027fopen
16028 .param_str = "P*cC*cC*"
16029 .header = .stdio
16030 .attributes = .{ .lib_function_without_prefix = true }
16031
16032fprintf
16033 .param_str = "iP*cC*."
16034 .header = .stdio
16035 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 1 }
16036
16037fread
16038 .param_str = "zv*zzP*"
16039 .header = .stdio
16040 .attributes = .{ .lib_function_without_prefix = true }
16041
16042free
16043 .param_str = "vv*"
16044 .header = .stdlib
16045 .attributes = .{ .lib_function_without_prefix = true }
16046
16047frexp
16048 .param_str = "ddi*"
16049 .header = .math
16050 .attributes = .{ .lib_function_without_prefix = true }
16051
16052frexpf
16053 .param_str = "ffi*"
16054 .header = .math
16055 .attributes = .{ .lib_function_without_prefix = true }
16056
16057frexpl
16058 .param_str = "LdLdi*"
16059 .header = .math
16060 .attributes = .{ .lib_function_without_prefix = true }
16061
16062fscanf
16063 .param_str = "iP*RcC*R."
16064 .header = .stdio
16065 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf, .format_string_position = 1 }
16066
16067fwrite
16068 .param_str = "zvC*zzP*"
16069 .header = .stdio
16070 .attributes = .{ .lib_function_without_prefix = true }
16071
16072getcontext
16073 .param_str = "iK*"
16074 .header = .setjmp
16075 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
16076
16077hypot
16078 .param_str = "ddd"
16079 .header = .math
16080 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16081
16082hypotf
16083 .param_str = "fff"
16084 .header = .math
16085 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16086
16087hypotl
16088 .param_str = "LdLdLd"
16089 .header = .math
16090 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16091
16092ilogb
16093 .param_str = "id"
16094 .header = .math
16095 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16096
16097ilogbf
16098 .param_str = "if"
16099 .header = .math
16100 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16101
16102ilogbl
16103 .param_str = "iLd"
16104 .header = .math
16105 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16106
16107index
16108 .param_str = "c*cC*i"
16109 .header = .strings, .language = .all_gnu_languages
16110 .attributes = .{ .lib_function_without_prefix = true }
16111
16112isalnum
16113 .param_str = "ii"
16114 .header = .ctype
16115 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16116
16117isalpha
16118 .param_str = "ii"
16119 .header = .ctype
16120 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16121
16122isblank
16123 .param_str = "ii"
16124 .header = .ctype
16125 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16126
16127iscntrl
16128 .param_str = "ii"
16129 .header = .ctype
16130 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16131
16132isdigit
16133 .param_str = "ii"
16134 .header = .ctype
16135 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16136
16137isgraph
16138 .param_str = "ii"
16139 .header = .ctype
16140 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16141
16142islower
16143 .param_str = "ii"
16144 .header = .ctype
16145 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16146
16147isprint
16148 .param_str = "ii"
16149 .header = .ctype
16150 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16151
16152ispunct
16153 .param_str = "ii"
16154 .header = .ctype
16155 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16156
16157isspace
16158 .param_str = "ii"
16159 .header = .ctype
16160 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16161
16162isupper
16163 .param_str = "ii"
16164 .header = .ctype
16165 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16166
16167isxdigit
16168 .param_str = "ii"
16169 .header = .ctype
16170 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16171
16172labs
16173 .param_str = "LiLi"
16174 .header = .stdlib
16175 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16176
16177ldexp
16178 .param_str = "ddi"
16179 .header = .math
16180 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16181
16182ldexpf
16183 .param_str = "ffi"
16184 .header = .math
16185 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16186
16187ldexpl
16188 .param_str = "LdLdi"
16189 .header = .math
16190 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16191
16192lgamma
16193 .param_str = "dd"
16194 .header = .math
16195 .attributes = .{ .lib_function_without_prefix = true }
16196
16197lgammaf
16198 .param_str = "ff"
16199 .header = .math
16200 .attributes = .{ .lib_function_without_prefix = true }
16201
16202lgammal
16203 .param_str = "LdLd"
16204 .header = .math
16205 .attributes = .{ .lib_function_without_prefix = true }
16206
16207llabs
16208 .param_str = "LLiLLi"
16209 .header = .stdlib
16210 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16211
16212llrint
16213 .param_str = "LLid"
16214 .header = .math
16215 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16216
16217llrintf
16218 .param_str = "LLif"
16219 .header = .math
16220 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16221
16222llrintl
16223 .param_str = "LLiLd"
16224 .header = .math
16225 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16226
16227llround
16228 .param_str = "LLid"
16229 .header = .math
16230 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16231
16232llroundf
16233 .param_str = "LLif"
16234 .header = .math
16235 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16236
16237llroundl
16238 .param_str = "LLiLd"
16239 .header = .math
16240 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16241
16242log
16243 .param_str = "dd"
16244 .header = .math
16245 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16246
16247log10
16248 .param_str = "dd"
16249 .header = .math
16250 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16251
16252log10f
16253 .param_str = "ff"
16254 .header = .math
16255 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16256
16257log10l
16258 .param_str = "LdLd"
16259 .header = .math
16260 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16261
16262log1p
16263 .param_str = "dd"
16264 .header = .math
16265 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16266
16267log1pf
16268 .param_str = "ff"
16269 .header = .math
16270 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16271
16272log1pl
16273 .param_str = "LdLd"
16274 .header = .math
16275 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16276
16277log2
16278 .param_str = "dd"
16279 .header = .math
16280 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16281
16282log2f
16283 .param_str = "ff"
16284 .header = .math
16285 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16286
16287log2l
16288 .param_str = "LdLd"
16289 .header = .math
16290 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16291
16292logb
16293 .param_str = "dd"
16294 .header = .math
16295 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16296
16297logbf
16298 .param_str = "ff"
16299 .header = .math
16300 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16301
16302logbl
16303 .param_str = "LdLd"
16304 .header = .math
16305 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16306
16307logf
16308 .param_str = "ff"
16309 .header = .math
16310 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16311
16312logl
16313 .param_str = "LdLd"
16314 .header = .math
16315 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16316
16317longjmp
16318 .param_str = "vJi"
16319 .header = .setjmp
16320 .attributes = .{ .noreturn = true, .allow_type_mismatch = true, .lib_function_without_prefix = true }
16321
16322lrint
16323 .param_str = "Lid"
16324 .header = .math
16325 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16326
16327lrintf
16328 .param_str = "Lif"
16329 .header = .math
16330 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16331
16332lrintl
16333 .param_str = "LiLd"
16334 .header = .math
16335 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16336
16337lround
16338 .param_str = "Lid"
16339 .header = .math
16340 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16341
16342lroundf
16343 .param_str = "Lif"
16344 .header = .math
16345 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16346
16347lroundl
16348 .param_str = "LiLd"
16349 .header = .math
16350 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16351
16352malloc
16353 .param_str = "v*z"
16354 .header = .stdlib
16355 .attributes = .{ .lib_function_without_prefix = true }
16356
16357memalign
16358 .param_str = "v*zz"
16359 .header = .malloc, .language = .all_gnu_languages
16360 .attributes = .{ .lib_function_without_prefix = true }
16361
16362memccpy
16363 .param_str = "v*v*vC*iz"
16364 .header = .string, .language = .all_gnu_languages
16365 .attributes = .{ .lib_function_without_prefix = true }
16366
16367memchr
16368 .param_str = "v*vC*iz"
16369 .header = .string
16370 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16371
16372memcmp
16373 .param_str = "ivC*vC*z"
16374 .header = .string
16375 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16376
16377memcpy
16378 .param_str = "v*v*vC*z"
16379 .header = .string
16380 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16381
16382memmove
16383 .param_str = "v*v*vC*z"
16384 .header = .string
16385 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16386
16387mempcpy
16388 .param_str = "v*v*vC*z"
16389 .header = .string, .language = .all_gnu_languages
16390 .attributes = .{ .lib_function_without_prefix = true }
16391
16392memset
16393 .param_str = "v*v*iz"
16394 .header = .string
16395 .attributes = .{ .lib_function_without_prefix = true }
16396
16397modf
16398 .param_str = "ddd*"
16399 .header = .math
16400 .attributes = .{ .lib_function_without_prefix = true }
16401
16402modff
16403 .param_str = "fff*"
16404 .header = .math
16405 .attributes = .{ .lib_function_without_prefix = true }
16406
16407modfl
16408 .param_str = "LdLdLd*"
16409 .header = .math
16410 .attributes = .{ .lib_function_without_prefix = true }
16411
16412nan
16413 .param_str = "dcC*"
16414 .header = .math
16415 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16416
16417nanf
16418 .param_str = "fcC*"
16419 .header = .math
16420 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16421
16422nanl
16423 .param_str = "LdcC*"
16424 .header = .math
16425 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16426
16427nearbyint
16428 .param_str = "dd"
16429 .header = .math
16430 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16431
16432nearbyintf
16433 .param_str = "ff"
16434 .header = .math
16435 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16436
16437nearbyintl
16438 .param_str = "LdLd"
16439 .header = .math
16440 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16441
16442nextafter
16443 .param_str = "ddd"
16444 .header = .math
16445 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16446
16447nextafterf
16448 .param_str = "fff"
16449 .header = .math
16450 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16451
16452nextafterl
16453 .param_str = "LdLdLd"
16454 .header = .math
16455 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16456
16457nexttoward
16458 .param_str = "ddLd"
16459 .header = .math
16460 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16461
16462nexttowardf
16463 .param_str = "ffLd"
16464 .header = .math
16465 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16466
16467nexttowardl
16468 .param_str = "LdLdLd"
16469 .header = .math
16470 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16471
16472pow
16473 .param_str = "ddd"
16474 .header = .math
16475 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16476
16477powf
16478 .param_str = "fff"
16479 .header = .math
16480 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16481
16482powl
16483 .param_str = "LdLdLd"
16484 .header = .math
16485 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16486
16487printf
16488 .param_str = "icC*."
16489 .header = .stdio
16490 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf }
16491
16492realloc
16493 .param_str = "v*v*z"
16494 .header = .stdlib
16495 .attributes = .{ .lib_function_without_prefix = true }
16496
16497remainder
16498 .param_str = "ddd"
16499 .header = .math
16500 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16501
16502remainderf
16503 .param_str = "fff"
16504 .header = .math
16505 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16506
16507remainderl
16508 .param_str = "LdLdLd"
16509 .header = .math
16510 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16511
16512remquo
16513 .param_str = "dddi*"
16514 .header = .math
16515 .attributes = .{ .lib_function_without_prefix = true }
16516
16517remquof
16518 .param_str = "fffi*"
16519 .header = .math
16520 .attributes = .{ .lib_function_without_prefix = true }
16521
16522remquol
16523 .param_str = "LdLdLdi*"
16524 .header = .math
16525 .attributes = .{ .lib_function_without_prefix = true }
16526
16527rindex
16528 .param_str = "c*cC*i"
16529 .header = .strings, .language = .all_gnu_languages
16530 .attributes = .{ .lib_function_without_prefix = true }
16531
16532rint
16533 .param_str = "dd"
16534 .header = .math
16535 .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true }
16536
16537rintf
16538 .param_str = "ff"
16539 .header = .math
16540 .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true }
16541
16542rintl
16543 .param_str = "LdLd"
16544 .header = .math
16545 .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true }
16546
16547round
16548 .param_str = "dd"
16549 .header = .math
16550 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16551
16552roundeven
16553 .param_str = "dd"
16554 .header = .math
16555 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16556
16557roundevenf
16558 .param_str = "ff"
16559 .header = .math
16560 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16561
16562roundevenl
16563 .param_str = "LdLd"
16564 .header = .math
16565 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16566
16567roundf
16568 .param_str = "ff"
16569 .header = .math
16570 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16571
16572roundl
16573 .param_str = "LdLd"
16574 .header = .math
16575 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16576
16577savectx
16578 .param_str = "iJ"
16579 .header = .setjmp
16580 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
16581
16582scalbln
16583 .param_str = "ddLi"
16584 .header = .math
16585 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16586
16587scalblnf
16588 .param_str = "ffLi"
16589 .header = .math
16590 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16591
16592scalblnl
16593 .param_str = "LdLdLi"
16594 .header = .math
16595 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16596
16597scalbn
16598 .param_str = "ddi"
16599 .header = .math
16600 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16601
16602scalbnf
16603 .param_str = "ffi"
16604 .header = .math
16605 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16606
16607scalbnl
16608 .param_str = "LdLdi"
16609 .header = .math
16610 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16611
16612scanf
16613 .param_str = "icC*R."
16614 .header = .stdio
16615 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf }
16616
16617setjmp
16618 .param_str = "iJ"
16619 .header = .setjmp
16620 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
16621
16622siglongjmp
16623 .param_str = "vSJi"
16624 .header = .setjmp, .language = .all_gnu_languages
16625 .attributes = .{ .noreturn = true, .allow_type_mismatch = true, .lib_function_without_prefix = true }
16626
16627sigsetjmp
16628 .param_str = "iSJi"
16629 .header = .setjmp
16630 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
16631
16632sin
16633 .param_str = "dd"
16634 .header = .math
16635 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16636
16637sinf
16638 .param_str = "ff"
16639 .header = .math
16640 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16641
16642sinh
16643 .param_str = "dd"
16644 .header = .math
16645 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16646
16647sinhf
16648 .param_str = "ff"
16649 .header = .math
16650 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16651
16652sinhl
16653 .param_str = "LdLd"
16654 .header = .math
16655 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16656
16657sinl
16658 .param_str = "LdLd"
16659 .header = .math
16660 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16661
16662snprintf
16663 .param_str = "ic*zcC*."
16664 .header = .stdio
16665 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 2 }
16666
16667sprintf
16668 .param_str = "ic*cC*."
16669 .header = .stdio
16670 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 1 }
16671
16672sqrt
16673 .param_str = "dd"
16674 .header = .math
16675 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16676
16677sqrtf
16678 .param_str = "ff"
16679 .header = .math
16680 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16681
16682sqrtl
16683 .param_str = "LdLd"
16684 .header = .math
16685 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16686
16687sscanf
16688 .param_str = "icC*RcC*R."
16689 .header = .stdio
16690 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf, .format_string_position = 1 }
16691
16692stpcpy
16693 .param_str = "c*c*cC*"
16694 .header = .string, .language = .all_gnu_languages
16695 .attributes = .{ .lib_function_without_prefix = true }
16696
16697stpncpy
16698 .param_str = "c*c*cC*z"
16699 .header = .string, .language = .all_gnu_languages
16700 .attributes = .{ .lib_function_without_prefix = true }
16701
16702strcasecmp
16703 .param_str = "icC*cC*"
16704 .header = .strings, .language = .all_gnu_languages
16705 .attributes = .{ .lib_function_without_prefix = true }
16706
16707strcat
16708 .param_str = "c*c*cC*"
16709 .header = .string
16710 .attributes = .{ .lib_function_without_prefix = true }
16711
16712strchr
16713 .param_str = "c*cC*i"
16714 .header = .string
16715 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16716
16717strcmp
16718 .param_str = "icC*cC*"
16719 .header = .string
16720 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16721
16722strcpy
16723 .param_str = "c*c*cC*"
16724 .header = .string
16725 .attributes = .{ .lib_function_without_prefix = true }
16726
16727strcspn
16728 .param_str = "zcC*cC*"
16729 .header = .string
16730 .attributes = .{ .lib_function_without_prefix = true }
16731
16732strdup
16733 .param_str = "c*cC*"
16734 .header = .string, .language = .all_gnu_languages
16735 .attributes = .{ .lib_function_without_prefix = true }
16736
16737strerror
16738 .param_str = "c*i"
16739 .header = .string
16740 .attributes = .{ .lib_function_without_prefix = true }
16741
16742strlcat
16743 .param_str = "zc*cC*z"
16744 .header = .string, .language = .all_gnu_languages
16745 .attributes = .{ .lib_function_without_prefix = true }
16746
16747strlcpy
16748 .param_str = "zc*cC*z"
16749 .header = .string, .language = .all_gnu_languages
16750 .attributes = .{ .lib_function_without_prefix = true }
16751
16752strlen
16753 .param_str = "zcC*"
16754 .header = .string
16755 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16756
16757strncasecmp
16758 .param_str = "icC*cC*z"
16759 .header = .strings, .language = .all_gnu_languages
16760 .attributes = .{ .lib_function_without_prefix = true }
16761
16762strncat
16763 .param_str = "c*c*cC*z"
16764 .header = .string
16765 .attributes = .{ .lib_function_without_prefix = true }
16766
16767strncmp
16768 .param_str = "icC*cC*z"
16769 .header = .string
16770 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16771
16772strncpy
16773 .param_str = "c*c*cC*z"
16774 .header = .string
16775 .attributes = .{ .lib_function_without_prefix = true }
16776
16777strndup
16778 .param_str = "c*cC*z"
16779 .header = .string, .language = .all_gnu_languages
16780 .attributes = .{ .lib_function_without_prefix = true }
16781
16782strpbrk
16783 .param_str = "c*cC*cC*"
16784 .header = .string
16785 .attributes = .{ .lib_function_without_prefix = true }
16786
16787strrchr
16788 .param_str = "c*cC*i"
16789 .header = .string
16790 .attributes = .{ .lib_function_without_prefix = true }
16791
16792strspn
16793 .param_str = "zcC*cC*"
16794 .header = .string
16795 .attributes = .{ .lib_function_without_prefix = true }
16796
16797strstr
16798 .param_str = "c*cC*cC*"
16799 .header = .string
16800 .attributes = .{ .lib_function_without_prefix = true }
16801
16802strtod
16803 .param_str = "dcC*c**"
16804 .header = .stdlib
16805 .attributes = .{ .lib_function_without_prefix = true }
16806
16807strtof
16808 .param_str = "fcC*c**"
16809 .header = .stdlib
16810 .attributes = .{ .lib_function_without_prefix = true }
16811
16812strtok
16813 .param_str = "c*c*cC*"
16814 .header = .string
16815 .attributes = .{ .lib_function_without_prefix = true }
16816
16817strtol
16818 .param_str = "LicC*c**i"
16819 .header = .stdlib
16820 .attributes = .{ .lib_function_without_prefix = true }
16821
16822strtold
16823 .param_str = "LdcC*c**"
16824 .header = .stdlib
16825 .attributes = .{ .lib_function_without_prefix = true }
16826
16827strtoll
16828 .param_str = "LLicC*c**i"
16829 .header = .stdlib
16830 .attributes = .{ .lib_function_without_prefix = true }
16831
16832strtoul
16833 .param_str = "ULicC*c**i"
16834 .header = .stdlib
16835 .attributes = .{ .lib_function_without_prefix = true }
16836
16837strtoull
16838 .param_str = "ULLicC*c**i"
16839 .header = .stdlib
16840 .attributes = .{ .lib_function_without_prefix = true }
16841
16842strxfrm
16843 .param_str = "zc*cC*z"
16844 .header = .string
16845 .attributes = .{ .lib_function_without_prefix = true }
16846
16847tan
16848 .param_str = "dd"
16849 .header = .math
16850 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16851
16852tanf
16853 .param_str = "ff"
16854 .header = .math
16855 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16856
16857tanh
16858 .param_str = "dd"
16859 .header = .math
16860 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16861
16862tanhf
16863 .param_str = "ff"
16864 .header = .math
16865 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16866
16867tanhl
16868 .param_str = "LdLd"
16869 .header = .math
16870 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16871
16872tanl
16873 .param_str = "LdLd"
16874 .header = .math
16875 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16876
16877tgamma
16878 .param_str = "dd"
16879 .header = .math
16880 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16881
16882tgammaf
16883 .param_str = "ff"
16884 .header = .math
16885 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16886
16887tgammal
16888 .param_str = "LdLd"
16889 .header = .math
16890 .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true }
16891
16892tolower
16893 .param_str = "ii"
16894 .header = .ctype
16895 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16896
16897toupper
16898 .param_str = "ii"
16899 .header = .ctype
16900 .attributes = .{ .pure = true, .lib_function_without_prefix = true }
16901
16902trunc
16903 .param_str = "dd"
16904 .header = .math
16905 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16906
16907truncf
16908 .param_str = "ff"
16909 .header = .math
16910 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16911
16912truncl
16913 .param_str = "LdLd"
16914 .header = .math
16915 .attributes = .{ .@"const" = true, .lib_function_without_prefix = true }
16916
16917va_copy
16918 .param_str = "vAA"
16919 .header = .stdarg
16920 .attributes = .{ .lib_function_without_prefix = true }
16921
16922va_end
16923 .param_str = "vA"
16924 .header = .stdarg
16925 .attributes = .{ .lib_function_without_prefix = true }
16926
16927va_start
16928 .param_str = "vA."
16929 .header = .stdarg
16930 .attributes = .{ .lib_function_without_prefix = true }
16931
16932vfork
16933 .param_str = "p"
16934 .header = .unistd
16935 .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true }
16936
16937vfprintf
16938 .param_str = "iP*cC*a"
16939 .header = .stdio
16940 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 1 }
16941
16942vfscanf
16943 .param_str = "iP*RcC*Ra"
16944 .header = .stdio
16945 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf, .format_string_position = 1 }
16946
16947vprintf
16948 .param_str = "icC*a"
16949 .header = .stdio
16950 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf }
16951
16952vscanf
16953 .param_str = "icC*Ra"
16954 .header = .stdio
16955 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf }
16956
16957vsnprintf
16958 .param_str = "ic*zcC*a"
16959 .header = .stdio
16960 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 2 }
16961
16962vsprintf
16963 .param_str = "ic*cC*a"
16964 .header = .stdio
16965 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 1 }
16966
16967vsscanf
16968 .param_str = "icC*RcC*Ra"
16969 .header = .stdio
16970 .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf, .format_string_position = 1 }
16971
16972wcschr
16973 .param_str = "w*wC*w"
16974 .header = .wchar
16975 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16976
16977wcscmp
16978 .param_str = "iwC*wC*"
16979 .header = .wchar
16980 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16981
16982wcslen
16983 .param_str = "zwC*"
16984 .header = .wchar
16985 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16986
16987wcsncmp
16988 .param_str = "iwC*wC*z"
16989 .header = .wchar
16990 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16991
16992wmemchr
16993 .param_str = "w*wC*wz"
16994 .header = .wchar
16995 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
16996
16997wmemcmp
16998 .param_str = "iwC*wC*z"
16999 .header = .wchar
17000 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
17001
17002wmemcpy
17003 .param_str = "w*w*wC*z"
17004 .header = .wchar
17005 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
17006
17007wmemmove
17008 .param_str = "w*w*wC*z"
17009 .header = .wchar
17010 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }
17011
17012__c11_atomic_init
17013 .param_str = "v."
17014 .attributes = .{ .custom_typecheck = true }
17015
17016__c11_atomic_load
17017 .param_str = "v."
17018 .attributes = .{ .custom_typecheck = true }
17019
17020__c11_atomic_store
17021 .param_str = "v."
17022 .attributes = .{ .custom_typecheck = true }
17023
17024__c11_atomic_exchange
17025 .param_str = "v."
17026 .attributes = .{ .custom_typecheck = true }
17027
17028__c11_atomic_compare_exchange_strong
17029 .param_str = "v."
17030 .attributes = .{ .custom_typecheck = true }
17031
17032__c11_atomic_compare_exchange_weak
17033 .param_str = "v."
17034 .attributes = .{ .custom_typecheck = true }
17035
17036__c11_atomic_fetch_add
17037 .param_str = "v."
17038 .attributes = .{ .custom_typecheck = true }
17039
17040__c11_atomic_fetch_sub
17041 .param_str = "v."
17042 .attributes = .{ .custom_typecheck = true }
17043
17044__c11_atomic_fetch_and
17045 .param_str = "v."
17046 .attributes = .{ .custom_typecheck = true }
17047
17048__c11_atomic_fetch_or
17049 .param_str = "v."
17050 .attributes = .{ .custom_typecheck = true }
17051
17052__c11_atomic_fetch_xor
17053 .param_str = "v."
17054 .attributes = .{ .custom_typecheck = true }
17055
17056__c11_atomic_fetch_nand
17057 .param_str = "v."
17058 .attributes = .{ .custom_typecheck = true }
17059
17060__c11_atomic_fetch_max
17061 .param_str = "v."
17062 .attributes = .{ .custom_typecheck = true }
17063
17064__c11_atomic_fetch_min
17065 .param_str = "v."
17066 .attributes = .{ .custom_typecheck = true }
17067
17068__atomic_load
17069 .param_str = "v."
17070 .attributes = .{ .custom_typecheck = true }
17071
17072__atomic_load_n
17073 .param_str = "v."
17074 .attributes = .{ .custom_typecheck = true }
17075
17076__atomic_store
17077 .param_str = "v."
17078 .attributes = .{ .custom_typecheck = true }
17079
17080__atomic_store_n
17081 .param_str = "v."
17082 .attributes = .{ .custom_typecheck = true }
17083
17084__atomic_exchange
17085 .param_str = "v."
17086 .attributes = .{ .custom_typecheck = true }
17087
17088__atomic_exchange_n
17089 .param_str = "v."
17090 .attributes = .{ .custom_typecheck = true }
17091
17092__atomic_compare_exchange
17093 .param_str = "v."
17094 .attributes = .{ .custom_typecheck = true }
17095
17096__atomic_compare_exchange_n
17097 .param_str = "v."
17098 .attributes = .{ .custom_typecheck = true }
17099
17100__atomic_fetch_add
17101 .param_str = "v."
17102 .attributes = .{ .custom_typecheck = true }
17103
17104__atomic_fetch_sub
17105 .param_str = "v."
17106 .attributes = .{ .custom_typecheck = true }
17107
17108__atomic_fetch_and
17109 .param_str = "v."
17110 .attributes = .{ .custom_typecheck = true }
17111
17112__atomic_fetch_or
17113 .param_str = "v."
17114 .attributes = .{ .custom_typecheck = true }
17115
17116__atomic_fetch_xor
17117 .param_str = "v."
17118 .attributes = .{ .custom_typecheck = true }
17119
17120__atomic_fetch_nand
17121 .param_str = "v."
17122 .attributes = .{ .custom_typecheck = true }
17123
17124__atomic_add_fetch
17125 .param_str = "v."
17126 .attributes = .{ .custom_typecheck = true }
17127
17128__atomic_sub_fetch
17129 .param_str = "v."
17130 .attributes = .{ .custom_typecheck = true }
17131
17132__atomic_and_fetch
17133 .param_str = "v."
17134 .attributes = .{ .custom_typecheck = true }
17135
17136__atomic_or_fetch
17137 .param_str = "v."
17138 .attributes = .{ .custom_typecheck = true }
17139
17140__atomic_xor_fetch
17141 .param_str = "v."
17142 .attributes = .{ .custom_typecheck = true }
17143
17144__atomic_max_fetch
17145 .param_str = "v."
17146 .attributes = .{ .custom_typecheck = true }
17147
17148__atomic_min_fetch
17149 .param_str = "v."
17150 .attributes = .{ .custom_typecheck = true }
17151
17152__atomic_nand_fetch
17153 .param_str = "v."
17154 .attributes = .{ .custom_typecheck = true }
17155
17156__atomic_fetch_min
17157 .param_str = "v."
17158 .attributes = .{ .custom_typecheck = true }
17159
17160__atomic_fetch_max
17161 .param_str = "v."
17162 .attributes = .{ .custom_typecheck = true }
deps/aro/aro/Builtins/Properties.zig deleted-143
......@@ -1,143 +0,0 @@
1const std = @import("std");
2
3const Properties = @This();
4
5param_str: []const u8,
6language: Language = .all_languages,
7attributes: Attributes = Attributes{},
8header: Header = .none,
9target_set: TargetSet = TargetSet.initOne(.basic),
10
11/// Header which must be included for a builtin to be available
12pub const Header = enum {
13 none,
14 /// stdio.h
15 stdio,
16 /// stdlib.h
17 stdlib,
18 /// setjmpex.h
19 setjmpex,
20 /// stdarg.h
21 stdarg,
22 /// string.h
23 string,
24 /// ctype.h
25 ctype,
26 /// wchar.h
27 wchar,
28 /// setjmp.h
29 setjmp,
30 /// malloc.h
31 malloc,
32 /// strings.h
33 strings,
34 /// unistd.h
35 unistd,
36 /// pthread.h
37 pthread,
38 /// math.h
39 math,
40 /// complex.h
41 complex,
42 /// Blocks.h
43 blocks,
44};
45
46/// Languages in which a builtin is available
47pub const Language = enum {
48 all_languages,
49 all_ms_languages,
50 all_gnu_languages,
51 gnu_lang,
52};
53
54pub const Attributes = packed struct {
55 /// Function does not return
56 noreturn: bool = false,
57
58 /// Function has no side effects
59 pure: bool = false,
60
61 /// Function has no side effects and does not read memory
62 @"const": bool = false,
63
64 /// Signature is meaningless; use custom typecheck
65 custom_typecheck: bool = false,
66
67 /// A declaration of this builtin should be recognized even if the type doesn't match the specified signature.
68 allow_type_mismatch: bool = false,
69
70 /// this is a libc/libm function with a '__builtin_' prefix added.
71 lib_function_with_builtin_prefix: bool = false,
72
73 /// this is a libc/libm function without a '__builtin_' prefix. This builtin is disableable by '-fno-builtin-foo'
74 lib_function_without_prefix: bool = false,
75
76 /// Function returns twice (e.g. setjmp)
77 returns_twice: bool = false,
78
79 /// Nature of the format string passed to this function
80 format_kind: enum(u3) {
81 /// Does not take a format string
82 none,
83 /// this is a printf-like function whose Nth argument is the format string
84 printf,
85 /// function is like vprintf in that it accepts its arguments as a va_list rather than through an ellipsis
86 vprintf,
87 /// this is a scanf-like function whose Nth argument is the format string
88 scanf,
89 /// the function is like vscanf in that it accepts its arguments as a va_list rather than through an ellipsis
90 vscanf,
91 } = .none,
92
93 /// Position of format string argument. Only meaningful if format_kind is not .none
94 format_string_position: u5 = 0,
95
96 /// if false, arguments are not evaluated
97 eval_args: bool = true,
98
99 /// no side effects and does not read memory, but only when -fno-math-errno and FP exceptions are ignored
100 const_without_errno_and_fp_exceptions: bool = false,
101
102 /// no side effects and does not read memory, but only when FP exceptions are ignored
103 const_without_fp_exceptions: bool = false,
104
105 /// this function can be constant evaluated by the frontend
106 const_evaluable: bool = false,
107};
108
109pub const Target = enum {
110 /// Supported on all targets
111 basic,
112 aarch64,
113 aarch64_neon_sve_bridge,
114 aarch64_neon_sve_bridge_cg,
115 amdgpu,
116 arm,
117 bpf,
118 hexagon,
119 hexagon_dep,
120 hexagon_map_custom_dep,
121 loong_arch,
122 mips,
123 neon,
124 nvptx,
125 ppc,
126 riscv,
127 riscv_vector,
128 sve,
129 systemz,
130 ve,
131 vevl_gen,
132 webassembly,
133 x86,
134 x86_64,
135 xcore,
136};
137
138/// Targets for which a builtin is enabled
139pub const TargetSet = std.enums.EnumSet(Target);
140
141pub fn isVarArgs(properties: Properties) bool {
142 return properties.param_str[properties.param_str.len - 1] == '.';
143}
deps/aro/aro/Builtins/TypeDescription.zig deleted-286
......@@ -1,286 +0,0 @@
1const std = @import("std");
2
3const TypeDescription = @This();
4
5prefix: []const Prefix,
6spec: Spec,
7suffix: []const Suffix,
8
9pub const Component = union(enum) {
10 prefix: Prefix,
11 spec: Spec,
12 suffix: Suffix,
13};
14
15pub const ComponentIterator = struct {
16 str: []const u8,
17 idx: usize,
18
19 pub fn init(str: []const u8) ComponentIterator {
20 return .{
21 .str = str,
22 .idx = 0,
23 };
24 }
25
26 pub fn peek(self: *ComponentIterator) ?Component {
27 const idx = self.idx;
28 defer self.idx = idx;
29 return self.next();
30 }
31
32 pub fn next(self: *ComponentIterator) ?Component {
33 if (self.idx == self.str.len) return null;
34 const c = self.str[self.idx];
35 self.idx += 1;
36 switch (c) {
37 'L' => {
38 if (self.str[self.idx] != 'L') return .{ .prefix = .L };
39 self.idx += 1;
40 if (self.str[self.idx] != 'L') return .{ .prefix = .LL };
41 self.idx += 1;
42 return .{ .prefix = .LLL };
43 },
44 'Z' => return .{ .prefix = .Z },
45 'W' => return .{ .prefix = .W },
46 'N' => return .{ .prefix = .N },
47 'O' => return .{ .prefix = .O },
48 'S' => {
49 if (self.str[self.idx] == 'J') {
50 self.idx += 1;
51 return .{ .spec = .SJ };
52 }
53 return .{ .prefix = .S };
54 },
55 'U' => return .{ .prefix = .U },
56 'I' => return .{ .prefix = .I },
57
58 'v' => return .{ .spec = .v },
59 'b' => return .{ .spec = .b },
60 'c' => return .{ .spec = .c },
61 's' => return .{ .spec = .s },
62 'i' => return .{ .spec = .i },
63 'h' => return .{ .spec = .h },
64 'x' => return .{ .spec = .x },
65 'y' => return .{ .spec = .y },
66 'f' => return .{ .spec = .f },
67 'd' => return .{ .spec = .d },
68 'z' => return .{ .spec = .z },
69 'w' => return .{ .spec = .w },
70 'F' => return .{ .spec = .F },
71 'G' => return .{ .spec = .G },
72 'H' => return .{ .spec = .H },
73 'M' => return .{ .spec = .M },
74 'a' => return .{ .spec = .a },
75 'A' => return .{ .spec = .A },
76 'V', 'q', 'E' => {
77 const start = self.idx;
78 while (std.ascii.isDigit(self.str[self.idx])) : (self.idx += 1) {}
79 const count = std.fmt.parseUnsigned(u32, self.str[start..self.idx], 10) catch unreachable;
80 return switch (c) {
81 'V' => .{ .spec = .{ .V = count } },
82 'q' => .{ .spec = .{ .q = count } },
83 'E' => .{ .spec = .{ .E = count } },
84 else => unreachable,
85 };
86 },
87 'X' => {
88 defer self.idx += 1;
89 switch (self.str[self.idx]) {
90 'f' => return .{ .spec = .{ .X = .float } },
91 'd' => return .{ .spec = .{ .X = .double } },
92 'L' => {
93 self.idx += 1;
94 return .{ .spec = .{ .X = .longdouble } };
95 },
96 else => unreachable,
97 }
98 },
99 'Y' => return .{ .spec = .Y },
100 'P' => return .{ .spec = .P },
101 'J' => return .{ .spec = .J },
102 'K' => return .{ .spec = .K },
103 'p' => return .{ .spec = .p },
104 '.' => {
105 // can only appear at end of param string; indicates varargs function
106 std.debug.assert(self.idx == self.str.len);
107 return null;
108 },
109 '!' => {
110 std.debug.assert(self.str.len == 1);
111 return .{ .spec = .@"!" };
112 },
113
114 '*' => {
115 if (self.idx < self.str.len and std.ascii.isDigit(self.str[self.idx])) {
116 defer self.idx += 1;
117 const addr_space = self.str[self.idx] - '0';
118 return .{ .suffix = .{ .@"*" = addr_space } };
119 } else {
120 return .{ .suffix = .{ .@"*" = null } };
121 }
122 },
123 'C' => return .{ .suffix = .C },
124 'D' => return .{ .suffix = .D },
125 'R' => return .{ .suffix = .R },
126 else => unreachable,
127 }
128 return null;
129 }
130};
131
132pub const TypeIterator = struct {
133 param_str: []const u8,
134 prefix: [4]Prefix,
135 spec: Spec,
136 suffix: [4]Suffix,
137 idx: usize,
138
139 pub fn init(param_str: []const u8) TypeIterator {
140 return .{
141 .param_str = param_str,
142 .prefix = undefined,
143 .spec = undefined,
144 .suffix = undefined,
145 .idx = 0,
146 };
147 }
148
149 /// Returned `TypeDescription` contains fields which are slices into the underlying `TypeIterator`
150 /// The returned value is invalidated when `.next()` is called again or the TypeIterator goes out
151 // of scope.
152 pub fn next(self: *TypeIterator) ?TypeDescription {
153 var it = ComponentIterator.init(self.param_str[self.idx..]);
154 defer self.idx += it.idx;
155
156 var prefix_count: usize = 0;
157 var maybe_spec: ?Spec = null;
158 var suffix_count: usize = 0;
159 while (it.peek()) |component| {
160 switch (component) {
161 .prefix => |prefix| {
162 if (maybe_spec != null) break;
163 self.prefix[prefix_count] = prefix;
164 prefix_count += 1;
165 },
166 .spec => |spec| {
167 if (maybe_spec != null) break;
168 maybe_spec = spec;
169 },
170 .suffix => |suffix| {
171 std.debug.assert(maybe_spec != null);
172 self.suffix[suffix_count] = suffix;
173 suffix_count += 1;
174 },
175 }
176 _ = it.next();
177 }
178 if (maybe_spec) |spec| {
179 return TypeDescription{
180 .prefix = self.prefix[0..prefix_count],
181 .spec = spec,
182 .suffix = self.suffix[0..suffix_count],
183 };
184 }
185 return null;
186 }
187};
188
189const Prefix = enum {
190 /// long (e.g. Li for 'long int', Ld for 'long double')
191 L,
192 /// long long (e.g. LLi for 'long long int', LLd for __float128)
193 LL,
194 /// __int128_t (e.g. LLLi)
195 LLL,
196 /// int32_t (require a native 32-bit integer type on the target)
197 Z,
198 /// int64_t (require a native 64-bit integer type on the target)
199 W,
200 /// 'int' size if target is LP64, 'L' otherwise.
201 N,
202 /// long for OpenCL targets, long long otherwise.
203 O,
204 /// signed
205 S,
206 /// unsigned
207 U,
208 /// Required to constant fold to an integer constant expression.
209 I,
210};
211
212const Spec = union(enum) {
213 /// void
214 v,
215 /// boolean
216 b,
217 /// char
218 c,
219 /// short
220 s,
221 /// int
222 i,
223 /// half (__fp16, OpenCL)
224 h,
225 /// half (_Float16)
226 x,
227 /// half (__bf16)
228 y,
229 /// float
230 f,
231 /// double
232 d,
233 /// size_t
234 z,
235 /// wchar_t
236 w,
237 /// constant CFString
238 F,
239 /// id
240 G,
241 /// SEL
242 H,
243 /// struct objc_super
244 M,
245 /// __builtin_va_list
246 a,
247 /// "reference" to __builtin_va_list
248 A,
249 /// Vector, followed by the number of elements and the base type.
250 V: u32,
251 /// Scalable vector, followed by the number of elements and the base type.
252 q: u32,
253 /// ext_vector, followed by the number of elements and the base type.
254 E: u32,
255 /// _Complex, followed by the base type.
256 X: enum {
257 float,
258 double,
259 longdouble,
260 },
261 /// ptrdiff_t
262 Y,
263 /// FILE
264 P,
265 /// jmp_buf
266 J,
267 /// sigjmp_buf
268 SJ,
269 /// ucontext_t
270 K,
271 /// pid_t
272 p,
273 /// Used to indicate a builtin with target-dependent param types. Must appear by itself
274 @"!",
275};
276
277const Suffix = union(enum) {
278 /// pointer (optionally followed by an address space number,if no address space is specified than any address space will be accepted)
279 @"*": ?u8,
280 /// const
281 C,
282 /// volatile
283 D,
284 /// restrict
285 R,
286};
deps/aro/aro/CodeGen.zig deleted-1295
......@@ -1,1295 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const backend = @import("backend");
5const Interner = backend.Interner;
6const Ir = backend.Ir;
7const Builtins = @import("Builtins.zig");
8const Builtin = Builtins.Builtin;
9const Compilation = @import("Compilation.zig");
10const Builder = Ir.Builder;
11const StrInt = @import("StringInterner.zig");
12const StringId = StrInt.StringId;
13const Tree = @import("Tree.zig");
14const NodeIndex = Tree.NodeIndex;
15const Type = @import("Type.zig");
16const Value = @import("Value.zig");
17
18const WipSwitch = struct {
19 cases: Cases = .{},
20 default: ?Ir.Ref = null,
21 size: u64,
22
23 const Cases = std.MultiArrayList(struct {
24 val: Interner.Ref,
25 label: Ir.Ref,
26 });
27};
28
29const Symbol = struct {
30 name: StringId,
31 val: Ir.Ref,
32};
33
34const Error = Compilation.Error;
35
36const CodeGen = @This();
37
38tree: Tree,
39comp: *Compilation,
40builder: Builder,
41node_tag: []const Tree.Tag,
42node_data: []const Tree.Node.Data,
43node_ty: []const Type,
44wip_switch: *WipSwitch = undefined,
45symbols: std.ArrayListUnmanaged(Symbol) = .{},
46ret_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
47phi_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
48record_elem_buf: std.ArrayListUnmanaged(Interner.Ref) = .{},
49record_cache: std.AutoHashMapUnmanaged(*Type.Record, Interner.Ref) = .{},
50cond_dummy_ty: ?Interner.Ref = null,
51bool_invert: bool = false,
52bool_end_label: Ir.Ref = .none,
53cond_dummy_ref: Ir.Ref = undefined,
54continue_label: Ir.Ref = undefined,
55break_label: Ir.Ref = undefined,
56return_label: Ir.Ref = undefined,
57
58fn fail(c: *CodeGen, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {
59 try c.comp.diagnostics.list.append(c.comp.gpa, .{
60 .tag = .cli_error,
61 .kind = .@"fatal error",
62 .extra = .{ .str = try std.fmt.allocPrint(c.comp.diagnostics.arena.allocator(), fmt, args) },
63 });
64 return error.FatalError;
65}
66
67pub fn genIr(tree: Tree) Compilation.Error!Ir {
68 const gpa = tree.comp.gpa;
69 var c = CodeGen{
70 .builder = .{
71 .gpa = tree.comp.gpa,
72 .interner = &tree.comp.interner,
73 .arena = std.heap.ArenaAllocator.init(gpa),
74 },
75 .tree = tree,
76 .comp = tree.comp,
77 .node_tag = tree.nodes.items(.tag),
78 .node_data = tree.nodes.items(.data),
79 .node_ty = tree.nodes.items(.ty),
80 };
81 defer c.symbols.deinit(gpa);
82 defer c.ret_nodes.deinit(gpa);
83 defer c.phi_nodes.deinit(gpa);
84 defer c.record_elem_buf.deinit(gpa);
85 defer c.record_cache.deinit(gpa);
86 defer c.builder.deinit();
87
88 const node_tags = tree.nodes.items(.tag);
89 for (tree.root_decls) |decl| {
90 c.builder.arena.deinit();
91 c.builder.arena = std.heap.ArenaAllocator.init(gpa);
92
93 switch (node_tags[@intFromEnum(decl)]) {
94 .static_assert,
95 .typedef,
96 .struct_decl_two,
97 .union_decl_two,
98 .enum_decl_two,
99 .struct_decl,
100 .union_decl,
101 .enum_decl,
102 => {},
103
104 .fn_proto,
105 .static_fn_proto,
106 .inline_fn_proto,
107 .inline_static_fn_proto,
108 .extern_var,
109 .threadlocal_extern_var,
110 => {},
111
112 .fn_def,
113 .static_fn_def,
114 .inline_fn_def,
115 .inline_static_fn_def,
116 => c.genFn(decl) catch |err| switch (err) {
117 error.FatalError => return error.FatalError,
118 error.OutOfMemory => return error.OutOfMemory,
119 },
120
121 .@"var",
122 .static_var,
123 .threadlocal_var,
124 .threadlocal_static_var,
125 => c.genVar(decl) catch |err| switch (err) {
126 error.FatalError => return error.FatalError,
127 error.OutOfMemory => return error.OutOfMemory,
128 },
129 else => unreachable,
130 }
131 }
132 return c.builder.finish();
133}
134
135fn genType(c: *CodeGen, base_ty: Type) !Interner.Ref {
136 var key: Interner.Key = undefined;
137 const ty = base_ty.canonicalize(.standard);
138 switch (ty.specifier) {
139 .void => return .void,
140 .bool => return .i1,
141 .@"struct" => {
142 if (c.record_cache.get(ty.data.record)) |some| return some;
143
144 const elem_buf_top = c.record_elem_buf.items.len;
145 defer c.record_elem_buf.items.len = elem_buf_top;
146
147 for (ty.data.record.fields) |field| {
148 if (!field.isRegularField()) {
149 return c.fail("TODO lower struct bitfields", .{});
150 }
151 // TODO handle padding bits
152 const field_ref = try c.genType(field.ty);
153 try c.record_elem_buf.append(c.builder.gpa, field_ref);
154 }
155
156 return c.builder.interner.put(c.builder.gpa, .{
157 .record_ty = c.record_elem_buf.items[elem_buf_top..],
158 });
159 },
160 .@"union" => {
161 return c.fail("TODO lower union types", .{});
162 },
163 else => {},
164 }
165 if (ty.isPtr()) return .ptr;
166 if (ty.isFunc()) return .func;
167 if (!ty.isReal()) return c.fail("TODO lower complex types", .{});
168 if (ty.isInt()) {
169 const bits = ty.bitSizeof(c.comp).?;
170 key = .{ .int_ty = @intCast(bits) };
171 } else if (ty.isFloat()) {
172 const bits = ty.bitSizeof(c.comp).?;
173 key = .{ .float_ty = @intCast(bits) };
174 } else if (ty.isArray()) {
175 const elem = try c.genType(ty.elemType());
176 key = .{ .array_ty = .{ .child = elem, .len = ty.arrayLen().? } };
177 } else if (ty.specifier == .vector) {
178 const elem = try c.genType(ty.elemType());
179 key = .{ .vector_ty = .{ .child = elem, .len = @intCast(ty.data.array.len) } };
180 } else if (ty.is(.nullptr_t)) {
181 return c.fail("TODO lower nullptr_t", .{});
182 }
183 return c.builder.interner.put(c.builder.gpa, key);
184}
185
186fn genFn(c: *CodeGen, decl: NodeIndex) Error!void {
187 const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
188 const func_ty = c.node_ty[@intFromEnum(decl)].canonicalize(.standard);
189 c.ret_nodes.items.len = 0;
190
191 try c.builder.startFn();
192
193 for (func_ty.data.func.params) |param| {
194 // TODO handle calling convention here
195 const arg = try c.builder.addArg(try c.genType(param.ty));
196
197 const size: u32 = @intCast(param.ty.sizeof(c.comp).?); // TODO add error in parser
198 const @"align" = param.ty.alignof(c.comp);
199 const alloc = try c.builder.addAlloc(size, @"align");
200 try c.builder.addStore(alloc, arg);
201 try c.symbols.append(c.comp.gpa, .{ .name = param.name, .val = alloc });
202 }
203
204 // Generate body
205 c.return_label = try c.builder.makeLabel("return");
206 try c.genStmt(c.node_data[@intFromEnum(decl)].decl.node);
207
208 // Relocate returns
209 if (c.ret_nodes.items.len == 0) {
210 _ = try c.builder.addInst(.ret, .{ .un = .none }, .noreturn);
211 } else if (c.ret_nodes.items.len == 1) {
212 c.builder.body.items.len -= 1;
213 _ = try c.builder.addInst(.ret, .{ .un = c.ret_nodes.items[0].value }, .noreturn);
214 } else {
215 try c.builder.startBlock(c.return_label);
216 const phi = try c.builder.addPhi(c.ret_nodes.items, try c.genType(func_ty.returnType()));
217 _ = try c.builder.addInst(.ret, .{ .un = phi }, .noreturn);
218 }
219
220 try c.builder.finishFn(name);
221}
222
223fn addUn(c: *CodeGen, tag: Ir.Inst.Tag, operand: Ir.Ref, ty: Type) !Ir.Ref {
224 return c.builder.addInst(tag, .{ .un = operand }, try c.genType(ty));
225}
226
227fn addBin(c: *CodeGen, tag: Ir.Inst.Tag, lhs: Ir.Ref, rhs: Ir.Ref, ty: Type) !Ir.Ref {
228 return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, try c.genType(ty));
229}
230
231fn addBranch(c: *CodeGen, cond: Ir.Ref, true_label: Ir.Ref, false_label: Ir.Ref) !void {
232 if (true_label == c.bool_end_label) {
233 if (false_label == c.bool_end_label) {
234 try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = cond });
235 return;
236 }
237 try c.addBoolPhi(!c.bool_invert);
238 }
239 if (false_label == c.bool_end_label) {
240 try c.addBoolPhi(c.bool_invert);
241 }
242 return c.builder.addBranch(cond, true_label, false_label);
243}
244
245fn addBoolPhi(c: *CodeGen, value: bool) !void {
246 const val = try c.builder.addConstant((try Value.int(@intFromBool(value), c.comp)).ref(), .i1);
247 try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = val });
248}
249
250fn genStmt(c: *CodeGen, node: NodeIndex) Error!void {
251 _ = try c.genExpr(node);
252}
253
254fn genExpr(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
255 std.debug.assert(node != .none);
256 const ty = c.node_ty[@intFromEnum(node)];
257 if (c.tree.value_map.get(node)) |val| {
258 return c.builder.addConstant(val.ref(), try c.genType(ty));
259 }
260 const data = c.node_data[@intFromEnum(node)];
261 switch (c.node_tag[@intFromEnum(node)]) {
262 .enumeration_ref,
263 .bool_literal,
264 .int_literal,
265 .char_literal,
266 .float_literal,
267 .imaginary_literal,
268 .string_literal_expr,
269 .alignof_expr,
270 => unreachable, // These should have an entry in value_map.
271 .fn_def,
272 .static_fn_def,
273 .inline_fn_def,
274 .inline_static_fn_def,
275 .invalid,
276 .threadlocal_var,
277 => unreachable,
278 .static_assert,
279 .fn_proto,
280 .static_fn_proto,
281 .inline_fn_proto,
282 .inline_static_fn_proto,
283 .extern_var,
284 .threadlocal_extern_var,
285 .typedef,
286 .struct_decl_two,
287 .union_decl_two,
288 .enum_decl_two,
289 .struct_decl,
290 .union_decl,
291 .enum_decl,
292 .enum_field_decl,
293 .record_field_decl,
294 .indirect_record_field_decl,
295 .struct_forward_decl,
296 .union_forward_decl,
297 .enum_forward_decl,
298 .null_stmt,
299 => {},
300 .static_var,
301 .implicit_static_var,
302 .threadlocal_static_var,
303 => try c.genVar(node), // TODO
304 .@"var" => {
305 const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
306 const @"align" = ty.alignof(c.comp);
307 const alloc = try c.builder.addAlloc(size, @"align");
308 const name = try StrInt.intern(c.comp, c.tree.tokSlice(data.decl.name));
309 try c.symbols.append(c.comp.gpa, .{ .name = name, .val = alloc });
310 if (data.decl.node != .none) {
311 try c.genInitializer(alloc, ty, data.decl.node);
312 }
313 },
314 .labeled_stmt => {
315 const label = try c.builder.makeLabel("label");
316 try c.builder.startBlock(label);
317 try c.genStmt(data.decl.node);
318 },
319 .compound_stmt_two => {
320 const old_sym_len = c.symbols.items.len;
321 c.symbols.items.len = old_sym_len;
322
323 if (data.bin.lhs != .none) try c.genStmt(data.bin.lhs);
324 if (data.bin.rhs != .none) try c.genStmt(data.bin.rhs);
325 },
326 .compound_stmt => {
327 const old_sym_len = c.symbols.items.len;
328 c.symbols.items.len = old_sym_len;
329
330 for (c.tree.data[data.range.start..data.range.end]) |stmt| try c.genStmt(stmt);
331 },
332 .if_then_else_stmt => {
333 const then_label = try c.builder.makeLabel("if.then");
334 const else_label = try c.builder.makeLabel("if.else");
335 const end_label = try c.builder.makeLabel("if.end");
336
337 try c.genBoolExpr(data.if3.cond, then_label, else_label);
338
339 try c.builder.startBlock(then_label);
340 try c.genStmt(c.tree.data[data.if3.body]); // then
341 try c.builder.addJump(end_label);
342
343 try c.builder.startBlock(else_label);
344 try c.genStmt(c.tree.data[data.if3.body + 1]); // else
345
346 try c.builder.startBlock(end_label);
347 },
348 .if_then_stmt => {
349 const then_label = try c.builder.makeLabel("if.then");
350 const end_label = try c.builder.makeLabel("if.end");
351
352 try c.genBoolExpr(data.bin.lhs, then_label, end_label);
353
354 try c.builder.startBlock(then_label);
355 try c.genStmt(data.bin.rhs); // then
356 try c.builder.startBlock(end_label);
357 },
358 .switch_stmt => {
359 var wip_switch = WipSwitch{
360 .size = c.node_ty[@intFromEnum(data.bin.lhs)].sizeof(c.comp).?,
361 };
362 defer wip_switch.cases.deinit(c.builder.gpa);
363
364 const old_wip_switch = c.wip_switch;
365 defer c.wip_switch = old_wip_switch;
366 c.wip_switch = &wip_switch;
367
368 const old_break_label = c.break_label;
369 defer c.break_label = old_break_label;
370 const end_ref = try c.builder.makeLabel("switch.end");
371 c.break_label = end_ref;
372
373 const cond = try c.genExpr(data.bin.lhs);
374 const switch_index = c.builder.instructions.len;
375 _ = try c.builder.addInst(.@"switch", undefined, .noreturn);
376
377 try c.genStmt(data.bin.rhs); // body
378
379 const default_ref = wip_switch.default orelse end_ref;
380 try c.builder.startBlock(end_ref);
381
382 const a = c.builder.arena.allocator();
383 const switch_data = try a.create(Ir.Inst.Switch);
384 switch_data.* = .{
385 .target = cond,
386 .cases_len = @intCast(wip_switch.cases.len),
387 .case_vals = (try a.dupe(Interner.Ref, wip_switch.cases.items(.val))).ptr,
388 .case_labels = (try a.dupe(Ir.Ref, wip_switch.cases.items(.label))).ptr,
389 .default = default_ref,
390 };
391 c.builder.instructions.items(.data)[switch_index] = .{ .@"switch" = switch_data };
392 },
393 .case_stmt => {
394 const val = c.tree.value_map.get(data.bin.lhs).?;
395 const label = try c.builder.makeLabel("case");
396 try c.builder.startBlock(label);
397 try c.wip_switch.cases.append(c.builder.gpa, .{
398 .val = val.ref(),
399 .label = label,
400 });
401 try c.genStmt(data.bin.rhs);
402 },
403 .default_stmt => {
404 const default = try c.builder.makeLabel("default");
405 try c.builder.startBlock(default);
406 c.wip_switch.default = default;
407 try c.genStmt(data.un);
408 },
409 .while_stmt => {
410 const old_break_label = c.break_label;
411 defer c.break_label = old_break_label;
412
413 const old_continue_label = c.continue_label;
414 defer c.continue_label = old_continue_label;
415
416 const cond_label = try c.builder.makeLabel("while.cond");
417 const then_label = try c.builder.makeLabel("while.then");
418 const end_label = try c.builder.makeLabel("while.end");
419
420 c.continue_label = cond_label;
421 c.break_label = end_label;
422
423 try c.builder.startBlock(cond_label);
424 try c.genBoolExpr(data.bin.lhs, then_label, end_label);
425
426 try c.builder.startBlock(then_label);
427 try c.genStmt(data.bin.rhs);
428 try c.builder.addJump(cond_label);
429 try c.builder.startBlock(end_label);
430 },
431 .do_while_stmt => {
432 const old_break_label = c.break_label;
433 defer c.break_label = old_break_label;
434
435 const old_continue_label = c.continue_label;
436 defer c.continue_label = old_continue_label;
437
438 const then_label = try c.builder.makeLabel("do.then");
439 const cond_label = try c.builder.makeLabel("do.cond");
440 const end_label = try c.builder.makeLabel("do.end");
441
442 c.continue_label = cond_label;
443 c.break_label = end_label;
444
445 try c.builder.startBlock(then_label);
446 try c.genStmt(data.bin.rhs);
447
448 try c.builder.startBlock(cond_label);
449 try c.genBoolExpr(data.bin.lhs, then_label, end_label);
450
451 try c.builder.startBlock(end_label);
452 },
453 .for_decl_stmt => {
454 const old_break_label = c.break_label;
455 defer c.break_label = old_break_label;
456
457 const old_continue_label = c.continue_label;
458 defer c.continue_label = old_continue_label;
459
460 const for_decl = data.forDecl(&c.tree);
461 for (for_decl.decls) |decl| try c.genStmt(decl);
462
463 const then_label = try c.builder.makeLabel("for.then");
464 var cond_label = then_label;
465 const cont_label = try c.builder.makeLabel("for.cont");
466 const end_label = try c.builder.makeLabel("for.end");
467
468 c.continue_label = cont_label;
469 c.break_label = end_label;
470
471 if (for_decl.cond != .none) {
472 cond_label = try c.builder.makeLabel("for.cond");
473 try c.builder.startBlock(cond_label);
474 try c.genBoolExpr(for_decl.cond, then_label, end_label);
475 }
476 try c.builder.startBlock(then_label);
477 try c.genStmt(for_decl.body);
478 if (for_decl.incr != .none) {
479 _ = try c.genExpr(for_decl.incr);
480 }
481 try c.builder.addJump(cond_label);
482 try c.builder.startBlock(end_label);
483 },
484 .forever_stmt => {
485 const old_break_label = c.break_label;
486 defer c.break_label = old_break_label;
487
488 const old_continue_label = c.continue_label;
489 defer c.continue_label = old_continue_label;
490
491 const then_label = try c.builder.makeLabel("for.then");
492 const end_label = try c.builder.makeLabel("for.end");
493
494 c.continue_label = then_label;
495 c.break_label = end_label;
496
497 try c.builder.startBlock(then_label);
498 try c.genStmt(data.un);
499 try c.builder.startBlock(end_label);
500 },
501 .for_stmt => {
502 const old_break_label = c.break_label;
503 defer c.break_label = old_break_label;
504
505 const old_continue_label = c.continue_label;
506 defer c.continue_label = old_continue_label;
507
508 const for_stmt = data.forStmt(&c.tree);
509 if (for_stmt.init != .none) _ = try c.genExpr(for_stmt.init);
510
511 const then_label = try c.builder.makeLabel("for.then");
512 var cond_label = then_label;
513 const cont_label = try c.builder.makeLabel("for.cont");
514 const end_label = try c.builder.makeLabel("for.end");
515
516 c.continue_label = cont_label;
517 c.break_label = end_label;
518
519 if (for_stmt.cond != .none) {
520 cond_label = try c.builder.makeLabel("for.cond");
521 try c.builder.startBlock(cond_label);
522 try c.genBoolExpr(for_stmt.cond, then_label, end_label);
523 }
524 try c.builder.startBlock(then_label);
525 try c.genStmt(for_stmt.body);
526 if (for_stmt.incr != .none) {
527 _ = try c.genExpr(for_stmt.incr);
528 }
529 try c.builder.addJump(cond_label);
530 try c.builder.startBlock(end_label);
531 },
532 .continue_stmt => try c.builder.addJump(c.continue_label),
533 .break_stmt => try c.builder.addJump(c.break_label),
534 .return_stmt => {
535 if (data.un != .none) {
536 const operand = try c.genExpr(data.un);
537 try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
538 }
539 try c.builder.addJump(c.return_label);
540 },
541 .implicit_return => {
542 if (data.return_zero) {
543 const operand = try c.builder.addConstant(.zero, try c.genType(ty));
544 try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
545 }
546 // No need to emit a jump since implicit_return is always the last instruction.
547 },
548 .case_range_stmt,
549 .goto_stmt,
550 .computed_goto_stmt,
551 .nullptr_literal,
552 => return c.fail("TODO CodeGen.genStmt {}\n", .{c.node_tag[@intFromEnum(node)]}),
553 .comma_expr => {
554 _ = try c.genExpr(data.bin.lhs);
555 return c.genExpr(data.bin.rhs);
556 },
557 .assign_expr => {
558 const rhs = try c.genExpr(data.bin.rhs);
559 const lhs = try c.genLval(data.bin.lhs);
560 try c.builder.addStore(lhs, rhs);
561 return rhs;
562 },
563 .mul_assign_expr => return c.genCompoundAssign(node, .mul),
564 .div_assign_expr => return c.genCompoundAssign(node, .div),
565 .mod_assign_expr => return c.genCompoundAssign(node, .mod),
566 .add_assign_expr => return c.genCompoundAssign(node, .add),
567 .sub_assign_expr => return c.genCompoundAssign(node, .sub),
568 .shl_assign_expr => return c.genCompoundAssign(node, .bit_shl),
569 .shr_assign_expr => return c.genCompoundAssign(node, .bit_shr),
570 .bit_and_assign_expr => return c.genCompoundAssign(node, .bit_and),
571 .bit_xor_assign_expr => return c.genCompoundAssign(node, .bit_xor),
572 .bit_or_assign_expr => return c.genCompoundAssign(node, .bit_or),
573 .bit_or_expr => return c.genBinOp(node, .bit_or),
574 .bit_xor_expr => return c.genBinOp(node, .bit_xor),
575 .bit_and_expr => return c.genBinOp(node, .bit_and),
576 .equal_expr => {
577 const cmp = try c.genComparison(node, .cmp_eq);
578 return c.addUn(.zext, cmp, ty);
579 },
580 .not_equal_expr => {
581 const cmp = try c.genComparison(node, .cmp_ne);
582 return c.addUn(.zext, cmp, ty);
583 },
584 .less_than_expr => {
585 const cmp = try c.genComparison(node, .cmp_lt);
586 return c.addUn(.zext, cmp, ty);
587 },
588 .less_than_equal_expr => {
589 const cmp = try c.genComparison(node, .cmp_lte);
590 return c.addUn(.zext, cmp, ty);
591 },
592 .greater_than_expr => {
593 const cmp = try c.genComparison(node, .cmp_gt);
594 return c.addUn(.zext, cmp, ty);
595 },
596 .greater_than_equal_expr => {
597 const cmp = try c.genComparison(node, .cmp_gte);
598 return c.addUn(.zext, cmp, ty);
599 },
600 .shl_expr => return c.genBinOp(node, .bit_shl),
601 .shr_expr => return c.genBinOp(node, .bit_shr),
602 .add_expr => {
603 if (ty.isPtr()) {
604 const lhs_ty = c.node_ty[@intFromEnum(data.bin.lhs)];
605 if (lhs_ty.isPtr()) {
606 const ptr = try c.genExpr(data.bin.lhs);
607 const offset = try c.genExpr(data.bin.rhs);
608 const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
609 return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
610 } else {
611 const offset = try c.genExpr(data.bin.lhs);
612 const ptr = try c.genExpr(data.bin.rhs);
613 const offset_ty = lhs_ty;
614 return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
615 }
616 }
617 return c.genBinOp(node, .add);
618 },
619 .sub_expr => {
620 if (ty.isPtr()) {
621 const ptr = try c.genExpr(data.bin.lhs);
622 const offset = try c.genExpr(data.bin.rhs);
623 const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
624 return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
625 }
626 return c.genBinOp(node, .sub);
627 },
628 .mul_expr => return c.genBinOp(node, .mul),
629 .div_expr => return c.genBinOp(node, .div),
630 .mod_expr => return c.genBinOp(node, .mod),
631 .addr_of_expr => return try c.genLval(data.un),
632 .deref_expr => {
633 const un_data = c.node_data[@intFromEnum(data.un)];
634 if (c.node_tag[@intFromEnum(data.un)] == .implicit_cast and un_data.cast.kind == .function_to_pointer) {
635 return c.genExpr(data.un);
636 }
637 const operand = try c.genLval(data.un);
638 return c.addUn(.load, operand, ty);
639 },
640 .plus_expr => return c.genExpr(data.un),
641 .negate_expr => {
642 const zero = try c.builder.addConstant(.zero, try c.genType(ty));
643 const operand = try c.genExpr(data.un);
644 return c.addBin(.sub, zero, operand, ty);
645 },
646 .bit_not_expr => {
647 const operand = try c.genExpr(data.un);
648 return c.addUn(.bit_not, operand, ty);
649 },
650 .bool_not_expr => {
651 const zero = try c.builder.addConstant(.zero, try c.genType(ty));
652 const operand = try c.genExpr(data.un);
653 return c.addBin(.cmp_ne, zero, operand, ty);
654 },
655 .pre_inc_expr => {
656 const operand = try c.genLval(data.un);
657 const val = try c.addUn(.load, operand, ty);
658 const one = try c.builder.addConstant(.one, try c.genType(ty));
659 const plus_one = try c.addBin(.add, val, one, ty);
660 try c.builder.addStore(operand, plus_one);
661 return plus_one;
662 },
663 .pre_dec_expr => {
664 const operand = try c.genLval(data.un);
665 const val = try c.addUn(.load, operand, ty);
666 const one = try c.builder.addConstant(.one, try c.genType(ty));
667 const plus_one = try c.addBin(.sub, val, one, ty);
668 try c.builder.addStore(operand, plus_one);
669 return plus_one;
670 },
671 .post_inc_expr => {
672 const operand = try c.genLval(data.un);
673 const val = try c.addUn(.load, operand, ty);
674 const one = try c.builder.addConstant(.one, try c.genType(ty));
675 const plus_one = try c.addBin(.add, val, one, ty);
676 try c.builder.addStore(operand, plus_one);
677 return val;
678 },
679 .post_dec_expr => {
680 const operand = try c.genLval(data.un);
681 const val = try c.addUn(.load, operand, ty);
682 const one = try c.builder.addConstant(.one, try c.genType(ty));
683 const plus_one = try c.addBin(.sub, val, one, ty);
684 try c.builder.addStore(operand, plus_one);
685 return val;
686 },
687 .paren_expr => return c.genExpr(data.un),
688 .decl_ref_expr => unreachable, // Lval expression.
689 .explicit_cast, .implicit_cast => switch (data.cast.kind) {
690 .no_op => return c.genExpr(data.cast.operand),
691 .to_void => {
692 _ = try c.genExpr(data.cast.operand);
693 return .none;
694 },
695 .lval_to_rval => {
696 const operand = try c.genLval(data.cast.operand);
697 return c.addUn(.load, operand, ty);
698 },
699 .function_to_pointer, .array_to_pointer => {
700 return c.genLval(data.cast.operand);
701 },
702 .int_cast => {
703 const operand = try c.genExpr(data.cast.operand);
704 const src_ty = c.node_ty[@intFromEnum(data.cast.operand)];
705 const src_bits = src_ty.bitSizeof(c.comp).?;
706 const dest_bits = ty.bitSizeof(c.comp).?;
707 if (src_bits == dest_bits) {
708 return operand;
709 } else if (src_bits < dest_bits) {
710 if (src_ty.isUnsignedInt(c.comp))
711 return c.addUn(.zext, operand, ty)
712 else
713 return c.addUn(.sext, operand, ty);
714 } else {
715 return c.addUn(.trunc, operand, ty);
716 }
717 },
718 .bool_to_int => {
719 const operand = try c.genExpr(data.cast.operand);
720 return c.addUn(.zext, operand, ty);
721 },
722 .pointer_to_bool, .int_to_bool, .float_to_bool => {
723 const lhs = try c.genExpr(data.cast.operand);
724 const rhs = try c.builder.addConstant(.zero, try c.genType(c.node_ty[@intFromEnum(node)]));
725 return c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
726 },
727 .bitcast,
728 .pointer_to_int,
729 .bool_to_float,
730 .bool_to_pointer,
731 .int_to_float,
732 .complex_int_to_complex_float,
733 .int_to_pointer,
734 .float_to_int,
735 .complex_float_to_complex_int,
736 .complex_int_cast,
737 .complex_int_to_real,
738 .real_to_complex_int,
739 .float_cast,
740 .complex_float_cast,
741 .complex_float_to_real,
742 .real_to_complex_float,
743 .null_to_pointer,
744 .union_cast,
745 .vector_splat,
746 => return c.fail("TODO CodeGen gen CastKind {}\n", .{data.cast.kind}),
747 },
748 .binary_cond_expr => {
749 if (c.tree.value_map.get(data.if3.cond)) |cond| {
750 if (cond.toBool(c.comp)) {
751 c.cond_dummy_ref = try c.genExpr(data.if3.cond);
752 return c.genExpr(c.tree.data[data.if3.body]); // then
753 } else {
754 return c.genExpr(c.tree.data[data.if3.body + 1]); // else
755 }
756 }
757
758 const then_label = try c.builder.makeLabel("ternary.then");
759 const else_label = try c.builder.makeLabel("ternary.else");
760 const end_label = try c.builder.makeLabel("ternary.end");
761 const cond_ty = c.node_ty[@intFromEnum(data.if3.cond)];
762 {
763 const old_cond_dummy_ty = c.cond_dummy_ty;
764 defer c.cond_dummy_ty = old_cond_dummy_ty;
765 c.cond_dummy_ty = try c.genType(cond_ty);
766
767 try c.genBoolExpr(data.if3.cond, then_label, else_label);
768 }
769
770 try c.builder.startBlock(then_label);
771 if (c.builder.instructions.items(.ty)[@intFromEnum(c.cond_dummy_ref)] == .i1) {
772 c.cond_dummy_ref = try c.addUn(.zext, c.cond_dummy_ref, cond_ty);
773 }
774 const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
775 try c.builder.addJump(end_label);
776 const then_exit = c.builder.current_label;
777
778 try c.builder.startBlock(else_label);
779 const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
780 const else_exit = c.builder.current_label;
781
782 try c.builder.startBlock(end_label);
783
784 var phi_buf: [2]Ir.Inst.Phi.Input = .{
785 .{ .value = then_val, .label = then_exit },
786 .{ .value = else_val, .label = else_exit },
787 };
788 return c.builder.addPhi(&phi_buf, try c.genType(ty));
789 },
790 .cond_dummy_expr => return c.cond_dummy_ref,
791 .cond_expr => {
792 if (c.tree.value_map.get(data.if3.cond)) |cond| {
793 if (cond.toBool(c.comp)) {
794 return c.genExpr(c.tree.data[data.if3.body]); // then
795 } else {
796 return c.genExpr(c.tree.data[data.if3.body + 1]); // else
797 }
798 }
799
800 const then_label = try c.builder.makeLabel("ternary.then");
801 const else_label = try c.builder.makeLabel("ternary.else");
802 const end_label = try c.builder.makeLabel("ternary.end");
803
804 try c.genBoolExpr(data.if3.cond, then_label, else_label);
805
806 try c.builder.startBlock(then_label);
807 const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
808 try c.builder.addJump(end_label);
809 const then_exit = c.builder.current_label;
810
811 try c.builder.startBlock(else_label);
812 const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
813 const else_exit = c.builder.current_label;
814
815 try c.builder.startBlock(end_label);
816
817 var phi_buf: [2]Ir.Inst.Phi.Input = .{
818 .{ .value = then_val, .label = then_exit },
819 .{ .value = else_val, .label = else_exit },
820 };
821 return c.builder.addPhi(&phi_buf, try c.genType(ty));
822 },
823 .call_expr_one => if (data.bin.rhs == .none) {
824 return c.genCall(data.bin.lhs, &.{}, ty);
825 } else {
826 return c.genCall(data.bin.lhs, &.{data.bin.rhs}, ty);
827 },
828 .call_expr => {
829 return c.genCall(c.tree.data[data.range.start], c.tree.data[data.range.start + 1 .. data.range.end], ty);
830 },
831 .bool_or_expr => {
832 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
833 if (!lhs.toBool(c.comp)) {
834 return c.builder.addConstant(.one, try c.genType(ty));
835 }
836 return c.genExpr(data.bin.rhs);
837 }
838
839 const false_label = try c.builder.makeLabel("bool_false");
840 const exit_label = try c.builder.makeLabel("bool_exit");
841
842 const old_bool_end_label = c.bool_end_label;
843 defer c.bool_end_label = old_bool_end_label;
844 c.bool_end_label = exit_label;
845
846 const phi_nodes_top = c.phi_nodes.items.len;
847 defer c.phi_nodes.items.len = phi_nodes_top;
848
849 try c.genBoolExpr(data.bin.lhs, exit_label, false_label);
850
851 try c.builder.startBlock(false_label);
852 try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
853
854 try c.builder.startBlock(exit_label);
855
856 const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
857 return c.addUn(.zext, phi, ty);
858 },
859 .bool_and_expr => {
860 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
861 if (!lhs.toBool(c.comp)) {
862 return c.builder.addConstant(.zero, try c.genType(ty));
863 }
864 return c.genExpr(data.bin.rhs);
865 }
866
867 const true_label = try c.builder.makeLabel("bool_true");
868 const exit_label = try c.builder.makeLabel("bool_exit");
869
870 const old_bool_end_label = c.bool_end_label;
871 defer c.bool_end_label = old_bool_end_label;
872 c.bool_end_label = exit_label;
873
874 const phi_nodes_top = c.phi_nodes.items.len;
875 defer c.phi_nodes.items.len = phi_nodes_top;
876
877 try c.genBoolExpr(data.bin.lhs, true_label, exit_label);
878
879 try c.builder.startBlock(true_label);
880 try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
881
882 try c.builder.startBlock(exit_label);
883
884 const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
885 return c.addUn(.zext, phi, ty);
886 },
887 .builtin_choose_expr => {
888 const cond = c.tree.value_map.get(data.if3.cond).?;
889 if (cond.toBool(c.comp)) {
890 return c.genExpr(c.tree.data[data.if3.body]);
891 } else {
892 return c.genExpr(c.tree.data[data.if3.body + 1]);
893 }
894 },
895 .generic_expr_one => {
896 const index = @intFromEnum(data.bin.rhs);
897 switch (c.node_tag[index]) {
898 .generic_association_expr, .generic_default_expr => {
899 return c.genExpr(c.node_data[index].un);
900 },
901 else => unreachable,
902 }
903 },
904 .generic_expr => {
905 const index = @intFromEnum(c.tree.data[data.range.start + 1]);
906 switch (c.node_tag[index]) {
907 .generic_association_expr, .generic_default_expr => {
908 return c.genExpr(c.node_data[index].un);
909 },
910 else => unreachable,
911 }
912 },
913 .generic_association_expr, .generic_default_expr => unreachable,
914 .stmt_expr => switch (c.node_tag[@intFromEnum(data.un)]) {
915 .compound_stmt_two => {
916 const old_sym_len = c.symbols.items.len;
917 c.symbols.items.len = old_sym_len;
918
919 const stmt_data = c.node_data[@intFromEnum(data.un)];
920 if (stmt_data.bin.rhs == .none) return c.genExpr(stmt_data.bin.lhs);
921 try c.genStmt(stmt_data.bin.lhs);
922 return c.genExpr(stmt_data.bin.rhs);
923 },
924 .compound_stmt => {
925 const old_sym_len = c.symbols.items.len;
926 c.symbols.items.len = old_sym_len;
927
928 const stmt_data = c.node_data[@intFromEnum(data.un)];
929 for (c.tree.data[stmt_data.range.start .. stmt_data.range.end - 1]) |stmt| try c.genStmt(stmt);
930 return c.genExpr(c.tree.data[stmt_data.range.end]);
931 },
932 else => unreachable,
933 },
934 .builtin_call_expr_one => {
935 const name = c.tree.tokSlice(data.decl.name);
936 const builtin = c.comp.builtins.lookup(name).builtin;
937 if (data.decl.node == .none) {
938 return c.genBuiltinCall(builtin, &.{}, ty);
939 } else {
940 return c.genBuiltinCall(builtin, &.{data.decl.node}, ty);
941 }
942 },
943 .builtin_call_expr => {
944 const name_node_idx = c.tree.data[data.range.start];
945 const name = c.tree.tokSlice(@intFromEnum(name_node_idx));
946 const builtin = c.comp.builtins.lookup(name).builtin;
947 return c.genBuiltinCall(builtin, c.tree.data[data.range.start + 1 .. data.range.end], ty);
948 },
949 .addr_of_label,
950 .imag_expr,
951 .real_expr,
952 .sizeof_expr,
953 .special_builtin_call_one,
954 => return c.fail("TODO CodeGen.genExpr {}\n", .{c.node_tag[@intFromEnum(node)]}),
955 else => unreachable, // Not an expression.
956 }
957 return .none;
958}
959
960fn genLval(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
961 std.debug.assert(node != .none);
962 assert(c.tree.isLval(node));
963 const data = c.node_data[@intFromEnum(node)];
964 switch (c.node_tag[@intFromEnum(node)]) {
965 .string_literal_expr => {
966 const val = c.tree.value_map.get(node).?;
967 return c.builder.addConstant(val.ref(), .ptr);
968 },
969 .paren_expr => return c.genLval(data.un),
970 .decl_ref_expr => {
971 const slice = c.tree.tokSlice(data.decl_ref);
972 const name = try StrInt.intern(c.comp, slice);
973 var i = c.symbols.items.len;
974 while (i > 0) {
975 i -= 1;
976 if (c.symbols.items[i].name == name) {
977 return c.symbols.items[i].val;
978 }
979 }
980
981 const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
982 const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
983 try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
984 return ref;
985 },
986 .deref_expr => return c.genExpr(data.un),
987 .compound_literal_expr => {
988 const ty = c.node_ty[@intFromEnum(node)];
989 const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
990 const @"align" = ty.alignof(c.comp);
991 const alloc = try c.builder.addAlloc(size, @"align");
992 try c.genInitializer(alloc, ty, data.un);
993 return alloc;
994 },
995 .builtin_choose_expr => {
996 const cond = c.tree.value_map.get(data.if3.cond).?;
997 if (cond.toBool(c.comp)) {
998 return c.genLval(c.tree.data[data.if3.body]);
999 } else {
1000 return c.genLval(c.tree.data[data.if3.body + 1]);
1001 }
1002 },
1003 .member_access_expr,
1004 .member_access_ptr_expr,
1005 .array_access_expr,
1006 .static_compound_literal_expr,
1007 .thread_local_compound_literal_expr,
1008 .static_thread_local_compound_literal_expr,
1009 => return c.fail("TODO CodeGen.genLval {}\n", .{c.node_tag[@intFromEnum(node)]}),
1010 else => unreachable, // Not an lval expression.
1011 }
1012}
1013
1014fn genBoolExpr(c: *CodeGen, base: NodeIndex, true_label: Ir.Ref, false_label: Ir.Ref) Error!void {
1015 var node = base;
1016 while (true) switch (c.node_tag[@intFromEnum(node)]) {
1017 .paren_expr => {
1018 node = c.node_data[@intFromEnum(node)].un;
1019 },
1020 else => break,
1021 };
1022
1023 const data = c.node_data[@intFromEnum(node)];
1024 switch (c.node_tag[@intFromEnum(node)]) {
1025 .bool_or_expr => {
1026 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
1027 if (lhs.toBool(c.comp)) {
1028 if (true_label == c.bool_end_label) {
1029 return c.addBoolPhi(!c.bool_invert);
1030 }
1031 return c.builder.addJump(true_label);
1032 }
1033 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1034 }
1035
1036 const new_false_label = try c.builder.makeLabel("bool_false");
1037 try c.genBoolExpr(data.bin.lhs, true_label, new_false_label);
1038 try c.builder.startBlock(new_false_label);
1039
1040 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1041 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1042 },
1043 .bool_and_expr => {
1044 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
1045 if (!lhs.toBool(c.comp)) {
1046 if (false_label == c.bool_end_label) {
1047 return c.addBoolPhi(c.bool_invert);
1048 }
1049 return c.builder.addJump(false_label);
1050 }
1051 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1052 }
1053
1054 const new_true_label = try c.builder.makeLabel("bool_true");
1055 try c.genBoolExpr(data.bin.lhs, new_true_label, false_label);
1056 try c.builder.startBlock(new_true_label);
1057
1058 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1059 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1060 },
1061 .bool_not_expr => {
1062 c.bool_invert = !c.bool_invert;
1063 defer c.bool_invert = !c.bool_invert;
1064
1065 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.zero, ty);
1066 return c.genBoolExpr(data.un, false_label, true_label);
1067 },
1068 .equal_expr => {
1069 const cmp = try c.genComparison(node, .cmp_eq);
1070 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1071 return c.addBranch(cmp, true_label, false_label);
1072 },
1073 .not_equal_expr => {
1074 const cmp = try c.genComparison(node, .cmp_ne);
1075 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1076 return c.addBranch(cmp, true_label, false_label);
1077 },
1078 .less_than_expr => {
1079 const cmp = try c.genComparison(node, .cmp_lt);
1080 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1081 return c.addBranch(cmp, true_label, false_label);
1082 },
1083 .less_than_equal_expr => {
1084 const cmp = try c.genComparison(node, .cmp_lte);
1085 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1086 return c.addBranch(cmp, true_label, false_label);
1087 },
1088 .greater_than_expr => {
1089 const cmp = try c.genComparison(node, .cmp_gt);
1090 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1091 return c.addBranch(cmp, true_label, false_label);
1092 },
1093 .greater_than_equal_expr => {
1094 const cmp = try c.genComparison(node, .cmp_gte);
1095 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1096 return c.addBranch(cmp, true_label, false_label);
1097 },
1098 .explicit_cast, .implicit_cast => switch (data.cast.kind) {
1099 .bool_to_int => {
1100 const operand = try c.genExpr(data.cast.operand);
1101 if (c.cond_dummy_ty != null) c.cond_dummy_ref = operand;
1102 return c.addBranch(operand, true_label, false_label);
1103 },
1104 else => {},
1105 },
1106 .binary_cond_expr => {
1107 if (c.tree.value_map.get(data.if3.cond)) |cond| {
1108 if (cond.toBool(c.comp)) {
1109 return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
1110 } else {
1111 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1112 }
1113 }
1114
1115 const new_false_label = try c.builder.makeLabel("ternary.else");
1116 try c.genBoolExpr(data.if3.cond, true_label, new_false_label);
1117
1118 try c.builder.startBlock(new_false_label);
1119 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1120 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1121 },
1122 .cond_expr => {
1123 if (c.tree.value_map.get(data.if3.cond)) |cond| {
1124 if (cond.toBool(c.comp)) {
1125 return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
1126 } else {
1127 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1128 }
1129 }
1130
1131 const new_true_label = try c.builder.makeLabel("ternary.then");
1132 const new_false_label = try c.builder.makeLabel("ternary.else");
1133 try c.genBoolExpr(data.if3.cond, new_true_label, new_false_label);
1134
1135 try c.builder.startBlock(new_true_label);
1136 try c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
1137 try c.builder.startBlock(new_false_label);
1138 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1139 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1140 },
1141 else => {},
1142 }
1143
1144 if (c.tree.value_map.get(node)) |value| {
1145 if (value.toBool(c.comp)) {
1146 if (true_label == c.bool_end_label) {
1147 return c.addBoolPhi(!c.bool_invert);
1148 }
1149 return c.builder.addJump(true_label);
1150 } else {
1151 if (false_label == c.bool_end_label) {
1152 return c.addBoolPhi(c.bool_invert);
1153 }
1154 return c.builder.addJump(false_label);
1155 }
1156 }
1157
1158 // Assume int operand.
1159 const lhs = try c.genExpr(node);
1160 const rhs = try c.builder.addConstant(.zero, try c.genType(c.node_ty[@intFromEnum(node)]));
1161 const cmp = try c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
1162 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1163 try c.addBranch(cmp, true_label, false_label);
1164}
1165
1166fn genBuiltinCall(c: *CodeGen, builtin: Builtin, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
1167 _ = arg_nodes;
1168 _ = ty;
1169 return c.fail("TODO CodeGen.genBuiltinCall {s}\n", .{Builtin.nameFromTag(builtin.tag).span()});
1170}
1171
1172fn genCall(c: *CodeGen, fn_node: NodeIndex, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
1173 // Detect direct calls.
1174 const fn_ref = blk: {
1175 const data = c.node_data[@intFromEnum(fn_node)];
1176 if (c.node_tag[@intFromEnum(fn_node)] != .implicit_cast or data.cast.kind != .function_to_pointer) {
1177 break :blk try c.genExpr(fn_node);
1178 }
1179
1180 var cur = @intFromEnum(data.cast.operand);
1181 while (true) switch (c.node_tag[cur]) {
1182 .paren_expr, .addr_of_expr, .deref_expr => {
1183 cur = @intFromEnum(c.node_data[cur].un);
1184 },
1185 .implicit_cast => {
1186 const cast = c.node_data[cur].cast;
1187 if (cast.kind != .function_to_pointer) {
1188 break :blk try c.genExpr(fn_node);
1189 }
1190 cur = @intFromEnum(cast.operand);
1191 },
1192 .decl_ref_expr => {
1193 const slice = c.tree.tokSlice(c.node_data[cur].decl_ref);
1194 const name = try StrInt.intern(c.comp, slice);
1195 var i = c.symbols.items.len;
1196 while (i > 0) {
1197 i -= 1;
1198 if (c.symbols.items[i].name == name) {
1199 break :blk try c.genExpr(fn_node);
1200 }
1201 }
1202
1203 const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
1204 const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
1205 try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
1206 break :blk ref;
1207 },
1208 else => break :blk try c.genExpr(fn_node),
1209 };
1210 };
1211
1212 const args = try c.builder.arena.allocator().alloc(Ir.Ref, arg_nodes.len);
1213 for (arg_nodes, args) |node, *arg| {
1214 // TODO handle calling convention here
1215 arg.* = try c.genExpr(node);
1216 }
1217 // TODO handle variadic call
1218 const call = try c.builder.arena.allocator().create(Ir.Inst.Call);
1219 call.* = .{
1220 .func = fn_ref,
1221 .args_len = @intCast(args.len),
1222 .args_ptr = args.ptr,
1223 };
1224 return c.builder.addInst(.call, .{ .call = call }, try c.genType(ty));
1225}
1226
1227fn genCompoundAssign(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
1228 const bin = c.node_data[@intFromEnum(node)].bin;
1229 const ty = c.node_ty[@intFromEnum(node)];
1230 const rhs = try c.genExpr(bin.rhs);
1231 const lhs = try c.genLval(bin.lhs);
1232 const res = try c.addBin(tag, lhs, rhs, ty);
1233 try c.builder.addStore(lhs, res);
1234 return res;
1235}
1236
1237fn genBinOp(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
1238 const bin = c.node_data[@intFromEnum(node)].bin;
1239 const ty = c.node_ty[@intFromEnum(node)];
1240 const lhs = try c.genExpr(bin.lhs);
1241 const rhs = try c.genExpr(bin.rhs);
1242 return c.addBin(tag, lhs, rhs, ty);
1243}
1244
1245fn genComparison(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
1246 const bin = c.node_data[@intFromEnum(node)].bin;
1247 const lhs = try c.genExpr(bin.lhs);
1248 const rhs = try c.genExpr(bin.rhs);
1249
1250 return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
1251}
1252
1253fn genPtrArithmetic(c: *CodeGen, ptr: Ir.Ref, offset: Ir.Ref, offset_ty: Type, ty: Type) Error!Ir.Ref {
1254 // TODO consider adding a getelemptr instruction
1255 const size = ty.elemType().sizeof(c.comp).?;
1256 if (size == 1) {
1257 return c.builder.addInst(.add, .{ .bin = .{ .lhs = ptr, .rhs = offset } }, try c.genType(ty));
1258 }
1259
1260 const size_inst = try c.builder.addConstant((try Value.int(size, c.comp)).ref(), try c.genType(offset_ty));
1261 const offset_inst = try c.addBin(.mul, offset, size_inst, offset_ty);
1262 return c.addBin(.add, ptr, offset_inst, offset_ty);
1263}
1264
1265fn genInitializer(c: *CodeGen, ptr: Ir.Ref, dest_ty: Type, initializer: NodeIndex) Error!void {
1266 std.debug.assert(initializer != .none);
1267 switch (c.node_tag[@intFromEnum(initializer)]) {
1268 .array_init_expr_two,
1269 .array_init_expr,
1270 .struct_init_expr_two,
1271 .struct_init_expr,
1272 .union_init_expr,
1273 .array_filler_expr,
1274 .default_init_expr,
1275 => return c.fail("TODO CodeGen.genInitializer {}\n", .{c.node_tag[@intFromEnum(initializer)]}),
1276 .string_literal_expr => {
1277 const val = c.tree.value_map.get(initializer).?;
1278 const str_ptr = try c.builder.addConstant(val.ref(), .ptr);
1279 if (dest_ty.isArray()) {
1280 return c.fail("TODO memcpy\n", .{});
1281 } else {
1282 try c.builder.addStore(ptr, str_ptr);
1283 }
1284 },
1285 else => {
1286 const res = try c.genExpr(initializer);
1287 try c.builder.addStore(ptr, res);
1288 },
1289 }
1290}
1291
1292fn genVar(c: *CodeGen, decl: NodeIndex) Error!void {
1293 _ = decl;
1294 return c.fail("TODO CodeGen.genVar\n", .{});
1295}
deps/aro/aro/Compilation.zig deleted-1678
......@@ -1,1678 +0,0 @@
1const std = @import("std");
2const Allocator = mem.Allocator;
3const assert = std.debug.assert;
4const EpochSeconds = std.time.epoch.EpochSeconds;
5const mem = std.mem;
6const Interner = @import("backend").Interner;
7const Builtins = @import("Builtins.zig");
8const Builtin = Builtins.Builtin;
9const Diagnostics = @import("Diagnostics.zig");
10const LangOpts = @import("LangOpts.zig");
11const Source = @import("Source.zig");
12const Tokenizer = @import("Tokenizer.zig");
13const Token = Tokenizer.Token;
14const Type = @import("Type.zig");
15const Pragma = @import("Pragma.zig");
16const StrInt = @import("StringInterner.zig");
17const record_layout = @import("record_layout.zig");
18const target_util = @import("target.zig");
19
20pub const Error = error{
21 /// A fatal error has ocurred and compilation has stopped.
22 FatalError,
23} || Allocator.Error;
24
25pub const bit_int_max_bits = std.math.maxInt(u16);
26const path_buf_stack_limit = 1024;
27
28/// Environment variables used during compilation / linking.
29pub const Environment = struct {
30 /// Directory to use for temporary files
31 /// TODO: not implemented yet
32 tmpdir: ?[]const u8 = null,
33
34 /// PATH environment variable used to search for programs
35 path: ?[]const u8 = null,
36
37 /// Directories to try when searching for subprograms.
38 /// TODO: not implemented yet
39 compiler_path: ?[]const u8 = null,
40
41 /// Directories to try when searching for special linker files, if compiling for the native target
42 /// TODO: not implemented yet
43 library_path: ?[]const u8 = null,
44
45 /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
46 /// Used regardless of the language being compiled
47 /// TODO: not implemented yet
48 cpath: ?[]const u8 = null,
49
50 /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
51 /// Used if the language being compiled is C
52 /// TODO: not implemented yet
53 c_include_path: ?[]const u8 = null,
54
55 /// UNIX timestamp to be used instead of the current date and time in the __DATE__ and __TIME__ macros
56 source_date_epoch: ?[]const u8 = null,
57
58 /// Load all of the environment variables using the std.process API. Do not use if using Aro as a shared library on Linux without libc
59 /// See https://github.com/ziglang/zig/issues/4524
60 pub fn loadAll(allocator: std.mem.Allocator) !Environment {
61 var env: Environment = .{};
62 errdefer env.deinit(allocator);
63
64 inline for (@typeInfo(@TypeOf(env)).Struct.fields) |field| {
65 std.debug.assert(@field(env, field.name) == null);
66
67 var env_var_buf: [field.name.len]u8 = undefined;
68 const env_var_name = std.ascii.upperString(&env_var_buf, field.name);
69 const val: ?[]const u8 = std.process.getEnvVarOwned(allocator, env_var_name) catch |err| switch (err) {
70 error.OutOfMemory => |e| return e,
71 error.EnvironmentVariableNotFound => null,
72 error.InvalidWtf8 => null,
73 };
74 @field(env, field.name) = val;
75 }
76 return env;
77 }
78
79 /// Use this only if environment slices were allocated with `allocator` (such as via `loadAll`)
80 pub fn deinit(self: *Environment, allocator: std.mem.Allocator) void {
81 inline for (@typeInfo(@TypeOf(self.*)).Struct.fields) |field| {
82 if (@field(self, field.name)) |slice| {
83 allocator.free(slice);
84 }
85 }
86 self.* = undefined;
87 }
88};
89
90const Compilation = @This();
91
92gpa: Allocator,
93diagnostics: Diagnostics,
94
95environment: Environment = .{},
96sources: std.StringArrayHashMapUnmanaged(Source) = .{},
97include_dirs: std.ArrayListUnmanaged([]const u8) = .{},
98system_include_dirs: std.ArrayListUnmanaged([]const u8) = .{},
99target: std.Target = @import("builtin").target,
100pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .{},
101langopts: LangOpts = .{},
102generated_buf: std.ArrayListUnmanaged(u8) = .{},
103builtins: Builtins = .{},
104types: struct {
105 wchar: Type = undefined,
106 uint_least16_t: Type = undefined,
107 uint_least32_t: Type = undefined,
108 ptrdiff: Type = undefined,
109 size: Type = undefined,
110 va_list: Type = undefined,
111 pid_t: Type = undefined,
112 ns_constant_string: struct {
113 ty: Type = undefined,
114 record: Type.Record = undefined,
115 fields: [4]Type.Record.Field = undefined,
116 int_ty: Type = .{ .specifier = .int, .qual = .{ .@"const" = true } },
117 char_ty: Type = .{ .specifier = .char, .qual = .{ .@"const" = true } },
118 } = .{},
119 file: Type = .{ .specifier = .invalid },
120 jmp_buf: Type = .{ .specifier = .invalid },
121 sigjmp_buf: Type = .{ .specifier = .invalid },
122 ucontext_t: Type = .{ .specifier = .invalid },
123 intmax: Type = .{ .specifier = .invalid },
124 intptr: Type = .{ .specifier = .invalid },
125 int16: Type = .{ .specifier = .invalid },
126 int64: Type = .{ .specifier = .invalid },
127} = .{},
128string_interner: StrInt = .{},
129interner: Interner = .{},
130ms_cwd_source_id: ?Source.Id = null,
131
132pub fn init(gpa: Allocator) Compilation {
133 return .{
134 .gpa = gpa,
135 .diagnostics = Diagnostics.init(gpa),
136 };
137}
138
139/// Initialize Compilation with default environment,
140/// pragma handlers and emulation mode set to target.
141pub fn initDefault(gpa: Allocator) !Compilation {
142 var comp: Compilation = .{
143 .gpa = gpa,
144 .environment = try Environment.loadAll(gpa),
145 .diagnostics = Diagnostics.init(gpa),
146 };
147 errdefer comp.deinit();
148 try comp.addDefaultPragmaHandlers();
149 comp.langopts.setEmulatedCompiler(target_util.systemCompiler(comp.target));
150 return comp;
151}
152
153pub fn deinit(comp: *Compilation) void {
154 for (comp.pragma_handlers.values()) |pragma| {
155 pragma.deinit(pragma, comp);
156 }
157 for (comp.sources.values()) |source| {
158 comp.gpa.free(source.path);
159 comp.gpa.free(source.buf);
160 comp.gpa.free(source.splice_locs);
161 }
162 comp.sources.deinit(comp.gpa);
163 comp.diagnostics.deinit();
164 comp.include_dirs.deinit(comp.gpa);
165 for (comp.system_include_dirs.items) |path| comp.gpa.free(path);
166 comp.system_include_dirs.deinit(comp.gpa);
167 comp.pragma_handlers.deinit(comp.gpa);
168 comp.generated_buf.deinit(comp.gpa);
169 comp.builtins.deinit(comp.gpa);
170 comp.string_interner.deinit(comp.gpa);
171 comp.interner.deinit(comp.gpa);
172 comp.environment.deinit(comp.gpa);
173}
174
175pub fn getSourceEpoch(self: *const Compilation, max: i64) !?i64 {
176 const provided = self.environment.source_date_epoch orelse return null;
177 const parsed = std.fmt.parseInt(i64, provided, 10) catch return error.InvalidEpoch;
178 if (parsed < 0 or parsed > max) return error.InvalidEpoch;
179 return parsed;
180}
181
182/// Dec 31 9999 23:59:59
183const max_timestamp = 253402300799;
184
185fn getTimestamp(comp: *Compilation) !u47 {
186 const provided: ?i64 = comp.getSourceEpoch(max_timestamp) catch blk: {
187 try comp.addDiagnostic(.{
188 .tag = .invalid_source_epoch,
189 .loc = .{ .id = .unused, .byte_offset = 0, .line = 0 },
190 }, &.{});
191 break :blk null;
192 };
193 const timestamp = provided orelse std.time.timestamp();
194 return @intCast(std.math.clamp(timestamp, 0, max_timestamp));
195}
196
197fn generateDateAndTime(w: anytype, timestamp: u47) !void {
198 const epoch_seconds = EpochSeconds{ .secs = timestamp };
199 const epoch_day = epoch_seconds.getEpochDay();
200 const day_seconds = epoch_seconds.getDaySeconds();
201 const year_day = epoch_day.calculateYearDay();
202 const month_day = year_day.calculateMonthDay();
203
204 const month_names = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
205 std.debug.assert(std.time.epoch.Month.jan.numeric() == 1);
206
207 const month_name = month_names[month_day.month.numeric() - 1];
208 try w.print("#define __DATE__ \"{s} {d: >2} {d}\"\n", .{
209 month_name,
210 month_day.day_index + 1,
211 year_day.year,
212 });
213 try w.print("#define __TIME__ \"{d:0>2}:{d:0>2}:{d:0>2}\"\n", .{
214 day_seconds.getHoursIntoDay(),
215 day_seconds.getMinutesIntoHour(),
216 day_seconds.getSecondsIntoMinute(),
217 });
218
219 const day_names = [_][]const u8{ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
220 // days since Thu Oct 1 1970
221 const day_name = day_names[@intCast((epoch_day.day + 3) % 7)];
222 try w.print("#define __TIMESTAMP__ \"{s} {s} {d: >2} {d:0>2}:{d:0>2}:{d:0>2} {d}\"\n", .{
223 day_name,
224 month_name,
225 month_day.day_index + 1,
226 day_seconds.getHoursIntoDay(),
227 day_seconds.getMinutesIntoHour(),
228 day_seconds.getSecondsIntoMinute(),
229 year_day.year,
230 });
231}
232
233/// Which set of system defines to generate via generateBuiltinMacros
234pub const SystemDefinesMode = enum {
235 /// Only define macros required by the C standard (date/time macros and those beginning with `__STDC`)
236 no_system_defines,
237 /// Define the standard set of system macros
238 include_system_defines,
239};
240
241fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
242 const ptr_width = comp.target.ptrBitWidth();
243
244 // os macros
245 switch (comp.target.os.tag) {
246 .linux => try w.writeAll(
247 \\#define linux 1
248 \\#define __linux 1
249 \\#define __linux__ 1
250 \\
251 ),
252 .windows => if (ptr_width == 32) try w.writeAll(
253 \\#define WIN32 1
254 \\#define _WIN32 1
255 \\#define __WIN32 1
256 \\#define __WIN32__ 1
257 \\
258 ) else try w.writeAll(
259 \\#define WIN32 1
260 \\#define WIN64 1
261 \\#define _WIN32 1
262 \\#define _WIN64 1
263 \\#define __WIN32 1
264 \\#define __WIN64 1
265 \\#define __WIN32__ 1
266 \\#define __WIN64__ 1
267 \\
268 ),
269 .freebsd => try w.print("#define __FreeBSD__ {d}\n", .{comp.target.os.version_range.semver.min.major}),
270 .netbsd => try w.writeAll("#define __NetBSD__ 1\n"),
271 .openbsd => try w.writeAll("#define __OpenBSD__ 1\n"),
272 .dragonfly => try w.writeAll("#define __DragonFly__ 1\n"),
273 .solaris => try w.writeAll(
274 \\#define sun 1
275 \\#define __sun 1
276 \\
277 ),
278 .macos => try w.writeAll(
279 \\#define __APPLE__ 1
280 \\#define __MACH__ 1
281 \\
282 ),
283 else => {},
284 }
285
286 // unix and other additional os macros
287 switch (comp.target.os.tag) {
288 .freebsd,
289 .netbsd,
290 .openbsd,
291 .dragonfly,
292 .linux,
293 => try w.writeAll(
294 \\#define unix 1
295 \\#define __unix 1
296 \\#define __unix__ 1
297 \\
298 ),
299 else => {},
300 }
301 if (comp.target.abi == .android) {
302 try w.writeAll("#define __ANDROID__ 1\n");
303 }
304
305 // architecture macros
306 switch (comp.target.cpu.arch) {
307 .x86_64 => try w.writeAll(
308 \\#define __amd64__ 1
309 \\#define __amd64 1
310 \\#define __x86_64 1
311 \\#define __x86_64__ 1
312 \\
313 ),
314 .x86 => try w.writeAll(
315 \\#define i386 1
316 \\#define __i386 1
317 \\#define __i386__ 1
318 \\
319 ),
320 .mips,
321 .mipsel,
322 .mips64,
323 .mips64el,
324 => try w.writeAll(
325 \\#define __mips__ 1
326 \\#define mips 1
327 \\
328 ),
329 .powerpc,
330 .powerpcle,
331 => try w.writeAll(
332 \\#define __powerpc__ 1
333 \\#define __POWERPC__ 1
334 \\#define __ppc__ 1
335 \\#define __PPC__ 1
336 \\#define _ARCH_PPC 1
337 \\
338 ),
339 .powerpc64,
340 .powerpc64le,
341 => try w.writeAll(
342 \\#define __powerpc 1
343 \\#define __powerpc__ 1
344 \\#define __powerpc64__ 1
345 \\#define __POWERPC__ 1
346 \\#define __ppc__ 1
347 \\#define __ppc64__ 1
348 \\#define __PPC__ 1
349 \\#define __PPC64__ 1
350 \\#define _ARCH_PPC 1
351 \\#define _ARCH_PPC64 1
352 \\
353 ),
354 .sparc64 => try w.writeAll(
355 \\#define __sparc__ 1
356 \\#define __sparc 1
357 \\#define __sparc_v9__ 1
358 \\
359 ),
360 .sparc, .sparcel => try w.writeAll(
361 \\#define __sparc__ 1
362 \\#define __sparc 1
363 \\
364 ),
365 .arm, .armeb => try w.writeAll(
366 \\#define __arm__ 1
367 \\#define __arm 1
368 \\
369 ),
370 .thumb, .thumbeb => try w.writeAll(
371 \\#define __arm__ 1
372 \\#define __arm 1
373 \\#define __thumb__ 1
374 \\
375 ),
376 .aarch64, .aarch64_be => try w.writeAll("#define __aarch64__ 1\n"),
377 .msp430 => try w.writeAll(
378 \\#define MSP430 1
379 \\#define __MSP430__ 1
380 \\
381 ),
382 else => {},
383 }
384
385 if (comp.target.os.tag != .windows) switch (ptr_width) {
386 64 => try w.writeAll(
387 \\#define _LP64 1
388 \\#define __LP64__ 1
389 \\
390 ),
391 32 => try w.writeAll("#define _ILP32 1\n"),
392 else => {},
393 };
394
395 try w.writeAll(
396 \\#define __ORDER_LITTLE_ENDIAN__ 1234
397 \\#define __ORDER_BIG_ENDIAN__ 4321
398 \\#define __ORDER_PDP_ENDIAN__ 3412
399 \\
400 );
401 if (comp.target.cpu.arch.endian() == .little) try w.writeAll(
402 \\#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
403 \\#define __LITTLE_ENDIAN__ 1
404 \\
405 ) else try w.writeAll(
406 \\#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
407 \\#define __BIG_ENDIAN__ 1
408 \\
409 );
410
411 // atomics
412 try w.writeAll(
413 \\#define __ATOMIC_RELAXED 0
414 \\#define __ATOMIC_CONSUME 1
415 \\#define __ATOMIC_ACQUIRE 2
416 \\#define __ATOMIC_RELEASE 3
417 \\#define __ATOMIC_ACQ_REL 4
418 \\#define __ATOMIC_SEQ_CST 5
419 \\
420 );
421
422 // types
423 if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
424 try w.writeAll("#define __CHAR_BIT__ 8\n");
425
426 // int maxs
427 try comp.generateIntWidth(w, "BOOL", .{ .specifier = .bool });
428 try comp.generateIntMaxAndWidth(w, "SCHAR", .{ .specifier = .schar });
429 try comp.generateIntMaxAndWidth(w, "SHRT", .{ .specifier = .short });
430 try comp.generateIntMaxAndWidth(w, "INT", .{ .specifier = .int });
431 try comp.generateIntMaxAndWidth(w, "LONG", .{ .specifier = .long });
432 try comp.generateIntMaxAndWidth(w, "LONG_LONG", .{ .specifier = .long_long });
433 try comp.generateIntMaxAndWidth(w, "WCHAR", comp.types.wchar);
434 // try comp.generateIntMax(w, "WINT", comp.types.wchar);
435 try comp.generateIntMaxAndWidth(w, "INTMAX", comp.types.intmax);
436 try comp.generateIntMaxAndWidth(w, "SIZE", comp.types.size);
437 try comp.generateIntMaxAndWidth(w, "UINTMAX", comp.types.intmax.makeIntegerUnsigned());
438 try comp.generateIntMaxAndWidth(w, "PTRDIFF", comp.types.ptrdiff);
439 try comp.generateIntMaxAndWidth(w, "INTPTR", comp.types.intptr);
440 try comp.generateIntMaxAndWidth(w, "UINTPTR", comp.types.intptr.makeIntegerUnsigned());
441
442 // int widths
443 try w.print("#define __BITINT_MAXWIDTH__ {d}\n", .{bit_int_max_bits});
444
445 // sizeof types
446 try comp.generateSizeofType(w, "__SIZEOF_FLOAT__", .{ .specifier = .float });
447 try comp.generateSizeofType(w, "__SIZEOF_DOUBLE__", .{ .specifier = .double });
448 try comp.generateSizeofType(w, "__SIZEOF_LONG_DOUBLE__", .{ .specifier = .long_double });
449 try comp.generateSizeofType(w, "__SIZEOF_SHORT__", .{ .specifier = .short });
450 try comp.generateSizeofType(w, "__SIZEOF_INT__", .{ .specifier = .int });
451 try comp.generateSizeofType(w, "__SIZEOF_LONG__", .{ .specifier = .long });
452 try comp.generateSizeofType(w, "__SIZEOF_LONG_LONG__", .{ .specifier = .long_long });
453 try comp.generateSizeofType(w, "__SIZEOF_POINTER__", .{ .specifier = .pointer });
454 try comp.generateSizeofType(w, "__SIZEOF_PTRDIFF_T__", comp.types.ptrdiff);
455 try comp.generateSizeofType(w, "__SIZEOF_SIZE_T__", comp.types.size);
456 try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar);
457 // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer });
458
459 if (target_util.hasInt128(comp.target)) {
460 try comp.generateSizeofType(w, "__SIZEOF_INT128__", .{ .specifier = .int128 });
461 }
462
463 // various int types
464 const mapper = comp.string_interner.getSlowTypeMapper();
465 try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts);
466 try generateTypeMacro(w, mapper, "__UINTPTR_TYPE__", comp.types.intptr.makeIntegerUnsigned(), comp.langopts);
467
468 try generateTypeMacro(w, mapper, "__INTMAX_TYPE__", comp.types.intmax, comp.langopts);
469 try comp.generateSuffixMacro("__INTMAX", w, comp.types.intptr);
470
471 try generateTypeMacro(w, mapper, "__UINTMAX_TYPE__", comp.types.intmax.makeIntegerUnsigned(), comp.langopts);
472 try comp.generateSuffixMacro("__UINTMAX", w, comp.types.intptr.makeIntegerUnsigned());
473
474 try generateTypeMacro(w, mapper, "__PTRDIFF_TYPE__", comp.types.ptrdiff, comp.langopts);
475 try generateTypeMacro(w, mapper, "__SIZE_TYPE__", comp.types.size, comp.langopts);
476 try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts);
477
478 try comp.generateExactWidthTypes(w, mapper);
479 try comp.generateFastAndLeastWidthTypes(w, mapper);
480
481 if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| {
482 try generateFloatMacros(w, "FLT16", half, "F16");
483 }
484 try generateFloatMacros(w, "FLT", target_util.FPSemantics.forType(.float, comp.target), "F");
485 try generateFloatMacros(w, "DBL", target_util.FPSemantics.forType(.double, comp.target), "");
486 try generateFloatMacros(w, "LDBL", target_util.FPSemantics.forType(.longdouble, comp.target), "L");
487
488 // TODO: clang treats __FLT_EVAL_METHOD__ as a special-cased macro because evaluating it within a scope
489 // where `#pragma clang fp eval_method(X)` has been called produces an error diagnostic.
490 const flt_eval_method = comp.langopts.fp_eval_method orelse target_util.defaultFpEvalMethod(comp.target);
491 try w.print("#define __FLT_EVAL_METHOD__ {d}\n", .{@intFromEnum(flt_eval_method)});
492
493 try w.writeAll(
494 \\#define __FLT_RADIX__ 2
495 \\#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
496 \\
497 );
498}
499
500/// Generate builtin macros that will be available to each source file.
501pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) !Source {
502 try comp.generateBuiltinTypes();
503
504 var buf = std.ArrayList(u8).init(comp.gpa);
505 defer buf.deinit();
506
507 if (system_defines_mode == .include_system_defines) {
508 try buf.appendSlice(
509 \\#define __VERSION__ "Aro
510 ++ @import("backend").version_str ++ "\"\n" ++
511 \\#define __Aro__
512 \\
513 );
514 }
515
516 try buf.appendSlice("#define __STDC__ 1\n");
517 try buf.writer().print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)});
518
519 // standard macros
520 try buf.appendSlice(
521 \\#define __STDC_NO_ATOMICS__ 1
522 \\#define __STDC_NO_COMPLEX__ 1
523 \\#define __STDC_NO_THREADS__ 1
524 \\#define __STDC_NO_VLA__ 1
525 \\#define __STDC_UTF_16__ 1
526 \\#define __STDC_UTF_32__ 1
527 \\
528 );
529 if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| {
530 try buf.appendSlice("#define __STDC_VERSION__ ");
531 try buf.appendSlice(stdc_version);
532 try buf.append('\n');
533 }
534
535 // timestamps
536 const timestamp = try comp.getTimestamp();
537 try generateDateAndTime(buf.writer(), timestamp);
538
539 if (system_defines_mode == .include_system_defines) {
540 try comp.generateSystemDefines(buf.writer());
541 }
542
543 return comp.addSourceFromBuffer("<builtin>", buf.items);
544}
545
546fn generateFloatMacros(w: anytype, prefix: []const u8, semantics: target_util.FPSemantics, ext: []const u8) !void {
547 const denormMin = semantics.chooseValue(
548 []const u8,
549 .{
550 "5.9604644775390625e-8",
551 "1.40129846e-45",
552 "4.9406564584124654e-324",
553 "3.64519953188247460253e-4951",
554 "4.94065645841246544176568792868221e-324",
555 "6.47517511943802511092443895822764655e-4966",
556 },
557 );
558 const digits = semantics.chooseValue(i32, .{ 3, 6, 15, 18, 31, 33 });
559 const decimalDigits = semantics.chooseValue(i32, .{ 5, 9, 17, 21, 33, 36 });
560 const epsilon = semantics.chooseValue(
561 []const u8,
562 .{
563 "9.765625e-4",
564 "1.19209290e-7",
565 "2.2204460492503131e-16",
566 "1.08420217248550443401e-19",
567 "4.94065645841246544176568792868221e-324",
568 "1.92592994438723585305597794258492732e-34",
569 },
570 );
571 const mantissaDigits = semantics.chooseValue(i32, .{ 11, 24, 53, 64, 106, 113 });
572
573 const min10Exp = semantics.chooseValue(i32, .{ -4, -37, -307, -4931, -291, -4931 });
574 const max10Exp = semantics.chooseValue(i32, .{ 4, 38, 308, 4932, 308, 4932 });
575
576 const minExp = semantics.chooseValue(i32, .{ -13, -125, -1021, -16381, -968, -16381 });
577 const maxExp = semantics.chooseValue(i32, .{ 16, 128, 1024, 16384, 1024, 16384 });
578
579 const min = semantics.chooseValue(
580 []const u8,
581 .{
582 "6.103515625e-5",
583 "1.17549435e-38",
584 "2.2250738585072014e-308",
585 "3.36210314311209350626e-4932",
586 "2.00416836000897277799610805135016e-292",
587 "3.36210314311209350626267781732175260e-4932",
588 },
589 );
590 const max = semantics.chooseValue(
591 []const u8,
592 .{
593 "6.5504e+4",
594 "3.40282347e+38",
595 "1.7976931348623157e+308",
596 "1.18973149535723176502e+4932",
597 "1.79769313486231580793728971405301e+308",
598 "1.18973149535723176508575932662800702e+4932",
599 },
600 );
601
602 var def_prefix_buf: [32]u8 = undefined;
603 const prefix_slice = std.fmt.bufPrint(&def_prefix_buf, "__{s}_", .{prefix}) catch
604 return error.OutOfMemory;
605
606 try w.print("#define {s}DENORM_MIN__ {s}{s}\n", .{ prefix_slice, denormMin, ext });
607 try w.print("#define {s}HAS_DENORM__\n", .{prefix_slice});
608 try w.print("#define {s}DIG__ {d}\n", .{ prefix_slice, digits });
609 try w.print("#define {s}DECIMAL_DIG__ {d}\n", .{ prefix_slice, decimalDigits });
610
611 try w.print("#define {s}EPSILON__ {s}{s}\n", .{ prefix_slice, epsilon, ext });
612 try w.print("#define {s}HAS_INFINITY__\n", .{prefix_slice});
613 try w.print("#define {s}HAS_QUIET_NAN__\n", .{prefix_slice});
614 try w.print("#define {s}MANT_DIG__ {d}\n", .{ prefix_slice, mantissaDigits });
615
616 try w.print("#define {s}MAX_10_EXP__ {d}\n", .{ prefix_slice, max10Exp });
617 try w.print("#define {s}MAX_EXP__ {d}\n", .{ prefix_slice, maxExp });
618 try w.print("#define {s}MAX__ {s}{s}\n", .{ prefix_slice, max, ext });
619
620 try w.print("#define {s}MIN_10_EXP__ ({d})\n", .{ prefix_slice, min10Exp });
621 try w.print("#define {s}MIN_EXP__ ({d})\n", .{ prefix_slice, minExp });
622 try w.print("#define {s}MIN__ {s}{s}\n", .{ prefix_slice, min, ext });
623}
624
625fn generateTypeMacro(w: anytype, mapper: StrInt.TypeMapper, name: []const u8, ty: Type, langopts: LangOpts) !void {
626 try w.print("#define {s} ", .{name});
627 try ty.print(mapper, langopts, w);
628 try w.writeByte('\n');
629}
630
631fn generateBuiltinTypes(comp: *Compilation) !void {
632 const os = comp.target.os.tag;
633 const wchar: Type = switch (comp.target.cpu.arch) {
634 .xcore => .{ .specifier = .uchar },
635 .ve, .msp430 => .{ .specifier = .uint },
636 .arm, .armeb, .thumb, .thumbeb => .{
637 .specifier = if (os != .windows and os != .netbsd and os != .openbsd) .uint else .int,
638 },
639 .aarch64, .aarch64_be, .aarch64_32 => .{
640 .specifier = if (!os.isDarwin() and os != .netbsd) .uint else .int,
641 },
642 .x86_64, .x86 => .{ .specifier = if (os == .windows) .ushort else .int },
643 else => .{ .specifier = .int },
644 };
645
646 const ptr_width = comp.target.ptrBitWidth();
647 const ptrdiff = if (os == .windows and ptr_width == 64)
648 Type{ .specifier = .long_long }
649 else switch (ptr_width) {
650 16 => Type{ .specifier = .int },
651 32 => Type{ .specifier = .int },
652 64 => Type{ .specifier = .long },
653 else => unreachable,
654 };
655
656 const size = if (os == .windows and ptr_width == 64)
657 Type{ .specifier = .ulong_long }
658 else switch (ptr_width) {
659 16 => Type{ .specifier = .uint },
660 32 => Type{ .specifier = .uint },
661 64 => Type{ .specifier = .ulong },
662 else => unreachable,
663 };
664
665 const va_list = try comp.generateVaListType();
666
667 const pid_t: Type = switch (os) {
668 .haiku => .{ .specifier = .long },
669 // Todo: pid_t is required to "a signed integer type"; are there any systems
670 // on which it is `short int`?
671 else => .{ .specifier = .int },
672 };
673
674 const intmax = target_util.intMaxType(comp.target);
675 const intptr = target_util.intPtrType(comp.target);
676 const int16 = target_util.int16Type(comp.target);
677 const int64 = target_util.int64Type(comp.target);
678
679 comp.types = .{
680 .wchar = wchar,
681 .ptrdiff = ptrdiff,
682 .size = size,
683 .va_list = va_list,
684 .pid_t = pid_t,
685 .intmax = intmax,
686 .intptr = intptr,
687 .int16 = int16,
688 .int64 = int64,
689 .uint_least16_t = comp.intLeastN(16, .unsigned),
690 .uint_least32_t = comp.intLeastN(32, .unsigned),
691 };
692
693 try comp.generateNsConstantStringType();
694}
695
696/// Smallest integer type with at least N bits
697fn intLeastN(comp: *const Compilation, bits: usize, signedness: std.builtin.Signedness) Type {
698 if (bits == 64 and (comp.target.isDarwin() or comp.target.isWasm())) {
699 // WebAssembly and Darwin use `long long` for `int_least64_t` and `int_fast64_t`.
700 return .{ .specifier = if (signedness == .signed) .long_long else .ulong_long };
701 }
702 if (bits == 16 and comp.target.cpu.arch == .avr) {
703 // AVR uses int for int_least16_t and int_fast16_t.
704 return .{ .specifier = if (signedness == .signed) .int else .uint };
705 }
706 const candidates = switch (signedness) {
707 .signed => &[_]Type.Specifier{ .schar, .short, .int, .long, .long_long },
708 .unsigned => &[_]Type.Specifier{ .uchar, .ushort, .uint, .ulong, .ulong_long },
709 };
710 for (candidates) |specifier| {
711 const ty: Type = .{ .specifier = specifier };
712 if (ty.sizeof(comp).? * 8 >= bits) return ty;
713 } else unreachable;
714}
715
716fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 {
717 const ty = Type{ .specifier = specifier };
718 return ty.sizeof(comp).?;
719}
720
721fn generateFastOrLeastType(
722 comp: *Compilation,
723 bits: usize,
724 kind: enum { least, fast },
725 signedness: std.builtin.Signedness,
726 w: anytype,
727 mapper: StrInt.TypeMapper,
728) !void {
729 const ty = comp.intLeastN(bits, signedness); // defining the fast types as the least types is permitted
730
731 var buf: [32]u8 = undefined;
732 const suffix = "_TYPE__";
733 const base_name = switch (signedness) {
734 .signed => "__INT_",
735 .unsigned => "__UINT_",
736 };
737 const kind_str = switch (kind) {
738 .fast => "FAST",
739 .least => "LEAST",
740 };
741
742 const full = std.fmt.bufPrint(&buf, "{s}{s}{d}{s}", .{
743 base_name, kind_str, bits, suffix,
744 }) catch return error.OutOfMemory;
745
746 try generateTypeMacro(w, mapper, full, ty, comp.langopts);
747
748 const prefix = full[2 .. full.len - suffix.len]; // remove "__" and "_TYPE__"
749
750 switch (signedness) {
751 .signed => try comp.generateIntMaxAndWidth(w, prefix, ty),
752 .unsigned => try comp.generateIntMax(w, prefix, ty),
753 }
754 try comp.generateFmt(prefix, w, ty);
755}
756
757fn generateFastAndLeastWidthTypes(comp: *Compilation, w: anytype, mapper: StrInt.TypeMapper) !void {
758 const sizes = [_]usize{ 8, 16, 32, 64 };
759 for (sizes) |size| {
760 try comp.generateFastOrLeastType(size, .least, .signed, w, mapper);
761 try comp.generateFastOrLeastType(size, .least, .unsigned, w, mapper);
762 try comp.generateFastOrLeastType(size, .fast, .signed, w, mapper);
763 try comp.generateFastOrLeastType(size, .fast, .unsigned, w, mapper);
764 }
765}
766
767fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper) !void {
768 try comp.generateExactWidthType(w, mapper, .schar);
769
770 if (comp.intSize(.short) > comp.intSize(.char)) {
771 try comp.generateExactWidthType(w, mapper, .short);
772 }
773
774 if (comp.intSize(.int) > comp.intSize(.short)) {
775 try comp.generateExactWidthType(w, mapper, .int);
776 }
777
778 if (comp.intSize(.long) > comp.intSize(.int)) {
779 try comp.generateExactWidthType(w, mapper, .long);
780 }
781
782 if (comp.intSize(.long_long) > comp.intSize(.long)) {
783 try comp.generateExactWidthType(w, mapper, .long_long);
784 }
785
786 try comp.generateExactWidthType(w, mapper, .uchar);
787 try comp.generateExactWidthIntMax(w, .uchar);
788 try comp.generateExactWidthIntMax(w, .schar);
789
790 if (comp.intSize(.short) > comp.intSize(.char)) {
791 try comp.generateExactWidthType(w, mapper, .ushort);
792 try comp.generateExactWidthIntMax(w, .ushort);
793 try comp.generateExactWidthIntMax(w, .short);
794 }
795
796 if (comp.intSize(.int) > comp.intSize(.short)) {
797 try comp.generateExactWidthType(w, mapper, .uint);
798 try comp.generateExactWidthIntMax(w, .uint);
799 try comp.generateExactWidthIntMax(w, .int);
800 }
801
802 if (comp.intSize(.long) > comp.intSize(.int)) {
803 try comp.generateExactWidthType(w, mapper, .ulong);
804 try comp.generateExactWidthIntMax(w, .ulong);
805 try comp.generateExactWidthIntMax(w, .long);
806 }
807
808 if (comp.intSize(.long_long) > comp.intSize(.long)) {
809 try comp.generateExactWidthType(w, mapper, .ulong_long);
810 try comp.generateExactWidthIntMax(w, .ulong_long);
811 try comp.generateExactWidthIntMax(w, .long_long);
812 }
813}
814
815fn generateFmt(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
816 const unsigned = ty.isUnsignedInt(comp);
817 const modifier = ty.formatModifier();
818 const formats = if (unsigned) "ouxX" else "di";
819 for (formats) |c| {
820 try w.print("#define {s}_FMT{c}__ \"{s}{c}\"\n", .{ prefix, c, modifier, c });
821 }
822}
823
824fn generateSuffixMacro(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
825 return w.print("#define {s}_C_SUFFIX__ {s}\n", .{ prefix, ty.intValueSuffix(comp) });
826}
827
828/// Generate the following for ty:
829/// Name macro (e.g. #define __UINT32_TYPE__ unsigned int)
830/// Format strings (e.g. #define __UINT32_FMTu__ "u")
831/// Suffix macro (e.g. #define __UINT32_C_SUFFIX__ U)
832fn generateExactWidthType(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper, specifier: Type.Specifier) !void {
833 var ty = Type{ .specifier = specifier };
834 const width = 8 * ty.sizeof(comp).?;
835 const unsigned = ty.isUnsignedInt(comp);
836
837 if (width == 16) {
838 ty = if (unsigned) comp.types.int16.makeIntegerUnsigned() else comp.types.int16;
839 } else if (width == 64) {
840 ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
841 }
842
843 var buffer: [16]u8 = undefined;
844 const suffix = "_TYPE__";
845 const full = std.fmt.bufPrint(&buffer, "{s}{d}{s}", .{
846 if (unsigned) "__UINT" else "__INT", width, suffix,
847 }) catch return error.OutOfMemory;
848
849 try generateTypeMacro(w, mapper, full, ty, comp.langopts);
850
851 const prefix = full[0 .. full.len - suffix.len]; // remove "_TYPE__"
852
853 try comp.generateFmt(prefix, w, ty);
854 try comp.generateSuffixMacro(prefix, w, ty);
855}
856
857pub fn hasFloat128(comp: *const Compilation) bool {
858 return target_util.hasFloat128(comp.target);
859}
860
861pub fn hasHalfPrecisionFloatABI(comp: *const Compilation) bool {
862 return comp.langopts.allow_half_args_and_returns or target_util.hasHalfPrecisionFloatABI(comp.target);
863}
864
865fn generateNsConstantStringType(comp: *Compilation) !void {
866 comp.types.ns_constant_string.record = .{
867 .name = try StrInt.intern(comp, "__NSConstantString_tag"),
868 .fields = &comp.types.ns_constant_string.fields,
869 .field_attributes = null,
870 .type_layout = undefined,
871 };
872 const const_int_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.int_ty } };
873 const const_char_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.char_ty } };
874
875 comp.types.ns_constant_string.fields[0] = .{ .name = try StrInt.intern(comp, "isa"), .ty = const_int_ptr };
876 comp.types.ns_constant_string.fields[1] = .{ .name = try StrInt.intern(comp, "flags"), .ty = .{ .specifier = .int } };
877 comp.types.ns_constant_string.fields[2] = .{ .name = try StrInt.intern(comp, "str"), .ty = const_char_ptr };
878 comp.types.ns_constant_string.fields[3] = .{ .name = try StrInt.intern(comp, "length"), .ty = .{ .specifier = .long } };
879 comp.types.ns_constant_string.ty = .{ .specifier = .@"struct", .data = .{ .record = &comp.types.ns_constant_string.record } };
880 record_layout.compute(&comp.types.ns_constant_string.record, comp.types.ns_constant_string.ty, comp, null);
881}
882
883fn generateVaListType(comp: *Compilation) !Type {
884 const Kind = enum { char_ptr, void_ptr, aarch64_va_list, x86_64_va_list };
885 const kind: Kind = switch (comp.target.cpu.arch) {
886 .aarch64 => switch (comp.target.os.tag) {
887 .windows => @as(Kind, .char_ptr),
888 .ios, .macos, .tvos, .watchos => .char_ptr,
889 else => .aarch64_va_list,
890 },
891 .sparc, .wasm32, .wasm64, .bpfel, .bpfeb, .riscv32, .riscv64, .avr, .spirv32, .spirv64 => .void_ptr,
892 .powerpc => switch (comp.target.os.tag) {
893 .ios, .macos, .tvos, .watchos, .aix => @as(Kind, .char_ptr),
894 else => return Type{ .specifier = .void }, // unknown
895 },
896 .x86, .msp430 => .char_ptr,
897 .x86_64 => switch (comp.target.os.tag) {
898 .windows => @as(Kind, .char_ptr),
899 else => .x86_64_va_list,
900 },
901 else => return Type{ .specifier = .void }, // unknown
902 };
903
904 // TODO this might be bad?
905 const arena = comp.diagnostics.arena.allocator();
906
907 var ty: Type = undefined;
908 switch (kind) {
909 .char_ptr => ty = .{ .specifier = .char },
910 .void_ptr => ty = .{ .specifier = .void },
911 .aarch64_va_list => {
912 const record_ty = try arena.create(Type.Record);
913 record_ty.* = .{
914 .name = try StrInt.intern(comp, "__va_list_tag"),
915 .fields = try arena.alloc(Type.Record.Field, 5),
916 .field_attributes = null,
917 .type_layout = undefined, // computed below
918 };
919 const void_ty = try arena.create(Type);
920 void_ty.* = .{ .specifier = .void };
921 const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
922 record_ty.fields[0] = .{ .name = try StrInt.intern(comp, "__stack"), .ty = void_ptr };
923 record_ty.fields[1] = .{ .name = try StrInt.intern(comp, "__gr_top"), .ty = void_ptr };
924 record_ty.fields[2] = .{ .name = try StrInt.intern(comp, "__vr_top"), .ty = void_ptr };
925 record_ty.fields[3] = .{ .name = try StrInt.intern(comp, "__gr_offs"), .ty = .{ .specifier = .int } };
926 record_ty.fields[4] = .{ .name = try StrInt.intern(comp, "__vr_offs"), .ty = .{ .specifier = .int } };
927 ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
928 record_layout.compute(record_ty, ty, comp, null);
929 },
930 .x86_64_va_list => {
931 const record_ty = try arena.create(Type.Record);
932 record_ty.* = .{
933 .name = try StrInt.intern(comp, "__va_list_tag"),
934 .fields = try arena.alloc(Type.Record.Field, 4),
935 .field_attributes = null,
936 .type_layout = undefined, // computed below
937 };
938 const void_ty = try arena.create(Type);
939 void_ty.* = .{ .specifier = .void };
940 const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
941 record_ty.fields[0] = .{ .name = try StrInt.intern(comp, "gp_offset"), .ty = .{ .specifier = .uint } };
942 record_ty.fields[1] = .{ .name = try StrInt.intern(comp, "fp_offset"), .ty = .{ .specifier = .uint } };
943 record_ty.fields[2] = .{ .name = try StrInt.intern(comp, "overflow_arg_area"), .ty = void_ptr };
944 record_ty.fields[3] = .{ .name = try StrInt.intern(comp, "reg_save_area"), .ty = void_ptr };
945 ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
946 record_layout.compute(record_ty, ty, comp, null);
947 },
948 }
949 if (kind == .char_ptr or kind == .void_ptr) {
950 const elem_ty = try arena.create(Type);
951 elem_ty.* = ty;
952 ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
953 } else {
954 const arr_ty = try arena.create(Type.Array);
955 arr_ty.* = .{ .len = 1, .elem = ty };
956 ty = Type{ .specifier = .array, .data = .{ .array = arr_ty } };
957 }
958
959 return ty;
960}
961
962fn generateIntMax(comp: *const Compilation, w: anytype, name: []const u8, ty: Type) !void {
963 const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
964 const unsigned = ty.isUnsignedInt(comp);
965 const max = if (bit_count == 128)
966 @as(u128, if (unsigned) std.math.maxInt(u128) else std.math.maxInt(u128))
967 else
968 ty.maxInt(comp);
969 try w.print("#define __{s}_MAX__ {d}{s}\n", .{ name, max, ty.intValueSuffix(comp) });
970}
971
972fn generateExactWidthIntMax(comp: *const Compilation, w: anytype, specifier: Type.Specifier) !void {
973 var ty = Type{ .specifier = specifier };
974 const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
975 const unsigned = ty.isUnsignedInt(comp);
976
977 if (bit_count == 64) {
978 ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
979 }
980
981 var name_buffer: [6]u8 = undefined;
982 const name = std.fmt.bufPrint(&name_buffer, "{s}{d}", .{
983 if (unsigned) "UINT" else "INT", bit_count,
984 }) catch return error.OutOfMemory;
985
986 return comp.generateIntMax(w, name, ty);
987}
988
989fn generateIntWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
990 try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, 8 * ty.sizeof(comp).? });
991}
992
993fn generateIntMaxAndWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
994 try comp.generateIntMax(w, name, ty);
995 try comp.generateIntWidth(w, name, ty);
996}
997
998fn generateSizeofType(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
999 try w.print("#define {s} {d}\n", .{ name, ty.sizeof(comp).? });
1000}
1001
1002pub fn nextLargestIntSameSign(comp: *const Compilation, ty: Type) ?Type {
1003 assert(ty.isInt());
1004 const specifiers = if (ty.isUnsignedInt(comp))
1005 [_]Type.Specifier{ .short, .int, .long, .long_long }
1006 else
1007 [_]Type.Specifier{ .ushort, .uint, .ulong, .ulong_long };
1008 const size = ty.sizeof(comp).?;
1009 for (specifiers) |specifier| {
1010 const candidate = Type{ .specifier = specifier };
1011 if (candidate.sizeof(comp).? > size) return candidate;
1012 }
1013 return null;
1014}
1015
1016/// If `enum E { ... }` syntax has a fixed underlying integer type regardless of the presence of
1017/// __attribute__((packed)) or the range of values of the corresponding enumerator constants,
1018/// specify it here.
1019/// TODO: likely incomplete
1020pub fn fixedEnumTagSpecifier(comp: *const Compilation) ?Type.Specifier {
1021 switch (comp.langopts.emulate) {
1022 .msvc => return .int,
1023 .clang => if (comp.target.os.tag == .windows) return .int,
1024 .gcc => {},
1025 }
1026 return null;
1027}
1028
1029pub fn getCharSignedness(comp: *const Compilation) std.builtin.Signedness {
1030 return comp.langopts.char_signedness_override orelse comp.target.charSignedness();
1031}
1032
1033pub fn defineSystemIncludes(comp: *Compilation, aro_dir: []const u8) !void {
1034 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1035 const allocator = stack_fallback.get();
1036 var search_path = aro_dir;
1037 while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) {
1038 var base_dir = std.fs.cwd().openDir(dirname, .{}) catch continue;
1039 defer base_dir.close();
1040
1041 base_dir.access("include/stddef.h", .{}) catch continue;
1042 const path = try std.fs.path.join(comp.gpa, &.{ dirname, "include" });
1043 errdefer comp.gpa.free(path);
1044 try comp.system_include_dirs.append(comp.gpa, path);
1045 break;
1046 } else return error.AroIncludeNotFound;
1047
1048 if (comp.target.os.tag == .linux) {
1049 const triple_str = try comp.target.linuxTriple(allocator);
1050 defer allocator.free(triple_str);
1051
1052 const multiarch_path = try std.fs.path.join(allocator, &.{ "/usr/include", triple_str });
1053 defer allocator.free(multiarch_path);
1054
1055 if (!std.meta.isError(std.fs.accessAbsolute(multiarch_path, .{}))) {
1056 const duped = try comp.gpa.dupe(u8, multiarch_path);
1057 errdefer comp.gpa.free(duped);
1058 try comp.system_include_dirs.append(comp.gpa, duped);
1059 }
1060 }
1061 const usr_include = try comp.gpa.dupe(u8, "/usr/include");
1062 errdefer comp.gpa.free(usr_include);
1063 try comp.system_include_dirs.append(comp.gpa, usr_include);
1064}
1065
1066pub fn getSource(comp: *const Compilation, id: Source.Id) Source {
1067 if (id == .generated) return .{
1068 .path = "<scratch space>",
1069 .buf = comp.generated_buf.items,
1070 .id = .generated,
1071 .splice_locs = &.{},
1072 .kind = .user,
1073 };
1074 return comp.sources.values()[@intFromEnum(id) - 2];
1075}
1076
1077/// Creates a Source from the contents of `reader` and adds it to the Compilation
1078pub fn addSourceFromReader(comp: *Compilation, reader: anytype, path: []const u8, kind: Source.Kind) !Source {
1079 const contents = try reader.readAllAlloc(comp.gpa, std.math.maxInt(u32));
1080 errdefer comp.gpa.free(contents);
1081 return comp.addSourceFromOwnedBuffer(contents, path, kind);
1082}
1083
1084/// Creates a Source from `buf` and adds it to the Compilation
1085/// Performs newline splicing and line-ending normalization to '\n'
1086/// `buf` will be modified and the allocation will be resized if newline splicing
1087/// or line-ending changes happen.
1088/// caller retains ownership of `path`
1089/// To add the contents of an arbitrary reader as a Source, see addSourceFromReader
1090/// To add a file's contents given its path, see addSourceFromPath
1091pub fn addSourceFromOwnedBuffer(comp: *Compilation, buf: []u8, path: []const u8, kind: Source.Kind) !Source {
1092 try comp.sources.ensureUnusedCapacity(comp.gpa, 1);
1093
1094 var contents = buf;
1095 const duped_path = try comp.gpa.dupe(u8, path);
1096 errdefer comp.gpa.free(duped_path);
1097
1098 var splice_list = std.ArrayList(u32).init(comp.gpa);
1099 defer splice_list.deinit();
1100
1101 const source_id: Source.Id = @enumFromInt(comp.sources.count() + 2);
1102
1103 var i: u32 = 0;
1104 var backslash_loc: u32 = undefined;
1105 var state: enum {
1106 beginning_of_file,
1107 bom1,
1108 bom2,
1109 start,
1110 back_slash,
1111 cr,
1112 back_slash_cr,
1113 trailing_ws,
1114 } = .beginning_of_file;
1115 var line: u32 = 1;
1116
1117 for (contents) |byte| {
1118 contents[i] = byte;
1119
1120 switch (byte) {
1121 '\r' => {
1122 switch (state) {
1123 .start, .cr, .beginning_of_file => {
1124 state = .start;
1125 line += 1;
1126 state = .cr;
1127 contents[i] = '\n';
1128 i += 1;
1129 },
1130 .back_slash, .trailing_ws, .back_slash_cr => {
1131 i = backslash_loc;
1132 try splice_list.append(i);
1133 if (state == .trailing_ws) {
1134 try comp.addDiagnostic(.{
1135 .tag = .backslash_newline_escape,
1136 .loc = .{ .id = source_id, .byte_offset = i, .line = line },
1137 }, &.{});
1138 }
1139 state = if (state == .back_slash_cr) .cr else .back_slash_cr;
1140 },
1141 .bom1, .bom2 => break, // invalid utf-8
1142 }
1143 },
1144 '\n' => {
1145 switch (state) {
1146 .start, .beginning_of_file => {
1147 state = .start;
1148 line += 1;
1149 i += 1;
1150 },
1151 .cr, .back_slash_cr => {},
1152 .back_slash, .trailing_ws => {
1153 i = backslash_loc;
1154 if (state == .back_slash or state == .trailing_ws) {
1155 try splice_list.append(i);
1156 }
1157 if (state == .trailing_ws) {
1158 try comp.addDiagnostic(.{
1159 .tag = .backslash_newline_escape,
1160 .loc = .{ .id = source_id, .byte_offset = i, .line = line },
1161 }, &.{});
1162 }
1163 },
1164 .bom1, .bom2 => break,
1165 }
1166 state = .start;
1167 },
1168 '\\' => {
1169 backslash_loc = i;
1170 state = .back_slash;
1171 i += 1;
1172 },
1173 '\t', '\x0B', '\x0C', ' ' => {
1174 switch (state) {
1175 .start, .trailing_ws => {},
1176 .beginning_of_file => state = .start,
1177 .cr, .back_slash_cr => state = .start,
1178 .back_slash => state = .trailing_ws,
1179 .bom1, .bom2 => break,
1180 }
1181 i += 1;
1182 },
1183 '\xEF' => {
1184 i += 1;
1185 state = switch (state) {
1186 .beginning_of_file => .bom1,
1187 else => .start,
1188 };
1189 },
1190 '\xBB' => {
1191 i += 1;
1192 state = switch (state) {
1193 .bom1 => .bom2,
1194 else => .start,
1195 };
1196 },
1197 '\xBF' => {
1198 switch (state) {
1199 .bom2 => i = 0, // rewind and overwrite the BOM
1200 else => i += 1,
1201 }
1202 state = .start;
1203 },
1204 else => {
1205 i += 1;
1206 state = .start;
1207 },
1208 }
1209 }
1210
1211 const splice_locs = try splice_list.toOwnedSlice();
1212 errdefer comp.gpa.free(splice_locs);
1213
1214 if (i != contents.len) contents = try comp.gpa.realloc(contents, i);
1215 errdefer @compileError("errdefers in callers would possibly free the realloced slice using the original len");
1216
1217 const source = Source{
1218 .id = source_id,
1219 .path = duped_path,
1220 .buf = contents,
1221 .splice_locs = splice_locs,
1222 .kind = kind,
1223 };
1224
1225 comp.sources.putAssumeCapacityNoClobber(duped_path, source);
1226 return source;
1227}
1228
1229/// Caller retains ownership of `path` and `buf`.
1230/// Dupes the source buffer; if it is acceptable to modify the source buffer and possibly resize
1231/// the allocation, please use `addSourceFromOwnedBuffer`
1232pub fn addSourceFromBuffer(comp: *Compilation, path: []const u8, buf: []const u8) !Source {
1233 if (comp.sources.get(path)) |some| return some;
1234 if (@as(u64, buf.len) > std.math.maxInt(u32)) return error.StreamTooLong;
1235
1236 const contents = try comp.gpa.dupe(u8, buf);
1237 errdefer comp.gpa.free(contents);
1238
1239 return comp.addSourceFromOwnedBuffer(contents, path, .user);
1240}
1241
1242/// Caller retains ownership of `path`.
1243pub fn addSourceFromPath(comp: *Compilation, path: []const u8) !Source {
1244 return comp.addSourceFromPathExtra(path, .user);
1245}
1246
1247/// Caller retains ownership of `path`.
1248fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kind) !Source {
1249 if (comp.sources.get(path)) |some| return some;
1250
1251 if (mem.indexOfScalar(u8, path, 0) != null) {
1252 return error.FileNotFound;
1253 }
1254
1255 const file = try std.fs.cwd().openFile(path, .{});
1256 defer file.close();
1257
1258 const contents = file.readToEndAlloc(comp.gpa, std.math.maxInt(u32)) catch |err| switch (err) {
1259 error.FileTooBig => return error.StreamTooLong,
1260 else => |e| return e,
1261 };
1262 errdefer comp.gpa.free(contents);
1263
1264 return comp.addSourceFromOwnedBuffer(contents, path, kind);
1265}
1266
1267pub const IncludeDirIterator = struct {
1268 comp: *const Compilation,
1269 cwd_source_id: ?Source.Id,
1270 include_dirs_idx: usize = 0,
1271 sys_include_dirs_idx: usize = 0,
1272 tried_ms_cwd: bool = false,
1273
1274 const FoundSource = struct {
1275 path: []const u8,
1276 kind: Source.Kind,
1277 };
1278
1279 fn next(self: *IncludeDirIterator) ?FoundSource {
1280 if (self.cwd_source_id) |source_id| {
1281 self.cwd_source_id = null;
1282 const path = self.comp.getSource(source_id).path;
1283 return .{ .path = std.fs.path.dirname(path) orelse ".", .kind = .user };
1284 }
1285 if (self.include_dirs_idx < self.comp.include_dirs.items.len) {
1286 defer self.include_dirs_idx += 1;
1287 return .{ .path = self.comp.include_dirs.items[self.include_dirs_idx], .kind = .user };
1288 }
1289 if (self.sys_include_dirs_idx < self.comp.system_include_dirs.items.len) {
1290 defer self.sys_include_dirs_idx += 1;
1291 return .{ .path = self.comp.system_include_dirs.items[self.sys_include_dirs_idx], .kind = .system };
1292 }
1293 if (self.comp.ms_cwd_source_id) |source_id| {
1294 if (self.tried_ms_cwd) return null;
1295 self.tried_ms_cwd = true;
1296 const path = self.comp.getSource(source_id).path;
1297 return .{ .path = std.fs.path.dirname(path) orelse ".", .kind = .user };
1298 }
1299 return null;
1300 }
1301
1302 /// Returned value's path field must be freed by allocator
1303 fn nextWithFile(self: *IncludeDirIterator, filename: []const u8, allocator: Allocator) !?FoundSource {
1304 while (self.next()) |found| {
1305 const path = try std.fs.path.join(allocator, &.{ found.path, filename });
1306 if (self.comp.langopts.ms_extensions) {
1307 std.mem.replaceScalar(u8, path, '\\', '/');
1308 }
1309 return .{ .path = path, .kind = found.kind };
1310 }
1311 return null;
1312 }
1313
1314 /// Advance the iterator until it finds an include directory that matches
1315 /// the directory which contains `source`.
1316 fn skipUntilDirMatch(self: *IncludeDirIterator, source: Source.Id) void {
1317 const path = self.comp.getSource(source).path;
1318 const includer_path = std.fs.path.dirname(path) orelse ".";
1319 while (self.next()) |found| {
1320 if (mem.eql(u8, includer_path, found.path)) break;
1321 }
1322 }
1323};
1324
1325pub fn hasInclude(
1326 comp: *const Compilation,
1327 filename: []const u8,
1328 includer_token_source: Source.Id,
1329 /// angle bracket vs quotes
1330 include_type: IncludeType,
1331 /// __has_include vs __has_include_next
1332 which: WhichInclude,
1333) !bool {
1334 const cwd = std.fs.cwd();
1335 if (std.fs.path.isAbsolute(filename)) {
1336 if (which == .next) return false;
1337 return !std.meta.isError(cwd.access(filename, .{}));
1338 }
1339
1340 const cwd_source_id = switch (include_type) {
1341 .quotes => switch (which) {
1342 .first => includer_token_source,
1343 .next => null,
1344 },
1345 .angle_brackets => null,
1346 };
1347 var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
1348 if (which == .next) {
1349 it.skipUntilDirMatch(includer_token_source);
1350 }
1351
1352 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1353 const sf_allocator = stack_fallback.get();
1354
1355 while (try it.nextWithFile(filename, sf_allocator)) |found| {
1356 defer sf_allocator.free(found.path);
1357 if (!std.meta.isError(cwd.access(found.path, .{}))) return true;
1358 }
1359 return false;
1360}
1361
1362pub const WhichInclude = enum {
1363 first,
1364 next,
1365};
1366
1367pub const IncludeType = enum {
1368 quotes,
1369 angle_brackets,
1370};
1371
1372fn getFileContents(comp: *Compilation, path: []const u8, limit: ?u32) ![]const u8 {
1373 if (mem.indexOfScalar(u8, path, 0) != null) {
1374 return error.FileNotFound;
1375 }
1376
1377 const file = try std.fs.cwd().openFile(path, .{});
1378 defer file.close();
1379
1380 var buf = std.ArrayList(u8).init(comp.gpa);
1381 defer buf.deinit();
1382
1383 const max = limit orelse std.math.maxInt(u32);
1384 file.reader().readAllArrayList(&buf, max) catch |e| switch (e) {
1385 error.StreamTooLong => if (limit == null) return e,
1386 else => return e,
1387 };
1388
1389 return buf.toOwnedSlice();
1390}
1391
1392pub fn findEmbed(
1393 comp: *Compilation,
1394 filename: []const u8,
1395 includer_token_source: Source.Id,
1396 /// angle bracket vs quotes
1397 include_type: IncludeType,
1398 limit: ?u32,
1399) !?[]const u8 {
1400 if (std.fs.path.isAbsolute(filename)) {
1401 return if (comp.getFileContents(filename, limit)) |some|
1402 some
1403 else |err| switch (err) {
1404 error.OutOfMemory => |e| return e,
1405 else => null,
1406 };
1407 }
1408
1409 const cwd_source_id = switch (include_type) {
1410 .quotes => includer_token_source,
1411 .angle_brackets => null,
1412 };
1413 var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
1414 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1415 const sf_allocator = stack_fallback.get();
1416
1417 while (try it.nextWithFile(filename, sf_allocator)) |found| {
1418 defer sf_allocator.free(found.path);
1419 if (comp.getFileContents(found.path, limit)) |some|
1420 return some
1421 else |err| switch (err) {
1422 error.OutOfMemory => return error.OutOfMemory,
1423 else => {},
1424 }
1425 }
1426 return null;
1427}
1428
1429pub fn findInclude(
1430 comp: *Compilation,
1431 filename: []const u8,
1432 includer_token: Token,
1433 /// angle bracket vs quotes
1434 include_type: IncludeType,
1435 /// include vs include_next
1436 which: WhichInclude,
1437) !?Source {
1438 if (std.fs.path.isAbsolute(filename)) {
1439 if (which == .next) return null;
1440 // TODO: classify absolute file as belonging to system includes or not?
1441 return if (comp.addSourceFromPath(filename)) |some|
1442 some
1443 else |err| switch (err) {
1444 error.OutOfMemory => |e| return e,
1445 else => null,
1446 };
1447 }
1448 const cwd_source_id = switch (include_type) {
1449 .quotes => switch (which) {
1450 .first => includer_token.source,
1451 .next => null,
1452 },
1453 .angle_brackets => null,
1454 };
1455 var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
1456
1457 if (which == .next) {
1458 it.skipUntilDirMatch(includer_token.source);
1459 }
1460
1461 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1462 const sf_allocator = stack_fallback.get();
1463
1464 while (try it.nextWithFile(filename, sf_allocator)) |found| {
1465 defer sf_allocator.free(found.path);
1466 if (comp.addSourceFromPathExtra(found.path, found.kind)) |some| {
1467 if (it.tried_ms_cwd) {
1468 try comp.addDiagnostic(.{
1469 .tag = .ms_search_rule,
1470 .extra = .{ .str = some.path },
1471 .loc = .{
1472 .id = includer_token.source,
1473 .byte_offset = includer_token.start,
1474 .line = includer_token.line,
1475 },
1476 }, &.{});
1477 }
1478 return some;
1479 } else |err| switch (err) {
1480 error.OutOfMemory => return error.OutOfMemory,
1481 else => {},
1482 }
1483 }
1484 return null;
1485}
1486
1487pub fn addPragmaHandler(comp: *Compilation, name: []const u8, handler: *Pragma) Allocator.Error!void {
1488 try comp.pragma_handlers.putNoClobber(comp.gpa, name, handler);
1489}
1490
1491pub fn addDefaultPragmaHandlers(comp: *Compilation) Allocator.Error!void {
1492 const GCC = @import("pragmas/gcc.zig");
1493 var gcc = try GCC.init(comp.gpa);
1494 errdefer gcc.deinit(gcc, comp);
1495
1496 const Once = @import("pragmas/once.zig");
1497 var once = try Once.init(comp.gpa);
1498 errdefer once.deinit(once, comp);
1499
1500 const Message = @import("pragmas/message.zig");
1501 var message = try Message.init(comp.gpa);
1502 errdefer message.deinit(message, comp);
1503
1504 const Pack = @import("pragmas/pack.zig");
1505 var pack = try Pack.init(comp.gpa);
1506 errdefer pack.deinit(pack, comp);
1507
1508 try comp.addPragmaHandler("GCC", gcc);
1509 try comp.addPragmaHandler("once", once);
1510 try comp.addPragmaHandler("message", message);
1511 try comp.addPragmaHandler("pack", pack);
1512}
1513
1514pub fn getPragma(comp: *Compilation, name: []const u8) ?*Pragma {
1515 return comp.pragma_handlers.get(name);
1516}
1517
1518const PragmaEvent = enum {
1519 before_preprocess,
1520 before_parse,
1521 after_parse,
1522};
1523
1524pub fn pragmaEvent(comp: *Compilation, event: PragmaEvent) void {
1525 for (comp.pragma_handlers.values()) |pragma| {
1526 const maybe_func = switch (event) {
1527 .before_preprocess => pragma.beforePreprocess,
1528 .before_parse => pragma.beforeParse,
1529 .after_parse => pragma.afterParse,
1530 };
1531 if (maybe_func) |func| func(pragma, comp);
1532 }
1533}
1534
1535pub fn hasBuiltin(comp: *const Compilation, name: []const u8) bool {
1536 if (std.mem.eql(u8, name, "__builtin_va_arg") or
1537 std.mem.eql(u8, name, "__builtin_choose_expr") or
1538 std.mem.eql(u8, name, "__builtin_bitoffsetof") or
1539 std.mem.eql(u8, name, "__builtin_offsetof") or
1540 std.mem.eql(u8, name, "__builtin_types_compatible_p")) return true;
1541
1542 const builtin = Builtin.fromName(name) orelse return false;
1543 return comp.hasBuiltinFunction(builtin);
1544}
1545
1546pub fn hasBuiltinFunction(comp: *const Compilation, builtin: Builtin) bool {
1547 if (!target_util.builtinEnabled(comp.target, builtin.properties.target_set)) return false;
1548
1549 switch (builtin.properties.language) {
1550 .all_languages => return true,
1551 .all_ms_languages => return comp.langopts.emulate == .msvc,
1552 .gnu_lang, .all_gnu_languages => return comp.langopts.standard.isGNU(),
1553 }
1554}
1555
1556pub const CharUnitSize = enum(u32) {
1557 @"1" = 1,
1558 @"2" = 2,
1559 @"4" = 4,
1560
1561 pub fn Type(comptime self: CharUnitSize) type {
1562 return switch (self) {
1563 .@"1" => u8,
1564 .@"2" => u16,
1565 .@"4" => u32,
1566 };
1567 }
1568};
1569
1570pub const addDiagnostic = Diagnostics.add;
1571
1572test "addSourceFromReader" {
1573 const Test = struct {
1574 fn addSourceFromReader(str: []const u8, expected: []const u8, warning_count: u32, splices: []const u32) !void {
1575 var comp = Compilation.init(std.testing.allocator);
1576 defer comp.deinit();
1577
1578 var buf_reader = std.io.fixedBufferStream(str);
1579 const source = try comp.addSourceFromReader(buf_reader.reader(), "path", .user);
1580
1581 try std.testing.expectEqualStrings(expected, source.buf);
1582 try std.testing.expectEqual(warning_count, @as(u32, @intCast(comp.diagnostics.list.items.len)));
1583 try std.testing.expectEqualSlices(u32, splices, source.splice_locs);
1584 }
1585
1586 fn withAllocationFailures(allocator: std.mem.Allocator) !void {
1587 var comp = Compilation.init(allocator);
1588 defer comp.deinit();
1589
1590 _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n");
1591 _ = try comp.addSourceFromBuffer("path", "non-spliced buffer\n");
1592 }
1593 };
1594 try Test.addSourceFromReader("ab\\\nc", "abc", 0, &.{2});
1595 try Test.addSourceFromReader("ab\\\rc", "abc", 0, &.{2});
1596 try Test.addSourceFromReader("ab\\\r\nc", "abc", 0, &.{2});
1597 try Test.addSourceFromReader("ab\\ \nc", "abc", 1, &.{2});
1598 try Test.addSourceFromReader("ab\\\t\nc", "abc", 1, &.{2});
1599 try Test.addSourceFromReader("ab\\ \t\nc", "abc", 1, &.{2});
1600 try Test.addSourceFromReader("ab\\\r \nc", "ab \nc", 0, &.{2});
1601 try Test.addSourceFromReader("ab\\\\\nc", "ab\\c", 0, &.{3});
1602 try Test.addSourceFromReader("ab\\ \r\nc", "abc", 1, &.{2});
1603 try Test.addSourceFromReader("ab\\ \\\nc", "ab\\ c", 0, &.{4});
1604 try Test.addSourceFromReader("ab\\\r\\\nc", "abc", 0, &.{ 2, 2 });
1605 try Test.addSourceFromReader("ab\\ \rc", "abc", 1, &.{2});
1606 try Test.addSourceFromReader("ab\\", "ab\\", 0, &.{});
1607 try Test.addSourceFromReader("ab\\\\", "ab\\\\", 0, &.{});
1608 try Test.addSourceFromReader("ab\\ ", "ab\\ ", 0, &.{});
1609 try Test.addSourceFromReader("ab\\\n", "ab", 0, &.{2});
1610 try Test.addSourceFromReader("ab\\\r\n", "ab", 0, &.{2});
1611 try Test.addSourceFromReader("ab\\\r", "ab", 0, &.{2});
1612
1613 // carriage return normalization
1614 try Test.addSourceFromReader("ab\r", "ab\n", 0, &.{});
1615 try Test.addSourceFromReader("ab\r\r", "ab\n\n", 0, &.{});
1616 try Test.addSourceFromReader("ab\r\r\n", "ab\n\n", 0, &.{});
1617 try Test.addSourceFromReader("ab\r\r\n\r", "ab\n\n\n", 0, &.{});
1618 try Test.addSourceFromReader("\r\\", "\n\\", 0, &.{});
1619 try Test.addSourceFromReader("\\\r\\", "\\", 0, &.{0});
1620
1621 try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.withAllocationFailures, .{});
1622}
1623
1624test "addSourceFromReader - exhaustive check for carriage return elimination" {
1625 const alphabet = [_]u8{ '\r', '\n', ' ', '\\', 'a' };
1626 const alen = alphabet.len;
1627 var buf: [alphabet.len]u8 = [1]u8{alphabet[0]} ** alen;
1628
1629 var comp = Compilation.init(std.testing.allocator);
1630 defer comp.deinit();
1631
1632 var source_count: u32 = 0;
1633
1634 while (true) {
1635 const source = try comp.addSourceFromBuffer(&buf, &buf);
1636 source_count += 1;
1637 try std.testing.expect(std.mem.indexOfScalar(u8, source.buf, '\r') == null);
1638
1639 if (std.mem.allEqual(u8, &buf, alphabet[alen - 1])) break;
1640
1641 var idx = std.mem.indexOfScalar(u8, &alphabet, buf[buf.len - 1]).?;
1642 buf[buf.len - 1] = alphabet[(idx + 1) % alen];
1643 var j = buf.len - 1;
1644 while (j > 0) : (j -= 1) {
1645 idx = std.mem.indexOfScalar(u8, &alphabet, buf[j - 1]).?;
1646 if (buf[j] == alphabet[0]) buf[j - 1] = alphabet[(idx + 1) % alen] else break;
1647 }
1648 }
1649 try std.testing.expect(source_count == std.math.powi(usize, alen, alen) catch unreachable);
1650}
1651
1652test "ignore BOM at beginning of file" {
1653 const BOM = "\xEF\xBB\xBF";
1654
1655 const Test = struct {
1656 fn run(buf: []const u8) !void {
1657 var comp = Compilation.init(std.testing.allocator);
1658 defer comp.deinit();
1659
1660 var buf_reader = std.io.fixedBufferStream(buf);
1661 const source = try comp.addSourceFromReader(buf_reader.reader(), "file.c", .user);
1662 const expected_output = if (mem.startsWith(u8, buf, BOM)) buf[BOM.len..] else buf;
1663 try std.testing.expectEqualStrings(expected_output, source.buf);
1664 }
1665 };
1666
1667 try Test.run(BOM);
1668 try Test.run(BOM ++ "x");
1669 try Test.run("x" ++ BOM);
1670 try Test.run(BOM ++ " ");
1671 try Test.run(BOM ++ "\n");
1672 try Test.run(BOM ++ "\\");
1673
1674 try Test.run(BOM[0..1] ++ "x");
1675 try Test.run(BOM[0..2] ++ "x");
1676 try Test.run(BOM[1..] ++ "x");
1677 try Test.run(BOM[2..] ++ "x");
1678}
deps/aro/aro/Diagnostics.zig deleted-589
......@@ -1,589 +0,0 @@
1const std = @import("std");
2const Allocator = mem.Allocator;
3const mem = std.mem;
4const Source = @import("Source.zig");
5const Compilation = @import("Compilation.zig");
6const Attribute = @import("Attribute.zig");
7const Builtins = @import("Builtins.zig");
8const Builtin = Builtins.Builtin;
9const Header = @import("Builtins/Properties.zig").Header;
10const Tree = @import("Tree.zig");
11const is_windows = @import("builtin").os.tag == .windows;
12const LangOpts = @import("LangOpts.zig");
13
14pub const Message = struct {
15 tag: Tag,
16 kind: Kind = undefined,
17 loc: Source.Location = .{},
18 extra: Extra = .{ .none = {} },
19
20 pub const Extra = union {
21 str: []const u8,
22 tok_id: struct {
23 expected: Tree.Token.Id,
24 actual: Tree.Token.Id,
25 },
26 tok_id_expected: Tree.Token.Id,
27 arguments: struct {
28 expected: u32,
29 actual: u32,
30 },
31 codepoints: struct {
32 actual: u21,
33 resembles: u21,
34 },
35 attr_arg_count: struct {
36 attribute: Attribute.Tag,
37 expected: u32,
38 },
39 attr_arg_type: struct {
40 expected: Attribute.ArgumentType,
41 actual: Attribute.ArgumentType,
42 },
43 attr_enum: struct {
44 tag: Attribute.Tag,
45 },
46 ignored_record_attr: struct {
47 tag: Attribute.Tag,
48 specifier: enum { @"struct", @"union", @"enum" },
49 },
50 builtin_with_header: struct {
51 builtin: Builtin.Tag,
52 header: Header,
53 },
54 invalid_escape: struct {
55 offset: u32,
56 char: u8,
57 },
58 actual_codepoint: u21,
59 ascii: u7,
60 unsigned: u64,
61 offset: u64,
62 pow_2_as_string: u8,
63 signed: i64,
64 normalized: []const u8,
65 none: void,
66 };
67};
68
69const Properties = struct {
70 msg: []const u8,
71 kind: Kind,
72 extra: std.meta.FieldEnum(Message.Extra) = .none,
73 opt: ?u8 = null,
74 all: bool = false,
75 w_extra: bool = false,
76 pedantic: bool = false,
77 suppress_version: ?LangOpts.Standard = null,
78 suppress_unless_version: ?LangOpts.Standard = null,
79 suppress_gnu: bool = false,
80 suppress_gcc: bool = false,
81 suppress_clang: bool = false,
82 suppress_msvc: bool = false,
83
84 pub fn makeOpt(comptime str: []const u8) u16 {
85 return @offsetOf(Options, str);
86 }
87 pub fn getKind(prop: Properties, options: *Options) Kind {
88 const opt = @as([*]Kind, @ptrCast(options))[prop.opt orelse return prop.kind];
89 if (opt == .default) return prop.kind;
90 return opt;
91 }
92 pub const max_bits = Compilation.bit_int_max_bits;
93};
94
95pub const Tag = @import("Diagnostics/messages.def").with(Properties).Tag;
96
97pub const Kind = enum { @"fatal error", @"error", note, warning, off, default };
98
99pub const Options = struct {
100 // do not directly use these, instead add `const NAME = true;`
101 all: Kind = .default,
102 extra: Kind = .default,
103 pedantic: Kind = .default,
104
105 @"unsupported-pragma": Kind = .default,
106 @"c99-extensions": Kind = .default,
107 @"implicit-int": Kind = .default,
108 @"duplicate-decl-specifier": Kind = .default,
109 @"missing-declaration": Kind = .default,
110 @"extern-initializer": Kind = .default,
111 @"implicit-function-declaration": Kind = .default,
112 @"unused-value": Kind = .default,
113 @"unreachable-code": Kind = .default,
114 @"unknown-warning-option": Kind = .default,
115 @"gnu-empty-struct": Kind = .default,
116 @"gnu-alignof-expression": Kind = .default,
117 @"macro-redefined": Kind = .default,
118 @"generic-qual-type": Kind = .default,
119 multichar: Kind = .default,
120 @"pointer-integer-compare": Kind = .default,
121 @"compare-distinct-pointer-types": Kind = .default,
122 @"literal-conversion": Kind = .default,
123 @"cast-qualifiers": Kind = .default,
124 @"array-bounds": Kind = .default,
125 @"int-conversion": Kind = .default,
126 @"pointer-type-mismatch": Kind = .default,
127 @"c23-extensions": Kind = .default,
128 @"incompatible-pointer-types": Kind = .default,
129 @"excess-initializers": Kind = .default,
130 @"division-by-zero": Kind = .default,
131 @"initializer-overrides": Kind = .default,
132 @"incompatible-pointer-types-discards-qualifiers": Kind = .default,
133 @"unknown-attributes": Kind = .default,
134 @"ignored-attributes": Kind = .default,
135 @"builtin-macro-redefined": Kind = .default,
136 @"gnu-label-as-value": Kind = .default,
137 @"malformed-warning-check": Kind = .default,
138 @"#pragma-messages": Kind = .default,
139 @"newline-eof": Kind = .default,
140 @"empty-translation-unit": Kind = .default,
141 @"implicitly-unsigned-literal": Kind = .default,
142 @"c99-compat": Kind = .default,
143 @"unicode-zero-width": Kind = .default,
144 @"unicode-homoglyph": Kind = .default,
145 unicode: Kind = .default,
146 @"return-type": Kind = .default,
147 @"dollar-in-identifier-extension": Kind = .default,
148 @"unknown-pragmas": Kind = .default,
149 @"predefined-identifier-outside-function": Kind = .default,
150 @"many-braces-around-scalar-init": Kind = .default,
151 uninitialized: Kind = .default,
152 @"gnu-statement-expression": Kind = .default,
153 @"gnu-imaginary-constant": Kind = .default,
154 @"gnu-complex-integer": Kind = .default,
155 @"ignored-qualifiers": Kind = .default,
156 @"integer-overflow": Kind = .default,
157 @"extra-semi": Kind = .default,
158 @"gnu-binary-literal": Kind = .default,
159 @"variadic-macros": Kind = .default,
160 varargs: Kind = .default,
161 @"#warnings": Kind = .default,
162 @"deprecated-declarations": Kind = .default,
163 @"backslash-newline-escape": Kind = .default,
164 @"pointer-to-int-cast": Kind = .default,
165 @"gnu-case-range": Kind = .default,
166 @"c++-compat": Kind = .default,
167 vla: Kind = .default,
168 @"float-overflow-conversion": Kind = .default,
169 @"float-zero-conversion": Kind = .default,
170 @"float-conversion": Kind = .default,
171 @"gnu-folding-constant": Kind = .default,
172 undef: Kind = .default,
173 @"ignored-pragmas": Kind = .default,
174 @"gnu-include-next": Kind = .default,
175 @"include-next-outside-header": Kind = .default,
176 @"include-next-absolute-path": Kind = .default,
177 @"enum-too-large": Kind = .default,
178 @"fixed-enum-extension": Kind = .default,
179 @"designated-init": Kind = .default,
180 @"attribute-warning": Kind = .default,
181 @"invalid-noreturn": Kind = .default,
182 @"zero-length-array": Kind = .default,
183 @"old-style-flexible-struct": Kind = .default,
184 @"gnu-zero-variadic-macro-arguments": Kind = .default,
185 @"main-return-type": Kind = .default,
186 @"expansion-to-defined": Kind = .default,
187 @"bit-int-extension": Kind = .default,
188 @"keyword-macro": Kind = .default,
189 @"pointer-arith": Kind = .default,
190 @"sizeof-array-argument": Kind = .default,
191 @"pre-c23-compat": Kind = .default,
192 @"pointer-bool-conversion": Kind = .default,
193 @"string-conversion": Kind = .default,
194 @"gnu-auto-type": Kind = .default,
195 @"gnu-union-cast": Kind = .default,
196 @"pointer-sign": Kind = .default,
197 @"fuse-ld-path": Kind = .default,
198 @"language-extension-token": Kind = .default,
199 @"complex-component-init": Kind = .default,
200 @"microsoft-include": Kind = .default,
201 @"microsoft-end-of-file": Kind = .default,
202 @"invalid-source-encoding": Kind = .default,
203 @"four-char-constants": Kind = .default,
204 @"unknown-escape-sequence": Kind = .default,
205 @"invalid-pp-token": Kind = .default,
206 @"deprecated-non-prototype": Kind = .default,
207 @"duplicate-embed-param": Kind = .default,
208 @"unsupported-embed-param": Kind = .default,
209 @"unused-result": Kind = .default,
210 normalized: Kind = .default,
211};
212
213const Diagnostics = @This();
214
215list: std.ArrayListUnmanaged(Message) = .{},
216arena: std.heap.ArenaAllocator,
217fatal_errors: bool = false,
218options: Options = .{},
219errors: u32 = 0,
220macro_backtrace_limit: u32 = 6,
221
222pub fn warningExists(name: []const u8) bool {
223 inline for (std.meta.fields(Options)) |f| {
224 if (mem.eql(u8, f.name, name)) return true;
225 }
226 return false;
227}
228
229pub fn set(d: *Diagnostics, name: []const u8, to: Kind) !void {
230 inline for (std.meta.fields(Options)) |f| {
231 if (mem.eql(u8, f.name, name)) {
232 @field(d.options, f.name) = to;
233 return;
234 }
235 }
236 try d.addExtra(.{}, .{
237 .tag = .unknown_warning,
238 .extra = .{ .str = name },
239 }, &.{}, true);
240}
241
242pub fn init(gpa: Allocator) Diagnostics {
243 return .{
244 .arena = std.heap.ArenaAllocator.init(gpa),
245 };
246}
247
248pub fn deinit(d: *Diagnostics) void {
249 d.list.deinit(d.arena.child_allocator);
250 d.arena.deinit();
251}
252
253pub fn add(comp: *Compilation, msg: Message, expansion_locs: []const Source.Location) Compilation.Error!void {
254 return comp.diagnostics.addExtra(comp.langopts, msg, expansion_locs, true);
255}
256
257pub fn addExtra(
258 d: *Diagnostics,
259 langopts: LangOpts,
260 msg: Message,
261 expansion_locs: []const Source.Location,
262 note_msg_loc: bool,
263) Compilation.Error!void {
264 const kind = d.tagKind(msg.tag, langopts);
265 if (kind == .off) return;
266 var copy = msg;
267 copy.kind = kind;
268
269 if (expansion_locs.len != 0) copy.loc = expansion_locs[expansion_locs.len - 1];
270 try d.list.append(d.arena.child_allocator, copy);
271 if (expansion_locs.len != 0) {
272 // Add macro backtrace notes in reverse order omitting from the middle if needed.
273 var i = expansion_locs.len - 1;
274 const half = d.macro_backtrace_limit / 2;
275 const limit = if (i < d.macro_backtrace_limit) 0 else i - half;
276 try d.list.ensureUnusedCapacity(
277 d.arena.child_allocator,
278 if (limit == 0) expansion_locs.len else d.macro_backtrace_limit + 1,
279 );
280 while (i > limit) {
281 i -= 1;
282 d.list.appendAssumeCapacity(.{
283 .tag = .expanded_from_here,
284 .kind = .note,
285 .loc = expansion_locs[i],
286 });
287 }
288 if (limit != 0) {
289 d.list.appendAssumeCapacity(.{
290 .tag = .skipping_macro_backtrace,
291 .kind = .note,
292 .extra = .{ .unsigned = expansion_locs.len - d.macro_backtrace_limit },
293 });
294 i = half - 1;
295 while (i > 0) {
296 i -= 1;
297 d.list.appendAssumeCapacity(.{
298 .tag = .expanded_from_here,
299 .kind = .note,
300 .loc = expansion_locs[i],
301 });
302 }
303 }
304
305 if (note_msg_loc) d.list.appendAssumeCapacity(.{
306 .tag = .expanded_from_here,
307 .kind = .note,
308 .loc = msg.loc,
309 });
310 }
311 if (kind == .@"fatal error" or (kind == .@"error" and d.fatal_errors))
312 return error.FatalError;
313}
314
315pub fn render(comp: *Compilation, config: std.io.tty.Config) void {
316 if (comp.diagnostics.list.items.len == 0) return;
317 var m = defaultMsgWriter(config);
318 defer m.deinit();
319 renderMessages(comp, &m);
320}
321pub fn defaultMsgWriter(config: std.io.tty.Config) MsgWriter {
322 return MsgWriter.init(config);
323}
324
325pub fn renderMessages(comp: *Compilation, m: anytype) void {
326 var errors: u32 = 0;
327 var warnings: u32 = 0;
328 for (comp.diagnostics.list.items) |msg| {
329 switch (msg.kind) {
330 .@"fatal error", .@"error" => errors += 1,
331 .warning => warnings += 1,
332 .note => {},
333 .off => continue, // happens if an error is added before it is disabled
334 .default => unreachable,
335 }
336 renderMessage(comp, m, msg);
337 }
338 const w_s: []const u8 = if (warnings == 1) "" else "s";
339 const e_s: []const u8 = if (errors == 1) "" else "s";
340 if (errors != 0 and warnings != 0) {
341 m.print("{d} warning{s} and {d} error{s} generated.\n", .{ warnings, w_s, errors, e_s });
342 } else if (warnings != 0) {
343 m.print("{d} warning{s} generated.\n", .{ warnings, w_s });
344 } else if (errors != 0) {
345 m.print("{d} error{s} generated.\n", .{ errors, e_s });
346 }
347
348 comp.diagnostics.list.items.len = 0;
349 comp.diagnostics.errors += errors;
350}
351
352pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
353 var line: ?[]const u8 = null;
354 var end_with_splice = false;
355 const width = if (msg.loc.id != .unused) blk: {
356 var loc = msg.loc;
357 switch (msg.tag) {
358 .escape_sequence_overflow,
359 .invalid_universal_character,
360 => loc.byte_offset += @truncate(msg.extra.offset),
361 .non_standard_escape_char,
362 .unknown_escape_sequence,
363 => loc.byte_offset += msg.extra.invalid_escape.offset,
364 else => {},
365 }
366 const source = comp.getSource(loc.id);
367 var line_col = source.lineCol(loc);
368 line = line_col.line;
369 end_with_splice = line_col.end_with_splice;
370 if (msg.tag == .backslash_newline_escape) {
371 line = line_col.line[0 .. line_col.col - 1];
372 line_col.col += 1;
373 line_col.width += 1;
374 }
375 m.location(source.path, line_col.line_no, line_col.col);
376 break :blk line_col.width;
377 } else 0;
378
379 m.start(msg.kind);
380 const prop = msg.tag.property();
381 switch (prop.extra) {
382 .str => printRt(m, prop.msg, .{"{s}"}, .{msg.extra.str}),
383 .tok_id => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
384 msg.extra.tok_id.expected.symbol(),
385 msg.extra.tok_id.actual.symbol(),
386 }),
387 .tok_id_expected => printRt(m, prop.msg, .{"{s}"}, .{msg.extra.tok_id_expected.symbol()}),
388 .arguments => printRt(m, prop.msg, .{ "{d}", "{d}" }, .{
389 msg.extra.arguments.expected,
390 msg.extra.arguments.actual,
391 }),
392 .codepoints => printRt(m, prop.msg, .{ "{X:0>4}", "{u}" }, .{
393 msg.extra.codepoints.actual,
394 msg.extra.codepoints.resembles,
395 }),
396 .attr_arg_count => printRt(m, prop.msg, .{ "{s}", "{d}" }, .{
397 @tagName(msg.extra.attr_arg_count.attribute),
398 msg.extra.attr_arg_count.expected,
399 }),
400 .attr_arg_type => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
401 msg.extra.attr_arg_type.expected.toString(),
402 msg.extra.attr_arg_type.actual.toString(),
403 }),
404 .actual_codepoint => printRt(m, prop.msg, .{"{X:0>4}"}, .{msg.extra.actual_codepoint}),
405 .ascii => printRt(m, prop.msg, .{"{c}"}, .{msg.extra.ascii}),
406 .unsigned => printRt(m, prop.msg, .{"{d}"}, .{msg.extra.unsigned}),
407 .pow_2_as_string => printRt(m, prop.msg, .{"{s}"}, .{switch (msg.extra.pow_2_as_string) {
408 63 => "9223372036854775808",
409 64 => "18446744073709551616",
410 127 => "170141183460469231731687303715884105728",
411 128 => "340282366920938463463374607431768211456",
412 else => unreachable,
413 }}),
414 .signed => printRt(m, prop.msg, .{"{d}"}, .{msg.extra.signed}),
415 .attr_enum => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
416 @tagName(msg.extra.attr_enum.tag),
417 Attribute.Formatting.choices(msg.extra.attr_enum.tag),
418 }),
419 .ignored_record_attr => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
420 @tagName(msg.extra.ignored_record_attr.tag),
421 @tagName(msg.extra.ignored_record_attr.specifier),
422 }),
423 .builtin_with_header => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
424 @tagName(msg.extra.builtin_with_header.header),
425 Builtin.nameFromTag(msg.extra.builtin_with_header.builtin).span(),
426 }),
427 .invalid_escape => {
428 if (std.ascii.isPrint(msg.extra.invalid_escape.char)) {
429 const str: [1]u8 = .{msg.extra.invalid_escape.char};
430 printRt(m, prop.msg, .{"{s}"}, .{&str});
431 } else {
432 var buf: [3]u8 = undefined;
433 const str = std.fmt.bufPrint(&buf, "x{x}", .{std.fmt.fmtSliceHexLower(&.{msg.extra.invalid_escape.char})}) catch unreachable;
434 printRt(m, prop.msg, .{"{s}"}, .{str});
435 }
436 },
437 .normalized => {
438 const f = struct {
439 pub fn f(
440 bytes: []const u8,
441 comptime _: []const u8,
442 _: std.fmt.FormatOptions,
443 writer: anytype,
444 ) !void {
445 var it: std.unicode.Utf8Iterator = .{
446 .bytes = bytes,
447 .i = 0,
448 };
449 while (it.nextCodepoint()) |codepoint| {
450 if (codepoint < 0x7F) {
451 try writer.writeByte(@intCast(codepoint));
452 } else if (codepoint < 0xFFFF) {
453 try writer.writeAll("\\u");
454 try std.fmt.formatInt(codepoint, 16, .upper, .{
455 .fill = '0',
456 .width = 4,
457 }, writer);
458 } else {
459 try writer.writeAll("\\U");
460 try std.fmt.formatInt(codepoint, 16, .upper, .{
461 .fill = '0',
462 .width = 8,
463 }, writer);
464 }
465 }
466 }
467 }.f;
468 printRt(m, prop.msg, .{"{s}"}, .{
469 std.fmt.Formatter(f){ .data = msg.extra.normalized },
470 });
471 },
472 .none, .offset => m.write(prop.msg),
473 }
474
475 if (prop.opt) |some| {
476 if (msg.kind == .@"error" and prop.kind != .@"error") {
477 m.print(" [-Werror,-W{s}]", .{optName(some)});
478 } else if (msg.kind != .note) {
479 m.print(" [-W{s}]", .{optName(some)});
480 }
481 }
482
483 m.end(line, width, end_with_splice);
484}
485
486fn printRt(m: anytype, str: []const u8, comptime fmts: anytype, args: anytype) void {
487 var i: usize = 0;
488 inline for (fmts, args) |fmt, arg| {
489 const new = std.mem.indexOfPos(u8, str, i, fmt).?;
490 m.write(str[i..new]);
491 i = new + fmt.len;
492 m.print(fmt, .{arg});
493 }
494 m.write(str[i..]);
495}
496
497fn optName(offset: u16) []const u8 {
498 return std.meta.fieldNames(Options)[offset / @sizeOf(Kind)];
499}
500
501fn tagKind(d: *Diagnostics, tag: Tag, langopts: LangOpts) Kind {
502 const prop = tag.property();
503 var kind = prop.getKind(&d.options);
504
505 if (prop.all) {
506 if (d.options.all != .default) kind = d.options.all;
507 }
508 if (prop.w_extra) {
509 if (d.options.extra != .default) kind = d.options.extra;
510 }
511 if (prop.pedantic) {
512 if (d.options.pedantic != .default) kind = d.options.pedantic;
513 }
514 if (prop.suppress_version) |some| if (langopts.standard.atLeast(some)) return .off;
515 if (prop.suppress_unless_version) |some| if (!langopts.standard.atLeast(some)) return .off;
516 if (prop.suppress_gnu and langopts.standard.isExplicitGNU()) return .off;
517 if (prop.suppress_gcc and langopts.emulate == .gcc) return .off;
518 if (prop.suppress_clang and langopts.emulate == .clang) return .off;
519 if (prop.suppress_msvc and langopts.emulate == .msvc) return .off;
520 if (kind == .@"error" and d.fatal_errors) kind = .@"fatal error";
521 return kind;
522}
523
524const MsgWriter = struct {
525 w: std.io.BufferedWriter(4096, std.fs.File.Writer),
526 config: std.io.tty.Config,
527
528 fn init(config: std.io.tty.Config) MsgWriter {
529 std.debug.getStderrMutex().lock();
530 return .{
531 .w = std.io.bufferedWriter(std.io.getStdErr().writer()),
532 .config = config,
533 };
534 }
535
536 pub fn deinit(m: *MsgWriter) void {
537 m.w.flush() catch {};
538 std.debug.getStderrMutex().unlock();
539 }
540
541 pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void {
542 m.w.writer().print(fmt, args) catch {};
543 }
544
545 fn write(m: *MsgWriter, msg: []const u8) void {
546 m.w.writer().writeAll(msg) catch {};
547 }
548
549 fn setColor(m: *MsgWriter, color: std.io.tty.Color) void {
550 m.config.setColor(m.w.writer(), color) catch {};
551 }
552
553 fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void {
554 m.setColor(.bold);
555 m.print("{s}:{d}:{d}: ", .{ path, line, col });
556 }
557
558 fn start(m: *MsgWriter, kind: Kind) void {
559 switch (kind) {
560 .@"fatal error", .@"error" => m.setColor(.bright_red),
561 .note => m.setColor(.bright_cyan),
562 .warning => m.setColor(.bright_magenta),
563 .off, .default => unreachable,
564 }
565 m.write(switch (kind) {
566 .@"fatal error" => "fatal error: ",
567 .@"error" => "error: ",
568 .note => "note: ",
569 .warning => "warning: ",
570 .off, .default => unreachable,
571 });
572 m.setColor(.white);
573 }
574
575 fn end(m: *MsgWriter, maybe_line: ?[]const u8, col: u32, end_with_splice: bool) void {
576 const line = maybe_line orelse {
577 m.write("\n");
578 m.setColor(.reset);
579 return;
580 };
581 const trailer = if (end_with_splice) "\\ " else "";
582 m.setColor(.reset);
583 m.print("\n{s}{s}\n{s: >[3]}", .{ line, trailer, "", col });
584 m.setColor(.bold);
585 m.setColor(.bright_green);
586 m.write("^\n");
587 m.setColor(.reset);
588 }
589};
deps/aro/aro/Diagnostics/messages.def deleted-2446
......@@ -1,2446 +0,0 @@
1const W = Properties.makeOpt;
2
3const pointer_sign_message = " converts between pointers to integer types with different sign";
4
5# Maybe someday this will no longer be needed.
6todo
7 .msg = "TODO: {s}"
8 .extra = .str
9 .kind = .@"error"
10
11error_directive
12 .msg = "{s}"
13 .extra = .str
14 .kind = .@"error"
15
16warning_directive
17 .msg = "{s}"
18 .opt = W("#warnings")
19 .extra = .str
20 .kind = .warning
21
22elif_without_if
23 .msg = "#elif without #if"
24 .kind = .@"error"
25
26elif_after_else
27 .msg = "#elif after #else"
28 .kind = .@"error"
29
30elifdef_without_if
31 .msg = "#elifdef without #if"
32 .kind = .@"error"
33
34elifdef_after_else
35 .msg = "#elifdef after #else"
36 .kind = .@"error"
37
38elifndef_without_if
39 .msg = "#elifndef without #if"
40 .kind = .@"error"
41
42elifndef_after_else
43 .msg = "#elifndef after #else"
44 .kind = .@"error"
45
46else_without_if
47 .msg = "#else without #if"
48 .kind = .@"error"
49
50else_after_else
51 .msg = "#else after #else"
52 .kind = .@"error"
53
54endif_without_if
55 .msg = "#endif without #if"
56 .kind = .@"error"
57
58unknown_pragma
59 .msg = "unknown pragma ignored"
60 .opt = W("unknown-pragmas")
61 .kind = .off
62 .all = true
63
64line_simple_digit
65 .msg = "#line directive requires a simple digit sequence"
66 .kind = .@"error"
67
68line_invalid_filename
69 .msg = "invalid filename for #line directive"
70 .kind = .@"error"
71
72unterminated_conditional_directive
73 .msg = "unterminated conditional directive"
74 .kind = .@"error"
75
76invalid_preprocessing_directive
77 .msg = "invalid preprocessing directive"
78 .kind = .@"error"
79
80macro_name_missing
81 .msg = "macro name missing"
82 .kind = .@"error"
83
84extra_tokens_directive_end
85 .msg = "extra tokens at end of macro directive"
86 .kind = .@"error"
87
88expected_value_in_expr
89 .msg = "expected value in expression"
90 .kind = .@"error"
91
92closing_paren
93 .msg = "expected closing ')'"
94 .kind = .@"error"
95
96to_match_paren
97 .msg = "to match this '('"
98 .kind = .note
99
100to_match_brace
101 .msg = "to match this '{'"
102 .kind = .note
103
104to_match_bracket
105 .msg = "to match this '['"
106 .kind = .note
107
108header_str_closing
109 .msg = "expected closing '>'"
110 .kind = .@"error"
111
112header_str_match
113 .msg = "to match this '<'"
114 .kind = .note
115
116string_literal_in_pp_expr
117 .msg = "string literal in preprocessor expression"
118 .kind = .@"error"
119
120float_literal_in_pp_expr
121 .msg = "floating point literal in preprocessor expression"
122 .kind = .@"error"
123
124defined_as_macro_name
125 .msg = "'defined' cannot be used as a macro name"
126 .kind = .@"error"
127
128macro_name_must_be_identifier
129 .msg = "macro name must be an identifier"
130 .kind = .@"error"
131
132whitespace_after_macro_name
133 .msg = "ISO C99 requires whitespace after the macro name"
134 .opt = W("c99-extensions")
135 .kind = .warning
136
137hash_hash_at_start
138 .msg = "'##' cannot appear at the start of a macro expansion"
139 .kind = .@"error"
140
141hash_hash_at_end
142 .msg = "'##' cannot appear at the end of a macro expansion"
143 .kind = .@"error"
144
145pasting_formed_invalid
146 .msg = "pasting formed '{s}', an invalid preprocessing token"
147 .extra = .str
148 .kind = .@"error"
149
150missing_paren_param_list
151 .msg = "missing ')' in macro parameter list"
152 .kind = .@"error"
153
154unterminated_macro_param_list
155 .msg = "unterminated macro param list"
156 .kind = .@"error"
157
158invalid_token_param_list
159 .msg = "invalid token in macro parameter list"
160 .kind = .@"error"
161
162expected_comma_param_list
163 .msg = "expected comma in macro parameter list"
164 .kind = .@"error"
165
166hash_not_followed_param
167 .msg = "'#' is not followed by a macro parameter"
168 .kind = .@"error"
169
170expected_filename
171 .msg = "expected \"FILENAME\" or <FILENAME>"
172 .kind = .@"error"
173
174empty_filename
175 .msg = "empty filename"
176 .kind = .@"error"
177
178expected_invalid
179 .msg = "expected '{s}', found invalid bytes"
180 .extra = .tok_id_expected
181 .kind = .@"error"
182
183expected_eof
184 .msg = "expected '{s}' before end of file"
185 .extra = .tok_id_expected
186 .kind = .@"error"
187
188expected_token
189 .msg = "expected '{s}', found '{s}'"
190 .extra = .tok_id
191 .kind = .@"error"
192
193expected_expr
194 .msg = "expected expression"
195 .kind = .@"error"
196
197expected_integer_constant_expr
198 .msg = "expression is not an integer constant expression"
199 .kind = .@"error"
200
201missing_type_specifier
202 .msg = "type specifier missing, defaults to 'int'"
203 .opt = W("implicit-int")
204 .kind = .warning
205 .all = true
206
207missing_type_specifier_c23
208 .msg = "a type specifier is required for all declarations"
209 .kind = .@"error"
210
211multiple_storage_class
212 .msg = "cannot combine with previous '{s}' declaration specifier"
213 .extra = .str
214 .kind = .@"error"
215
216static_assert_failure
217 .msg = "static assertion failed"
218 .kind = .@"error"
219
220static_assert_failure_message
221 .msg = "static assertion failed {s}"
222 .extra = .str
223 .kind = .@"error"
224
225expected_type
226 .msg = "expected a type"
227 .kind = .@"error"
228
229cannot_combine_spec
230 .msg = "cannot combine with previous '{s}' specifier"
231 .extra = .str
232 .kind = .@"error"
233
234duplicate_decl_spec
235 .msg = "duplicate '{s}' declaration specifier"
236 .extra = .str
237 .opt = W("duplicate-decl-specifier")
238 .kind = .warning
239 .all = true
240
241restrict_non_pointer
242 .msg = "restrict requires a pointer or reference ('{s}' is invalid)"
243 .extra = .str
244 .kind = .@"error"
245
246expected_external_decl
247 .msg = "expected external declaration"
248 .kind = .@"error"
249
250expected_ident_or_l_paren
251 .msg = "expected identifier or '('"
252 .kind = .@"error"
253
254missing_declaration
255 .msg = "declaration does not declare anything"
256 .opt = W("missing-declaration")
257 .kind = .warning
258
259func_not_in_root
260 .msg = "function definition is not allowed here"
261 .kind = .@"error"
262
263illegal_initializer
264 .msg = "illegal initializer (only variables can be initialized)"
265 .kind = .@"error"
266
267extern_initializer
268 .msg = "extern variable has initializer"
269 .opt = W("extern-initializer")
270 .kind = .warning
271
272spec_from_typedef
273 .msg = "'{s}' came from typedef"
274 .extra = .str
275 .kind = .note
276
277param_before_var_args
278 .msg = "ISO C requires a named parameter before '...'"
279 .kind = .@"error"
280 .suppress_version = .c23
281
282void_only_param
283 .msg = "'void' must be the only parameter if specified"
284 .kind = .@"error"
285
286void_param_qualified
287 .msg = "'void' parameter cannot be qualified"
288 .kind = .@"error"
289
290void_must_be_first_param
291 .msg = "'void' must be the first parameter if specified"
292 .kind = .@"error"
293
294invalid_storage_on_param
295 .msg = "invalid storage class on function parameter"
296 .kind = .@"error"
297
298threadlocal_non_var
299 .msg = "_Thread_local only allowed on variables"
300 .kind = .@"error"
301
302func_spec_non_func
303 .msg = "'{s}' can only appear on functions"
304 .extra = .str
305 .kind = .@"error"
306
307illegal_storage_on_func
308 .msg = "illegal storage class on function"
309 .kind = .@"error"
310
311illegal_storage_on_global
312 .msg = "illegal storage class on global variable"
313 .kind = .@"error"
314
315expected_stmt
316 .msg = "expected statement"
317 .kind = .@"error"
318
319func_cannot_return_func
320 .msg = "function cannot return a function"
321 .kind = .@"error"
322
323func_cannot_return_array
324 .msg = "function cannot return an array"
325 .kind = .@"error"
326
327undeclared_identifier
328 .msg = "use of undeclared identifier '{s}'"
329 .extra = .str
330 .kind = .@"error"
331
332not_callable
333 .msg = "cannot call non function type '{s}'"
334 .extra = .str
335 .kind = .@"error"
336
337unsupported_str_cat
338 .msg = "unsupported string literal concatenation"
339 .kind = .@"error"
340
341static_func_not_global
342 .msg = "static functions must be global"
343 .kind = .@"error"
344
345implicit_func_decl
346 .msg = "call to undeclared function '{s}'; ISO C99 and later do not support implicit function declarations"
347 .extra = .str
348 .opt = W("implicit-function-declaration")
349 .kind = .@"error"
350 .all = true
351
352unknown_builtin
353 .msg = "use of unknown builtin '{s}'"
354 .extra = .str
355 .opt = W("implicit-function-declaration")
356 .kind = .@"error"
357 .all = true
358
359implicit_builtin
360 .msg = "implicitly declaring library function '{s}'"
361 .extra = .str
362 .opt = W("implicit-function-declaration")
363 .kind = .@"error"
364 .all = true
365
366implicit_builtin_header_note
367 .msg = "include the header <{s}.h> or explicitly provide a declaration for '{s}'"
368 .extra = .builtin_with_header
369 .opt = W("implicit-function-declaration")
370 .kind = .note
371 .all = true
372
373expected_param_decl
374 .msg = "expected parameter declaration"
375 .kind = .@"error"
376
377invalid_old_style_params
378 .msg = "identifier parameter lists are only allowed in function definitions"
379 .kind = .@"error"
380
381expected_fn_body
382 .msg = "expected function body after function declaration"
383 .kind = .@"error"
384
385invalid_void_param
386 .msg = "parameter cannot have void type"
387 .kind = .@"error"
388
389unused_value
390 .msg = "expression result unused"
391 .opt = W("unused-value")
392 .kind = .warning
393 .all = true
394
395continue_not_in_loop
396 .msg = "'continue' statement not in a loop"
397 .kind = .@"error"
398
399break_not_in_loop_or_switch
400 .msg = "'break' statement not in a loop or a switch"
401 .kind = .@"error"
402
403unreachable_code
404 .msg = "unreachable code"
405 .opt = W("unreachable-code")
406 .kind = .warning
407 .all = true
408
409duplicate_label
410 .msg = "duplicate label '{s}'"
411 .extra = .str
412 .kind = .@"error"
413
414previous_label
415 .msg = "previous definition of label '{s}' was here"
416 .extra = .str
417 .kind = .note
418
419undeclared_label
420 .msg = "use of undeclared label '{s}'"
421 .extra = .str
422 .kind = .@"error"
423
424case_not_in_switch
425 .msg = "'{s}' statement not in a switch statement"
426 .extra = .str
427 .kind = .@"error"
428
429duplicate_switch_case
430 .msg = "duplicate case value '{s}'"
431 .extra = .str
432 .kind = .@"error"
433
434multiple_default
435 .msg = "multiple default cases in the same switch"
436 .kind = .@"error"
437
438previous_case
439 .msg = "previous case defined here"
440 .kind = .note
441
442const expected_arguments = "expected {d} argument(s) got {d}";
443
444expected_arguments
445 .msg = expected_arguments
446 .extra = .arguments
447 .kind = .@"error"
448
449expected_arguments_old
450 .msg = expected_arguments
451 .extra = .arguments
452 .kind = .warning
453
454expected_at_least_arguments
455 .msg = "expected at least {d} argument(s) got {d}"
456 .extra = .arguments
457 .kind = .warning
458
459invalid_static_star
460 .msg = "'static' may not be used with an unspecified variable length array size"
461 .kind = .@"error"
462
463static_non_param
464 .msg = "'static' used outside of function parameters"
465 .kind = .@"error"
466
467array_qualifiers
468 .msg = "type qualifier in non parameter array type"
469 .kind = .@"error"
470
471star_non_param
472 .msg = "star modifier used outside of function parameters"
473 .kind = .@"error"
474
475variable_len_array_file_scope
476 .msg = "variable length arrays not allowed at file scope"
477 .kind = .@"error"
478
479useless_static
480 .msg = "'static' useless without a constant size"
481 .kind = .warning
482 .w_extra = true
483
484negative_array_size
485 .msg = "array size must be 0 or greater"
486 .kind = .@"error"
487
488array_incomplete_elem
489 .msg = "array has incomplete element type '{s}'"
490 .extra = .str
491 .kind = .@"error"
492
493array_func_elem
494 .msg = "arrays cannot have functions as their element type"
495 .kind = .@"error"
496
497static_non_outermost_array
498 .msg = "'static' used in non-outermost array type"
499 .kind = .@"error"
500
501qualifier_non_outermost_array
502 .msg = "type qualifier used in non-outermost array type"
503 .kind = .@"error"
504
505unterminated_macro_arg_list
506 .msg = "unterminated function macro argument list"
507 .kind = .@"error"
508
509unknown_warning
510 .msg = "unknown warning '{s}'"
511 .extra = .str
512 .opt = W("unknown-warning-option")
513 .kind = .warning
514
515overflow
516 .msg = "overflow in expression; result is '{s}'"
517 .extra = .str
518 .opt = W("integer-overflow")
519 .kind = .warning
520
521int_literal_too_big
522 .msg = "integer literal is too large to be represented in any integer type"
523 .kind = .@"error"
524
525indirection_ptr
526 .msg = "indirection requires pointer operand"
527 .kind = .@"error"
528
529addr_of_rvalue
530 .msg = "cannot take the address of an rvalue"
531 .kind = .@"error"
532
533addr_of_bitfield
534 .msg = "address of bit-field requested"
535 .kind = .@"error"
536
537not_assignable
538 .msg = "expression is not assignable"
539 .kind = .@"error"
540
541ident_or_l_brace
542 .msg = "expected identifier or '{'"
543 .kind = .@"error"
544
545empty_enum
546 .msg = "empty enum is invalid"
547 .kind = .@"error"
548
549redefinition
550 .msg = "redefinition of '{s}'"
551 .extra = .str
552 .kind = .@"error"
553
554previous_definition
555 .msg = "previous definition is here"
556 .kind = .note
557
558expected_identifier
559 .msg = "expected identifier"
560 .kind = .@"error"
561
562expected_str_literal
563 .msg = "expected string literal for diagnostic message in static_assert"
564 .kind = .@"error"
565
566expected_str_literal_in
567 .msg = "expected string literal in '{s}'"
568 .extra = .str
569 .kind = .@"error"
570
571parameter_missing
572 .msg = "parameter named '{s}' is missing"
573 .extra = .str
574 .kind = .@"error"
575
576empty_record
577 .msg = "empty {s} is a GNU extension"
578 .extra = .str
579 .opt = W("gnu-empty-struct")
580 .kind = .off
581 .pedantic = true
582
583empty_record_size
584 .msg = "empty {s} has size 0 in C, size 1 in C++"
585 .extra = .str
586 .opt = W("c++-compat")
587 .kind = .off
588
589wrong_tag
590 .msg = "use of '{s}' with tag type that does not match previous definition"
591 .extra = .str
592 .kind = .@"error"
593
594expected_parens_around_typename
595 .msg = "expected parentheses around type name"
596 .kind = .@"error"
597
598alignof_expr
599 .msg = "'_Alignof' applied to an expression is a GNU extension"
600 .opt = W("gnu-alignof-expression")
601 .kind = .warning
602 .suppress_gnu = true
603
604invalid_alignof
605 .msg = "invalid application of 'alignof' to an incomplete type '{s}'"
606 .extra = .str
607 .kind = .@"error"
608
609invalid_sizeof
610 .msg = "invalid application of 'sizeof' to an incomplete type '{s}'"
611 .extra = .str
612 .kind = .@"error"
613
614macro_redefined
615 .msg = "'{s}' macro redefined"
616 .extra = .str
617 .opt = W("macro-redefined")
618 .kind = .warning
619
620generic_qual_type
621 .msg = "generic association with qualifiers cannot be matched with"
622 .opt = W("generic-qual-type")
623 .kind = .warning
624
625generic_array_type
626 .msg = "generic association array type cannot be matched with"
627 .opt = W("generic-qual-type")
628 .kind = .warning
629
630generic_func_type
631 .msg = "generic association function type cannot be matched with"
632 .opt = W("generic-qual-type")
633 .kind = .warning
634
635generic_duplicate
636 .msg = "type '{s}' in generic association compatible with previously specified type"
637 .extra = .str
638 .kind = .@"error"
639
640generic_duplicate_here
641 .msg = "compatible type '{s}' specified here"
642 .extra = .str
643 .kind = .note
644
645generic_duplicate_default
646 .msg = "duplicate default generic association"
647 .kind = .@"error"
648
649generic_no_match
650 .msg = "controlling expression type '{s}' not compatible with any generic association type"
651 .extra = .str
652 .kind = .@"error"
653
654escape_sequence_overflow
655 .msg = "escape sequence out of range"
656 .kind = .@"error"
657
658invalid_universal_character
659 .msg = "invalid universal character"
660 .kind = .@"error"
661
662incomplete_universal_character
663 .msg = "incomplete universal character name"
664 .kind = .@"error"
665
666multichar_literal_warning
667 .msg = "multi-character character constant"
668 .opt = W("multichar")
669 .kind = .warning
670 .all = true
671
672invalid_multichar_literal
673 .msg = "{s} character literals may not contain multiple characters"
674 .kind = .@"error"
675 .extra = .str
676
677wide_multichar_literal
678 .msg = "extraneous characters in character constant ignored"
679 .kind = .warning
680
681char_lit_too_wide
682 .msg = "character constant too long for its type"
683 .kind = .warning
684 .all = true
685
686char_too_large
687 .msg = "character too large for enclosing character literal type"
688 .kind = .@"error"
689
690must_use_struct
691 .msg = "must use 'struct' tag to refer to type '{s}'"
692 .extra = .str
693 .kind = .@"error"
694
695must_use_union
696 .msg = "must use 'union' tag to refer to type '{s}'"
697 .extra = .str
698 .kind = .@"error"
699
700must_use_enum
701 .msg = "must use 'enum' tag to refer to type '{s}'"
702 .extra = .str
703 .kind = .@"error"
704
705redefinition_different_sym
706 .msg = "redefinition of '{s}' as different kind of symbol"
707 .extra = .str
708 .kind = .@"error"
709
710redefinition_incompatible
711 .msg = "redefinition of '{s}' with a different type"
712 .extra = .str
713 .kind = .@"error"
714
715redefinition_of_parameter
716 .msg = "redefinition of parameter '{s}'"
717 .extra = .str
718 .kind = .@"error"
719
720invalid_bin_types
721 .msg = "invalid operands to binary expression ({s})"
722 .extra = .str
723 .kind = .@"error"
724
725comparison_ptr_int
726 .msg = "comparison between pointer and integer ({s})"
727 .extra = .str
728 .opt = W("pointer-integer-compare")
729 .kind = .warning
730
731comparison_distinct_ptr
732 .msg = "comparison of distinct pointer types ({s})"
733 .extra = .str
734 .opt = W("compare-distinct-pointer-types")
735 .kind = .warning
736
737incompatible_pointers
738 .msg = "incompatible pointer types ({s})"
739 .extra = .str
740 .kind = .@"error"
741
742invalid_argument_un
743 .msg = "invalid argument type '{s}' to unary expression"
744 .extra = .str
745 .kind = .@"error"
746
747incompatible_assign
748 .msg = "assignment to {s}"
749 .extra = .str
750 .kind = .@"error"
751
752implicit_ptr_to_int
753 .msg = "implicit pointer to integer conversion from {s}"
754 .extra = .str
755 .opt = W("int-conversion")
756 .kind = .warning
757
758invalid_cast_to_float
759 .msg = "pointer cannot be cast to type '{s}'"
760 .extra = .str
761 .kind = .@"error"
762
763invalid_cast_to_pointer
764 .msg = "operand of type '{s}' cannot be cast to a pointer type"
765 .extra = .str
766 .kind = .@"error"
767
768invalid_cast_type
769 .msg = "cannot cast to non arithmetic or pointer type '{s}'"
770 .extra = .str
771 .kind = .@"error"
772
773qual_cast
774 .msg = "cast to type '{s}' will not preserve qualifiers"
775 .extra = .str
776 .opt = W("cast-qualifiers")
777 .kind = .warning
778
779invalid_index
780 .msg = "array subscript is not an integer"
781 .kind = .@"error"
782
783invalid_subscript
784 .msg = "subscripted value is not an array or pointer"
785 .kind = .@"error"
786
787array_after
788 .msg = "array index {s} is past the end of the array"
789 .extra = .str
790 .opt = W("array-bounds")
791 .kind = .warning
792
793array_before
794 .msg = "array index {s} is before the beginning of the array"
795 .extra = .str
796 .opt = W("array-bounds")
797 .kind = .warning
798
799statement_int
800 .msg = "statement requires expression with integer type ('{s}' invalid)"
801 .extra = .str
802 .kind = .@"error"
803
804statement_scalar
805 .msg = "statement requires expression with scalar type ('{s}' invalid)"
806 .extra = .str
807 .kind = .@"error"
808
809func_should_return
810 .msg = "non-void function '{s}' should return a value"
811 .extra = .str
812 .opt = W("return-type")
813 .kind = .@"error"
814 .all = true
815
816incompatible_return
817 .msg = "returning {s}"
818 .extra = .str
819 .kind = .@"error"
820
821incompatible_return_sign
822 .msg = "returning {s}" ++ pointer_sign_message
823 .extra = .str
824 .kind = .warning
825 .opt = W("pointer-sign")
826
827implicit_int_to_ptr
828 .msg = "implicit integer to pointer conversion from {s}"
829 .extra = .str
830 .opt = W("int-conversion")
831 .kind = .warning
832
833func_does_not_return
834 .msg = "non-void function '{s}' does not return a value"
835 .extra = .str
836 .opt = W("return-type")
837 .kind = .warning
838 .all = true
839
840void_func_returns_value
841 .msg = "void function '{s}' should not return a value"
842 .extra = .str
843 .opt = W("return-type")
844 .kind = .@"error"
845 .all = true
846
847incompatible_arg
848 .msg = "passing {s}"
849 .extra = .str
850 .kind = .@"error"
851
852incompatible_ptr_arg
853 .msg = "passing {s}"
854 .extra = .str
855 .kind = .warning
856 .opt = W("incompatible-pointer-types")
857
858incompatible_ptr_arg_sign
859 .msg = "passing {s}" ++ pointer_sign_message
860 .extra = .str
861 .kind = .warning
862 .opt = W("pointer-sign")
863
864parameter_here
865 .msg = "passing argument to parameter here"
866 .kind = .note
867
868atomic_array
869 .msg = "atomic cannot be applied to array type '{s}'"
870 .extra = .str
871 .kind = .@"error"
872
873atomic_func
874 .msg = "atomic cannot be applied to function type '{s}'"
875 .extra = .str
876 .kind = .@"error"
877
878atomic_incomplete
879 .msg = "atomic cannot be applied to incomplete type '{s}'"
880 .extra = .str
881 .kind = .@"error"
882
883addr_of_register
884 .msg = "address of register variable requested"
885 .kind = .@"error"
886
887variable_incomplete_ty
888 .msg = "variable has incomplete type '{s}'"
889 .extra = .str
890 .kind = .@"error"
891
892parameter_incomplete_ty
893 .msg = "parameter has incomplete type '{s}'"
894 .extra = .str
895 .kind = .@"error"
896
897tentative_array
898 .msg = "tentative array definition assumed to have one element"
899 .kind = .warning
900
901deref_incomplete_ty_ptr
902 .msg = "dereferencing pointer to incomplete type '{s}'"
903 .extra = .str
904 .kind = .@"error"
905
906alignas_on_func
907 .msg = "'_Alignas' attribute only applies to variables and fields"
908 .kind = .@"error"
909
910alignas_on_param
911 .msg = "'_Alignas' attribute cannot be applied to a function parameter"
912 .kind = .@"error"
913
914minimum_alignment
915 .msg = "requested alignment is less than minimum alignment of {d}"
916 .extra = .unsigned
917 .kind = .@"error"
918
919maximum_alignment
920 .msg = "requested alignment of {s} is too large"
921 .extra = .str
922 .kind = .@"error"
923
924negative_alignment
925 .msg = "requested negative alignment of {s} is invalid"
926 .extra = .str
927 .kind = .@"error"
928
929align_ignored
930 .msg = "'_Alignas' attribute is ignored here"
931 .kind = .warning
932
933zero_align_ignored
934 .msg = "requested alignment of zero is ignored"
935 .kind = .warning
936
937non_pow2_align
938 .msg = "requested alignment is not a power of 2"
939 .kind = .@"error"
940
941pointer_mismatch
942 .msg = "pointer type mismatch ({s})"
943 .extra = .str
944 .opt = W("pointer-type-mismatch")
945 .kind = .warning
946
947static_assert_not_constant
948 .msg = "static_assert expression is not an integral constant expression"
949 .kind = .@"error"
950
951static_assert_missing_message
952 .msg = "static_assert with no message is a C23 extension"
953 .opt = W("c23-extensions")
954 .kind = .warning
955 .suppress_version = .c23
956
957pre_c23_compat
958 .msg = "{s} is incompatible with C standards before C23"
959 .extra = .str
960 .kind = .off
961 .suppress_unless_version = .c23
962 .opt = W("pre-c23-compat")
963
964unbound_vla
965 .msg = "variable length array must be bound in function definition"
966 .kind = .@"error"
967
968array_too_large
969 .msg = "array is too large"
970 .kind = .@"error"
971
972incompatible_ptr_init
973 .msg = "incompatible pointer types initializing {s}"
974 .extra = .str
975 .opt = W("incompatible-pointer-types")
976 .kind = .warning
977
978incompatible_ptr_init_sign
979 .msg = "incompatible pointer types initializing {s}" ++ pointer_sign_message
980 .extra = .str
981 .opt = W("pointer-sign")
982 .kind = .warning
983
984incompatible_ptr_assign
985 .msg = "incompatible pointer types assigning to {s}"
986 .extra = .str
987 .opt = W("incompatible-pointer-types")
988 .kind = .warning
989
990incompatible_ptr_assign_sign
991 .msg = "incompatible pointer types assigning to {s} " ++ pointer_sign_message
992 .extra = .str
993 .opt = W("pointer-sign")
994 .kind = .warning
995
996vla_init
997 .msg = "variable-sized object may not be initialized"
998 .kind = .@"error"
999
1000func_init
1001 .msg = "illegal initializer type"
1002 .kind = .@"error"
1003
1004incompatible_init
1005 .msg = "initializing {s}"
1006 .extra = .str
1007 .kind = .@"error"
1008
1009empty_scalar_init
1010 .msg = "scalar initializer cannot be empty"
1011 .kind = .@"error"
1012
1013excess_scalar_init
1014 .msg = "excess elements in scalar initializer"
1015 .opt = W("excess-initializers")
1016 .kind = .warning
1017
1018excess_str_init
1019 .msg = "excess elements in string initializer"
1020 .opt = W("excess-initializers")
1021 .kind = .warning
1022
1023excess_struct_init
1024 .msg = "excess elements in struct initializer"
1025 .opt = W("excess-initializers")
1026 .kind = .warning
1027
1028excess_array_init
1029 .msg = "excess elements in array initializer"
1030 .opt = W("excess-initializers")
1031 .kind = .warning
1032
1033str_init_too_long
1034 .msg = "initializer-string for char array is too long"
1035 .opt = W("excess-initializers")
1036 .kind = .warning
1037
1038arr_init_too_long
1039 .msg = "cannot initialize type ({s})"
1040 .extra = .str
1041 .kind = .@"error"
1042
1043invalid_typeof
1044 .msg = "'{s} typeof' is invalid"
1045 .extra = .str
1046 .kind = .@"error"
1047
1048division_by_zero
1049 .msg = "{s} by zero is undefined"
1050 .extra = .str
1051 .opt = W("division-by-zero")
1052 .kind = .warning
1053
1054division_by_zero_macro
1055 .msg = "{s} by zero in preprocessor expression"
1056 .extra = .str
1057 .kind = .@"error"
1058
1059builtin_choose_cond
1060 .msg = "'__builtin_choose_expr' requires a constant expression"
1061 .kind = .@"error"
1062
1063alignas_unavailable
1064 .msg = "'_Alignas' attribute requires integer constant expression"
1065 .kind = .@"error"
1066
1067case_val_unavailable
1068 .msg = "case value must be an integer constant expression"
1069 .kind = .@"error"
1070
1071enum_val_unavailable
1072 .msg = "enum value must be an integer constant expression"
1073 .kind = .@"error"
1074
1075incompatible_array_init
1076 .msg = "cannot initialize array of type {s}"
1077 .extra = .str
1078 .kind = .@"error"
1079
1080array_init_str
1081 .msg = "array initializer must be an initializer list or wide string literal"
1082 .kind = .@"error"
1083
1084initializer_overrides
1085 .msg = "initializer overrides previous initialization"
1086 .opt = W("initializer-overrides")
1087 .kind = .warning
1088 .w_extra = true
1089
1090previous_initializer
1091 .msg = "previous initialization"
1092 .kind = .note
1093
1094invalid_array_designator
1095 .msg = "array designator used for non-array type '{s}'"
1096 .extra = .str
1097 .kind = .@"error"
1098
1099negative_array_designator
1100 .msg = "array designator value {s} is negative"
1101 .extra = .str
1102 .kind = .@"error"
1103
1104oob_array_designator
1105 .msg = "array designator index {s} exceeds array bounds"
1106 .extra = .str
1107 .kind = .@"error"
1108
1109invalid_field_designator
1110 .msg = "field designator used for non-record type '{s}'"
1111 .extra = .str
1112 .kind = .@"error"
1113
1114no_such_field_designator
1115 .msg = "record type has no field named '{s}'"
1116 .extra = .str
1117 .kind = .@"error"
1118
1119empty_aggregate_init_braces
1120 .msg = "initializer for aggregate with no elements requires explicit braces"
1121 .kind = .@"error"
1122
1123ptr_init_discards_quals
1124 .msg = "initializing {s} discards qualifiers"
1125 .extra = .str
1126 .opt = W("incompatible-pointer-types-discards-qualifiers")
1127 .kind = .warning
1128
1129ptr_assign_discards_quals
1130 .msg = "assigning to {s} discards qualifiers"
1131 .extra = .str
1132 .opt = W("incompatible-pointer-types-discards-qualifiers")
1133 .kind = .warning
1134
1135ptr_ret_discards_quals
1136 .msg = "returning {s} discards qualifiers"
1137 .extra = .str
1138 .opt = W("incompatible-pointer-types-discards-qualifiers")
1139 .kind = .warning
1140
1141ptr_arg_discards_quals
1142 .msg = "passing {s} discards qualifiers"
1143 .extra = .str
1144 .opt = W("incompatible-pointer-types-discards-qualifiers")
1145 .kind = .warning
1146
1147unknown_attribute
1148 .msg = "unknown attribute '{s}' ignored"
1149 .extra = .str
1150 .opt = W("unknown-attributes")
1151 .kind = .warning
1152
1153ignored_attribute
1154 .msg = "{s}"
1155 .extra = .str
1156 .opt = W("ignored-attributes")
1157 .kind = .warning
1158
1159invalid_fallthrough
1160 .msg = "fallthrough annotation does not directly precede switch label"
1161 .kind = .@"error"
1162
1163cannot_apply_attribute_to_statement
1164 .msg = "'{s}' attribute cannot be applied to a statement"
1165 .extra = .str
1166 .kind = .@"error"
1167
1168builtin_macro_redefined
1169 .msg = "redefining builtin macro"
1170 .opt = W("builtin-macro-redefined")
1171 .kind = .warning
1172
1173feature_check_requires_identifier
1174 .msg = "builtin feature check macro requires a parenthesized identifier"
1175 .kind = .@"error"
1176
1177missing_tok_builtin
1178 .msg = "missing '{s}', after builtin feature-check macro"
1179 .extra = .tok_id_expected
1180 .kind = .@"error"
1181
1182gnu_label_as_value
1183 .msg = "use of GNU address-of-label extension"
1184 .opt = W("gnu-label-as-value")
1185 .kind = .off
1186 .pedantic = true
1187
1188expected_record_ty
1189 .msg = "member reference base type '{s}' is not a structure or union"
1190 .extra = .str
1191 .kind = .@"error"
1192
1193member_expr_not_ptr
1194 .msg = "member reference type '{s}' is not a pointer; did you mean to use '.'?"
1195 .extra = .str
1196 .kind = .@"error"
1197
1198member_expr_ptr
1199 .msg = "member reference type '{s}' is a pointer; did you mean to use '->'?"
1200 .extra = .str
1201 .kind = .@"error"
1202
1203no_such_member
1204 .msg = "no member named {s}"
1205 .extra = .str
1206 .kind = .@"error"
1207
1208malformed_warning_check
1209 .msg = "{s} expected option name (e.g. \"-Wundef\")"
1210 .extra = .str
1211 .opt = W("malformed-warning-check")
1212 .kind = .warning
1213 .all = true
1214
1215invalid_computed_goto
1216 .msg = "computed goto in function with no address-of-label expressions"
1217 .kind = .@"error"
1218
1219pragma_warning_message
1220 .msg = "{s}"
1221 .extra = .str
1222 .opt = W("#pragma-messages")
1223 .kind = .warning
1224
1225pragma_error_message
1226 .msg = "{s}"
1227 .extra = .str
1228 .kind = .@"error"
1229
1230pragma_message
1231 .msg = "#pragma message: {s}"
1232 .extra = .str
1233 .kind = .note
1234
1235pragma_requires_string_literal
1236 .msg = "pragma {s} requires string literal"
1237 .extra = .str
1238 .kind = .@"error"
1239
1240poisoned_identifier
1241 .msg = "attempt to use a poisoned identifier"
1242 .kind = .@"error"
1243
1244pragma_poison_identifier
1245 .msg = "can only poison identifier tokens"
1246 .kind = .@"error"
1247
1248pragma_poison_macro
1249 .msg = "poisoning existing macro"
1250 .kind = .warning
1251
1252newline_eof
1253 .msg = "no newline at end of file"
1254 .opt = W("newline-eof")
1255 .kind = .off
1256 .pedantic = true
1257
1258empty_translation_unit
1259 .msg = "ISO C requires a translation unit to contain at least one declaration"
1260 .opt = W("empty-translation-unit")
1261 .kind = .off
1262 .pedantic = true
1263
1264omitting_parameter_name
1265 .msg = "omitting the parameter name in a function definition is a C23 extension"
1266 .opt = W("c23-extensions")
1267 .kind = .warning
1268 .suppress_version = .c23
1269
1270non_int_bitfield
1271 .msg = "bit-field has non-integer type '{s}'"
1272 .extra = .str
1273 .kind = .@"error"
1274
1275negative_bitwidth
1276 .msg = "bit-field has negative width ({s})"
1277 .extra = .str
1278 .kind = .@"error"
1279
1280zero_width_named_field
1281 .msg = "named bit-field has zero width"
1282 .kind = .@"error"
1283
1284bitfield_too_big
1285 .msg = "width of bit-field exceeds width of its type"
1286 .kind = .@"error"
1287
1288invalid_utf8
1289 .msg = "source file is not valid UTF-8"
1290 .kind = .@"error"
1291
1292implicitly_unsigned_literal
1293 .msg = "integer literal is too large to be represented in a signed integer type, interpreting as unsigned"
1294 .opt = W("implicitly-unsigned-literal")
1295 .kind = .warning
1296
1297invalid_preproc_operator
1298 .msg = "token is not a valid binary operator in a preprocessor subexpression"
1299 .kind = .@"error"
1300
1301invalid_preproc_expr_start
1302 .msg = "invalid token at start of a preprocessor expression"
1303 .kind = .@"error"
1304
1305c99_compat
1306 .msg = "using this character in an identifier is incompatible with C99"
1307 .opt = W("c99-compat")
1308 .kind = .off
1309
1310unexpected_character
1311 .msg = "unexpected character <U+{X:0>4}>"
1312 .extra = .actual_codepoint
1313 .kind = .@"error"
1314
1315invalid_identifier_start_char
1316 .msg = "character <U+{X:0>4}> not allowed at the start of an identifier"
1317 .extra = .actual_codepoint
1318 .kind = .@"error"
1319
1320unicode_zero_width
1321 .msg = "identifier contains Unicode character <U+{X:0>4}> that is invisible in some environments"
1322 .opt = W("unicode-homoglyph")
1323 .extra = .actual_codepoint
1324 .kind = .warning
1325
1326unicode_homoglyph
1327 .msg = "treating Unicode character <U+{X:0>4}> as identifier character rather than as '{u}' symbol"
1328 .extra = .codepoints
1329 .opt = W("unicode-homoglyph")
1330 .kind = .warning
1331
1332meaningless_asm_qual
1333 .msg = "meaningless '{s}' on assembly outside function"
1334 .extra = .str
1335 .kind = .@"error"
1336
1337duplicate_asm_qual
1338 .msg = "duplicate asm qualifier '{s}'"
1339 .extra = .str
1340 .kind = .@"error"
1341
1342invalid_asm_str
1343 .msg = "cannot use {s} string literal in assembly"
1344 .extra = .str
1345 .kind = .@"error"
1346
1347dollar_in_identifier_extension
1348 .msg = "'$' in identifier"
1349 .opt = W("dollar-in-identifier-extension")
1350 .kind = .off
1351 .pedantic = true
1352
1353dollars_in_identifiers
1354 .msg = "illegal character '$' in identifier"
1355 .kind = .@"error"
1356
1357expanded_from_here
1358 .msg = "expanded from here"
1359 .kind = .note
1360
1361skipping_macro_backtrace
1362 .msg = "(skipping {d} expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)"
1363 .extra = .unsigned
1364 .kind = .note
1365
1366pragma_operator_string_literal
1367 .msg = "_Pragma requires exactly one string literal token"
1368 .kind = .@"error"
1369
1370unknown_gcc_pragma
1371 .msg = "pragma GCC expected 'error', 'warning', 'diagnostic', 'poison'"
1372 .opt = W("unknown-pragmas")
1373 .kind = .off
1374 .all = true
1375
1376unknown_gcc_pragma_directive
1377 .msg = "pragma GCC diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'"
1378 .opt = W("unknown-pragmas")
1379 .kind = .warning
1380 .all = true
1381
1382predefined_top_level
1383 .msg = "predefined identifier is only valid inside function"
1384 .opt = W("predefined-identifier-outside-function")
1385 .kind = .warning
1386
1387incompatible_va_arg
1388 .msg = "first argument to va_arg, is of type '{s}' and not 'va_list'"
1389 .extra = .str
1390 .kind = .@"error"
1391
1392too_many_scalar_init_braces
1393 .msg = "too many braces around scalar initializer"
1394 .opt = W("many-braces-around-scalar-init")
1395 .kind = .warning
1396
1397uninitialized_in_own_init
1398 .msg = "variable '{s}' is uninitialized when used within its own initialization"
1399 .extra = .str
1400 .opt = W("uninitialized")
1401 .kind = .off
1402 .all = true
1403
1404gnu_statement_expression
1405 .msg = "use of GNU statement expression extension"
1406 .opt = W("gnu-statement-expression")
1407 .kind = .off
1408 .suppress_gnu = true
1409 .pedantic = true
1410
1411stmt_expr_not_allowed_file_scope
1412 .msg = "statement expression not allowed at file scope"
1413 .kind = .@"error"
1414
1415gnu_imaginary_constant
1416 .msg = "imaginary constants are a GNU extension"
1417 .opt = W("gnu-imaginary-constant")
1418 .kind = .off
1419 .suppress_gnu = true
1420 .pedantic = true
1421
1422plain_complex
1423 .msg = "plain '_Complex' requires a type specifier; assuming '_Complex double'"
1424 .kind = .warning
1425
1426complex_int
1427 .msg = "complex integer types are a GNU extension"
1428 .opt = W("gnu-complex-integer")
1429 .suppress_gnu = true
1430 .kind = .off
1431
1432qual_on_ret_type
1433 .msg = "'{s}' type qualifier on return type has no effect"
1434 .opt = W("ignored-qualifiers")
1435 .extra = .str
1436 .kind = .off
1437 .all = true
1438
1439cli_invalid_standard
1440 .msg = "invalid standard '{s}'"
1441 .extra = .str
1442 .kind = .@"error"
1443
1444cli_invalid_target
1445 .msg = "invalid target '{s}'"
1446 .extra = .str
1447 .kind = .@"error"
1448
1449cli_invalid_emulate
1450 .msg = "invalid compiler '{s}'"
1451 .extra = .str
1452 .kind = .@"error"
1453
1454cli_unknown_arg
1455 .msg = "unknown argument '{s}'"
1456 .extra = .str
1457 .kind = .@"error"
1458
1459cli_error
1460 .msg = "{s}"
1461 .extra = .str
1462 .kind = .@"error"
1463
1464cli_unused_link_object
1465 .msg = "{s}: linker input file unused because linking not done"
1466 .extra = .str
1467 .kind = .warning
1468
1469cli_unknown_linker
1470 .msg = "unrecognized linker '{s}'"
1471 .extra = .str
1472 .kind = .@"error"
1473
1474extra_semi
1475 .msg = "extra ';' outside of a function"
1476 .opt = W("extra-semi")
1477 .kind = .off
1478 .pedantic = true
1479
1480func_field
1481 .msg = "field declared as a function"
1482 .kind = .@"error"
1483
1484vla_field
1485 .msg = "variable length array fields extension is not supported"
1486 .kind = .@"error"
1487
1488field_incomplete_ty
1489 .msg = "field has incomplete type '{s}'"
1490 .extra = .str
1491 .kind = .@"error"
1492
1493flexible_in_union
1494 .msg = "flexible array member in union is not allowed"
1495 .kind = .@"error"
1496 .suppress_msvc = true
1497
1498flexible_non_final
1499 .msg = "flexible array member is not at the end of struct"
1500 .kind = .@"error"
1501
1502flexible_in_empty
1503 .msg = "flexible array member in otherwise empty struct"
1504 .kind = .@"error"
1505 .suppress_msvc = true
1506
1507duplicate_member
1508 .msg = "duplicate member '{s}'"
1509 .extra = .str
1510 .kind = .@"error"
1511
1512binary_integer_literal
1513 .msg = "binary integer literals are a GNU extension"
1514 .kind = .off
1515 .opt = W("gnu-binary-literal")
1516 .pedantic = true
1517
1518gnu_va_macro
1519 .msg = "named variadic macros are a GNU extension"
1520 .opt = W("variadic-macros")
1521 .kind = .off
1522 .pedantic = true
1523
1524builtin_must_be_called
1525 .msg = "builtin function must be directly called"
1526 .kind = .@"error"
1527
1528va_start_not_in_func
1529 .msg = "'va_start' cannot be used outside a function"
1530 .kind = .@"error"
1531
1532va_start_fixed_args
1533 .msg = "'va_start' used in a function with fixed args"
1534 .kind = .@"error"
1535
1536va_start_not_last_param
1537 .msg = "second argument to 'va_start' is not the last named parameter"
1538 .opt = W("varargs")
1539 .kind = .warning
1540
1541attribute_not_enough_args
1542 .msg = "'{s}' attribute takes at least {d} argument(s)"
1543 .kind = .@"error"
1544 .extra = .attr_arg_count
1545
1546attribute_too_many_args
1547 .msg = "'{s}' attribute takes at most {d} argument(s)"
1548 .kind = .@"error"
1549 .extra = .attr_arg_count
1550
1551attribute_arg_invalid
1552 .msg = "Attribute argument is invalid, expected {s} but got {s}"
1553 .kind = .@"error"
1554 .extra = .attr_arg_type
1555
1556unknown_attr_enum
1557 .msg = "Unknown `{s}` argument. Possible values are: {s}"
1558 .kind = .@"error"
1559 .extra = .attr_enum
1560
1561attribute_requires_identifier
1562 .msg = "'{s}' attribute requires an identifier"
1563 .kind = .@"error"
1564 .extra = .str
1565
1566declspec_not_enabled
1567 .msg = "'__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes"
1568 .kind = .@"error"
1569
1570declspec_attr_not_supported
1571 .msg = "__declspec attribute '{s}' is not supported"
1572 .extra = .str
1573 .opt = W("ignored-attributes")
1574 .kind = .warning
1575
1576deprecated_declarations
1577 .msg = "{s}"
1578 .extra = .str
1579 .opt = W("deprecated-declarations")
1580 .kind = .warning
1581
1582deprecated_note
1583 .msg = "'{s}' has been explicitly marked deprecated here"
1584 .extra = .str
1585 .opt = W("deprecated-declarations")
1586 .kind = .note
1587
1588unavailable
1589 .msg = "{s}"
1590 .extra = .str
1591 .kind = .@"error"
1592
1593unavailable_note
1594 .msg = "'{s}' has been explicitly marked unavailable here"
1595 .extra = .str
1596 .kind = .note
1597
1598warning_attribute
1599 .msg = "{s}"
1600 .extra = .str
1601 .kind = .warning
1602 .opt = W("attribute-warning")
1603
1604error_attribute
1605 .msg = "{s}"
1606 .extra = .str
1607 .kind = .@"error"
1608
1609ignored_record_attr
1610 .msg = "attribute '{s}' is ignored, place it after \"{s}\" to apply attribute to type declaration"
1611 .extra = .ignored_record_attr
1612 .kind = .warning
1613 .opt = W("ignored-attributes")
1614
1615backslash_newline_escape
1616 .msg = "backslash and newline separated by space"
1617 .kind = .warning
1618 .opt = W("backslash-newline-escape")
1619
1620array_size_non_int
1621 .msg = "size of array has non-integer type '{s}'"
1622 .extra = .str
1623 .kind = .@"error"
1624
1625cast_to_smaller_int
1626 .msg = "cast to smaller integer type {s}"
1627 .extra = .str
1628 .kind = .warning
1629 .opt = W("pointer-to-int-cast")
1630
1631gnu_switch_range
1632 .msg = "use of GNU case range extension"
1633 .opt = W("gnu-case-range")
1634 .kind = .off
1635 .pedantic = true
1636
1637empty_case_range
1638 .msg = "empty case range specified"
1639 .kind = .warning
1640
1641non_standard_escape_char
1642 .msg = "use of non-standard escape character '\\{s}'"
1643 .kind = .off
1644 .opt = W("pedantic")
1645 .extra = .invalid_escape
1646
1647invalid_pp_stringify_escape
1648 .msg = "invalid string literal, ignoring final '\\'"
1649 .kind = .warning
1650
1651vla
1652 .msg = "variable length array used"
1653 .kind = .off
1654 .opt = W("vla")
1655
1656float_overflow_conversion
1657 .msg = "implicit conversion of non-finite value from {s} is undefined"
1658 .extra = .str
1659 .kind = .off
1660 .opt = W("float-overflow-conversion")
1661
1662float_out_of_range
1663 .msg = "implicit conversion of out of range value from {s} is undefined"
1664 .extra = .str
1665 .kind = .warning
1666 .opt = W("literal-conversion")
1667
1668float_zero_conversion
1669 .msg = "implicit conversion from {s}"
1670 .extra = .str
1671 .kind = .off
1672 .opt = W("float-zero-conversion")
1673
1674float_value_changed
1675 .msg = "implicit conversion from {s}"
1676 .extra = .str
1677 .kind = .warning
1678 .opt = W("float-conversion")
1679
1680float_to_int
1681 .msg = "implicit conversion turns floating-point number into integer: {s}"
1682 .extra = .str
1683 .kind = .off
1684 .opt = W("literal-conversion")
1685
1686const_decl_folded
1687 .msg = "expression is not an integer constant expression; folding it to a constant is a GNU extension"
1688 .kind = .off
1689 .opt = W("gnu-folding-constant")
1690 .pedantic = true
1691
1692const_decl_folded_vla
1693 .msg = "variable length array folded to constant array as an extension"
1694 .kind = .off
1695 .opt = W("gnu-folding-constant")
1696 .pedantic = true
1697
1698redefinition_of_typedef
1699 .msg = "typedef redefinition with different types ({s})"
1700 .extra = .str
1701 .kind = .@"error"
1702
1703undefined_macro
1704 .msg = "'{s}' is not defined, evaluates to 0"
1705 .extra = .str
1706 .kind = .off
1707 .opt = W("undef")
1708
1709fn_macro_undefined
1710 .msg = "function-like macro '{s}' is not defined"
1711 .extra = .str
1712 .kind = .@"error"
1713
1714preprocessing_directive_only
1715 .msg = "'{s}' must be used within a preprocessing directive"
1716 .extra = .tok_id_expected
1717 .kind = .@"error"
1718
1719missing_lparen_after_builtin
1720 .msg = "Missing '(' after built-in macro '{s}'"
1721 .extra = .str
1722 .kind = .@"error"
1723
1724offsetof_ty
1725 .msg = "offsetof requires struct or union type, '{s}' invalid"
1726 .extra = .str
1727 .kind = .@"error"
1728
1729offsetof_incomplete
1730 .msg = "offsetof of incomplete type '{s}'"
1731 .extra = .str
1732 .kind = .@"error"
1733
1734offsetof_array
1735 .msg = "offsetof requires array type, '{s}' invalid"
1736 .extra = .str
1737 .kind = .@"error"
1738
1739pragma_pack_lparen
1740 .msg = "missing '(' after '#pragma pack' - ignoring"
1741 .kind = .warning
1742 .opt = W("ignored-pragmas")
1743
1744pragma_pack_rparen
1745 .msg = "missing ')' after '#pragma pack' - ignoring"
1746 .kind = .warning
1747 .opt = W("ignored-pragmas")
1748
1749pragma_pack_unknown_action
1750 .msg = "unknown action for '#pragma pack' - ignoring"
1751 .opt = W("ignored-pragmas")
1752 .kind = .warning
1753
1754pragma_pack_show
1755 .msg = "value of #pragma pack(show) == {d}"
1756 .extra = .unsigned
1757 .kind = .warning
1758
1759pragma_pack_int
1760 .msg = "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'"
1761 .opt = W("ignored-pragmas")
1762 .kind = .warning
1763
1764pragma_pack_int_ident
1765 .msg = "expected integer or identifier in '#pragma pack' - ignored"
1766 .opt = W("ignored-pragmas")
1767 .kind = .warning
1768
1769pragma_pack_undefined_pop
1770 .msg = "specifying both a name and alignment to 'pop' is undefined"
1771 .kind = .warning
1772
1773pragma_pack_empty_stack
1774 .msg = "#pragma pack(pop, ...) failed: stack empty"
1775 .opt = W("ignored-pragmas")
1776 .kind = .warning
1777
1778cond_expr_type
1779 .msg = "used type '{s}' where arithmetic or pointer type is required"
1780 .extra = .str
1781 .kind = .@"error"
1782
1783too_many_includes
1784 .msg = "#include nested too deeply"
1785 .kind = .@"error"
1786
1787enumerator_too_small
1788 .msg = "ISO C restricts enumerator values to range of 'int' ({s} is too small)"
1789 .extra = .str
1790 .kind = .off
1791 .opt = W("pedantic")
1792
1793enumerator_too_large
1794 .msg = "ISO C restricts enumerator values to range of 'int' ({s} is too large)"
1795 .extra = .str
1796 .kind = .off
1797 .opt = W("pedantic")
1798
1799include_next
1800 .msg = "#include_next is a language extension"
1801 .kind = .off
1802 .pedantic = true
1803 .opt = W("gnu-include-next")
1804
1805include_next_outside_header
1806 .msg = "#include_next in primary source file; will search from start of include path"
1807 .kind = .warning
1808 .opt = W("include-next-outside-header")
1809
1810enumerator_overflow
1811 .msg = "overflow in enumeration value"
1812 .kind = .warning
1813
1814enum_not_representable
1815 .msg = "incremented enumerator value {s} is not representable in the largest integer type"
1816 .kind = .warning
1817 .opt = W("enum-too-large")
1818 .extra = .pow_2_as_string
1819
1820enum_too_large
1821 .msg = "enumeration values exceed range of largest integer"
1822 .kind = .warning
1823 .opt = W("enum-too-large")
1824
1825enum_fixed
1826 .msg = "enumeration types with a fixed underlying type are a Clang extension"
1827 .kind = .off
1828 .pedantic = true
1829 .opt = W("fixed-enum-extension")
1830
1831enum_prev_nonfixed
1832 .msg = "enumeration previously declared with nonfixed underlying type"
1833 .kind = .@"error"
1834
1835enum_prev_fixed
1836 .msg = "enumeration previously declared with fixed underlying type"
1837 .kind = .@"error"
1838
1839enum_different_explicit_ty
1840 # str will be like 'new' (was 'old'
1841 .msg = "enumeration redeclared with different underlying type {s})"
1842 .extra = .str
1843 .kind = .@"error"
1844
1845enum_not_representable_fixed
1846 .msg = "enumerator value is not representable in the underlying type '{s}'"
1847 .extra = .str
1848 .kind = .@"error"
1849
1850transparent_union_wrong_type
1851 .msg = "'transparent_union' attribute only applies to unions"
1852 .opt = W("ignored-attributes")
1853 .kind = .warning
1854
1855transparent_union_one_field
1856 .msg = "transparent union definition must contain at least one field; transparent_union attribute ignored"
1857 .opt = W("ignored-attributes")
1858 .kind = .warning
1859
1860transparent_union_size
1861 .msg = "size of field {s} bits) does not match the size of the first field in transparent union; transparent_union attribute ignored"
1862 .extra = .str
1863 .opt = W("ignored-attributes")
1864 .kind = .warning
1865
1866transparent_union_size_note
1867 .msg = "size of first field is {d}"
1868 .extra = .unsigned
1869 .kind = .note
1870
1871designated_init_invalid
1872 .msg = "'designated_init' attribute is only valid on 'struct' type'"
1873 .kind = .@"error"
1874
1875designated_init_needed
1876 .msg = "positional initialization of field in 'struct' declared with 'designated_init' attribute"
1877 .opt = W("designated-init")
1878 .kind = .warning
1879
1880ignore_common
1881 .msg = "ignoring attribute 'common' because it conflicts with attribute 'nocommon'"
1882 .opt = W("ignored-attributes")
1883 .kind = .warning
1884
1885ignore_nocommon
1886 .msg = "ignoring attribute 'nocommon' because it conflicts with attribute 'common'"
1887 .opt = W("ignored-attributes")
1888 .kind = .warning
1889
1890non_string_ignored
1891 .msg = "'nonstring' attribute ignored on objects of type '{s}'"
1892 .opt = W("ignored-attributes")
1893 .kind = .warning
1894
1895local_variable_attribute
1896 .msg = "'{s}' attribute only applies to local variables"
1897 .extra = .str
1898 .opt = W("ignored-attributes")
1899 .kind = .warning
1900
1901ignore_cold
1902 .msg = "ignoring attribute 'cold' because it conflicts with attribute 'hot'"
1903 .opt = W("ignored-attributes")
1904 .kind = .warning
1905
1906ignore_hot
1907 .msg = "ignoring attribute 'hot' because it conflicts with attribute 'cold'"
1908 .opt = W("ignored-attributes")
1909 .kind = .warning
1910
1911ignore_noinline
1912 .msg = "ignoring attribute 'noinline' because it conflicts with attribute 'always_inline'"
1913 .opt = W("ignored-attributes")
1914 .kind = .warning
1915
1916ignore_always_inline
1917 .msg = "ignoring attribute 'always_inline' because it conflicts with attribute 'noinline'"
1918 .opt = W("ignored-attributes")
1919 .kind = .warning
1920
1921invalid_noreturn
1922 .msg = "function '{s}' declared 'noreturn' should not return"
1923 .extra = .str
1924 .kind = .warning
1925 .opt = W("invalid-noreturn")
1926
1927nodiscard_unused
1928 .msg = "ignoring return value of '{s}', declared with 'nodiscard' attribute"
1929 .extra = .str
1930 .kind = .warning
1931 .opt = W("unused-result")
1932
1933warn_unused_result
1934 .msg = "ignoring return value of '{s}', declared with 'warn_unused_result' attribute"
1935 .extra = .str
1936 .kind = .warning
1937 .opt = W("unused-result")
1938
1939invalid_vec_elem_ty
1940 .msg = "invalid vector element type '{s}'"
1941 .extra = .str
1942 .kind = .@"error"
1943
1944vec_size_not_multiple
1945 .msg = "vector size not an integral multiple of component size"
1946 .kind = .@"error"
1947
1948invalid_imag
1949 .msg = "invalid type '{s}' to __imag operator"
1950 .extra = .str
1951 .kind = .@"error"
1952
1953invalid_real
1954 .msg = "invalid type '{s}' to __real operator"
1955 .extra = .str
1956 .kind = .@"error"
1957
1958zero_length_array
1959 .msg = "zero size arrays are an extension"
1960 .kind = .off
1961 .pedantic = true
1962 .opt = W("zero-length-array")
1963
1964old_style_flexible_struct
1965 .msg = "array index {s} is past the end of the array"
1966 .extra = .str
1967 .kind = .off
1968 .pedantic = true
1969 .opt = W("old-style-flexible-struct")
1970
1971comma_deletion_va_args
1972 .msg = "token pasting of ',' and __VA_ARGS__ is a GNU extension"
1973 .kind = .off
1974 .pedantic = true
1975 .opt = W("gnu-zero-variadic-macro-arguments")
1976 .suppress_gcc = true
1977
1978main_return_type
1979 .msg = "return type of 'main' is not 'int'"
1980 .kind = .warning
1981 .opt = W("main-return-type")
1982
1983expansion_to_defined
1984 .msg = "macro expansion producing 'defined' has undefined behavior"
1985 .kind = .off
1986 .pedantic = true
1987 .opt = W("expansion-to-defined")
1988
1989invalid_int_suffix
1990 .msg = "invalid suffix '{s}' on integer constant"
1991 .extra = .str
1992 .kind = .@"error"
1993
1994invalid_float_suffix
1995 .msg = "invalid suffix '{s}' on floating constant"
1996 .extra = .str
1997 .kind = .@"error"
1998
1999invalid_octal_digit
2000 .msg = "invalid digit '{c}' in octal constant"
2001 .extra = .ascii
2002 .kind = .@"error"
2003
2004invalid_binary_digit
2005 .msg = "invalid digit '{c}' in binary constant"
2006 .extra = .ascii
2007 .kind = .@"error"
2008
2009exponent_has_no_digits
2010 .msg = "exponent has no digits"
2011 .kind = .@"error"
2012
2013hex_floating_constant_requires_exponent
2014 .msg = "hexadecimal floating constant requires an exponent"
2015 .kind = .@"error"
2016
2017sizeof_returns_zero
2018 .msg = "sizeof returns 0"
2019 .kind = .warning
2020 .suppress_gcc = true
2021 .suppress_clang = true
2022
2023declspec_not_allowed_after_declarator
2024 .msg = "'declspec' attribute not allowed after declarator"
2025 .kind = .@"error"
2026
2027declarator_name_tok
2028 .msg = "this declarator"
2029 .kind = .note
2030
2031type_not_supported_on_target
2032 .msg = "{s} is not supported on this target"
2033 .extra = .str
2034 .kind = .@"error"
2035
2036bit_int
2037 .msg = "'_BitInt' in C17 and earlier is a Clang extension'"
2038 .kind = .off
2039 .pedantic = true
2040 .opt = W("bit-int-extension")
2041 .suppress_version = .c23
2042
2043unsigned_bit_int_too_small
2044 .msg = "{s} must have a bit size of at least 1"
2045 .extra = .str
2046 .kind = .@"error"
2047
2048signed_bit_int_too_small
2049 .msg = "{s} must have a bit size of at least 2"
2050 .extra = .str
2051 .kind = .@"error"
2052
2053bit_int_too_big
2054 .msg = "{s} of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Properties.max_bits}) ++ " not supported"
2055 .extra = .str
2056 .kind = .@"error"
2057
2058keyword_macro
2059 .msg = "keyword is hidden by macro definition"
2060 .kind = .off
2061 .pedantic = true
2062 .opt = W("keyword-macro")
2063
2064ptr_arithmetic_incomplete
2065 .msg = "arithmetic on a pointer to an incomplete type '{s}'"
2066 .extra = .str
2067 .kind = .@"error"
2068
2069callconv_not_supported
2070 .msg = "'{s}' calling convention is not supported for this target"
2071 .extra = .str
2072 .opt = W("ignored-attributes")
2073 .kind = .warning
2074
2075pointer_arith_void
2076 .msg = "invalid application of '{s}' to a void type"
2077 .extra = .str
2078 .kind = .off
2079 .pedantic = true
2080 .opt = W("pointer-arith")
2081
2082sizeof_array_arg
2083 .msg = "sizeof on array function parameter will return size of {s}"
2084 .extra = .str
2085 .kind = .warning
2086 .opt = W("sizeof-array-argument")
2087
2088array_address_to_bool
2089 .msg = "address of array '{s}' will always evaluate to 'true'"
2090 .extra = .str
2091 .kind = .warning
2092 .opt = W("pointer-bool-conversion")
2093
2094string_literal_to_bool
2095 .msg = "implicit conversion turns string literal into bool: {s}"
2096 .extra = .str
2097 .kind = .off
2098 .opt = W("string-conversion")
2099
2100constant_expression_conversion_not_allowed
2101 .msg = "this conversion is not allowed in a constant expression"
2102 .kind = .note
2103
2104invalid_object_cast
2105 .msg = "cannot cast an object of type {s}"
2106 .extra = .str
2107 .kind = .@"error"
2108
2109cli_invalid_fp_eval_method
2110 .msg = "unsupported argument '{s}' to option '-ffp-eval-method='; expected 'source', 'double', or 'extended'"
2111 .extra = .str
2112 .kind = .@"error"
2113
2114suggest_pointer_for_invalid_fp16
2115 .msg = "{s} cannot have __fp16 type; did you forget * ?"
2116 .extra = .str
2117 .kind = .@"error"
2118
2119bitint_suffix
2120 .msg = "'_BitInt' suffix for literals is a C23 extension"
2121 .opt = W("c23-extensions")
2122 .kind = .warning
2123 .suppress_version = .c23
2124
2125auto_type_extension
2126 .msg = "'__auto_type' is a GNU extension"
2127 .opt = W("gnu-auto-type")
2128 .kind = .off
2129 .pedantic = true
2130
2131auto_type_not_allowed
2132 .msg = "'__auto_type' not allowed in {s}"
2133 .kind = .@"error"
2134 .extra = .str
2135
2136auto_type_requires_initializer
2137 .msg = "declaration of variable '{s}' with deduced type requires an initializer"
2138 .kind = .@"error"
2139 .extra = .str
2140
2141auto_type_requires_single_declarator
2142 .msg = "'__auto_type' may only be used with a single declarator"
2143 .kind = .@"error"
2144
2145auto_type_requires_plain_declarator
2146 .msg = "'__auto_type' requires a plain identifier as declarator"
2147 .kind = .@"error"
2148
2149invalid_cast_to_auto_type
2150 .msg = "invalid cast to '__auto_type'"
2151 .kind = .@"error"
2152
2153auto_type_from_bitfield
2154 .msg = "cannot use bit-field as '__auto_type' initializer"
2155 .kind = .@"error"
2156
2157array_of_auto_type
2158 .msg = "'{s}' declared as array of '__auto_type'"
2159 .kind = .@"error"
2160 .extra = .str
2161
2162auto_type_with_init_list
2163 .msg = "cannot use '__auto_type' with initializer list"
2164 .kind = .@"error"
2165
2166missing_semicolon
2167 .msg = "expected ';' at end of declaration list"
2168 .kind = .warning
2169
2170tentative_definition_incomplete
2171 .msg = "tentative definition has type '{s}' that is never completed"
2172 .kind = .@"error"
2173 .extra = .str
2174
2175forward_declaration_here
2176 .msg = "forward declaration of '{s}'"
2177 .kind = .note
2178 .extra = .str
2179
2180gnu_union_cast
2181 .msg = "cast to union type is a GNU extension"
2182 .opt = W("gnu-union-cast")
2183 .kind = .off
2184 .pedantic = true
2185
2186invalid_union_cast
2187 .msg = "cast to union type from type '{s}' not present in union"
2188 .kind = .@"error"
2189 .extra = .str
2190
2191cast_to_incomplete_type
2192 .msg = "cast to incomplete type '{s}'"
2193 .kind = .@"error"
2194 .extra = .str
2195
2196invalid_source_epoch
2197 .msg = "environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799"
2198 .kind = .@"error"
2199
2200fuse_ld_path
2201 .msg = "'-fuse-ld=' taking a path is deprecated; use '--ld-path=' instead"
2202 .kind = .off
2203 .opt = W("fuse-ld-path")
2204
2205invalid_rtlib
2206 .msg = "invalid runtime library name '{s}'"
2207 .kind = .@"error"
2208 .extra = .str
2209
2210unsupported_rtlib_gcc
2211 .msg = "unsupported runtime library 'libgcc' for platform '{s}'"
2212 .kind = .@"error"
2213 .extra = .str
2214
2215invalid_unwindlib
2216 .msg = "invalid unwind library name '{s}'"
2217 .kind = .@"error"
2218 .extra = .str
2219
2220incompatible_unwindlib
2221 .msg = "--rtlib=libgcc requires --unwindlib=libgcc"
2222 .kind = .@"error"
2223
2224gnu_asm_disabled
2225 .msg = "GNU-style inline assembly is disabled"
2226 .kind = .@"error"
2227
2228extension_token_used
2229 .msg = "extension used"
2230 .kind = .off
2231 .pedantic = true
2232 .opt = W("language-extension-token")
2233
2234complex_component_init
2235 .msg = "complex initialization specifying real and imaginary components is an extension"
2236 .opt = W("complex-component-init")
2237 .kind = .off
2238 .pedantic = true
2239
2240complex_prefix_postfix_op
2241 .msg = "ISO C does not support '++'/'--' on complex type '{s}'"
2242 .opt = W("pedantic")
2243 .extra = .str
2244 .kind = .off
2245
2246not_floating_type
2247 .msg = "argument type '{s}' is not a real floating point type"
2248 .extra = .str
2249 .kind = .@"error"
2250
2251argument_types_differ
2252 .msg = "arguments are of different types ({s})"
2253 .extra = .str
2254 .kind = .@"error"
2255
2256ms_search_rule
2257 .msg = "#include resolved using non-portable Microsoft search rules as: {s}"
2258 .extra = .str
2259 .opt = W("microsoft-include")
2260 .kind = .warning
2261
2262ctrl_z_eof
2263 .msg = "treating Ctrl-Z as end-of-file is a Microsoft extension"
2264 .opt = W("microsoft-end-of-file")
2265 .kind = .off
2266 .pedantic = true
2267
2268illegal_char_encoding_warning
2269 .msg = "illegal character encoding in character literal"
2270 .opt = W("invalid-source-encoding")
2271 .kind = .warning
2272
2273illegal_char_encoding_error
2274 .msg = "illegal character encoding in character literal"
2275 .kind = .@"error"
2276
2277ucn_basic_char_error
2278 .msg = "character '{c}' cannot be specified by a universal character name"
2279 .kind = .@"error"
2280 .extra = .ascii
2281
2282ucn_basic_char_warning
2283 .msg = "specifying character '{c}' with a universal character name is incompatible with C standards before C23"
2284 .kind = .off
2285 .extra = .ascii
2286 .suppress_unless_version = .c23
2287 .opt = W("pre-c23-compat")
2288
2289ucn_control_char_error
2290 .msg = "universal character name refers to a control character"
2291 .kind = .@"error"
2292
2293ucn_control_char_warning
2294 .msg = "universal character name referring to a control character is incompatible with C standards before C23"
2295 .kind = .off
2296 .suppress_unless_version = .c23
2297 .opt = W("pre-c23-compat")
2298
2299c89_ucn_in_literal
2300 .msg = "universal character names are only valid in C99 or later"
2301 .suppress_version = .c99
2302 .kind = .warning
2303 .opt = W("unicode")
2304
2305four_char_char_literal
2306 .msg = "multi-character character constant"
2307 .opt = W("four-char-constants")
2308 .kind = .off
2309
2310multi_char_char_literal
2311 .msg = "multi-character character constant"
2312 .kind = .off
2313
2314missing_hex_escape
2315 .msg = "\\{c} used with no following hex digits"
2316 .kind = .@"error"
2317 .extra = .ascii
2318
2319unknown_escape_sequence
2320 .msg = "unknown escape sequence '\\{s}'"
2321 .kind = .warning
2322 .opt = W("unknown-escape-sequence")
2323 .extra = .invalid_escape
2324
2325attribute_requires_string
2326 .msg = "attribute '{s}' requires an ordinary string"
2327 .kind = .@"error"
2328 .extra = .str
2329
2330unterminated_string_literal_warning
2331 .msg = "missing terminating '\"' character"
2332 .kind = .warning
2333 .opt = W("invalid-pp-token")
2334
2335unterminated_string_literal_error
2336 .msg = "missing terminating '\"' character"
2337 .kind = .@"error"
2338
2339empty_char_literal_warning
2340 .msg = "empty character constant"
2341 .kind = .warning
2342 .opt = W("invalid-pp-token")
2343
2344empty_char_literal_error
2345 .msg = "empty character constant"
2346 .kind = .@"error"
2347
2348unterminated_char_literal_warning
2349 .msg = "missing terminating ' character"
2350 .kind = .warning
2351 .opt = W("invalid-pp-token")
2352
2353unterminated_char_literal_error
2354 .msg = "missing terminating ' character"
2355 .kind = .@"error"
2356
2357unterminated_comment
2358 .msg = "unterminated comment"
2359 .kind = .@"error"
2360
2361def_no_proto_deprecated
2362 .msg = "a function definition without a prototype is deprecated in all versions of C and is not supported in C23"
2363 .kind = .warning
2364 .opt = W("deprecated-non-prototype")
2365
2366passing_args_to_kr
2367 .msg = "passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23"
2368 .kind = .warning
2369 .opt = W("deprecated-non-prototype")
2370
2371unknown_type_name
2372 .msg = "unknown type name '{s}'"
2373 .kind = .@"error"
2374 .extra = .str
2375
2376label_compound_end
2377 .msg = "label at end of compound statement is a C23 extension"
2378 .opt = W("c23-extensions")
2379 .kind = .warning
2380 .suppress_version = .c23
2381
2382u8_char_lit
2383 .msg = "UTF-8 character literal is a C23 extension"
2384 .opt = W("c23-extensions")
2385 .kind = .warning
2386 .suppress_version = .c23
2387
2388malformed_embed_param
2389 .msg = "unexpected token in embed parameter"
2390 .kind = .@"error"
2391
2392malformed_embed_limit
2393 .msg = "the limit parameter expects one non-negative integer as a parameter"
2394 .kind = .@"error"
2395
2396duplicate_embed_param
2397 .msg = "duplicate embed parameter '{s}'"
2398 .kind = .warning
2399 .extra = .str
2400 .opt = W("duplicate-embed-param")
2401
2402unsupported_embed_param
2403 .msg = "unsupported embed parameter '{s}' embed parameter"
2404 .kind = .warning
2405 .extra = .str
2406 .opt = W("unsupported-embed-param")
2407
2408invalid_compound_literal_storage_class
2409 .msg = "compound literal cannot have {s} storage class"
2410 .kind = .@"error"
2411 .extra = .str
2412
2413va_opt_lparen
2414 .msg = "missing '(' following __VA_OPT__"
2415 .kind = .@"error"
2416
2417va_opt_rparen
2418 .msg = "unterminated __VA_OPT__ argument list"
2419 .kind = .@"error"
2420
2421attribute_int_out_of_range
2422 .msg = "attribute value '{s}' out of range"
2423 .kind = .@"error"
2424 .extra = .str
2425
2426identifier_not_normalized
2427 .msg = "'{s}' is not in NFC"
2428 .kind = .warning
2429 .extra = .normalized
2430 .opt = W("normalized")
2431
2432c23_auto_plain_declarator
2433 .msg = "'auto' requires a plain identifier declarator"
2434 .kind = .@"error"
2435
2436c23_auto_single_declarator
2437 .msg = "'auto' can only be used with a single declarator"
2438 .kind = .@"error"
2439
2440c32_auto_requires_initializer
2441 .msg = "'auto' requires an initializer"
2442 .kind = .@"error"
2443
2444c23_auto_scalar_init
2445 .msg = "'auto' requires a scalar initializer"
2446 .kind = .@"error"
deps/aro/aro/Driver.zig deleted-811
......@@ -1,811 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const process = std.process;
5const backend = @import("backend");
6const Ir = backend.Ir;
7const Object = backend.Object;
8const Compilation = @import("Compilation.zig");
9const Diagnostics = @import("Diagnostics.zig");
10const LangOpts = @import("LangOpts.zig");
11const Preprocessor = @import("Preprocessor.zig");
12const Source = @import("Source.zig");
13const Toolchain = @import("Toolchain.zig");
14const target_util = @import("target.zig");
15
16pub const Linker = enum {
17 ld,
18 bfd,
19 gold,
20 lld,
21 mold,
22};
23
24const Driver = @This();
25
26comp: *Compilation,
27inputs: std.ArrayListUnmanaged(Source) = .{},
28link_objects: std.ArrayListUnmanaged([]const u8) = .{},
29output_name: ?[]const u8 = null,
30sysroot: ?[]const u8 = null,
31system_defines: Compilation.SystemDefinesMode = .include_system_defines,
32temp_file_count: u32 = 0,
33/// If false, do not emit line directives in -E mode
34line_commands: bool = true,
35/// If true, use `#line <num>` instead of `# <num>` for line directives
36use_line_directives: bool = false,
37only_preprocess: bool = false,
38only_syntax: bool = false,
39only_compile: bool = false,
40only_preprocess_and_compile: bool = false,
41verbose_ast: bool = false,
42verbose_pp: bool = false,
43verbose_ir: bool = false,
44verbose_linker_args: bool = false,
45color: ?bool = null,
46
47/// Full path to the aro executable
48aro_name: []const u8 = "",
49
50/// Value of --triple= passed via CLI
51raw_target_triple: ?[]const u8 = null,
52
53// linker options
54use_linker: ?[]const u8 = null,
55linker_path: ?[]const u8 = null,
56nodefaultlibs: bool = false,
57nolibc: bool = false,
58nostartfiles: bool = false,
59nostdlib: bool = false,
60pie: ?bool = null,
61rdynamic: bool = false,
62relocatable: bool = false,
63rtlib: ?[]const u8 = null,
64shared: bool = false,
65shared_libgcc: bool = false,
66static: bool = false,
67static_libgcc: bool = false,
68static_pie: bool = false,
69strip: bool = false,
70unwindlib: ?[]const u8 = null,
71
72pub fn deinit(d: *Driver) void {
73 for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
74 std.fs.deleteFileAbsolute(obj) catch {};
75 d.comp.gpa.free(obj);
76 }
77 d.inputs.deinit(d.comp.gpa);
78 d.link_objects.deinit(d.comp.gpa);
79 d.* = undefined;
80}
81
82pub const usage =
83 \\Usage {s}: [options] file..
84 \\
85 \\General options:
86 \\ -h, --help Print this message.
87 \\ -v, --version Print aro version.
88 \\
89 \\Compile options:
90 \\ -c, --compile Only run preprocess, compile, and assemble steps
91 \\ -D <macro>=<value> Define <macro> to <value> (defaults to 1)
92 \\ -E Only run the preprocessor
93 \\ -fchar8_t Enable char8_t (enabled by default in C23 and later)
94 \\ -fno-char8_t Disable char8_t (disabled by default for pre-C23)
95 \\ -fcolor-diagnostics Enable colors in diagnostics
96 \\ -fno-color-diagnostics Disable colors in diagnostics
97 \\ -fdeclspec Enable support for __declspec attributes
98 \\ -fno-declspec Disable support for __declspec attributes
99 \\ -ffp-eval-method=[source|double|extended]
100 \\ Evaluation method to use for floating-point arithmetic
101 \\ -ffreestanding Compilation in a freestanding environment
102 \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled)
103 \\ -fno-gnu-inline-asm Disable GNU style inline asm
104 \\ -fhosted Compilation in a hosted environment
105 \\ -fms-extensions Enable support for Microsoft extensions
106 \\ -fno-ms-extensions Disable support for Microsoft extensions
107 \\ -fdollars-in-identifiers
108 \\ Allow '$' in identifiers
109 \\ -fno-dollars-in-identifiers
110 \\ Disallow '$' in identifiers
111 \\ -fmacro-backtrace-limit=<limit>
112 \\ Set limit on how many macro expansion traces are shown in errors (default 6)
113 \\ -fnative-half-type Use the native half type for __fp16 instead of promoting to float
114 \\ -fnative-half-arguments-and-returns
115 \\ Allow half-precision function arguments and return values
116 \\ -fshort-enums Use the narrowest possible integer type for enums
117 \\ -fno-short-enums Use "int" as the tag type for enums
118 \\ -fsigned-char "char" is signed
119 \\ -fno-signed-char "char" is unsigned
120 \\ -fsyntax-only Only run the preprocessor, parser, and semantic analysis stages
121 \\ -funsigned-char "char" is unsigned
122 \\ -fno-unsigned-char "char" is signed
123 \\ -fuse-line-directives Use `#line <num>` linemarkers in preprocessed output
124 \\ -fno-use-line-directives
125 \\ Use `# <num>` linemarkers in preprocessed output
126 \\ -I <dir> Add directory to include search path
127 \\ -isystem Add directory to SYSTEM include search path
128 \\ --emulate=[clang|gcc|msvc]
129 \\ Select which C compiler to emulate (default clang)
130 \\ -o <file> Write output to <file>
131 \\ -P, --no-line-commands Disable linemarker output in -E mode
132 \\ -pedantic Warn on language extensions
133 \\ --rtlib=<arg> Compiler runtime library to use (libgcc or compiler-rt)
134 \\ -std=<standard> Specify language standard
135 \\ -S, --assemble Only run preprocess and compilation steps
136 \\ --sysroot=<dir> Use dir as the logical root directory for headers and libraries (not fully implemented)
137 \\ --target=<value> Generate code for the given target
138 \\ -U <macro> Undefine <macro>
139 \\ -undef Do not predefine any system-specific macros. Standard predefined macros remain defined.
140 \\ -Werror Treat all warnings as errors
141 \\ -Werror=<warning> Treat warning as error
142 \\ -W<warning> Enable the specified warning
143 \\ -Wno-<warning> Disable the specified warning
144 \\
145 \\Link options:
146 \\ -fuse-ld=[bfd|gold|lld|mold]
147 \\ Use specific linker
148 \\ -nodefaultlibs Do not use the standard system libraries when linking.
149 \\ -nolibc Do not use the C library or system libraries tightly coupled with it when linking.
150 \\ -nostdlib Do not use the standard system startup files or libraries when linking
151 \\ -nostartfiles Do not use the standard system startup files when linking.
152 \\ -pie Produce a dynamically linked position independent executable on targets that support it.
153 \\ --ld-path=<path> Use linker specified by <path>
154 \\ -r Produce a relocatable object as output.
155 \\ -rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it.
156 \\ -s Remove all symbol table and relocation information from the executable.
157 \\ -shared Produce a shared object which can then be linked with other objects to form an executable.
158 \\ -shared-libgcc On systems that provide libgcc as a shared library, force the use of the shared version
159 \\ -static On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries.
160 \\ -static-libgcc On systems that provide libgcc as a shared library, force the use of the static version
161 \\ -static-pie Produce a static position independent executable on targets that support it.
162 \\ --unwindlib=<arg> Unwind library to use ("none", "libgcc", or "libunwind") If not specified, will match runtime library
163 \\
164 \\Debug options:
165 \\ --verbose-ast Dump produced AST to stdout
166 \\ --verbose-pp Dump preprocessor state
167 \\ --verbose-ir Dump ir to stdout
168 \\ --verbose-linker-args Dump linker args to stdout
169 \\
170 \\
171;
172
173/// Process command line arguments, returns true if something was written to std_out.
174pub fn parseArgs(
175 d: *Driver,
176 std_out: anytype,
177 macro_buf: anytype,
178 args: []const []const u8,
179) !bool {
180 var i: usize = 1;
181 var comment_arg: []const u8 = "";
182 var hosted: ?bool = null;
183 while (i < args.len) : (i += 1) {
184 const arg = args[i];
185 if (mem.startsWith(u8, arg, "-") and arg.len > 1) {
186 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
187 std_out.print(usage, .{args[0]}) catch |er| {
188 return d.fatal("unable to print usage: {s}", .{errorDescription(er)});
189 };
190 return true;
191 } else if (mem.eql(u8, arg, "-v") or mem.eql(u8, arg, "--version")) {
192 std_out.writeAll(@import("backend").version_str ++ "\n") catch |er| {
193 return d.fatal("unable to print version: {s}", .{errorDescription(er)});
194 };
195 return true;
196 } else if (mem.startsWith(u8, arg, "-D")) {
197 var macro = arg["-D".len..];
198 if (macro.len == 0) {
199 i += 1;
200 if (i >= args.len) {
201 try d.err("expected argument after -I");
202 continue;
203 }
204 macro = args[i];
205 }
206 var value: []const u8 = "1";
207 if (mem.indexOfScalar(u8, macro, '=')) |some| {
208 value = macro[some + 1 ..];
209 macro = macro[0..some];
210 }
211 try macro_buf.print("#define {s} {s}\n", .{ macro, value });
212 } else if (mem.startsWith(u8, arg, "-U")) {
213 var macro = arg["-U".len..];
214 if (macro.len == 0) {
215 i += 1;
216 if (i >= args.len) {
217 try d.err("expected argument after -I");
218 continue;
219 }
220 macro = args[i];
221 }
222 try macro_buf.print("#undef {s}\n", .{macro});
223 } else if (mem.eql(u8, arg, "-undef")) {
224 d.system_defines = .no_system_defines;
225 } else if (mem.eql(u8, arg, "-c") or mem.eql(u8, arg, "--compile")) {
226 d.only_compile = true;
227 } else if (mem.eql(u8, arg, "-E")) {
228 d.only_preprocess = true;
229 } else if (mem.eql(u8, arg, "-P") or mem.eql(u8, arg, "--no-line-commands")) {
230 d.line_commands = false;
231 } else if (mem.eql(u8, arg, "-fuse-line-directives")) {
232 d.use_line_directives = true;
233 } else if (mem.eql(u8, arg, "-fno-use-line-directives")) {
234 d.use_line_directives = false;
235 } else if (mem.eql(u8, arg, "-fchar8_t")) {
236 d.comp.langopts.has_char8_t_override = true;
237 } else if (mem.eql(u8, arg, "-fno-char8_t")) {
238 d.comp.langopts.has_char8_t_override = false;
239 } else if (mem.eql(u8, arg, "-fcolor-diagnostics")) {
240 d.color = true;
241 } else if (mem.eql(u8, arg, "-fno-color-diagnostics")) {
242 d.color = false;
243 } else if (mem.eql(u8, arg, "-fdollars-in-identifiers")) {
244 d.comp.langopts.dollars_in_identifiers = true;
245 } else if (mem.eql(u8, arg, "-fno-dollars-in-identifiers")) {
246 d.comp.langopts.dollars_in_identifiers = false;
247 } else if (mem.eql(u8, arg, "-fdigraphs")) {
248 d.comp.langopts.digraphs = true;
249 } else if (mem.eql(u8, arg, "-fgnu-inline-asm")) {
250 d.comp.langopts.gnu_asm = true;
251 } else if (mem.eql(u8, arg, "-fno-gnu-inline-asm")) {
252 d.comp.langopts.gnu_asm = false;
253 } else if (mem.eql(u8, arg, "-fno-digraphs")) {
254 d.comp.langopts.digraphs = false;
255 } else if (option(arg, "-fmacro-backtrace-limit=")) |limit_str| {
256 var limit = std.fmt.parseInt(u32, limit_str, 10) catch {
257 try d.err("-fmacro-backtrace-limit takes a number argument");
258 continue;
259 };
260
261 if (limit == 0) limit = std.math.maxInt(u32);
262 d.comp.diagnostics.macro_backtrace_limit = limit;
263 } else if (mem.eql(u8, arg, "-fnative-half-type")) {
264 d.comp.langopts.use_native_half_type = true;
265 } else if (mem.eql(u8, arg, "-fnative-half-arguments-and-returns")) {
266 d.comp.langopts.allow_half_args_and_returns = true;
267 } else if (mem.eql(u8, arg, "-fshort-enums")) {
268 d.comp.langopts.short_enums = true;
269 } else if (mem.eql(u8, arg, "-fno-short-enums")) {
270 d.comp.langopts.short_enums = false;
271 } else if (mem.eql(u8, arg, "-fsigned-char")) {
272 d.comp.langopts.setCharSignedness(.signed);
273 } else if (mem.eql(u8, arg, "-fno-signed-char")) {
274 d.comp.langopts.setCharSignedness(.unsigned);
275 } else if (mem.eql(u8, arg, "-funsigned-char")) {
276 d.comp.langopts.setCharSignedness(.unsigned);
277 } else if (mem.eql(u8, arg, "-fno-unsigned-char")) {
278 d.comp.langopts.setCharSignedness(.signed);
279 } else if (mem.eql(u8, arg, "-fdeclspec")) {
280 d.comp.langopts.declspec_attrs = true;
281 } else if (mem.eql(u8, arg, "-fno-declspec")) {
282 d.comp.langopts.declspec_attrs = false;
283 } else if (mem.eql(u8, arg, "-ffreestanding")) {
284 hosted = false;
285 } else if (mem.eql(u8, arg, "-fhosted")) {
286 hosted = true;
287 } else if (mem.eql(u8, arg, "-fms-extensions")) {
288 d.comp.langopts.enableMSExtensions();
289 } else if (mem.eql(u8, arg, "-fno-ms-extensions")) {
290 d.comp.langopts.disableMSExtensions();
291 } else if (mem.startsWith(u8, arg, "-I")) {
292 var path = arg["-I".len..];
293 if (path.len == 0) {
294 i += 1;
295 if (i >= args.len) {
296 try d.err("expected argument after -I");
297 continue;
298 }
299 path = args[i];
300 }
301 try d.comp.include_dirs.append(d.comp.gpa, path);
302 } else if (mem.startsWith(u8, arg, "-fsyntax-only")) {
303 d.only_syntax = true;
304 } else if (mem.startsWith(u8, arg, "-fno-syntax-only")) {
305 d.only_syntax = false;
306 } else if (mem.startsWith(u8, arg, "-isystem")) {
307 var path = arg["-isystem".len..];
308 if (path.len == 0) {
309 i += 1;
310 if (i >= args.len) {
311 try d.err("expected argument after -isystem");
312 continue;
313 }
314 path = args[i];
315 }
316 const duped = try d.comp.gpa.dupe(u8, path);
317 errdefer d.comp.gpa.free(duped);
318 try d.comp.system_include_dirs.append(d.comp.gpa, duped);
319 } else if (option(arg, "--emulate=")) |compiler_str| {
320 const compiler = std.meta.stringToEnum(LangOpts.Compiler, compiler_str) orelse {
321 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_emulate, .extra = .{ .str = arg } }, &.{});
322 continue;
323 };
324 d.comp.langopts.setEmulatedCompiler(compiler);
325 } else if (option(arg, "-ffp-eval-method=")) |fp_method_str| {
326 const fp_eval_method = std.meta.stringToEnum(LangOpts.FPEvalMethod, fp_method_str) orelse .indeterminate;
327 if (fp_eval_method == .indeterminate) {
328 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_fp_eval_method, .extra = .{ .str = fp_method_str } }, &.{});
329 continue;
330 }
331 d.comp.langopts.setFpEvalMethod(fp_eval_method);
332 } else if (mem.startsWith(u8, arg, "-o")) {
333 var file = arg["-o".len..];
334 if (file.len == 0) {
335 i += 1;
336 if (i >= args.len) {
337 try d.err("expected argument after -o");
338 continue;
339 }
340 file = args[i];
341 }
342 d.output_name = file;
343 } else if (option(arg, "--sysroot=")) |sysroot| {
344 d.sysroot = sysroot;
345 } else if (mem.eql(u8, arg, "-pedantic")) {
346 d.comp.diagnostics.options.pedantic = .warning;
347 } else if (option(arg, "--rtlib=")) |rtlib| {
348 if (mem.eql(u8, rtlib, "compiler-rt") or mem.eql(u8, rtlib, "libgcc") or mem.eql(u8, rtlib, "platform")) {
349 d.rtlib = rtlib;
350 } else {
351 try d.comp.addDiagnostic(.{ .tag = .invalid_rtlib, .extra = .{ .str = rtlib } }, &.{});
352 }
353 } else if (option(arg, "-Werror=")) |err_name| {
354 try d.comp.diagnostics.set(err_name, .@"error");
355 } else if (mem.eql(u8, arg, "-Wno-fatal-errors")) {
356 d.comp.diagnostics.fatal_errors = false;
357 } else if (option(arg, "-Wno-")) |err_name| {
358 try d.comp.diagnostics.set(err_name, .off);
359 } else if (mem.eql(u8, arg, "-Wfatal-errors")) {
360 d.comp.diagnostics.fatal_errors = true;
361 } else if (option(arg, "-W")) |err_name| {
362 try d.comp.diagnostics.set(err_name, .warning);
363 } else if (option(arg, "-std=")) |standard| {
364 d.comp.langopts.setStandard(standard) catch
365 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_standard, .extra = .{ .str = arg } }, &.{});
366 } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) {
367 d.only_preprocess_and_compile = true;
368 } else if (option(arg, "--target=")) |triple| {
369 const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch {
370 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{});
371 continue;
372 };
373 const target = std.zig.system.resolveTargetQuery(query) catch |e| {
374 return d.fatal("unable to resolve target: {s}", .{errorDescription(e)});
375 };
376 d.comp.target = target;
377 d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(target));
378 d.raw_target_triple = triple;
379 } else if (mem.eql(u8, arg, "--verbose-ast")) {
380 d.verbose_ast = true;
381 } else if (mem.eql(u8, arg, "--verbose-pp")) {
382 d.verbose_pp = true;
383 } else if (mem.eql(u8, arg, "--verbose-ir")) {
384 d.verbose_ir = true;
385 } else if (mem.eql(u8, arg, "--verbose-linker-args")) {
386 d.verbose_linker_args = true;
387 } else if (mem.eql(u8, arg, "-C") or mem.eql(u8, arg, "--comments")) {
388 d.comp.langopts.preserve_comments = true;
389 comment_arg = arg;
390 } else if (mem.eql(u8, arg, "-CC") or mem.eql(u8, arg, "--comments-in-macros")) {
391 d.comp.langopts.preserve_comments = true;
392 d.comp.langopts.preserve_comments_in_macros = true;
393 comment_arg = arg;
394 } else if (option(arg, "-fuse-ld=")) |linker_name| {
395 d.use_linker = linker_name;
396 } else if (mem.eql(u8, arg, "-fuse-ld=")) {
397 d.use_linker = null;
398 } else if (option(arg, "--ld-path=")) |linker_path| {
399 d.linker_path = linker_path;
400 } else if (mem.eql(u8, arg, "-r")) {
401 d.relocatable = true;
402 } else if (mem.eql(u8, arg, "-shared")) {
403 d.shared = true;
404 } else if (mem.eql(u8, arg, "-shared-libgcc")) {
405 d.shared_libgcc = true;
406 } else if (mem.eql(u8, arg, "-static")) {
407 d.static = true;
408 } else if (mem.eql(u8, arg, "-static-libgcc")) {
409 d.static_libgcc = true;
410 } else if (mem.eql(u8, arg, "-static-pie")) {
411 d.static_pie = true;
412 } else if (mem.eql(u8, arg, "-pie")) {
413 d.pie = true;
414 } else if (mem.eql(u8, arg, "-no-pie") or mem.eql(u8, arg, "-nopie")) {
415 d.pie = false;
416 } else if (mem.eql(u8, arg, "-rdynamic")) {
417 d.rdynamic = true;
418 } else if (mem.eql(u8, arg, "-s")) {
419 d.strip = true;
420 } else if (mem.eql(u8, arg, "-nodefaultlibs")) {
421 d.nodefaultlibs = true;
422 } else if (mem.eql(u8, arg, "-nolibc")) {
423 d.nolibc = true;
424 } else if (mem.eql(u8, arg, "-nostdlib")) {
425 d.nostdlib = true;
426 } else if (mem.eql(u8, arg, "-nostartfiles")) {
427 d.nostartfiles = true;
428 } else if (option(arg, "--unwindlib=")) |unwindlib| {
429 const valid_unwindlibs: [5][]const u8 = .{ "", "none", "platform", "libunwind", "libgcc" };
430 for (valid_unwindlibs) |name| {
431 if (mem.eql(u8, name, unwindlib)) {
432 d.unwindlib = unwindlib;
433 break;
434 }
435 } else {
436 try d.comp.addDiagnostic(.{ .tag = .invalid_unwindlib, .extra = .{ .str = unwindlib } }, &.{});
437 }
438 } else {
439 try d.comp.addDiagnostic(.{ .tag = .cli_unknown_arg, .extra = .{ .str = arg } }, &.{});
440 }
441 } else if (std.mem.endsWith(u8, arg, ".o") or std.mem.endsWith(u8, arg, ".obj")) {
442 try d.link_objects.append(d.comp.gpa, arg);
443 } else {
444 const source = d.addSource(arg) catch |er| {
445 return d.fatal("unable to add source file '{s}': {s}", .{ arg, errorDescription(er) });
446 };
447 try d.inputs.append(d.comp.gpa, source);
448 }
449 }
450 if (d.comp.langopts.preserve_comments and !d.only_preprocess) {
451 return d.fatal("invalid argument '{s}' only allowed with '-E'", .{comment_arg});
452 }
453 if (hosted) |is_hosted| {
454 if (is_hosted) {
455 if (d.comp.target.os.tag == .freestanding) {
456 return d.fatal("Cannot use freestanding target with `-fhosted`", .{});
457 }
458 } else {
459 d.comp.target.os.tag = .freestanding;
460 }
461 }
462 return false;
463}
464
465fn option(arg: []const u8, name: []const u8) ?[]const u8 {
466 if (std.mem.startsWith(u8, arg, name) and arg.len > name.len) {
467 return arg[name.len..];
468 }
469 return null;
470}
471
472fn addSource(d: *Driver, path: []const u8) !Source {
473 if (mem.eql(u8, "-", path)) {
474 const stdin = std.io.getStdIn().reader();
475 const input = try stdin.readAllAlloc(d.comp.gpa, std.math.maxInt(u32));
476 defer d.comp.gpa.free(input);
477 return d.comp.addSourceFromBuffer("<stdin>", input);
478 }
479 return d.comp.addSourceFromPath(path);
480}
481
482pub fn err(d: *Driver, msg: []const u8) !void {
483 try d.comp.addDiagnostic(.{ .tag = .cli_error, .extra = .{ .str = msg } }, &.{});
484}
485
486pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {
487 try d.comp.diagnostics.list.append(d.comp.gpa, .{
488 .tag = .cli_error,
489 .kind = .@"fatal error",
490 .extra = .{ .str = try std.fmt.allocPrint(d.comp.diagnostics.arena.allocator(), fmt, args) },
491 });
492 return error.FatalError;
493}
494
495pub fn renderErrors(d: *Driver) void {
496 Diagnostics.render(d.comp, d.detectConfig(std.io.getStdErr()));
497}
498
499pub fn detectConfig(d: *Driver, file: std.fs.File) std.io.tty.Config {
500 if (d.color == true) return .escape_codes;
501 if (d.color == false) return .no_color;
502
503 if (file.supportsAnsiEscapeCodes()) return .escape_codes;
504 if (@import("builtin").os.tag == .windows and file.isTty()) {
505 var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
506 if (std.os.windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != std.os.windows.TRUE) {
507 return .no_color;
508 }
509 return .{ .windows_api = .{
510 .handle = file.handle,
511 .reset_attributes = info.wAttributes,
512 } };
513 }
514
515 return .no_color;
516}
517
518pub fn errorDescription(e: anyerror) []const u8 {
519 return switch (e) {
520 error.OutOfMemory => "ran out of memory",
521 error.FileNotFound => "file not found",
522 error.IsDir => "is a directory",
523 error.NotDir => "is not a directory",
524 error.NotOpenForReading => "file is not open for reading",
525 error.NotOpenForWriting => "file is not open for writing",
526 error.InvalidUtf8 => "path is not valid UTF-8",
527 error.InvalidWtf8 => "path is not valid WTF-8",
528 error.FileBusy => "file is busy",
529 error.NameTooLong => "file name is too long",
530 error.AccessDenied => "access denied",
531 error.FileTooBig => "file is too big",
532 error.ProcessFdQuotaExceeded, error.SystemFdQuotaExceeded => "ran out of file descriptors",
533 error.SystemResources => "ran out of system resources",
534 error.FatalError => "a fatal error occurred",
535 error.Unexpected => "an unexpected error occurred",
536 else => @errorName(e),
537 };
538}
539
540/// The entry point of the Aro compiler.
541/// **MAY call `exit` if `fast_exit` is set.**
542pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_exit: bool) !void {
543 var macro_buf = std.ArrayList(u8).init(d.comp.gpa);
544 defer macro_buf.deinit();
545
546 const std_out = std.io.getStdOut().writer();
547 if (try parseArgs(d, std_out, macro_buf.writer(), args)) return;
548
549 const linking = !(d.only_preprocess or d.only_syntax or d.only_compile or d.only_preprocess_and_compile);
550
551 if (d.inputs.items.len == 0) {
552 return d.fatal("no input files", .{});
553 } else if (d.inputs.items.len != 1 and d.output_name != null and !linking) {
554 return d.fatal("cannot specify -o when generating multiple output files", .{});
555 }
556
557 if (!linking) for (d.link_objects.items) |obj| {
558 try d.comp.addDiagnostic(.{ .tag = .cli_unused_link_object, .extra = .{ .str = obj } }, &.{});
559 };
560
561 d.comp.defineSystemIncludes(d.aro_name) catch |er| switch (er) {
562 error.OutOfMemory => return error.OutOfMemory,
563 error.AroIncludeNotFound => return d.fatal("unable to find Aro builtin headers", .{}),
564 };
565
566 const builtin = try d.comp.generateBuiltinMacros(d.system_defines);
567 const user_macros = try d.comp.addSourceFromBuffer("<command line>", macro_buf.items);
568
569 if (fast_exit and d.inputs.items.len == 1) {
570 d.processSource(tc, d.inputs.items[0], builtin, user_macros, fast_exit) catch |e| switch (e) {
571 error.FatalError => {
572 d.renderErrors();
573 d.exitWithCleanup(1);
574 },
575 else => |er| return er,
576 };
577 unreachable;
578 }
579
580 for (d.inputs.items) |source| {
581 d.processSource(tc, source, builtin, user_macros, fast_exit) catch |e| switch (e) {
582 error.FatalError => {
583 d.renderErrors();
584 },
585 else => |er| return er,
586 };
587 }
588 if (d.comp.diagnostics.errors != 0) {
589 if (fast_exit) d.exitWithCleanup(1);
590 return;
591 }
592 if (linking) {
593 try d.invokeLinker(tc, fast_exit);
594 }
595 if (fast_exit) std.process.exit(0);
596}
597
598fn processSource(
599 d: *Driver,
600 tc: *Toolchain,
601 source: Source,
602 builtin: Source,
603 user_macros: Source,
604 comptime fast_exit: bool,
605) !void {
606 d.comp.generated_buf.items.len = 0;
607 var pp = try Preprocessor.initDefault(d.comp);
608 defer pp.deinit();
609
610 if (d.comp.langopts.ms_extensions) {
611 d.comp.ms_cwd_source_id = source.id;
612 }
613
614 if (d.verbose_pp) pp.verbose = true;
615 if (d.only_preprocess) {
616 pp.preserve_whitespace = true;
617 if (d.line_commands) {
618 pp.linemarkers = if (d.use_line_directives) .line_directives else .numeric_directives;
619 }
620 }
621
622 try pp.preprocessSources(&.{ source, builtin, user_macros });
623
624 if (d.only_preprocess) {
625 d.renderErrors();
626
627 if (d.comp.diagnostics.errors != 0) {
628 if (fast_exit) std.process.exit(1); // Not linking, no need for cleanup.
629 return;
630 }
631
632 const file = if (d.output_name) |some|
633 std.fs.cwd().createFile(some, .{}) catch |er|
634 return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) })
635 else
636 std.io.getStdOut();
637 defer if (d.output_name != null) file.close();
638
639 var buf_w = std.io.bufferedWriter(file.writer());
640 pp.prettyPrintTokens(buf_w.writer()) catch |er|
641 return d.fatal("unable to write result: {s}", .{errorDescription(er)});
642
643 buf_w.flush() catch |er|
644 return d.fatal("unable to write result: {s}", .{errorDescription(er)});
645 if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
646 return;
647 }
648
649 var tree = try pp.parse();
650 defer tree.deinit();
651
652 if (d.verbose_ast) {
653 const stdout = std.io.getStdOut();
654 var buf_writer = std.io.bufferedWriter(stdout.writer());
655 tree.dump(d.detectConfig(stdout), buf_writer.writer()) catch {};
656 buf_writer.flush() catch {};
657 }
658
659 const prev_errors = d.comp.diagnostics.errors;
660 d.renderErrors();
661
662 if (d.comp.diagnostics.errors != prev_errors) {
663 if (fast_exit) d.exitWithCleanup(1);
664 return; // do not compile if there were errors
665 }
666
667 if (d.only_syntax) {
668 if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
669 return;
670 }
671
672 if (d.comp.target.ofmt != .elf or d.comp.target.cpu.arch != .x86_64) {
673 return d.fatal(
674 "unsupported target {s}-{s}-{s}, currently only x86-64 elf is supported",
675 .{ @tagName(d.comp.target.cpu.arch), @tagName(d.comp.target.os.tag), @tagName(d.comp.target.abi) },
676 );
677 }
678
679 var ir = try tree.genIr();
680 defer ir.deinit(d.comp.gpa);
681
682 if (d.verbose_ir) {
683 const stdout = std.io.getStdOut();
684 var buf_writer = std.io.bufferedWriter(stdout.writer());
685 ir.dump(d.comp.gpa, d.detectConfig(stdout), buf_writer.writer()) catch {};
686 buf_writer.flush() catch {};
687 }
688
689 var render_errors: Ir.Renderer.ErrorList = .{};
690 defer {
691 for (render_errors.values()) |msg| d.comp.gpa.free(msg);
692 render_errors.deinit(d.comp.gpa);
693 }
694
695 var obj = ir.render(d.comp.gpa, d.comp.target, &render_errors) catch |e| switch (e) {
696 error.OutOfMemory => return error.OutOfMemory,
697 error.LowerFail => {
698 return d.fatal(
699 "unable to render Ir to machine code: {s}",
700 .{render_errors.values()[0]},
701 );
702 },
703 };
704 defer obj.deinit();
705
706 // If it's used, name_buf will either hold a filename or `/tmp/<12 random bytes with base-64 encoding>.<extension>`
707 // both of which should fit into MAX_NAME_BYTES for all systems
708 var name_buf: [std.fs.MAX_NAME_BYTES]u8 = undefined;
709
710 const out_file_name = if (d.only_compile) blk: {
711 const fmt_template = "{s}{s}";
712 const fmt_args = .{
713 std.fs.path.stem(source.path),
714 d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
715 };
716 break :blk d.output_name orelse
717 std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
718 } else blk: {
719 const random_bytes_count = 12;
720 const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);
721
722 var random_bytes: [random_bytes_count]u8 = undefined;
723 std.crypto.random.bytes(&random_bytes);
724 var random_name: [sub_path_len]u8 = undefined;
725 _ = std.fs.base64_encoder.encode(&random_name, &random_bytes);
726
727 const fmt_template = "/tmp/{s}{s}";
728 const fmt_args = .{
729 random_name,
730 d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
731 };
732 break :blk std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
733 };
734
735 const out_file = std.fs.cwd().createFile(out_file_name, .{}) catch |er|
736 return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) });
737 defer out_file.close();
738
739 obj.finish(out_file) catch |er|
740 return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, errorDescription(er) });
741
742 if (d.only_compile) {
743 if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
744 return;
745 }
746 try d.link_objects.ensureUnusedCapacity(d.comp.gpa, 1);
747 d.link_objects.appendAssumeCapacity(try d.comp.gpa.dupe(u8, out_file_name));
748 d.temp_file_count += 1;
749 if (fast_exit) {
750 try d.invokeLinker(tc, fast_exit);
751 }
752}
753
754fn dumpLinkerArgs(items: []const []const u8) !void {
755 const stdout = std.io.getStdOut().writer();
756 for (items, 0..) |item, i| {
757 if (i > 0) try stdout.writeByte(' ');
758 try stdout.print("\"{}\"", .{std.zig.fmtEscapes(item)});
759 }
760 try stdout.writeByte('\n');
761}
762
763/// The entry point of the Aro compiler.
764/// **MAY call `exit` if `fast_exit` is set.**
765pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) !void {
766 try tc.discover();
767
768 var argv = std.ArrayList([]const u8).init(d.comp.gpa);
769 defer argv.deinit();
770
771 var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
772 const linker_path = try tc.getLinkerPath(&linker_path_buf);
773 try argv.append(linker_path);
774
775 try tc.buildLinkerArgs(&argv);
776
777 if (d.verbose_linker_args) {
778 dumpLinkerArgs(argv.items) catch |er| {
779 return d.fatal("unable to dump linker args: {s}", .{errorDescription(er)});
780 };
781 }
782 var child = std.ChildProcess.init(argv.items, d.comp.gpa);
783 // TODO handle better
784 child.stdin_behavior = .Inherit;
785 child.stdout_behavior = .Inherit;
786 child.stderr_behavior = .Inherit;
787
788 const term = child.spawnAndWait() catch |er| {
789 return d.fatal("unable to spawn linker: {s}", .{errorDescription(er)});
790 };
791 switch (term) {
792 .Exited => |code| if (code != 0) {
793 const e = d.fatal("linker exited with an error code", .{});
794 if (fast_exit) d.exitWithCleanup(code);
795 return e;
796 },
797 else => {
798 const e = d.fatal("linker crashed", .{});
799 if (fast_exit) d.exitWithCleanup(1);
800 return e;
801 },
802 }
803 if (fast_exit) d.exitWithCleanup(0);
804}
805
806fn exitWithCleanup(d: *Driver, code: u8) noreturn {
807 for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
808 std.fs.deleteFileAbsolute(obj) catch {};
809 }
810 std.process.exit(code);
811}
deps/aro/aro/Driver/Distro.zig deleted-328
......@@ -1,328 +0,0 @@
1//! Tools for figuring out what Linux distro we're running on
2
3const std = @import("std");
4const mem = std.mem;
5const Filesystem = @import("Filesystem.zig").Filesystem;
6
7const MAX_BYTES = 1024; // TODO: Can we assume 1024 bytes enough for the info we need?
8
9/// Value for linker `--hash-style=` argument
10pub const HashStyle = enum {
11 both,
12 gnu,
13};
14
15pub const Tag = enum {
16 alpine,
17 arch,
18 debian_lenny,
19 debian_squeeze,
20 debian_wheezy,
21 debian_jessie,
22 debian_stretch,
23 debian_buster,
24 debian_bullseye,
25 debian_bookworm,
26 debian_trixie,
27 exherbo,
28 rhel5,
29 rhel6,
30 rhel7,
31 fedora,
32 gentoo,
33 open_suse,
34 ubuntu_hardy,
35 ubuntu_intrepid,
36 ubuntu_jaunty,
37 ubuntu_karmic,
38 ubuntu_lucid,
39 ubuntu_maverick,
40 ubuntu_natty,
41 ubuntu_oneiric,
42 ubuntu_precise,
43 ubuntu_quantal,
44 ubuntu_raring,
45 ubuntu_saucy,
46 ubuntu_trusty,
47 ubuntu_utopic,
48 ubuntu_vivid,
49 ubuntu_wily,
50 ubuntu_xenial,
51 ubuntu_yakkety,
52 ubuntu_zesty,
53 ubuntu_artful,
54 ubuntu_bionic,
55 ubuntu_cosmic,
56 ubuntu_disco,
57 ubuntu_eoan,
58 ubuntu_focal,
59 ubuntu_groovy,
60 ubuntu_hirsute,
61 ubuntu_impish,
62 ubuntu_jammy,
63 ubuntu_kinetic,
64 ubuntu_lunar,
65 unknown,
66
67 pub fn getHashStyle(self: Tag) HashStyle {
68 if (self.isOpenSUSE()) return .both;
69 return switch (self) {
70 .ubuntu_lucid,
71 .ubuntu_jaunty,
72 .ubuntu_karmic,
73 => .both,
74 else => .gnu,
75 };
76 }
77
78 pub fn isRedhat(self: Tag) bool {
79 return switch (self) {
80 .fedora,
81 .rhel5,
82 .rhel6,
83 .rhel7,
84 => true,
85 else => false,
86 };
87 }
88
89 pub fn isOpenSUSE(self: Tag) bool {
90 return self == .open_suse;
91 }
92
93 pub fn isDebian(self: Tag) bool {
94 return switch (self) {
95 .debian_lenny,
96 .debian_squeeze,
97 .debian_wheezy,
98 .debian_jessie,
99 .debian_stretch,
100 .debian_buster,
101 .debian_bullseye,
102 .debian_bookworm,
103 .debian_trixie,
104 => true,
105 else => false,
106 };
107 }
108 pub fn isUbuntu(self: Tag) bool {
109 return switch (self) {
110 .ubuntu_hardy,
111 .ubuntu_intrepid,
112 .ubuntu_jaunty,
113 .ubuntu_karmic,
114 .ubuntu_lucid,
115 .ubuntu_maverick,
116 .ubuntu_natty,
117 .ubuntu_oneiric,
118 .ubuntu_precise,
119 .ubuntu_quantal,
120 .ubuntu_raring,
121 .ubuntu_saucy,
122 .ubuntu_trusty,
123 .ubuntu_utopic,
124 .ubuntu_vivid,
125 .ubuntu_wily,
126 .ubuntu_xenial,
127 .ubuntu_yakkety,
128 .ubuntu_zesty,
129 .ubuntu_artful,
130 .ubuntu_bionic,
131 .ubuntu_cosmic,
132 .ubuntu_disco,
133 .ubuntu_eoan,
134 .ubuntu_focal,
135 .ubuntu_groovy,
136 .ubuntu_hirsute,
137 .ubuntu_impish,
138 .ubuntu_jammy,
139 .ubuntu_kinetic,
140 .ubuntu_lunar,
141 => true,
142
143 else => false,
144 };
145 }
146 pub fn isAlpine(self: Tag) bool {
147 return self == .alpine;
148 }
149 pub fn isGentoo(self: Tag) bool {
150 return self == .gentoo;
151 }
152};
153
154fn scanForOsRelease(buf: []const u8) ?Tag {
155 var it = mem.splitScalar(u8, buf, '\n');
156 while (it.next()) |line| {
157 if (mem.startsWith(u8, line, "ID=")) {
158 const rest = line["ID=".len..];
159 if (mem.eql(u8, rest, "alpine")) return .alpine;
160 if (mem.eql(u8, rest, "fedora")) return .fedora;
161 if (mem.eql(u8, rest, "gentoo")) return .gentoo;
162 if (mem.eql(u8, rest, "arch")) return .arch;
163 if (mem.eql(u8, rest, "sles")) return .open_suse;
164 if (mem.eql(u8, rest, "opensuse")) return .open_suse;
165 if (mem.eql(u8, rest, "exherbo")) return .exherbo;
166 }
167 }
168 return null;
169}
170
171fn detectOsRelease(fs: Filesystem) ?Tag {
172 var buf: [MAX_BYTES]u8 = undefined;
173 const data = fs.readFile("/etc/os-release", &buf) orelse fs.readFile("/usr/lib/os-release", &buf) orelse return null;
174 return scanForOsRelease(data);
175}
176
177fn scanForLSBRelease(buf: []const u8) ?Tag {
178 var it = mem.splitScalar(u8, buf, '\n');
179 while (it.next()) |line| {
180 if (mem.startsWith(u8, line, "DISTRIB_CODENAME=")) {
181 const rest = line["DISTRIB_CODENAME=".len..];
182 if (mem.eql(u8, rest, "hardy")) return .ubuntu_hardy;
183 if (mem.eql(u8, rest, "intrepid")) return .ubuntu_intrepid;
184 if (mem.eql(u8, rest, "jaunty")) return .ubuntu_jaunty;
185 if (mem.eql(u8, rest, "karmic")) return .ubuntu_karmic;
186 if (mem.eql(u8, rest, "lucid")) return .ubuntu_lucid;
187 if (mem.eql(u8, rest, "maverick")) return .ubuntu_maverick;
188 if (mem.eql(u8, rest, "natty")) return .ubuntu_natty;
189 if (mem.eql(u8, rest, "oneiric")) return .ubuntu_oneiric;
190 if (mem.eql(u8, rest, "precise")) return .ubuntu_precise;
191 if (mem.eql(u8, rest, "quantal")) return .ubuntu_quantal;
192 if (mem.eql(u8, rest, "raring")) return .ubuntu_raring;
193 if (mem.eql(u8, rest, "saucy")) return .ubuntu_saucy;
194 if (mem.eql(u8, rest, "trusty")) return .ubuntu_trusty;
195 if (mem.eql(u8, rest, "utopic")) return .ubuntu_utopic;
196 if (mem.eql(u8, rest, "vivid")) return .ubuntu_vivid;
197 if (mem.eql(u8, rest, "wily")) return .ubuntu_wily;
198 if (mem.eql(u8, rest, "xenial")) return .ubuntu_xenial;
199 if (mem.eql(u8, rest, "yakkety")) return .ubuntu_yakkety;
200 if (mem.eql(u8, rest, "zesty")) return .ubuntu_zesty;
201 if (mem.eql(u8, rest, "artful")) return .ubuntu_artful;
202 if (mem.eql(u8, rest, "bionic")) return .ubuntu_bionic;
203 if (mem.eql(u8, rest, "cosmic")) return .ubuntu_cosmic;
204 if (mem.eql(u8, rest, "disco")) return .ubuntu_disco;
205 if (mem.eql(u8, rest, "eoan")) return .ubuntu_eoan;
206 if (mem.eql(u8, rest, "focal")) return .ubuntu_focal;
207 if (mem.eql(u8, rest, "groovy")) return .ubuntu_groovy;
208 if (mem.eql(u8, rest, "hirsute")) return .ubuntu_hirsute;
209 if (mem.eql(u8, rest, "impish")) return .ubuntu_impish;
210 if (mem.eql(u8, rest, "jammy")) return .ubuntu_jammy;
211 if (mem.eql(u8, rest, "kinetic")) return .ubuntu_kinetic;
212 if (mem.eql(u8, rest, "lunar")) return .ubuntu_lunar;
213 }
214 }
215 return null;
216}
217
218fn detectLSBRelease(fs: Filesystem) ?Tag {
219 var buf: [MAX_BYTES]u8 = undefined;
220 const data = fs.readFile("/etc/lsb-release", &buf) orelse return null;
221
222 return scanForLSBRelease(data);
223}
224
225fn scanForRedHat(buf: []const u8) Tag {
226 if (mem.startsWith(u8, buf, "Fedora release")) return .fedora;
227 if (mem.startsWith(u8, buf, "Red Hat Enterprise Linux") or mem.startsWith(u8, buf, "CentOS") or mem.startsWith(u8, buf, "Scientific Linux")) {
228 if (mem.indexOfPos(u8, buf, 0, "release 7") != null) return .rhel7;
229 if (mem.indexOfPos(u8, buf, 0, "release 6") != null) return .rhel6;
230 if (mem.indexOfPos(u8, buf, 0, "release 5") != null) return .rhel5;
231 }
232
233 return .unknown;
234}
235
236fn detectRedhat(fs: Filesystem) ?Tag {
237 var buf: [MAX_BYTES]u8 = undefined;
238 const data = fs.readFile("/etc/redhat-release", &buf) orelse return null;
239 return scanForRedHat(data);
240}
241
242fn scanForDebian(buf: []const u8) Tag {
243 var it = mem.splitScalar(u8, buf, '.');
244 if (std.fmt.parseInt(u8, it.next().?, 10)) |major| {
245 return switch (major) {
246 5 => .debian_lenny,
247 6 => .debian_squeeze,
248 7 => .debian_wheezy,
249 8 => .debian_jessie,
250 9 => .debian_stretch,
251 10 => .debian_buster,
252 11 => .debian_bullseye,
253 12 => .debian_bookworm,
254 13 => .debian_trixie,
255 else => .unknown,
256 };
257 } else |_| {}
258
259 it = mem.splitScalar(u8, buf, '\n');
260 const name = it.next().?;
261 if (mem.eql(u8, name, "squeeze/sid")) return .debian_squeeze;
262 if (mem.eql(u8, name, "wheezy/sid")) return .debian_wheezy;
263 if (mem.eql(u8, name, "jessie/sid")) return .debian_jessie;
264 if (mem.eql(u8, name, "stretch/sid")) return .debian_stretch;
265 if (mem.eql(u8, name, "buster/sid")) return .debian_buster;
266 if (mem.eql(u8, name, "bullseye/sid")) return .debian_bullseye;
267 if (mem.eql(u8, name, "bookworm/sid")) return .debian_bookworm;
268
269 return .unknown;
270}
271
272fn detectDebian(fs: Filesystem) ?Tag {
273 var buf: [MAX_BYTES]u8 = undefined;
274 const data = fs.readFile("/etc/debian_version", &buf) orelse return null;
275 return scanForDebian(data);
276}
277
278pub fn detect(target: std.Target, fs: Filesystem) Tag {
279 if (target.os.tag != .linux) return .unknown;
280
281 if (detectOsRelease(fs)) |tag| return tag;
282 if (detectLSBRelease(fs)) |tag| return tag;
283 if (detectRedhat(fs)) |tag| return tag;
284 if (detectDebian(fs)) |tag| return tag;
285
286 if (fs.exists("/etc/gentoo-release")) return .gentoo;
287
288 return .unknown;
289}
290
291test scanForDebian {
292 try std.testing.expectEqual(Tag.debian_squeeze, scanForDebian("squeeze/sid"));
293 try std.testing.expectEqual(Tag.debian_bullseye, scanForDebian("11.1.2"));
294 try std.testing.expectEqual(Tag.unknown, scanForDebian("None"));
295 try std.testing.expectEqual(Tag.unknown, scanForDebian(""));
296}
297
298test scanForRedHat {
299 try std.testing.expectEqual(Tag.fedora, scanForRedHat("Fedora release 7"));
300 try std.testing.expectEqual(Tag.rhel7, scanForRedHat("Red Hat Enterprise Linux release 7"));
301 try std.testing.expectEqual(Tag.rhel5, scanForRedHat("CentOS release 5"));
302 try std.testing.expectEqual(Tag.unknown, scanForRedHat("CentOS release 4"));
303 try std.testing.expectEqual(Tag.unknown, scanForRedHat(""));
304}
305
306test scanForLSBRelease {
307 const text =
308 \\DISTRIB_ID=Ubuntu
309 \\DISTRIB_RELEASE=20.04
310 \\DISTRIB_CODENAME=focal
311 \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
312 \\
313 ;
314 try std.testing.expectEqual(Tag.ubuntu_focal, scanForLSBRelease(text).?);
315}
316
317test scanForOsRelease {
318 const text =
319 \\NAME="Alpine Linux"
320 \\ID=alpine
321 \\VERSION_ID=3.18.2
322 \\PRETTY_NAME="Alpine Linux v3.18"
323 \\HOME_URL="https://alpinelinux.org/"
324 \\BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
325 \\
326 ;
327 try std.testing.expectEqual(Tag.alpine, scanForOsRelease(text).?);
328}
deps/aro/aro/Driver/Filesystem.zig deleted-239
......@@ -1,239 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const builtin = @import("builtin");
4const is_windows = builtin.os.tag == .windows;
5
6fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 {
7 @setCold(true);
8 for (entries) |entry| {
9 if (mem.eql(u8, entry.path, path)) {
10 const len = @min(entry.contents.len, buf.len);
11 @memcpy(buf[0..len], entry.contents[0..len]);
12 return buf[0..len];
13 }
14 }
15 return null;
16}
17
18fn findProgramByNameFake(entries: []const Filesystem.Entry, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
19 @setCold(true);
20 if (mem.indexOfScalar(u8, name, '/') != null) {
21 @memcpy(buf[0..name.len], name);
22 return buf[0..name.len];
23 }
24 const path_env = path orelse return null;
25 var fib = std.heap.FixedBufferAllocator.init(buf);
26
27 var it = mem.tokenizeScalar(u8, path_env, std.fs.path.delimiter);
28 while (it.next()) |path_dir| {
29 defer fib.reset();
30 const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
31 if (canExecuteFake(entries, full_path)) return full_path;
32 }
33
34 return null;
35}
36
37fn canExecuteFake(entries: []const Filesystem.Entry, path: []const u8) bool {
38 @setCold(true);
39 for (entries) |entry| {
40 if (mem.eql(u8, entry.path, path)) {
41 return entry.executable;
42 }
43 }
44 return false;
45}
46
47fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool {
48 @setCold(true);
49 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
50 var fib = std.heap.FixedBufferAllocator.init(&buf);
51 const resolved = std.fs.path.resolvePosix(fib.allocator(), &.{path}) catch return false;
52 for (entries) |entry| {
53 if (mem.eql(u8, entry.path, resolved)) return true;
54 }
55 return false;
56}
57
58fn canExecutePosix(path: []const u8) bool {
59 std.os.access(path, std.os.X_OK) catch return false;
60 // Todo: ensure path is not a directory
61 return true;
62}
63
64/// TODO
65fn canExecuteWindows(path: []const u8) bool {
66 _ = path;
67 return true;
68}
69
70/// TODO
71fn findProgramByNameWindows(allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
72 _ = path;
73 _ = buf;
74 _ = name;
75 _ = allocator;
76 return null;
77}
78
79/// TODO: does WASI need special handling?
80fn findProgramByNamePosix(name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
81 if (mem.indexOfScalar(u8, name, '/') != null) {
82 @memcpy(buf[0..name.len], name);
83 return buf[0..name.len];
84 }
85 const path_env = path orelse return null;
86 var fib = std.heap.FixedBufferAllocator.init(buf);
87
88 var it = mem.tokenizeScalar(u8, path_env, std.fs.path.delimiter);
89 while (it.next()) |path_dir| {
90 defer fib.reset();
91 const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
92 if (canExecutePosix(full_path)) return full_path;
93 }
94
95 return null;
96}
97
98pub const Filesystem = union(enum) {
99 real: void,
100 fake: []const Entry,
101
102 const Entry = struct {
103 path: []const u8,
104 contents: []const u8 = "",
105 executable: bool = false,
106 };
107
108 const FakeDir = struct {
109 entries: []const Entry,
110 path: []const u8,
111
112 fn iterate(self: FakeDir) FakeDir.Iterator {
113 return .{
114 .entries = self.entries,
115 .base = self.path,
116 };
117 }
118
119 const Iterator = struct {
120 entries: []const Entry,
121 base: []const u8,
122 i: usize = 0,
123
124 fn next(self: *@This()) !?std.fs.Dir.Entry {
125 while (self.i < self.entries.len) {
126 const entry = self.entries[self.i];
127 self.i += 1;
128 if (entry.path.len == self.base.len) continue;
129 if (std.mem.startsWith(u8, entry.path, self.base)) {
130 const remaining = entry.path[self.base.len + 1 ..];
131 if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue;
132 const extension = std.fs.path.extension(remaining);
133 const kind: std.fs.Dir.Entry.Kind = if (extension.len == 0) .directory else .file;
134 return .{ .name = remaining, .kind = kind };
135 }
136 }
137 return null;
138 }
139 };
140 };
141
142 const Dir = union(enum) {
143 dir: std.fs.Dir,
144 fake: FakeDir,
145
146 pub fn iterate(self: Dir) Iterator {
147 return switch (self) {
148 .dir => |dir| .{ .iterator = dir.iterate() },
149 .fake => |fake| .{ .fake = fake.iterate() },
150 };
151 }
152
153 pub fn close(self: *Dir) void {
154 switch (self.*) {
155 .dir => |*d| d.close(),
156 .fake => {},
157 }
158 }
159 };
160
161 const Iterator = union(enum) {
162 iterator: std.fs.Dir.Iterator,
163 fake: FakeDir.Iterator,
164
165 pub fn next(self: *Iterator) std.fs.Dir.Iterator.Error!?std.fs.Dir.Entry {
166 return switch (self.*) {
167 .iterator => |*it| it.next(),
168 .fake => |*it| it.next(),
169 };
170 }
171 };
172
173 pub fn exists(fs: Filesystem, path: []const u8) bool {
174 switch (fs) {
175 .real => {
176 std.os.access(path, std.os.F_OK) catch return false;
177 return true;
178 },
179 .fake => |paths| return existsFake(paths, path),
180 }
181 }
182
183 pub fn joinedExists(fs: Filesystem, parts: []const []const u8) bool {
184 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
185 var fib = std.heap.FixedBufferAllocator.init(&buf);
186 const joined = std.fs.path.join(fib.allocator(), parts) catch return false;
187 return fs.exists(joined);
188 }
189
190 pub fn canExecute(fs: Filesystem, path: []const u8) bool {
191 return switch (fs) {
192 .real => if (is_windows) canExecuteWindows(path) else canExecutePosix(path),
193 .fake => |entries| canExecuteFake(entries, path),
194 };
195 }
196
197 /// Search for an executable named `name` using platform-specific logic
198 /// If it's found, write the full path to `buf` and return a slice of it
199 /// Otherwise retun null
200 pub fn findProgramByName(fs: Filesystem, allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
201 std.debug.assert(name.len > 0);
202 return switch (fs) {
203 .real => if (is_windows) findProgramByNameWindows(allocator, name, path, buf) else findProgramByNamePosix(name, path, buf),
204 .fake => |entries| findProgramByNameFake(entries, name, path, buf),
205 };
206 }
207
208 /// Read the file at `path` into `buf`.
209 /// Returns null if any errors are encountered
210 /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned
211 pub fn readFile(fs: Filesystem, path: []const u8, buf: []u8) ?[]const u8 {
212 return switch (fs) {
213 .real => {
214 const file = std.fs.cwd().openFile(path, .{}) catch return null;
215 defer file.close();
216
217 const bytes_read = file.readAll(buf) catch return null;
218 return buf[0..bytes_read];
219 },
220 .fake => |entries| readFileFake(entries, path, buf),
221 };
222 }
223
224 pub fn openDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!Dir {
225 return switch (fs) {
226 .real => .{ .dir = try std.fs.cwd().openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) },
227 .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },
228 };
229 }
230};
231
232test "Fake filesystem" {
233 const fs: Filesystem = .{ .fake = &.{
234 .{ .path = "/usr/bin" },
235 } };
236 try std.testing.expect(fs.exists("/usr/bin"));
237 try std.testing.expect(fs.exists("/usr/bin/foo/.."));
238 try std.testing.expect(!fs.exists("/usr/bin/bar"));
239}
deps/aro/aro/Driver/GCCDetector.zig deleted-638
......@@ -1,638 +0,0 @@
1const std = @import("std");
2const Toolchain = @import("../Toolchain.zig");
3const target_util = @import("../target.zig");
4const system_defaults = @import("system_defaults");
5const GCCVersion = @import("GCCVersion.zig");
6const Multilib = @import("Multilib.zig");
7
8const GCCDetector = @This();
9
10is_valid: bool = false,
11install_path: []const u8 = "",
12parent_lib_path: []const u8 = "",
13version: GCCVersion = .{},
14gcc_triple: []const u8 = "",
15selected: Multilib = .{},
16biarch_sibling: ?Multilib = null,
17
18pub fn deinit(self: *GCCDetector) void {
19 if (!self.is_valid) return;
20}
21
22pub fn appendToolPath(self: *const GCCDetector, tc: *Toolchain) !void {
23 if (!self.is_valid) return;
24 return tc.addPathFromComponents(&.{
25 self.parent_lib_path,
26 "..",
27 self.gcc_triple,
28 "bin",
29 }, .program);
30}
31
32fn addDefaultGCCPrefixes(prefixes: *std.ArrayListUnmanaged([]const u8), tc: *const Toolchain) !void {
33 const sysroot = tc.getSysroot();
34 const target = tc.getTarget();
35 if (sysroot.len == 0 and target.os.tag == .linux and tc.filesystem.exists("/opt/rh")) {
36 prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-12/root/usr");
37 prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-11/root/usr");
38 prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-10/root/usr");
39 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-12/root/usr");
40 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-11/root/usr");
41 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-10/root/usr");
42 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-9/root/usr");
43 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-8/root/usr");
44 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-7/root/usr");
45 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-6/root/usr");
46 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-4/root/usr");
47 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-3/root/usr");
48 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-2/root/usr");
49 }
50 if (sysroot.len == 0) {
51 prefixes.appendAssumeCapacity("/usr");
52 } else {
53 var usr_path = try tc.arena.alloc(u8, 4 + sysroot.len);
54 @memcpy(usr_path[0..4], "/usr");
55 @memcpy(usr_path[4..], sysroot);
56 prefixes.appendAssumeCapacity(usr_path);
57 }
58}
59
60fn collectLibDirsAndTriples(
61 tc: *Toolchain,
62 lib_dirs: *std.ArrayListUnmanaged([]const u8),
63 triple_aliases: *std.ArrayListUnmanaged([]const u8),
64 biarch_libdirs: *std.ArrayListUnmanaged([]const u8),
65 biarch_triple_aliases: *std.ArrayListUnmanaged([]const u8),
66) !void {
67 const AArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
68 const AArch64Triples: [4][]const u8 = .{ "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux" };
69 const AArch64beLibDirs: [1][]const u8 = .{"/lib"};
70 const AArch64beTriples: [2][]const u8 = .{ "aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu" };
71
72 const ARMLibDirs: [1][]const u8 = .{"/lib"};
73 const ARMTriples: [1][]const u8 = .{"arm-linux-gnueabi"};
74 const ARMHFTriples: [4][]const u8 = .{ "arm-linux-gnueabihf", "armv7hl-redhat-linux-gnueabi", "armv6hl-suse-linux-gnueabi", "armv7hl-suse-linux-gnueabi" };
75
76 const ARMebLibDirs: [1][]const u8 = .{"/lib"};
77 const ARMebTriples: [1][]const u8 = .{"armeb-linux-gnueabi"};
78 const ARMebHFTriples: [2][]const u8 = .{ "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi" };
79
80 const AVRLibDirs: [1][]const u8 = .{"/lib"};
81 const AVRTriples: [1][]const u8 = .{"avr"};
82
83 const CSKYLibDirs: [1][]const u8 = .{"/lib"};
84 const CSKYTriples: [3][]const u8 = .{ "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2" };
85
86 const X86_64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
87 const X86_64Triples: [11][]const u8 = .{
88 "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",
89 "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",
90 "x86_64-redhat-linux", "x86_64-suse-linux",
91 "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
92 "x86_64-slackware-linux", "x86_64-unknown-linux",
93 "x86_64-amazon-linux",
94 };
95 const X32Triples: [2][]const u8 = .{ "x86_64-linux-gnux32", "x86_64-pc-linux-gnux32" };
96 const X32LibDirs: [2][]const u8 = .{ "/libx32", "/lib" };
97 const X86LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
98 const X86Triples: [9][]const u8 = .{
99 "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu",
100 "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux",
101 "i586-suse-linux", "i686-montavista-linux", "i686-gnu",
102 };
103
104 const LoongArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
105 const LoongArch64Triples: [2][]const u8 = .{ "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu" };
106
107 const M68kLibDirs: [1][]const u8 = .{"/lib"};
108 const M68kTriples: [3][]const u8 = .{ "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux" };
109
110 const MIPSLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
111 const MIPSTriples: [5][]const u8 = .{
112 "mips-linux-gnu", "mips-mti-linux",
113 "mips-mti-linux-gnu", "mips-img-linux-gnu",
114 "mipsisa32r6-linux-gnu",
115 };
116 const MIPSELLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
117 const MIPSELTriples: [3][]const u8 = .{ "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu" };
118
119 const MIPS64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
120 const MIPS64Triples: [6][]const u8 = .{
121 "mips64-linux-gnu", "mips-mti-linux-gnu",
122 "mips-img-linux-gnu", "mips64-linux-gnuabi64",
123 "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64",
124 };
125 const MIPS64ELLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
126 const MIPS64ELTriples: [6][]const u8 = .{
127 "mips64el-linux-gnu", "mips-mti-linux-gnu",
128 "mips-img-linux-gnu", "mips64el-linux-gnuabi64",
129 "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64",
130 };
131
132 const MIPSN32LibDirs: [1][]const u8 = .{"/lib32"};
133 const MIPSN32Triples: [2][]const u8 = .{ "mips64-linux-gnuabin32", "mipsisa64r6-linux-gnuabin32" };
134 const MIPSN32ELLibDirs: [1][]const u8 = .{"/lib32"};
135 const MIPSN32ELTriples: [2][]const u8 = .{ "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32" };
136
137 const MSP430LibDirs: [1][]const u8 = .{"/lib"};
138 const MSP430Triples: [1][]const u8 = .{"msp430-elf"};
139
140 const PPCLibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
141 const PPCTriples: [5][]const u8 = .{
142 "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
143 // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
144 // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".
145 "powerpc64-suse-linux", "powerpc-montavista-linuxspe",
146 };
147 const PPCLELibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
148 const PPCLETriples: [3][]const u8 = .{ "powerpcle-linux-gnu", "powerpcle-unknown-linux-gnu", "powerpcle-linux-musl" };
149
150 const PPC64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
151 const PPC64Triples: [4][]const u8 = .{
152 "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
153 "powerpc64-suse-linux", "ppc64-redhat-linux",
154 };
155 const PPC64LELibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
156 const PPC64LETriples: [5][]const u8 = .{
157 "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
158 "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux",
159 "ppc64le-redhat-linux",
160 };
161
162 const RISCV32LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
163 const RISCV32Triples: [3][]const u8 = .{ "riscv32-unknown-linux-gnu", "riscv32-linux-gnu", "riscv32-unknown-elf" };
164 const RISCV64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
165 const RISCV64Triples: [3][]const u8 = .{
166 "riscv64-unknown-linux-gnu",
167 "riscv64-linux-gnu",
168 "riscv64-unknown-elf",
169 };
170
171 const SPARCv8LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
172 const SPARCv8Triples: [2][]const u8 = .{ "sparc-linux-gnu", "sparcv8-linux-gnu" };
173 const SPARCv9LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
174 const SPARCv9Triples: [2][]const u8 = .{ "sparc64-linux-gnu", "sparcv9-linux-gnu" };
175
176 const SystemZLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
177 const SystemZTriples: [5][]const u8 = .{
178 "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
179 "s390x-suse-linux", "s390x-redhat-linux",
180 };
181 const target = tc.getTarget();
182 if (target.os.tag == .solaris) {
183 // TODO
184 return;
185 }
186 if (target.isAndroid()) {
187 const AArch64AndroidTriples: [1][]const u8 = .{"aarch64-linux-android"};
188 const ARMAndroidTriples: [1][]const u8 = .{"arm-linux-androideabi"};
189 const MIPSELAndroidTriples: [1][]const u8 = .{"mipsel-linux-android"};
190 const MIPS64ELAndroidTriples: [1][]const u8 = .{"mips64el-linux-android"};
191 const X86AndroidTriples: [1][]const u8 = .{"i686-linux-android"};
192 const X86_64AndroidTriples: [1][]const u8 = .{"x86_64-linux-android"};
193
194 switch (target.cpu.arch) {
195 .aarch64 => {
196 lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
197 triple_aliases.appendSliceAssumeCapacity(&AArch64AndroidTriples);
198 },
199 .arm,
200 .thumb,
201 => {
202 lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
203 triple_aliases.appendSliceAssumeCapacity(&ARMAndroidTriples);
204 },
205 .mipsel => {
206 lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
207 triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
208 biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
209 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
210 },
211 .mips64el => {
212 lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
213 triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
214 biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
215 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
216 },
217 .x86_64 => {
218 lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
219 triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
220 biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
221 biarch_triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
222 },
223 .x86 => {
224 lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
225 triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
226 biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
227 biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
228 },
229 else => {},
230 }
231 return;
232 }
233 switch (target.cpu.arch) {
234 .aarch64 => {
235 lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
236 triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
237 biarch_libdirs.appendSliceAssumeCapacity(&AArch64LibDirs);
238 biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
239 },
240 .aarch64_be => {
241 lib_dirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
242 triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
243 biarch_libdirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
244 biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
245 },
246 .arm, .thumb => {
247 lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
248 if (target.abi == .gnueabihf) {
249 triple_aliases.appendSliceAssumeCapacity(&ARMHFTriples);
250 } else {
251 triple_aliases.appendSliceAssumeCapacity(&ARMTriples);
252 }
253 },
254 .armeb, .thumbeb => {
255 lib_dirs.appendSliceAssumeCapacity(&ARMebLibDirs);
256 if (target.abi == .gnueabihf) {
257 triple_aliases.appendSliceAssumeCapacity(&ARMebHFTriples);
258 } else {
259 triple_aliases.appendSliceAssumeCapacity(&ARMebTriples);
260 }
261 },
262 .avr => {
263 lib_dirs.appendSliceAssumeCapacity(&AVRLibDirs);
264 triple_aliases.appendSliceAssumeCapacity(&AVRTriples);
265 },
266 .csky => {
267 lib_dirs.appendSliceAssumeCapacity(&CSKYLibDirs);
268 triple_aliases.appendSliceAssumeCapacity(&CSKYTriples);
269 },
270 .x86_64 => {
271 if (target.abi == .gnux32 or target.abi == .muslx32) {
272 lib_dirs.appendSliceAssumeCapacity(&X32LibDirs);
273 triple_aliases.appendSliceAssumeCapacity(&X32Triples);
274 biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
275 biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
276 } else {
277 lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
278 triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
279 biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
280 biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
281 }
282 biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
283 biarch_triple_aliases.appendSliceAssumeCapacity(&X86Triples);
284 },
285 .x86 => {
286 lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
287 // MCU toolchain is 32 bit only and its triple alias is TargetTriple
288 // itself, which will be appended below.
289 if (target.os.tag != .elfiamcu) {
290 triple_aliases.appendSliceAssumeCapacity(&X86Triples);
291 biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
292 biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
293 biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
294 biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
295 }
296 },
297 .loongarch64 => {
298 lib_dirs.appendSliceAssumeCapacity(&LoongArch64LibDirs);
299 triple_aliases.appendSliceAssumeCapacity(&LoongArch64Triples);
300 },
301 .m68k => {
302 lib_dirs.appendSliceAssumeCapacity(&M68kLibDirs);
303 triple_aliases.appendSliceAssumeCapacity(&M68kTriples);
304 },
305 .mips => {
306 lib_dirs.appendSliceAssumeCapacity(&MIPSLibDirs);
307 triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
308 biarch_libdirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
309 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
310 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
311 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
312 },
313 .mipsel => {
314 lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
315 triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
316 triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
317 biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
318 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
319 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
320 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
321 },
322 .mips64 => {
323 lib_dirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
324 triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
325 biarch_libdirs.appendSliceAssumeCapacity(&MIPSLibDirs);
326 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
327 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
328 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
329 },
330 .mips64el => {
331 lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
332 triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
333 biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
334 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
335 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
336 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
337 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
338 },
339 .msp430 => {
340 lib_dirs.appendSliceAssumeCapacity(&MSP430LibDirs);
341 triple_aliases.appendSliceAssumeCapacity(&MSP430Triples);
342 },
343 .powerpc => {
344 lib_dirs.appendSliceAssumeCapacity(&PPCLibDirs);
345 triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
346 biarch_libdirs.appendSliceAssumeCapacity(&PPC64LibDirs);
347 biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
348 },
349 .powerpcle => {
350 lib_dirs.appendSliceAssumeCapacity(&PPCLELibDirs);
351 triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
352 biarch_libdirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
353 biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
354 },
355 .powerpc64 => {
356 lib_dirs.appendSliceAssumeCapacity(&PPC64LibDirs);
357 triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
358 biarch_libdirs.appendSliceAssumeCapacity(&PPCLibDirs);
359 biarch_triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
360 },
361 .powerpc64le => {
362 lib_dirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
363 triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
364 biarch_libdirs.appendSliceAssumeCapacity(&PPCLELibDirs);
365 biarch_triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
366 },
367 .riscv32 => {
368 lib_dirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
369 triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
370 biarch_libdirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
371 biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
372 },
373 .riscv64 => {
374 lib_dirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
375 triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
376 biarch_libdirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
377 biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
378 },
379 .sparc, .sparcel => {
380 lib_dirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
381 triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
382 biarch_libdirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
383 biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
384 },
385 .sparc64 => {
386 lib_dirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
387 triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
388 biarch_libdirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
389 biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
390 },
391 .s390x => {
392 lib_dirs.appendSliceAssumeCapacity(&SystemZLibDirs);
393 triple_aliases.appendSliceAssumeCapacity(&SystemZTriples);
394 },
395 else => {},
396 }
397}
398
399pub fn discover(self: *GCCDetector, tc: *Toolchain) !void {
400 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
401 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
402
403 const target = tc.getTarget();
404 const biarch_variant_target = if (target.ptrBitWidth() == 32)
405 target_util.get64BitArchVariant(target)
406 else
407 target_util.get32BitArchVariant(target);
408
409 var candidate_lib_dirs_buffer: [16][]const u8 = undefined;
410 var candidate_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_lib_dirs_buffer);
411
412 var candidate_triple_aliases_buffer: [16][]const u8 = undefined;
413 var candidate_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_triple_aliases_buffer);
414
415 var candidate_biarch_lib_dirs_buffer: [16][]const u8 = undefined;
416 var candidate_biarch_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_lib_dirs_buffer);
417
418 var candidate_biarch_triple_aliases_buffer: [16][]const u8 = undefined;
419 var candidate_biarch_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_triple_aliases_buffer);
420
421 try collectLibDirsAndTriples(
422 tc,
423 &candidate_lib_dirs,
424 &candidate_triple_aliases,
425 &candidate_biarch_lib_dirs,
426 &candidate_biarch_triple_aliases,
427 );
428
429 var target_buf: [64]u8 = undefined;
430 const triple_str = target_util.toLLVMTriple(target, &target_buf);
431 candidate_triple_aliases.appendAssumeCapacity(triple_str);
432
433 // Also include the multiarch variant if it's different.
434 var biarch_buf: [64]u8 = undefined;
435 if (biarch_variant_target) |biarch_target| {
436 const biarch_triple_str = target_util.toLLVMTriple(biarch_target, &biarch_buf);
437 if (!std.mem.eql(u8, biarch_triple_str, triple_str)) {
438 candidate_triple_aliases.appendAssumeCapacity(biarch_triple_str);
439 }
440 }
441
442 var prefixes_buf: [16][]const u8 = undefined;
443 var prefixes = std.ArrayListUnmanaged([]const u8).initBuffer(&prefixes_buf);
444 const gcc_toolchain_dir = gccToolchainDir(tc);
445 if (gcc_toolchain_dir.len != 0) {
446 const adjusted = if (gcc_toolchain_dir[gcc_toolchain_dir.len - 1] == '/')
447 gcc_toolchain_dir[0 .. gcc_toolchain_dir.len - 1]
448 else
449 gcc_toolchain_dir;
450 prefixes.appendAssumeCapacity(adjusted);
451 } else {
452 const sysroot = tc.getSysroot();
453 if (sysroot.len > 0) {
454 prefixes.appendAssumeCapacity(sysroot);
455 try addDefaultGCCPrefixes(&prefixes, tc);
456 }
457
458 if (sysroot.len == 0) {
459 try addDefaultGCCPrefixes(&prefixes, tc);
460 }
461 // TODO: Special-case handling for Gentoo
462 }
463
464 const v0 = GCCVersion.parse("0.0.0");
465 for (prefixes.items) |prefix| {
466 if (!tc.filesystem.exists(prefix)) continue;
467
468 for (candidate_lib_dirs.items) |suffix| {
469 defer fib.reset();
470 const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
471 if (!tc.filesystem.exists(lib_dir)) continue;
472
473 const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
474 const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
475
476 try self.scanLibDirForGCCTriple(tc, target, lib_dir, triple_str, false, gcc_dir_exists, gcc_cross_dir_exists);
477 for (candidate_triple_aliases.items) |candidate| {
478 try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, false, gcc_dir_exists, gcc_cross_dir_exists);
479 }
480 }
481 for (candidate_biarch_lib_dirs.items) |suffix| {
482 const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
483 if (!tc.filesystem.exists(lib_dir)) continue;
484
485 const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
486 const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
487 for (candidate_biarch_triple_aliases.items) |candidate| {
488 try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, true, gcc_dir_exists, gcc_cross_dir_exists);
489 }
490 }
491 if (self.version.order(v0) == .gt) break;
492 }
493}
494
495fn findBiarchMultilibs(
496 tc: *const Toolchain,
497 result: *Multilib.Detected,
498 target: std.Target,
499 path: [2][]const u8,
500 needs_biarch_suffix: bool,
501) !bool {
502 const suff64 = if (target.os.tag == .solaris) switch (target.cpu.arch) {
503 .x86, .x86_64 => "/amd64",
504 .sparc => "/sparcv9",
505 else => "/64",
506 } else "/64";
507
508 const alt_64 = Multilib.init(suff64, suff64, &.{ "-m32", "+m64", "-mx32" });
509 const alt_32 = Multilib.init("/32", "/32", &.{ "+m32", "-m64", "-mx32" });
510 const alt_x32 = Multilib.init("/x32", "/x32", &.{ "-m32", "-m64", "+mx32" });
511
512 const multilib_filter = Multilib.Filter{
513 .base = path,
514 .file = if (target.os.tag == .elfiamcu) "libgcc.a" else "crtbegin.o",
515 };
516
517 const Want = enum {
518 want32,
519 want64,
520 wantx32,
521 };
522 const is_x32 = target.abi == .gnux32 or target.abi == .muslx32;
523 const target_ptr_width = target.ptrBitWidth();
524 const want: Want = if (target_ptr_width == 32 and multilib_filter.exists(alt_32, tc.filesystem))
525 .want64
526 else if (target_ptr_width == 64 and is_x32 and multilib_filter.exists(alt_x32, tc.filesystem))
527 .want64
528 else if (target_ptr_width == 64 and !is_x32 and multilib_filter.exists(alt_64, tc.filesystem))
529 .want32
530 else if (target_ptr_width == 32)
531 if (needs_biarch_suffix) .want64 else .want32
532 else if (is_x32)
533 if (needs_biarch_suffix) .want64 else .wantx32
534 else if (needs_biarch_suffix) .want32 else .want64;
535
536 const default = switch (want) {
537 .want32 => Multilib.init("", "", &.{ "+m32", "-m64", "-mx32" }),
538 .want64 => Multilib.init("", "", &.{ "-m32", "+m64", "-mx32" }),
539 .wantx32 => Multilib.init("", "", &.{ "-m32", "-m64", "+mx32" }),
540 };
541 result.multilibs.appendSliceAssumeCapacity(&.{
542 default,
543 alt_64,
544 alt_32,
545 alt_x32,
546 });
547 result.filter(multilib_filter, tc.filesystem);
548 var flags: Multilib.Flags = .{};
549 flags.appendAssumeCapacity(if (target_ptr_width == 64 and !is_x32) "+m64" else "-m64");
550 flags.appendAssumeCapacity(if (target_ptr_width == 32) "+m32" else "-m32");
551 flags.appendAssumeCapacity(if (target_ptr_width == 64 and is_x32) "+mx32" else "-mx32");
552
553 return result.select(flags);
554}
555
556fn scanGCCForMultilibs(
557 self: *GCCDetector,
558 tc: *const Toolchain,
559 target: std.Target,
560 path: [2][]const u8,
561 needs_biarch_suffix: bool,
562) !bool {
563 var detected: Multilib.Detected = .{};
564 if (target.cpu.arch == .csky) {
565 // TODO
566 } else if (target.cpu.arch.isMIPS()) {
567 // TODO
568 } else if (target.cpu.arch.isRISCV()) {
569 // TODO
570 } else if (target.cpu.arch == .msp430) {
571 // TODO
572 } else if (target.cpu.arch == .avr) {
573 // No multilibs
574 } else if (!try findBiarchMultilibs(tc, &detected, target, path, needs_biarch_suffix)) {
575 return false;
576 }
577 self.selected = detected.selected;
578 self.biarch_sibling = detected.biarch_sibling;
579 return true;
580}
581
582fn scanLibDirForGCCTriple(
583 self: *GCCDetector,
584 tc: *const Toolchain,
585 target: std.Target,
586 lib_dir: []const u8,
587 candidate_triple: []const u8,
588 needs_biarch_suffix: bool,
589 gcc_dir_exists: bool,
590 gcc_cross_dir_exists: bool,
591) !void {
592 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
593 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
594 for (0..2) |i| {
595 if (i == 0 and !gcc_dir_exists) continue;
596 if (i == 1 and !gcc_cross_dir_exists) continue;
597 defer fib.reset();
598
599 const base: []const u8 = if (i == 0) "gcc" else "gcc-cross";
600 var lib_suffix_buf: [64]u8 = undefined;
601 var suffix_buf_fib = std.heap.FixedBufferAllocator.init(&lib_suffix_buf);
602 const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue;
603
604 const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue;
605 var parent_dir = tc.filesystem.openDir(dir_name) catch continue;
606 defer parent_dir.close();
607
608 var it = parent_dir.iterate();
609 while (it.next() catch continue) |entry| {
610 if (entry.kind != .directory) continue;
611
612 const version_text = entry.name;
613 const candidate_version = GCCVersion.parse(version_text);
614 if (candidate_version.major != -1) {
615 // TODO: cache path so we're not repeatedly scanning
616 }
617 if (candidate_version.isLessThan(4, 1, 1, "")) continue;
618 switch (candidate_version.order(self.version)) {
619 .lt, .eq => continue,
620 .gt => {},
621 }
622
623 if (!try self.scanGCCForMultilibs(tc, target, .{ dir_name, version_text }, needs_biarch_suffix)) continue;
624
625 self.version = candidate_version;
626 self.gcc_triple = try tc.arena.dupe(u8, candidate_triple);
627 self.install_path = try std.fs.path.join(tc.arena, &.{ lib_dir, lib_suffix, version_text });
628 self.parent_lib_path = try std.fs.path.join(tc.arena, &.{ self.install_path, "..", "..", ".." });
629 self.is_valid = true;
630 }
631 }
632}
633
634fn gccToolchainDir(tc: *const Toolchain) []const u8 {
635 const sysroot = tc.getSysroot();
636 if (sysroot.len != 0) return "";
637 return system_defaults.gcc_install_prefix;
638}
deps/aro/aro/Driver/GCCVersion.zig deleted-122
......@@ -1,122 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Order = std.math.Order;
4
5const GCCVersion = @This();
6
7/// Raw version number text
8raw: []const u8 = "",
9
10/// -1 indicates not present
11major: i32 = -1,
12/// -1 indicates not present
13minor: i32 = -1,
14/// -1 indicates not present
15patch: i32 = -1,
16
17/// Text of parsed major version number
18major_str: []const u8 = "",
19/// Text of parsed major + minor version number
20minor_str: []const u8 = "",
21
22/// Patch number suffix
23suffix: []const u8 = "",
24
25/// This orders versions according to the preferred usage order, not a notion of release-time ordering
26/// Higher version numbers are preferred, but nonexistent minor/patch/suffix is preferred to one that does exist
27/// e.g. `4.1` is preferred over `4.0` but `4` is preferred over both `4.0` and `4.1`
28pub fn isLessThan(self: GCCVersion, rhs_major: i32, rhs_minor: i32, rhs_patch: i32, rhs_suffix: []const u8) bool {
29 if (self.major != rhs_major) {
30 return self.major < rhs_major;
31 }
32 if (self.minor != rhs_minor) {
33 if (rhs_minor == -1) return true;
34 if (self.minor == -1) return false;
35 return self.minor < rhs_minor;
36 }
37 if (self.patch != rhs_patch) {
38 if (rhs_patch == -1) return true;
39 if (self.patch == -1) return false;
40 return self.patch < rhs_patch;
41 }
42 if (!mem.eql(u8, self.suffix, rhs_suffix)) {
43 if (rhs_suffix.len == 0) return true;
44 if (self.suffix.len == 0) return false;
45 return switch (std.mem.order(u8, self.suffix, rhs_suffix)) {
46 .lt => true,
47 .eq => unreachable,
48 .gt => false,
49 };
50 }
51 return false;
52}
53
54/// Strings in the returned GCCVersion struct have the same lifetime as `text`
55pub fn parse(text: []const u8) GCCVersion {
56 const bad = GCCVersion{ .major = -1 };
57 var good = bad;
58
59 var it = mem.splitScalar(u8, text, '.');
60 const first = it.next().?;
61 const second = it.next() orelse "";
62 const rest = it.next() orelse "";
63
64 good.major = std.fmt.parseInt(i32, first, 10) catch return bad;
65 if (good.major < 0) return bad;
66 good.major_str = first;
67
68 if (second.len == 0) return good;
69 var minor_str = second;
70
71 if (rest.len == 0) {
72 const end = mem.indexOfNone(u8, minor_str, "0123456789") orelse minor_str.len;
73 if (end > 0) {
74 good.suffix = minor_str[end..];
75 minor_str = minor_str[0..end];
76 }
77 }
78 good.minor = std.fmt.parseInt(i32, minor_str, 10) catch return bad;
79 if (good.minor < 0) return bad;
80 good.minor_str = minor_str;
81
82 if (rest.len > 0) {
83 const end = mem.indexOfNone(u8, rest, "0123456789") orelse rest.len;
84 if (end > 0) {
85 const patch_num_text = rest[0..end];
86 good.patch = std.fmt.parseInt(i32, patch_num_text, 10) catch return bad;
87 if (good.patch < 0) return bad;
88 good.suffix = rest[end..];
89 }
90 }
91
92 return good;
93}
94
95pub fn order(a: GCCVersion, b: GCCVersion) Order {
96 if (a.isLessThan(b.major, b.minor, b.patch, b.suffix)) return .lt;
97 if (b.isLessThan(a.major, a.minor, a.patch, a.suffix)) return .gt;
98 return .eq;
99}
100
101test parse {
102 const versions = [10]GCCVersion{
103 parse("5"),
104 parse("4"),
105 parse("4.2"),
106 parse("4.0"),
107 parse("4.0-patched"),
108 parse("4.0.2"),
109 parse("4.0.1"),
110 parse("4.0.1-patched"),
111 parse("4.0.0"),
112 parse("4.0.0-patched"),
113 };
114
115 for (versions[0 .. versions.len - 1], versions[1..versions.len]) |first, second| {
116 try std.testing.expectEqual(Order.eq, first.order(first));
117 try std.testing.expectEqual(Order.gt, first.order(second));
118 try std.testing.expectEqual(Order.lt, second.order(first));
119 }
120 const last = versions[versions.len - 1];
121 try std.testing.expectEqual(Order.eq, last.order(last));
122}
deps/aro/aro/Driver/Multilib.zig deleted-71
......@@ -1,71 +0,0 @@
1const std = @import("std");
2const Filesystem = @import("Filesystem.zig").Filesystem;
3
4pub const Flags = std.BoundedArray([]const u8, 6);
5
6/// Large enough for GCCDetector for Linux; may need to be increased to support other toolchains.
7const max_multilibs = 4;
8
9const MultilibArray = std.BoundedArray(Multilib, max_multilibs);
10
11pub const Detected = struct {
12 multilibs: MultilibArray = .{},
13 selected: Multilib = .{},
14 biarch_sibling: ?Multilib = null,
15
16 pub fn filter(self: *Detected, multilib_filter: Filter, fs: Filesystem) void {
17 var found_count: usize = 0;
18 for (self.multilibs.constSlice()) |multilib| {
19 if (multilib_filter.exists(multilib, fs)) {
20 self.multilibs.set(found_count, multilib);
21 found_count += 1;
22 }
23 }
24 self.multilibs.resize(found_count) catch unreachable;
25 }
26
27 pub fn select(self: *Detected, flags: Flags) !bool {
28 var filtered: MultilibArray = .{};
29 for (self.multilibs.constSlice()) |multilib| {
30 for (multilib.flags.constSlice()) |multilib_flag| {
31 const matched = for (flags.constSlice()) |arg_flag| {
32 if (std.mem.eql(u8, arg_flag[1..], multilib_flag[1..])) break arg_flag;
33 } else multilib_flag;
34 if (matched[0] != multilib_flag[0]) break;
35 } else {
36 filtered.appendAssumeCapacity(multilib);
37 }
38 }
39 if (filtered.len == 0) return false;
40 if (filtered.len == 1) {
41 self.selected = filtered.get(0);
42 return true;
43 }
44 return error.TooManyMultilibs;
45 }
46};
47
48pub const Filter = struct {
49 base: [2][]const u8,
50 file: []const u8,
51 pub fn exists(self: Filter, m: Multilib, fs: Filesystem) bool {
52 return fs.joinedExists(&.{ self.base[0], self.base[1], m.gcc_suffix, self.file });
53 }
54};
55
56const Multilib = @This();
57
58gcc_suffix: []const u8 = "",
59os_suffix: []const u8 = "",
60include_suffix: []const u8 = "",
61flags: Flags = .{},
62priority: u32 = 0,
63
64pub fn init(gcc_suffix: []const u8, os_suffix: []const u8, flags: []const []const u8) Multilib {
65 var self: Multilib = .{
66 .gcc_suffix = gcc_suffix,
67 .os_suffix = os_suffix,
68 };
69 self.flags.appendSliceAssumeCapacity(flags);
70 return self;
71}
deps/aro/aro/InitList.zig deleted-153
......@@ -1,153 +0,0 @@
1//! Sparsely populated list of used indexes.
2//! Used for detecting duplicate initializers.
3const std = @import("std");
4const Allocator = std.mem.Allocator;
5const testing = std.testing;
6const Tree = @import("Tree.zig");
7const Token = Tree.Token;
8const TokenIndex = Tree.TokenIndex;
9const NodeIndex = Tree.NodeIndex;
10const Type = @import("Type.zig");
11const Diagnostics = @import("Diagnostics.zig");
12const NodeList = std.ArrayList(NodeIndex);
13const Parser = @import("Parser.zig");
14
15const Item = struct {
16 list: InitList = .{},
17 index: u64,
18
19 fn order(_: void, a: Item, b: Item) std.math.Order {
20 return std.math.order(a.index, b.index);
21 }
22};
23
24const InitList = @This();
25
26list: std.ArrayListUnmanaged(Item) = .{},
27node: NodeIndex = .none,
28tok: TokenIndex = 0,
29
30/// Deinitialize freeing all memory.
31pub fn deinit(il: *InitList, gpa: Allocator) void {
32 for (il.list.items) |*item| item.list.deinit(gpa);
33 il.list.deinit(gpa);
34 il.* = undefined;
35}
36
37/// Insert initializer at index, returning previous entry if one exists.
38pub fn put(il: *InitList, gpa: Allocator, index: usize, node: NodeIndex, tok: TokenIndex) !?TokenIndex {
39 const items = il.list.items;
40 var left: usize = 0;
41 var right: usize = items.len;
42
43 // Append new value to empty list
44 if (left == right) {
45 const item = try il.list.addOne(gpa);
46 item.* = .{
47 .list = .{ .node = node, .tok = tok },
48 .index = index,
49 };
50 return null;
51 }
52
53 while (left < right) {
54 // Avoid overflowing in the midpoint calculation
55 const mid = left + (right - left) / 2;
56 // Compare the key with the midpoint element
57 switch (std.math.order(index, items[mid].index)) {
58 .eq => {
59 // Replace previous entry.
60 const prev = items[mid].list.tok;
61 items[mid].list.deinit(gpa);
62 items[mid] = .{
63 .list = .{ .node = node, .tok = tok },
64 .index = index,
65 };
66 return prev;
67 },
68 .gt => left = mid + 1,
69 .lt => right = mid,
70 }
71 }
72
73 // Insert a new value into a sorted position.
74 try il.list.insert(gpa, left, .{
75 .list = .{ .node = node, .tok = tok },
76 .index = index,
77 });
78 return null;
79}
80
81/// Find item at index, create new if one does not exist.
82pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
83 const items = il.list.items;
84 var left: usize = 0;
85 var right: usize = items.len;
86
87 // Append new value to empty list
88 if (left == right) {
89 const item = try il.list.addOne(gpa);
90 item.* = .{
91 .list = .{ .node = .none, .tok = 0 },
92 .index = index,
93 };
94 return &item.list;
95 }
96
97 while (left < right) {
98 // Avoid overflowing in the midpoint calculation
99 const mid = left + (right - left) / 2;
100 // Compare the key with the midpoint element
101 switch (std.math.order(index, items[mid].index)) {
102 .eq => return &items[mid].list,
103 .gt => left = mid + 1,
104 .lt => right = mid,
105 }
106 }
107
108 // Insert a new value into a sorted position.
109 try il.list.insert(gpa, left, .{
110 .list = .{ .node = .none, .tok = 0 },
111 .index = index,
112 });
113 return &il.list.items[left].list;
114}
115
116test "basic usage" {
117 const gpa = testing.allocator;
118 var il: InitList = .{};
119 defer il.deinit(gpa);
120
121 {
122 var i: usize = 0;
123 while (i < 5) : (i += 1) {
124 const prev = try il.put(gpa, i, .none, 0);
125 try testing.expect(prev == null);
126 }
127 }
128
129 {
130 const failing = testing.failing_allocator;
131 var i: usize = 0;
132 while (i < 5) : (i += 1) {
133 _ = try il.find(failing, i);
134 }
135 }
136
137 {
138 var item = try il.find(gpa, 0);
139 var i: usize = 1;
140 while (i < 5) : (i += 1) {
141 item = try item.find(gpa, i);
142 }
143 }
144
145 {
146 const failing = testing.failing_allocator;
147 var item = try il.find(failing, 0);
148 var i: usize = 1;
149 while (i < 5) : (i += 1) {
150 item = try item.find(failing, i);
151 }
152 }
153}
deps/aro/aro/LangOpts.zig deleted-171
......@@ -1,171 +0,0 @@
1const std = @import("std");
2const DiagnosticTag = @import("Diagnostics.zig").Tag;
3const char_info = @import("char_info.zig");
4
5pub const Compiler = enum {
6 clang,
7 gcc,
8 msvc,
9};
10
11/// The floating-point evaluation method for intermediate results within a single expression
12pub const FPEvalMethod = enum(i8) {
13 /// The evaluation method cannot be determined or is inconsistent for this target.
14 indeterminate = -1,
15 /// Use the type declared in the source
16 source = 0,
17 /// Use double as the floating-point evaluation method for all float expressions narrower than double.
18 double = 1,
19 /// Use long double as the floating-point evaluation method for all float expressions narrower than long double.
20 extended = 2,
21};
22
23pub const Standard = enum {
24 /// ISO C 1990
25 c89,
26 /// ISO C 1990 with amendment 1
27 iso9899,
28 /// ISO C 1990 with GNU extensions
29 gnu89,
30 /// ISO C 1999
31 c99,
32 /// ISO C 1999 with GNU extensions
33 gnu99,
34 /// ISO C 2011
35 c11,
36 /// ISO C 2011 with GNU extensions
37 gnu11,
38 /// ISO C 2017
39 c17,
40 /// Default value if nothing specified; adds the GNU keywords to
41 /// C17 but does not suppress warnings about using GNU extensions
42 default,
43 /// ISO C 2017 with GNU extensions
44 gnu17,
45 /// Working Draft for ISO C23
46 c23,
47 /// Working Draft for ISO C23 with GNU extensions
48 gnu23,
49
50 const NameMap = std.ComptimeStringMap(Standard, .{
51 .{ "c89", .c89 }, .{ "c90", .c89 }, .{ "iso9899:1990", .c89 },
52 .{ "iso9899:199409", .iso9899 }, .{ "gnu89", .gnu89 }, .{ "gnu90", .gnu89 },
53 .{ "c99", .c99 }, .{ "iso9899:1999", .c99 }, .{ "c9x", .c99 },
54 .{ "iso9899:199x", .c99 }, .{ "gnu99", .gnu99 }, .{ "gnu9x", .gnu99 },
55 .{ "c11", .c11 }, .{ "iso9899:2011", .c11 }, .{ "c1x", .c11 },
56 .{ "iso9899:201x", .c11 }, .{ "gnu11", .gnu11 }, .{ "c17", .c17 },
57 .{ "iso9899:2017", .c17 }, .{ "c18", .c17 }, .{ "iso9899:2018", .c17 },
58 .{ "gnu17", .gnu17 }, .{ "gnu18", .gnu17 }, .{ "c23", .c23 },
59 .{ "gnu23", .gnu23 }, .{ "c2x", .c23 }, .{ "gnu2x", .gnu23 },
60 });
61
62 pub fn atLeast(self: Standard, other: Standard) bool {
63 return @intFromEnum(self) >= @intFromEnum(other);
64 }
65
66 pub fn isGNU(standard: Standard) bool {
67 return switch (standard) {
68 .gnu89, .gnu99, .gnu11, .default, .gnu17, .gnu23 => true,
69 else => false,
70 };
71 }
72
73 pub fn isExplicitGNU(standard: Standard) bool {
74 return standard.isGNU() and standard != .default;
75 }
76
77 /// Value reported by __STDC_VERSION__ macro
78 pub fn StdCVersionMacro(standard: Standard) ?[]const u8 {
79 return switch (standard) {
80 .c89, .gnu89 => null,
81 .iso9899 => "199409L",
82 .c99, .gnu99 => "199901L",
83 .c11, .gnu11 => "201112L",
84 .default, .c17, .gnu17 => "201710L",
85 .c23, .gnu23 => "202311L",
86 };
87 }
88
89 pub fn codepointAllowedInIdentifier(standard: Standard, codepoint: u21, is_start: bool) bool {
90 if (is_start) {
91 return if (standard.atLeast(.c23))
92 char_info.isXidStart(codepoint)
93 else if (standard.atLeast(.c11))
94 char_info.isC11IdChar(codepoint) and !char_info.isC11DisallowedInitialIdChar(codepoint)
95 else
96 char_info.isC99IdChar(codepoint) and !char_info.isC99DisallowedInitialIDChar(codepoint);
97 } else {
98 return if (standard.atLeast(.c23))
99 char_info.isXidContinue(codepoint)
100 else if (standard.atLeast(.c11))
101 char_info.isC11IdChar(codepoint)
102 else
103 char_info.isC99IdChar(codepoint);
104 }
105 }
106};
107
108const LangOpts = @This();
109
110emulate: Compiler = .clang,
111standard: Standard = .default,
112/// -fshort-enums option, makes enums only take up as much space as they need to hold all the values.
113short_enums: bool = false,
114dollars_in_identifiers: bool = true,
115declspec_attrs: bool = false,
116ms_extensions: bool = false,
117/// true or false if digraph support explicitly enabled/disabled with -fdigraphs/-fno-digraphs
118digraphs: ?bool = null,
119/// If set, use the native half type instead of promoting to float
120use_native_half_type: bool = false,
121/// If set, function arguments and return values may be of type __fp16 even if there is no standard ABI for it
122allow_half_args_and_returns: bool = false,
123/// null indicates that the user did not select a value, use target to determine default
124fp_eval_method: ?FPEvalMethod = null,
125/// If set, use specified signedness for `char` instead of the target's default char signedness
126char_signedness_override: ?std.builtin.Signedness = null,
127/// If set, override the default availability of char8_t (by default, enabled in C23 and later; disabled otherwise)
128has_char8_t_override: ?bool = null,
129
130/// Whether to allow GNU-style inline assembly
131gnu_asm: bool = true,
132
133/// Preserve comments when preprocessing
134preserve_comments: bool = false,
135/// Preserve comments in macros when preprocessing
136preserve_comments_in_macros: bool = false,
137
138pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {
139 self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;
140}
141
142pub fn enableMSExtensions(self: *LangOpts) void {
143 self.declspec_attrs = true;
144 self.ms_extensions = true;
145}
146
147pub fn disableMSExtensions(self: *LangOpts) void {
148 self.declspec_attrs = false;
149 self.ms_extensions = true;
150}
151
152pub fn hasChar8_T(self: *const LangOpts) bool {
153 return self.has_char8_t_override orelse self.standard.atLeast(.c23);
154}
155
156pub fn hasDigraphs(self: *const LangOpts) bool {
157 return self.digraphs orelse self.standard.atLeast(.gnu89);
158}
159
160pub fn setEmulatedCompiler(self: *LangOpts, compiler: Compiler) void {
161 self.emulate = compiler;
162 if (compiler == .msvc) self.enableMSExtensions();
163}
164
165pub fn setFpEvalMethod(self: *LangOpts, fp_eval_method: FPEvalMethod) void {
166 self.fp_eval_method = fp_eval_method;
167}
168
169pub fn setCharSignedness(self: *LangOpts, signedness: std.builtin.Signedness) void {
170 self.char_signedness_override = signedness;
171}
deps/aro/aro/Parser.zig deleted-8437
......@@ -1,8437 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const assert = std.debug.assert;
5const big = std.math.big;
6const Compilation = @import("Compilation.zig");
7const Source = @import("Source.zig");
8const Tokenizer = @import("Tokenizer.zig");
9const Preprocessor = @import("Preprocessor.zig");
10const Tree = @import("Tree.zig");
11const Token = Tree.Token;
12const NumberPrefix = Token.NumberPrefix;
13const NumberSuffix = Token.NumberSuffix;
14const TokenIndex = Tree.TokenIndex;
15const NodeIndex = Tree.NodeIndex;
16const Type = @import("Type.zig");
17const Diagnostics = @import("Diagnostics.zig");
18const NodeList = std.ArrayList(NodeIndex);
19const InitList = @import("InitList.zig");
20const Attribute = @import("Attribute.zig");
21const char_info = @import("char_info.zig");
22const text_literal = @import("text_literal.zig");
23const Value = @import("Value.zig");
24const SymbolStack = @import("SymbolStack.zig");
25const Symbol = SymbolStack.Symbol;
26const record_layout = @import("record_layout.zig");
27const StrInt = @import("StringInterner.zig");
28const StringId = StrInt.StringId;
29const Builtins = @import("Builtins.zig");
30const Builtin = Builtins.Builtin;
31const target_util = @import("target.zig");
32
33const Switch = struct {
34 default: ?TokenIndex = null,
35 ranges: std.ArrayList(Range),
36 ty: Type,
37 comp: *Compilation,
38
39 const Range = struct {
40 first: Value,
41 last: Value,
42 tok: TokenIndex,
43 };
44
45 fn add(self: *Switch, first: Value, last: Value, tok: TokenIndex) !?Range {
46 for (self.ranges.items) |range| {
47 if (last.compare(.gte, range.first, self.comp) and first.compare(.lte, range.last, self.comp)) {
48 return range; // They overlap.
49 }
50 }
51 try self.ranges.append(.{
52 .first = first,
53 .last = last,
54 .tok = tok,
55 });
56 return null;
57 }
58};
59
60const Label = union(enum) {
61 unresolved_goto: TokenIndex,
62 label: TokenIndex,
63};
64
65pub const Error = Compilation.Error || error{ParsingFailed};
66
67/// An attribute that has been parsed but not yet validated in its context
68const TentativeAttribute = struct {
69 attr: Attribute,
70 tok: TokenIndex,
71};
72
73/// How the parser handles const int decl references when it is expecting an integer
74/// constant expression.
75const ConstDeclFoldingMode = enum {
76 /// fold const decls as if they were literals
77 fold_const_decls,
78 /// fold const decls as if they were literals and issue GNU extension diagnostic
79 gnu_folding_extension,
80 /// fold const decls as if they were literals and issue VLA diagnostic
81 gnu_vla_folding_extension,
82 /// folding const decls is prohibited; return an unavailable value
83 no_const_decl_folding,
84};
85
86const Parser = @This();
87
88// values from preprocessor
89pp: *Preprocessor,
90comp: *Compilation,
91gpa: mem.Allocator,
92tok_ids: []const Token.Id,
93tok_i: TokenIndex = 0,
94
95// values of the incomplete Tree
96arena: Allocator,
97nodes: Tree.Node.List = .{},
98data: NodeList,
99value_map: Tree.ValueMap,
100
101// buffers used during compilation
102syms: SymbolStack = .{},
103strings: std.ArrayList(u8),
104labels: std.ArrayList(Label),
105list_buf: NodeList,
106decl_buf: NodeList,
107param_buf: std.ArrayList(Type.Func.Param),
108enum_buf: std.ArrayList(Type.Enum.Field),
109record_buf: std.ArrayList(Type.Record.Field),
110attr_buf: std.MultiArrayList(TentativeAttribute) = .{},
111attr_application_buf: std.ArrayListUnmanaged(Attribute) = .{},
112field_attr_buf: std.ArrayList([]const Attribute),
113/// type name -> variable name location for tentative definitions (top-level defs with thus-far-incomplete types)
114/// e.g. `struct Foo bar;` where `struct Foo` is not defined yet.
115/// The key is the StringId of `Foo` and the value is the TokenIndex of `bar`
116/// Items are removed if the type is subsequently completed with a definition.
117/// We only store the first tentative definition that uses a given type because this map is only used
118/// for issuing an error message, and correcting the first error for a type will fix all of them for that type.
119tentative_defs: std.AutoHashMapUnmanaged(StringId, TokenIndex) = .{},
120
121// configuration and miscellaneous info
122no_eval: bool = false,
123in_macro: bool = false,
124extension_suppressed: bool = false,
125contains_address_of_label: bool = false,
126label_count: u32 = 0,
127const_decl_folding: ConstDeclFoldingMode = .fold_const_decls,
128/// location of first computed goto in function currently being parsed
129/// if a computed goto is used, the function must contain an
130/// address-of-label expression (tracked with contains_address_of_label)
131computed_goto_tok: ?TokenIndex = null,
132
133/// Various variables that are different for each function.
134func: struct {
135 /// null if not in function, will always be plain func, var_args_func or old_style_func
136 ty: ?Type = null,
137 name: TokenIndex = 0,
138 ident: ?Result = null,
139 pretty_ident: ?Result = null,
140} = .{},
141/// Various variables that are different for each record.
142record: struct {
143 // invalid means we're not parsing a record
144 kind: Token.Id = .invalid,
145 flexible_field: ?TokenIndex = null,
146 start: usize = 0,
147 field_attr_start: usize = 0,
148
149 fn addField(r: @This(), p: *Parser, name: StringId, tok: TokenIndex) Error!void {
150 var i = p.record_members.items.len;
151 while (i > r.start) {
152 i -= 1;
153 if (p.record_members.items[i].name == name) {
154 try p.errStr(.duplicate_member, tok, p.tokSlice(tok));
155 try p.errTok(.previous_definition, p.record_members.items[i].tok);
156 break;
157 }
158 }
159 try p.record_members.append(p.gpa, .{ .name = name, .tok = tok });
160 }
161
162 fn addFieldsFromAnonymous(r: @This(), p: *Parser, ty: Type) Error!void {
163 for (ty.data.record.fields) |f| {
164 if (f.isAnonymousRecord()) {
165 try r.addFieldsFromAnonymous(p, f.ty.canonicalize(.standard));
166 } else if (f.name_tok != 0) {
167 try r.addField(p, f.name, f.name_tok);
168 }
169 }
170 }
171} = .{},
172record_members: std.ArrayListUnmanaged(struct { tok: TokenIndex, name: StringId }) = .{},
173@"switch": ?*Switch = null,
174in_loop: bool = false,
175pragma_pack: ?u8 = null,
176string_ids: struct {
177 declspec_id: StringId,
178 main_id: StringId,
179 file: StringId,
180 jmp_buf: StringId,
181 sigjmp_buf: StringId,
182 ucontext_t: StringId,
183},
184
185/// Checks codepoint for various pedantic warnings
186/// Returns true if diagnostic issued
187fn checkIdentifierCodepointWarnings(comp: *Compilation, codepoint: u21, loc: Source.Location) Compilation.Error!bool {
188 assert(codepoint >= 0x80);
189
190 const err_start = comp.diagnostics.list.items.len;
191
192 if (!char_info.isC99IdChar(codepoint)) {
193 try comp.addDiagnostic(.{
194 .tag = .c99_compat,
195 .loc = loc,
196 }, &.{});
197 }
198 if (char_info.isInvisible(codepoint)) {
199 try comp.addDiagnostic(.{
200 .tag = .unicode_zero_width,
201 .loc = loc,
202 .extra = .{ .actual_codepoint = codepoint },
203 }, &.{});
204 }
205 if (char_info.homoglyph(codepoint)) |resembles| {
206 try comp.addDiagnostic(.{
207 .tag = .unicode_homoglyph,
208 .loc = loc,
209 .extra = .{ .codepoints = .{ .actual = codepoint, .resembles = resembles } },
210 }, &.{});
211 }
212 return comp.diagnostics.list.items.len != err_start;
213}
214
215/// Issues diagnostics for the current extended identifier token
216/// Return value indicates whether the token should be considered an identifier
217/// true means consider the token to actually be an identifier
218/// false means it is not
219fn validateExtendedIdentifier(p: *Parser) !bool {
220 assert(p.tok_ids[p.tok_i] == .extended_identifier);
221
222 const slice = p.tokSlice(p.tok_i);
223 const view = std.unicode.Utf8View.init(slice) catch {
224 try p.errTok(.invalid_utf8, p.tok_i);
225 return error.FatalError;
226 };
227 var it = view.iterator();
228
229 var valid_identifier = true;
230 var warned = false;
231 var len: usize = 0;
232 var invalid_char: u21 = undefined;
233 var loc = p.pp.tokens.items(.loc)[p.tok_i];
234
235 var normalized = true;
236 var last_canonical_class: char_info.CanonicalCombiningClass = .not_reordered;
237 const standard = p.comp.langopts.standard;
238 while (it.nextCodepoint()) |codepoint| {
239 defer {
240 len += 1;
241 loc.byte_offset += std.unicode.utf8CodepointSequenceLength(codepoint) catch unreachable;
242 }
243 if (codepoint == '$') {
244 warned = true;
245 if (p.comp.langopts.dollars_in_identifiers) try p.comp.addDiagnostic(.{
246 .tag = .dollar_in_identifier_extension,
247 .loc = loc,
248 }, &.{});
249 }
250
251 if (codepoint <= 0x7F) continue;
252 if (!valid_identifier) continue;
253
254 const allowed = standard.codepointAllowedInIdentifier(codepoint, len == 0);
255 if (!allowed) {
256 invalid_char = codepoint;
257 valid_identifier = false;
258 continue;
259 }
260
261 if (!warned) {
262 warned = try checkIdentifierCodepointWarnings(p.comp, codepoint, loc);
263 }
264
265 // Check NFC normalization.
266 if (!normalized) continue;
267 const canonical_class = char_info.getCanonicalClass(codepoint);
268 if (@intFromEnum(last_canonical_class) > @intFromEnum(canonical_class) and
269 canonical_class != .not_reordered)
270 {
271 normalized = false;
272 try p.errStr(.identifier_not_normalized, p.tok_i, slice);
273 continue;
274 }
275 if (char_info.isNormalized(codepoint) != .yes) {
276 normalized = false;
277 try p.errExtra(.identifier_not_normalized, p.tok_i, .{ .normalized = slice });
278 }
279 last_canonical_class = canonical_class;
280 }
281
282 if (!valid_identifier) {
283 if (len == 1) {
284 try p.errExtra(.unexpected_character, p.tok_i, .{ .actual_codepoint = invalid_char });
285 return false;
286 } else {
287 try p.errExtra(.invalid_identifier_start_char, p.tok_i, .{ .actual_codepoint = invalid_char });
288 }
289 }
290
291 return true;
292}
293
294fn eatIdentifier(p: *Parser) !?TokenIndex {
295 switch (p.tok_ids[p.tok_i]) {
296 .identifier => {},
297 .extended_identifier => {
298 if (!try p.validateExtendedIdentifier()) {
299 p.tok_i += 1;
300 return null;
301 }
302 },
303 else => return null,
304 }
305 p.tok_i += 1;
306
307 // Handle illegal '$' characters in identifiers
308 if (!p.comp.langopts.dollars_in_identifiers) {
309 if (p.tok_ids[p.tok_i] == .invalid and p.tokSlice(p.tok_i)[0] == '$') {
310 try p.err(.dollars_in_identifiers);
311 p.tok_i += 1;
312 return error.ParsingFailed;
313 }
314 }
315
316 return p.tok_i - 1;
317}
318
319fn expectIdentifier(p: *Parser) Error!TokenIndex {
320 const actual = p.tok_ids[p.tok_i];
321 if (actual != .identifier and actual != .extended_identifier) {
322 return p.errExpectedToken(.identifier, actual);
323 }
324
325 return (try p.eatIdentifier()) orelse error.ParsingFailed;
326}
327
328fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex {
329 assert(id != .identifier and id != .extended_identifier); // use eatIdentifier
330 if (p.tok_ids[p.tok_i] == id) {
331 defer p.tok_i += 1;
332 return p.tok_i;
333 } else return null;
334}
335
336fn expectToken(p: *Parser, expected: Token.Id) Error!TokenIndex {
337 assert(expected != .identifier and expected != .extended_identifier); // use expectIdentifier
338 const actual = p.tok_ids[p.tok_i];
339 if (actual != expected) return p.errExpectedToken(expected, actual);
340 defer p.tok_i += 1;
341 return p.tok_i;
342}
343
344pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 {
345 if (p.tok_ids[tok].lexeme()) |some| return some;
346 const loc = p.pp.tokens.items(.loc)[tok];
347 var tmp_tokenizer = Tokenizer{
348 .buf = p.comp.getSource(loc.id).buf,
349 .langopts = p.comp.langopts,
350 .index = loc.byte_offset,
351 .source = .generated,
352 };
353 const res = tmp_tokenizer.next();
354 return tmp_tokenizer.buf[res.start..res.end];
355}
356
357fn expectClosing(p: *Parser, opening: TokenIndex, id: Token.Id) Error!void {
358 _ = p.expectToken(id) catch |e| {
359 if (e == error.ParsingFailed) {
360 try p.errTok(switch (id) {
361 .r_paren => .to_match_paren,
362 .r_brace => .to_match_brace,
363 .r_bracket => .to_match_brace,
364 else => unreachable,
365 }, opening);
366 }
367 return e;
368 };
369}
370
371fn errOverflow(p: *Parser, op_tok: TokenIndex, res: Result) !void {
372 try p.errStr(.overflow, op_tok, try res.str(p));
373}
374
375fn errExpectedToken(p: *Parser, expected: Token.Id, actual: Token.Id) Error {
376 switch (actual) {
377 .invalid => try p.errExtra(.expected_invalid, p.tok_i, .{ .tok_id_expected = expected }),
378 .eof => try p.errExtra(.expected_eof, p.tok_i, .{ .tok_id_expected = expected }),
379 else => try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{
380 .expected = expected,
381 .actual = actual,
382 } }),
383 }
384 return error.ParsingFailed;
385}
386
387pub fn errStr(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, str: []const u8) Compilation.Error!void {
388 @setCold(true);
389 return p.errExtra(tag, tok_i, .{ .str = str });
390}
391
392pub fn errExtra(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, extra: Diagnostics.Message.Extra) Compilation.Error!void {
393 @setCold(true);
394 const tok = p.pp.tokens.get(tok_i);
395 var loc = tok.loc;
396 if (tok_i != 0 and tok.id == .eof) {
397 // if the token is EOF, point at the end of the previous token instead
398 const prev = p.pp.tokens.get(tok_i - 1);
399 loc = prev.loc;
400 loc.byte_offset += @intCast(p.tokSlice(tok_i - 1).len);
401 }
402 try p.comp.addDiagnostic(.{
403 .tag = tag,
404 .loc = loc,
405 .extra = extra,
406 }, tok.expansionSlice());
407}
408
409pub fn errTok(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex) Compilation.Error!void {
410 @setCold(true);
411 return p.errExtra(tag, tok_i, .{ .none = {} });
412}
413
414pub fn err(p: *Parser, tag: Diagnostics.Tag) Compilation.Error!void {
415 @setCold(true);
416 return p.errExtra(tag, p.tok_i, .{ .none = {} });
417}
418
419pub fn todo(p: *Parser, msg: []const u8) Error {
420 try p.errStr(.todo, p.tok_i, msg);
421 return error.ParsingFailed;
422}
423
424pub fn removeNull(p: *Parser, str: Value) !Value {
425 const strings_top = p.strings.items.len;
426 defer p.strings.items.len = strings_top;
427 {
428 const bytes = p.comp.interner.get(str.ref()).bytes;
429 try p.strings.appendSlice(bytes[0 .. bytes.len - 1]);
430 }
431 return Value.intern(p.comp, .{ .bytes = p.strings.items[strings_top..] });
432}
433
434pub fn typeStr(p: *Parser, ty: Type) ![]const u8 {
435 if (Type.Builder.fromType(ty).str(p.comp.langopts)) |str| return str;
436 const strings_top = p.strings.items.len;
437 defer p.strings.items.len = strings_top;
438
439 const mapper = p.comp.string_interner.getSlowTypeMapper();
440 try ty.print(mapper, p.comp.langopts, p.strings.writer());
441 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
442}
443
444pub fn typePairStr(p: *Parser, a: Type, b: Type) ![]const u8 {
445 return p.typePairStrExtra(a, " and ", b);
446}
447
448pub fn typePairStrExtra(p: *Parser, a: Type, msg: []const u8, b: Type) ![]const u8 {
449 const strings_top = p.strings.items.len;
450 defer p.strings.items.len = strings_top;
451
452 try p.strings.append('\'');
453 const mapper = p.comp.string_interner.getSlowTypeMapper();
454 try a.print(mapper, p.comp.langopts, p.strings.writer());
455 try p.strings.append('\'');
456 try p.strings.appendSlice(msg);
457 try p.strings.append('\'');
458 try b.print(mapper, p.comp.langopts, p.strings.writer());
459 try p.strings.append('\'');
460 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
461}
462
463pub fn floatValueChangedStr(p: *Parser, res: *Result, old_value: Value, int_ty: Type) ![]const u8 {
464 const strings_top = p.strings.items.len;
465 defer p.strings.items.len = strings_top;
466
467 var w = p.strings.writer();
468 const type_pair_str = try p.typePairStrExtra(res.ty, " to ", int_ty);
469 try w.writeAll(type_pair_str);
470
471 try w.writeAll(" changes ");
472 if (res.val.isZero(p.comp)) try w.writeAll("non-zero ");
473 try w.writeAll("value from ");
474 try old_value.print(res.ty, p.comp, w);
475 try w.writeAll(" to ");
476 try res.val.print(int_ty, p.comp, w);
477
478 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
479}
480
481fn checkDeprecatedUnavailable(p: *Parser, ty: Type, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {
482 if (ty.getAttribute(.@"error")) |@"error"| {
483 const strings_top = p.strings.items.len;
484 defer p.strings.items.len = strings_top;
485
486 const w = p.strings.writer();
487 const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes;
488 try w.print("call to '{s}' declared with attribute error: {}", .{
489 p.tokSlice(@"error".__name_tok), std.zig.fmtEscapes(msg_str),
490 });
491 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
492 try p.errStr(.error_attribute, usage_tok, str);
493 }
494 if (ty.getAttribute(.warning)) |warning| {
495 const strings_top = p.strings.items.len;
496 defer p.strings.items.len = strings_top;
497
498 const w = p.strings.writer();
499 const msg_str = p.comp.interner.get(warning.msg.ref()).bytes;
500 try w.print("call to '{s}' declared with attribute warning: {}", .{
501 p.tokSlice(warning.__name_tok), std.zig.fmtEscapes(msg_str),
502 });
503 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
504 try p.errStr(.warning_attribute, usage_tok, str);
505 }
506 if (ty.getAttribute(.unavailable)) |unavailable| {
507 try p.errDeprecated(.unavailable, usage_tok, unavailable.msg);
508 try p.errStr(.unavailable_note, unavailable.__name_tok, p.tokSlice(decl_tok));
509 return error.ParsingFailed;
510 } else if (ty.getAttribute(.deprecated)) |deprecated| {
511 try p.errDeprecated(.deprecated_declarations, usage_tok, deprecated.msg);
512 try p.errStr(.deprecated_note, deprecated.__name_tok, p.tokSlice(decl_tok));
513 }
514}
515
516fn errDeprecated(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, msg: ?Value) Compilation.Error!void {
517 const strings_top = p.strings.items.len;
518 defer p.strings.items.len = strings_top;
519
520 const w = p.strings.writer();
521 try w.print("'{s}' is ", .{p.tokSlice(tok_i)});
522 const reason: []const u8 = switch (tag) {
523 .unavailable => "unavailable",
524 .deprecated_declarations => "deprecated",
525 else => unreachable,
526 };
527 try w.writeAll(reason);
528 if (msg) |m| {
529 const str = p.comp.interner.get(m.ref()).bytes;
530 try w.print(": {}", .{std.zig.fmtEscapes(str)});
531 }
532 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
533 return p.errStr(tag, tok_i, str);
534}
535
536fn addNode(p: *Parser, node: Tree.Node) Allocator.Error!NodeIndex {
537 if (p.in_macro) return .none;
538 const res = p.nodes.len;
539 try p.nodes.append(p.gpa, node);
540 return @enumFromInt(res);
541}
542
543fn addList(p: *Parser, nodes: []const NodeIndex) Allocator.Error!Tree.Node.Range {
544 if (p.in_macro) return Tree.Node.Range{ .start = 0, .end = 0 };
545 const start: u32 = @intCast(p.data.items.len);
546 try p.data.appendSlice(nodes);
547 const end: u32 = @intCast(p.data.items.len);
548 return Tree.Node.Range{ .start = start, .end = end };
549}
550
551fn findLabel(p: *Parser, name: []const u8) ?TokenIndex {
552 for (p.labels.items) |item| {
553 switch (item) {
554 .label => |l| if (mem.eql(u8, p.tokSlice(l), name)) return l,
555 .unresolved_goto => {},
556 }
557 }
558 return null;
559}
560
561fn nodeIs(p: *Parser, node: NodeIndex, tag: Tree.Tag) bool {
562 return p.getNode(node, tag) != null;
563}
564
565fn getNode(p: *Parser, node: NodeIndex, tag: Tree.Tag) ?NodeIndex {
566 var cur = node;
567 const tags = p.nodes.items(.tag);
568 const data = p.nodes.items(.data);
569 while (true) {
570 const cur_tag = tags[@intFromEnum(cur)];
571 if (cur_tag == .paren_expr) {
572 cur = data[@intFromEnum(cur)].un;
573 } else if (cur_tag == tag) {
574 return cur;
575 } else {
576 return null;
577 }
578 }
579}
580
581fn nodeIsCompoundLiteral(p: *Parser, node: NodeIndex) bool {
582 var cur = node;
583 const tags = p.nodes.items(.tag);
584 const data = p.nodes.items(.data);
585 while (true) {
586 switch (tags[@intFromEnum(cur)]) {
587 .paren_expr => cur = data[@intFromEnum(cur)].un,
588 .compound_literal_expr,
589 .static_compound_literal_expr,
590 .thread_local_compound_literal_expr,
591 .static_thread_local_compound_literal_expr,
592 => return true,
593 else => return false,
594 }
595 }
596}
597
598fn tmpTree(p: *Parser) Tree {
599 return .{
600 .nodes = p.nodes.slice(),
601 .data = p.data.items,
602 .value_map = p.value_map,
603 .comp = p.comp,
604 .arena = undefined,
605 .generated = undefined,
606 .tokens = undefined,
607 .root_decls = undefined,
608 };
609}
610
611fn pragma(p: *Parser) Compilation.Error!bool {
612 var found_pragma = false;
613 while (p.eatToken(.keyword_pragma)) |_| {
614 found_pragma = true;
615
616 const name_tok = p.tok_i;
617 const name = p.tokSlice(name_tok);
618
619 const end_idx = mem.indexOfScalarPos(Token.Id, p.tok_ids, p.tok_i, .nl).?;
620 const pragma_len = @as(TokenIndex, @intCast(end_idx)) - p.tok_i;
621 defer p.tok_i += pragma_len + 1; // skip past .nl as well
622 if (p.comp.getPragma(name)) |prag| {
623 try prag.parserCB(p, p.tok_i);
624 }
625 }
626 return found_pragma;
627}
628
629/// Issue errors for top-level definitions whose type was never completed.
630fn diagnoseIncompleteDefinitions(p: *Parser) !void {
631 @setCold(true);
632
633 const node_slices = p.nodes.slice();
634 const tags = node_slices.items(.tag);
635 const tys = node_slices.items(.ty);
636 const data = node_slices.items(.data);
637
638 const err_start = p.comp.diagnostics.list.items.len;
639 for (p.decl_buf.items) |decl_node| {
640 const idx = @intFromEnum(decl_node);
641 switch (tags[idx]) {
642 .struct_forward_decl, .union_forward_decl, .enum_forward_decl => {},
643 else => continue,
644 }
645
646 const ty = tys[idx];
647 const decl_type_name = if (ty.getRecord()) |rec|
648 rec.name
649 else if (ty.get(.@"enum")) |en|
650 en.data.@"enum".name
651 else
652 unreachable;
653
654 const tentative_def_tok = p.tentative_defs.get(decl_type_name) orelse continue;
655 const type_str = try p.typeStr(ty);
656 try p.errStr(.tentative_definition_incomplete, tentative_def_tok, type_str);
657 try p.errStr(.forward_declaration_here, data[idx].decl_ref, type_str);
658 }
659 const errors_added = p.comp.diagnostics.list.items.len - err_start;
660 assert(errors_added == 2 * p.tentative_defs.count()); // Each tentative def should add an error + note
661}
662
663/// root : (decl | assembly ';' | staticAssert)*
664pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {
665 assert(pp.linemarkers == .none);
666 pp.comp.pragmaEvent(.before_parse);
667
668 var arena = std.heap.ArenaAllocator.init(pp.comp.gpa);
669 errdefer arena.deinit();
670 var p = Parser{
671 .pp = pp,
672 .comp = pp.comp,
673 .gpa = pp.comp.gpa,
674 .arena = arena.allocator(),
675 .tok_ids = pp.tokens.items(.id),
676 .strings = std.ArrayList(u8).init(pp.comp.gpa),
677 .value_map = Tree.ValueMap.init(pp.comp.gpa),
678 .data = NodeList.init(pp.comp.gpa),
679 .labels = std.ArrayList(Label).init(pp.comp.gpa),
680 .list_buf = NodeList.init(pp.comp.gpa),
681 .decl_buf = NodeList.init(pp.comp.gpa),
682 .param_buf = std.ArrayList(Type.Func.Param).init(pp.comp.gpa),
683 .enum_buf = std.ArrayList(Type.Enum.Field).init(pp.comp.gpa),
684 .record_buf = std.ArrayList(Type.Record.Field).init(pp.comp.gpa),
685 .field_attr_buf = std.ArrayList([]const Attribute).init(pp.comp.gpa),
686 .string_ids = .{
687 .declspec_id = try StrInt.intern(pp.comp, "__declspec"),
688 .main_id = try StrInt.intern(pp.comp, "main"),
689 .file = try StrInt.intern(pp.comp, "FILE"),
690 .jmp_buf = try StrInt.intern(pp.comp, "jmp_buf"),
691 .sigjmp_buf = try StrInt.intern(pp.comp, "sigjmp_buf"),
692 .ucontext_t = try StrInt.intern(pp.comp, "ucontext_t"),
693 },
694 };
695 errdefer {
696 p.nodes.deinit(pp.comp.gpa);
697 p.value_map.deinit();
698 }
699 defer {
700 p.data.deinit();
701 p.labels.deinit();
702 p.strings.deinit();
703 p.syms.deinit(pp.comp.gpa);
704 p.list_buf.deinit();
705 p.decl_buf.deinit();
706 p.param_buf.deinit();
707 p.enum_buf.deinit();
708 p.record_buf.deinit();
709 p.record_members.deinit(pp.comp.gpa);
710 p.attr_buf.deinit(pp.comp.gpa);
711 p.attr_application_buf.deinit(pp.comp.gpa);
712 p.tentative_defs.deinit(pp.comp.gpa);
713 assert(p.field_attr_buf.items.len == 0);
714 p.field_attr_buf.deinit();
715 }
716
717 try p.syms.pushScope(&p);
718 defer p.syms.popScope();
719
720 // NodeIndex 0 must be invalid
721 _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined });
722
723 {
724 if (p.comp.langopts.hasChar8_T()) {
725 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "char8_t"), .{ .specifier = .uchar }, 0, .none);
726 }
727 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__int128_t"), .{ .specifier = .int128 }, 0, .none);
728 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__uint128_t"), .{ .specifier = .uint128 }, 0, .none);
729
730 const elem_ty = try p.arena.create(Type);
731 elem_ty.* = .{ .specifier = .char };
732 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__builtin_ms_va_list"), .{
733 .specifier = .pointer,
734 .data = .{ .sub_type = elem_ty },
735 }, 0, .none);
736
737 const ty = &pp.comp.types.va_list;
738 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__builtin_va_list"), ty.*, 0, .none);
739
740 if (ty.isArray()) ty.decayArray();
741
742 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__NSConstantString"), pp.comp.types.ns_constant_string.ty, 0, .none);
743 }
744
745 while (p.eatToken(.eof) == null) {
746 if (try p.pragma()) continue;
747 if (try p.parseOrNextDecl(staticAssert)) continue;
748 if (try p.parseOrNextDecl(decl)) continue;
749 if (p.eatToken(.keyword_extension)) |_| {
750 const saved_extension = p.extension_suppressed;
751 defer p.extension_suppressed = saved_extension;
752 p.extension_suppressed = true;
753
754 if (try p.parseOrNextDecl(decl)) continue;
755 switch (p.tok_ids[p.tok_i]) {
756 .semicolon => p.tok_i += 1,
757 .keyword_static_assert,
758 .keyword_c23_static_assert,
759 .keyword_pragma,
760 .keyword_extension,
761 .keyword_asm,
762 .keyword_asm1,
763 .keyword_asm2,
764 => {},
765 else => try p.err(.expected_external_decl),
766 }
767 continue;
768 }
769 if (p.assembly(.global) catch |er| switch (er) {
770 error.ParsingFailed => {
771 p.nextExternDecl();
772 continue;
773 },
774 else => |e| return e,
775 }) |node| {
776 try p.decl_buf.append(node);
777 continue;
778 }
779 if (p.eatToken(.semicolon)) |tok| {
780 try p.errTok(.extra_semi, tok);
781 continue;
782 }
783 try p.err(.expected_external_decl);
784 p.tok_i += 1;
785 }
786 if (p.tentative_defs.count() > 0) {
787 try p.diagnoseIncompleteDefinitions();
788 }
789
790 const root_decls = try p.decl_buf.toOwnedSlice();
791 errdefer pp.comp.gpa.free(root_decls);
792 if (root_decls.len == 0) {
793 try p.errTok(.empty_translation_unit, p.tok_i - 1);
794 }
795 pp.comp.pragmaEvent(.after_parse);
796
797 const data = try p.data.toOwnedSlice();
798 errdefer pp.comp.gpa.free(data);
799 return Tree{
800 .comp = pp.comp,
801 .tokens = pp.tokens.slice(),
802 .arena = arena,
803 .generated = pp.comp.generated_buf.items,
804 .nodes = p.nodes.toOwnedSlice(),
805 .data = data,
806 .root_decls = root_decls,
807 .value_map = p.value_map,
808 };
809}
810
811fn skipToPragmaSentinel(p: *Parser) void {
812 while (true) : (p.tok_i += 1) {
813 if (p.tok_ids[p.tok_i] == .nl) return;
814 if (p.tok_ids[p.tok_i] == .eof) {
815 p.tok_i -= 1;
816 return;
817 }
818 }
819}
820
821fn parseOrNextDecl(p: *Parser, comptime func: fn (*Parser) Error!bool) Compilation.Error!bool {
822 return func(p) catch |er| switch (er) {
823 error.ParsingFailed => {
824 p.nextExternDecl();
825 return true;
826 },
827 else => |e| return e,
828 };
829}
830
831fn nextExternDecl(p: *Parser) void {
832 var parens: u32 = 0;
833 while (true) : (p.tok_i += 1) {
834 switch (p.tok_ids[p.tok_i]) {
835 .l_paren, .l_brace, .l_bracket => parens += 1,
836 .r_paren, .r_brace, .r_bracket => if (parens != 0) {
837 parens -= 1;
838 },
839 .keyword_typedef,
840 .keyword_extern,
841 .keyword_static,
842 .keyword_auto,
843 .keyword_register,
844 .keyword_thread_local,
845 .keyword_c23_thread_local,
846 .keyword_inline,
847 .keyword_inline1,
848 .keyword_inline2,
849 .keyword_noreturn,
850 .keyword_void,
851 .keyword_bool,
852 .keyword_c23_bool,
853 .keyword_char,
854 .keyword_short,
855 .keyword_int,
856 .keyword_long,
857 .keyword_signed,
858 .keyword_unsigned,
859 .keyword_float,
860 .keyword_double,
861 .keyword_complex,
862 .keyword_atomic,
863 .keyword_enum,
864 .keyword_struct,
865 .keyword_union,
866 .keyword_alignas,
867 .keyword_c23_alignas,
868 .identifier,
869 .extended_identifier,
870 .keyword_typeof,
871 .keyword_typeof1,
872 .keyword_typeof2,
873 .keyword_typeof_unqual,
874 .keyword_extension,
875 .keyword_bit_int,
876 => if (parens == 0) return,
877 .keyword_pragma => p.skipToPragmaSentinel(),
878 .eof => return,
879 .semicolon => if (parens == 0) {
880 p.tok_i += 1;
881 return;
882 },
883 else => {},
884 }
885 }
886}
887
888fn skipTo(p: *Parser, id: Token.Id) void {
889 var parens: u32 = 0;
890 while (true) : (p.tok_i += 1) {
891 if (p.tok_ids[p.tok_i] == id and parens == 0) {
892 p.tok_i += 1;
893 return;
894 }
895 switch (p.tok_ids[p.tok_i]) {
896 .l_paren, .l_brace, .l_bracket => parens += 1,
897 .r_paren, .r_brace, .r_bracket => if (parens != 0) {
898 parens -= 1;
899 },
900 .keyword_pragma => p.skipToPragmaSentinel(),
901 .eof => return,
902 else => {},
903 }
904 }
905}
906
907/// Called after a typedef is defined
908fn typedefDefined(p: *Parser, name: StringId, ty: Type) void {
909 if (name == p.string_ids.file) {
910 p.comp.types.file = ty;
911 } else if (name == p.string_ids.jmp_buf) {
912 p.comp.types.jmp_buf = ty;
913 } else if (name == p.string_ids.sigjmp_buf) {
914 p.comp.types.sigjmp_buf = ty;
915 } else if (name == p.string_ids.ucontext_t) {
916 p.comp.types.ucontext_t = ty;
917 }
918}
919
920// ====== declarations ======
921
922/// decl
923/// : declSpec (initDeclarator ( ',' initDeclarator)*)? ';'
924/// | declSpec declarator decl* compoundStmt
925fn decl(p: *Parser) Error!bool {
926 _ = try p.pragma();
927 const first_tok = p.tok_i;
928 const attr_buf_top = p.attr_buf.len;
929 defer p.attr_buf.len = attr_buf_top;
930
931 try p.attributeSpecifier();
932
933 var decl_spec = if (try p.declSpec()) |some| some else blk: {
934 if (p.func.ty != null) {
935 p.tok_i = first_tok;
936 return false;
937 }
938 switch (p.tok_ids[first_tok]) {
939 .asterisk, .l_paren, .identifier, .extended_identifier => {},
940 else => if (p.tok_i != first_tok) {
941 try p.err(.expected_ident_or_l_paren);
942 return error.ParsingFailed;
943 } else return false,
944 }
945 var spec: Type.Builder = .{};
946 break :blk DeclSpec{ .ty = try spec.finish(p) };
947 };
948 if (decl_spec.noreturn) |tok| {
949 const attr = Attribute{ .tag = .noreturn, .args = .{ .noreturn = .{} }, .syntax = .keyword };
950 try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = tok });
951 }
952 var init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
953 _ = try p.expectToken(.semicolon);
954 if (decl_spec.ty.is(.@"enum") or
955 (decl_spec.ty.isRecord() and !decl_spec.ty.isAnonymousRecord(p.comp) and
956 !decl_spec.ty.isTypeof())) // we follow GCC and clang's behavior here
957 {
958 const specifier = decl_spec.ty.canonicalize(.standard).specifier;
959 const attrs = p.attr_buf.items(.attr)[attr_buf_top..];
960 const toks = p.attr_buf.items(.tok)[attr_buf_top..];
961 for (attrs, toks) |attr, tok| {
962 try p.errExtra(.ignored_record_attr, tok, .{
963 .ignored_record_attr = .{ .tag = attr.tag, .specifier = switch (specifier) {
964 .@"enum" => .@"enum",
965 .@"struct" => .@"struct",
966 .@"union" => .@"union",
967 else => unreachable,
968 } },
969 });
970 }
971 return true;
972 }
973
974 try p.errTok(.missing_declaration, first_tok);
975 return true;
976 };
977
978 // Check for function definition.
979 if (init_d.d.func_declarator != null and init_d.initializer.node == .none and init_d.d.ty.isFunc()) fn_def: {
980 if (decl_spec.auto_type) |tok_i| {
981 try p.errStr(.auto_type_not_allowed, tok_i, "function return type");
982 return error.ParsingFailed;
983 }
984
985 switch (p.tok_ids[p.tok_i]) {
986 .comma, .semicolon => break :fn_def,
987 .l_brace => {},
988 else => if (init_d.d.old_style_func == null) {
989 try p.err(.expected_fn_body);
990 return true;
991 },
992 }
993 if (p.func.ty != null) try p.err(.func_not_in_root);
994
995 const node = try p.addNode(undefined); // reserve space
996 const interned_declarator_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name));
997 try p.syms.defineSymbol(p, interned_declarator_name, init_d.d.ty, init_d.d.name, node, .{}, false);
998
999 const func = p.func;
1000 p.func = .{
1001 .ty = init_d.d.ty,
1002 .name = init_d.d.name,
1003 };
1004 if (interned_declarator_name == p.string_ids.main_id and !init_d.d.ty.returnType().is(.int)) {
1005 try p.errTok(.main_return_type, init_d.d.name);
1006 }
1007 defer p.func = func;
1008
1009 try p.syms.pushScope(p);
1010 defer p.syms.popScope();
1011
1012 // Collect old style parameter declarations.
1013 if (init_d.d.old_style_func != null) {
1014 const attrs = init_d.d.ty.getAttributes();
1015 var base_ty = if (init_d.d.ty.specifier == .attributed) init_d.d.ty.data.attributed.base else init_d.d.ty;
1016 base_ty.specifier = .func;
1017 init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);
1018
1019 const param_buf_top = p.param_buf.items.len;
1020 defer p.param_buf.items.len = param_buf_top;
1021
1022 param_loop: while (true) {
1023 const param_decl_spec = (try p.declSpec()) orelse break;
1024 if (p.eatToken(.semicolon)) |semi| {
1025 try p.errTok(.missing_declaration, semi);
1026 continue :param_loop;
1027 }
1028
1029 while (true) {
1030 const attr_buf_top_declarator = p.attr_buf.len;
1031 defer p.attr_buf.len = attr_buf_top_declarator;
1032
1033 var d = (try p.declarator(param_decl_spec.ty, .param)) orelse {
1034 try p.errTok(.missing_declaration, first_tok);
1035 _ = try p.expectToken(.semicolon);
1036 continue :param_loop;
1037 };
1038 try p.attributeSpecifier();
1039
1040 if (d.ty.hasIncompleteSize() and !d.ty.is(.void)) try p.errStr(.parameter_incomplete_ty, d.name, try p.typeStr(d.ty));
1041 if (d.ty.isFunc()) {
1042 // Params declared as functions are converted to function pointers.
1043 const elem_ty = try p.arena.create(Type);
1044 elem_ty.* = d.ty;
1045 d.ty = Type{
1046 .specifier = .pointer,
1047 .data = .{ .sub_type = elem_ty },
1048 };
1049 } else if (d.ty.isArray()) {
1050 // params declared as arrays are converted to pointers
1051 d.ty.decayArray();
1052 } else if (d.ty.is(.void)) {
1053 try p.errTok(.invalid_void_param, d.name);
1054 }
1055
1056 // find and correct parameter types
1057 // TODO check for missing declarations and redefinitions
1058 const name_str = p.tokSlice(d.name);
1059 const interned_name = try StrInt.intern(p.comp, name_str);
1060 for (init_d.d.ty.params()) |*param| {
1061 if (param.name == interned_name) {
1062 param.ty = d.ty;
1063 break;
1064 }
1065 } else {
1066 try p.errStr(.parameter_missing, d.name, name_str);
1067 }
1068 d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param);
1069
1070 // bypass redefinition check to avoid duplicate errors
1071 try p.syms.define(p.gpa, .{
1072 .kind = .def,
1073 .name = interned_name,
1074 .tok = d.name,
1075 .ty = d.ty,
1076 .val = .{},
1077 });
1078 if (p.eatToken(.comma) == null) break;
1079 }
1080 _ = try p.expectToken(.semicolon);
1081 }
1082 } else {
1083 for (init_d.d.ty.params()) |param| {
1084 if (param.ty.hasUnboundVLA()) try p.errTok(.unbound_vla, param.name_tok);
1085 if (param.ty.hasIncompleteSize() and !param.ty.is(.void) and param.ty.specifier != .invalid) try p.errStr(.parameter_incomplete_ty, param.name_tok, try p.typeStr(param.ty));
1086
1087 if (param.name == .empty) {
1088 try p.errTok(.omitting_parameter_name, param.name_tok);
1089 continue;
1090 }
1091
1092 // bypass redefinition check to avoid duplicate errors
1093 try p.syms.define(p.gpa, .{
1094 .kind = .def,
1095 .name = param.name,
1096 .tok = param.name_tok,
1097 .ty = param.ty,
1098 .val = .{},
1099 });
1100 }
1101 }
1102
1103 const body = (try p.compoundStmt(true, null)) orelse {
1104 assert(init_d.d.old_style_func != null);
1105 try p.err(.expected_fn_body);
1106 return true;
1107 };
1108 p.nodes.set(@intFromEnum(node), .{
1109 .ty = init_d.d.ty,
1110 .tag = try decl_spec.validateFnDef(p),
1111 .data = .{ .decl = .{ .name = init_d.d.name, .node = body } },
1112 });
1113 try p.decl_buf.append(node);
1114
1115 // check gotos
1116 if (func.ty == null) {
1117 for (p.labels.items) |item| {
1118 if (item == .unresolved_goto)
1119 try p.errStr(.undeclared_label, item.unresolved_goto, p.tokSlice(item.unresolved_goto));
1120 }
1121 if (p.computed_goto_tok) |goto_tok| {
1122 if (!p.contains_address_of_label) try p.errTok(.invalid_computed_goto, goto_tok);
1123 }
1124 p.labels.items.len = 0;
1125 p.label_count = 0;
1126 p.contains_address_of_label = false;
1127 p.computed_goto_tok = null;
1128 }
1129 return true;
1130 }
1131
1132 // Declare all variable/typedef declarators.
1133 var warned_auto = false;
1134 while (true) {
1135 if (init_d.d.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
1136 const tag = try decl_spec.validate(p, &init_d.d.ty, init_d.initializer.node != .none);
1137
1138 const node = try p.addNode(.{ .ty = init_d.d.ty, .tag = tag, .data = .{
1139 .decl = .{ .name = init_d.d.name, .node = init_d.initializer.node },
1140 } });
1141 try p.decl_buf.append(node);
1142
1143 const interned_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name));
1144 if (decl_spec.storage_class == .typedef) {
1145 try p.syms.defineTypedef(p, interned_name, init_d.d.ty, init_d.d.name, node);
1146 p.typedefDefined(interned_name, init_d.d.ty);
1147 } else if (init_d.initializer.node != .none or
1148 (p.func.ty != null and decl_spec.storage_class != .@"extern"))
1149 {
1150 // TODO validate global variable/constexpr initializer comptime known
1151 try p.syms.defineSymbol(
1152 p,
1153 interned_name,
1154 init_d.d.ty,
1155 init_d.d.name,
1156 node,
1157 if (init_d.d.ty.isConst() or decl_spec.constexpr != null) init_d.initializer.val else .{},
1158 decl_spec.constexpr != null,
1159 );
1160 } else {
1161 try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, node);
1162 }
1163
1164 if (p.eatToken(.comma) == null) break;
1165
1166 if (!warned_auto) {
1167 if (decl_spec.auto_type) |tok_i| {
1168 try p.errTok(.auto_type_requires_single_declarator, tok_i);
1169 warned_auto = true;
1170 }
1171 if (p.comp.langopts.standard.atLeast(.c23) and decl_spec.storage_class == .auto) {
1172 try p.errTok(.c23_auto_single_declarator, decl_spec.storage_class.auto);
1173 warned_auto = true;
1174 }
1175 }
1176
1177 init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
1178 try p.err(.expected_ident_or_l_paren);
1179 continue;
1180 };
1181 }
1182
1183 _ = try p.expectToken(.semicolon);
1184 return true;
1185}
1186
1187fn staticAssertMessage(p: *Parser, cond_node: NodeIndex, message: Result) !?[]const u8 {
1188 const cond_tag = p.nodes.items(.tag)[@intFromEnum(cond_node)];
1189 if (cond_tag != .builtin_types_compatible_p and message.node == .none) return null;
1190
1191 var buf = std.ArrayList(u8).init(p.gpa);
1192 defer buf.deinit();
1193
1194 if (cond_tag == .builtin_types_compatible_p) {
1195 const mapper = p.comp.string_interner.getSlowTypeMapper();
1196 const data = p.nodes.items(.data)[@intFromEnum(cond_node)].bin;
1197
1198 try buf.appendSlice("'__builtin_types_compatible_p(");
1199
1200 const lhs_ty = p.nodes.items(.ty)[@intFromEnum(data.lhs)];
1201 try lhs_ty.print(mapper, p.comp.langopts, buf.writer());
1202 try buf.appendSlice(", ");
1203
1204 const rhs_ty = p.nodes.items(.ty)[@intFromEnum(data.rhs)];
1205 try rhs_ty.print(mapper, p.comp.langopts, buf.writer());
1206
1207 try buf.appendSlice(")'");
1208 }
1209 if (message.node != .none) {
1210 assert(p.nodes.items(.tag)[@intFromEnum(message.node)] == .string_literal_expr);
1211 if (buf.items.len > 0) {
1212 try buf.append(' ');
1213 }
1214 const bytes = p.comp.interner.get(message.val.ref()).bytes;
1215 try buf.ensureUnusedCapacity(bytes.len);
1216 try Value.printString(bytes, message.ty, p.comp, buf.writer());
1217 }
1218 return try p.comp.diagnostics.arena.allocator().dupe(u8, buf.items);
1219}
1220
1221/// staticAssert
1222/// : keyword_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
1223/// | keyword_c23_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
1224fn staticAssert(p: *Parser) Error!bool {
1225 const static_assert = p.eatToken(.keyword_static_assert) orelse p.eatToken(.keyword_c23_static_assert) orelse return false;
1226 const l_paren = try p.expectToken(.l_paren);
1227 const res_token = p.tok_i;
1228 var res = try p.constExpr(.gnu_folding_extension);
1229 const res_node = res.node;
1230 const str = if (p.eatToken(.comma) != null)
1231 switch (p.tok_ids[p.tok_i]) {
1232 .string_literal,
1233 .string_literal_utf_16,
1234 .string_literal_utf_8,
1235 .string_literal_utf_32,
1236 .string_literal_wide,
1237 .unterminated_string_literal,
1238 => try p.stringLiteral(),
1239 else => {
1240 try p.err(.expected_str_literal);
1241 return error.ParsingFailed;
1242 },
1243 }
1244 else
1245 Result{};
1246 try p.expectClosing(l_paren, .r_paren);
1247 _ = try p.expectToken(.semicolon);
1248 if (str.node == .none) {
1249 try p.errTok(.static_assert_missing_message, static_assert);
1250 try p.errStr(.pre_c23_compat, static_assert, "'_Static_assert' with no message");
1251 }
1252
1253 // Array will never be zero; a value of zero for a pointer is a null pointer constant
1254 if ((res.ty.isArray() or res.ty.isPtr()) and !res.val.isZero(p.comp)) {
1255 const err_start = p.comp.diagnostics.list.items.len;
1256 try p.errTok(.const_decl_folded, res_token);
1257 if (res.ty.isPtr() and err_start != p.comp.diagnostics.list.items.len) {
1258 // Don't show the note if the .const_decl_folded diagnostic was not added
1259 try p.errTok(.constant_expression_conversion_not_allowed, res_token);
1260 }
1261 }
1262 try res.boolCast(p, .{ .specifier = .bool }, res_token);
1263 if (res.val.opt_ref == .none) {
1264 if (res.ty.specifier != .invalid) {
1265 try p.errTok(.static_assert_not_constant, res_token);
1266 }
1267 } else {
1268 if (!res.val.toBool(p.comp)) {
1269 if (try p.staticAssertMessage(res_node, str)) |message| {
1270 try p.errStr(.static_assert_failure_message, static_assert, message);
1271 } else {
1272 try p.errTok(.static_assert_failure, static_assert);
1273 }
1274 }
1275 }
1276
1277 const node = try p.addNode(.{
1278 .tag = .static_assert,
1279 .data = .{ .bin = .{
1280 .lhs = res.node,
1281 .rhs = str.node,
1282 } },
1283 });
1284 try p.decl_buf.append(node);
1285 return true;
1286}
1287
1288pub const DeclSpec = struct {
1289 storage_class: union(enum) {
1290 auto: TokenIndex,
1291 @"extern": TokenIndex,
1292 register: TokenIndex,
1293 static: TokenIndex,
1294 typedef: TokenIndex,
1295 none,
1296 } = .none,
1297 thread_local: ?TokenIndex = null,
1298 constexpr: ?TokenIndex = null,
1299 @"inline": ?TokenIndex = null,
1300 noreturn: ?TokenIndex = null,
1301 auto_type: ?TokenIndex = null,
1302 ty: Type,
1303
1304 fn validateParam(d: DeclSpec, p: *Parser, ty: *Type) Error!void {
1305 switch (d.storage_class) {
1306 .none => {},
1307 .register => ty.qual.register = true,
1308 .auto, .@"extern", .static, .typedef => |tok_i| try p.errTok(.invalid_storage_on_param, tok_i),
1309 }
1310 if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
1311 if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
1312 if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
1313 if (d.constexpr) |tok_i| try p.errTok(.invalid_storage_on_param, tok_i);
1314 if (d.auto_type) |tok_i| {
1315 try p.errStr(.auto_type_not_allowed, tok_i, "function prototype");
1316 ty.* = Type.invalid;
1317 }
1318 }
1319
1320 fn validateFnDef(d: DeclSpec, p: *Parser) Error!Tree.Tag {
1321 switch (d.storage_class) {
1322 .none, .@"extern", .static => {},
1323 .auto, .register, .typedef => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
1324 }
1325 if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
1326 if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
1327
1328 const is_static = d.storage_class == .static;
1329 const is_inline = d.@"inline" != null;
1330 if (is_static) {
1331 if (is_inline) return .inline_static_fn_def;
1332 return .static_fn_def;
1333 } else {
1334 if (is_inline) return .inline_fn_def;
1335 return .fn_def;
1336 }
1337 }
1338
1339 fn validate(d: DeclSpec, p: *Parser, ty: *Type, has_init: bool) Error!Tree.Tag {
1340 const is_static = d.storage_class == .static;
1341 if (ty.isFunc() and d.storage_class != .typedef) {
1342 switch (d.storage_class) {
1343 .none, .@"extern" => {},
1344 .static => |tok_i| if (p.func.ty != null) try p.errTok(.static_func_not_global, tok_i),
1345 .typedef => unreachable,
1346 .auto, .register => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
1347 }
1348 if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
1349 if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
1350
1351 const is_inline = d.@"inline" != null;
1352 if (is_static) {
1353 if (is_inline) return .inline_static_fn_proto;
1354 return .static_fn_proto;
1355 } else {
1356 if (is_inline) return .inline_fn_proto;
1357 return .fn_proto;
1358 }
1359 } else {
1360 if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
1361 // TODO move to attribute validation
1362 if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
1363 switch (d.storage_class) {
1364 .auto => if (p.func.ty == null and !p.comp.langopts.standard.atLeast(.c23)) {
1365 try p.err(.illegal_storage_on_global);
1366 },
1367 .register => if (p.func.ty == null) try p.err(.illegal_storage_on_global),
1368 .typedef => return .typedef,
1369 else => {},
1370 }
1371 ty.qual.register = d.storage_class == .register;
1372
1373 const is_extern = d.storage_class == .@"extern" and !has_init;
1374 if (d.thread_local != null) {
1375 if (is_static) return .threadlocal_static_var;
1376 if (is_extern) return .threadlocal_extern_var;
1377 return .threadlocal_var;
1378 } else {
1379 if (is_static) return .static_var;
1380 if (is_extern) return .extern_var;
1381 return .@"var";
1382 }
1383 }
1384 }
1385};
1386
1387/// typeof
1388/// : keyword_typeof '(' typeName ')'
1389/// | keyword_typeof '(' expr ')'
1390fn typeof(p: *Parser) Error!?Type {
1391 var unqual = false;
1392 switch (p.tok_ids[p.tok_i]) {
1393 .keyword_typeof, .keyword_typeof1, .keyword_typeof2 => p.tok_i += 1,
1394 .keyword_typeof_unqual => {
1395 p.tok_i += 1;
1396 unqual = true;
1397 },
1398 else => return null,
1399 }
1400 const l_paren = try p.expectToken(.l_paren);
1401 if (try p.typeName()) |ty| {
1402 try p.expectClosing(l_paren, .r_paren);
1403 const typeof_ty = try p.arena.create(Type);
1404 typeof_ty.* = .{
1405 .data = ty.data,
1406 .qual = if (unqual) .{} else ty.qual.inheritFromTypeof(),
1407 .specifier = ty.specifier,
1408 };
1409
1410 return Type{
1411 .data = .{ .sub_type = typeof_ty },
1412 .specifier = .typeof_type,
1413 };
1414 }
1415 const typeof_expr = try p.parseNoEval(expr);
1416 try typeof_expr.expect(p);
1417 try p.expectClosing(l_paren, .r_paren);
1418 // Special case nullptr_t since it's defined as typeof(nullptr)
1419 if (typeof_expr.ty.is(.nullptr_t)) {
1420 return Type{
1421 .specifier = .nullptr_t,
1422 .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
1423 };
1424 }
1425
1426 const inner = try p.arena.create(Type.Expr);
1427 inner.* = .{
1428 .node = typeof_expr.node,
1429 .ty = .{
1430 .data = typeof_expr.ty.data,
1431 .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
1432 .specifier = typeof_expr.ty.specifier,
1433 .decayed = typeof_expr.ty.decayed,
1434 },
1435 };
1436
1437 return Type{
1438 .data = .{ .expr = inner },
1439 .specifier = .typeof_expr,
1440 .decayed = typeof_expr.ty.decayed,
1441 };
1442}
1443
1444/// declSpec: (storageClassSpec | typeSpec | typeQual | funcSpec | alignSpec)+
1445/// funcSpec : keyword_inline | keyword_noreturn
1446fn declSpec(p: *Parser) Error!?DeclSpec {
1447 var d: DeclSpec = .{ .ty = .{ .specifier = undefined } };
1448 var spec: Type.Builder = .{};
1449
1450 var combined_auto = !p.comp.langopts.standard.atLeast(.c23);
1451 const start = p.tok_i;
1452 while (true) {
1453 if (!combined_auto and d.storage_class == .auto) {
1454 try spec.combine(p, .c23_auto, d.storage_class.auto);
1455 combined_auto = true;
1456 }
1457 if (try p.storageClassSpec(&d)) continue;
1458 if (try p.typeSpec(&spec)) continue;
1459 const id = p.tok_ids[p.tok_i];
1460 switch (id) {
1461 .keyword_inline, .keyword_inline1, .keyword_inline2 => {
1462 if (d.@"inline" != null) {
1463 try p.errStr(.duplicate_decl_spec, p.tok_i, "inline");
1464 }
1465 d.@"inline" = p.tok_i;
1466 },
1467 .keyword_noreturn => {
1468 if (d.noreturn != null) {
1469 try p.errStr(.duplicate_decl_spec, p.tok_i, "_Noreturn");
1470 }
1471 d.noreturn = p.tok_i;
1472 },
1473 else => break,
1474 }
1475 p.tok_i += 1;
1476 }
1477
1478 if (p.tok_i == start) return null;
1479
1480 d.ty = try spec.finish(p);
1481 d.auto_type = spec.auto_type_tok;
1482 return d;
1483}
1484
1485/// storageClassSpec:
1486/// : keyword_typedef
1487/// | keyword_extern
1488/// | keyword_static
1489/// | keyword_threadlocal
1490/// | keyword_auto
1491/// | keyword_register
1492fn storageClassSpec(p: *Parser, d: *DeclSpec) Error!bool {
1493 const start = p.tok_i;
1494 while (true) {
1495 const id = p.tok_ids[p.tok_i];
1496 switch (id) {
1497 .keyword_typedef,
1498 .keyword_extern,
1499 .keyword_static,
1500 .keyword_auto,
1501 .keyword_register,
1502 => {
1503 if (d.storage_class != .none) {
1504 try p.errStr(.multiple_storage_class, p.tok_i, @tagName(d.storage_class));
1505 return error.ParsingFailed;
1506 }
1507 if (d.thread_local != null) {
1508 switch (id) {
1509 .keyword_extern, .keyword_static => {},
1510 else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
1511 }
1512 if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1513 }
1514 if (d.constexpr != null) {
1515 switch (id) {
1516 .keyword_auto, .keyword_register, .keyword_static => {},
1517 else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
1518 }
1519 if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1520 }
1521 switch (id) {
1522 .keyword_typedef => d.storage_class = .{ .typedef = p.tok_i },
1523 .keyword_extern => d.storage_class = .{ .@"extern" = p.tok_i },
1524 .keyword_static => d.storage_class = .{ .static = p.tok_i },
1525 .keyword_auto => d.storage_class = .{ .auto = p.tok_i },
1526 .keyword_register => d.storage_class = .{ .register = p.tok_i },
1527 else => unreachable,
1528 }
1529 },
1530 .keyword_thread_local,
1531 .keyword_c23_thread_local,
1532 => {
1533 if (d.thread_local != null) {
1534 try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
1535 }
1536 if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1537 switch (d.storage_class) {
1538 .@"extern", .none, .static => {},
1539 else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
1540 }
1541 d.thread_local = p.tok_i;
1542 },
1543 .keyword_constexpr => {
1544 if (d.constexpr != null) {
1545 try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
1546 }
1547 if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1548 switch (d.storage_class) {
1549 .auto, .register, .none, .static => {},
1550 else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
1551 }
1552 d.constexpr = p.tok_i;
1553 },
1554 else => break,
1555 }
1556 p.tok_i += 1;
1557 }
1558 return p.tok_i != start;
1559}
1560
1561const InitDeclarator = struct { d: Declarator, initializer: Result = .{} };
1562
1563/// attribute
1564/// : attrIdentifier
1565/// | attrIdentifier '(' identifier ')'
1566/// | attrIdentifier '(' identifier (',' expr)+ ')'
1567/// | attrIdentifier '(' (expr (',' expr)*)? ')'
1568fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?TentativeAttribute {
1569 const name_tok = p.tok_i;
1570 switch (p.tok_ids[p.tok_i]) {
1571 .keyword_const, .keyword_const1, .keyword_const2 => p.tok_i += 1,
1572 else => _ = try p.expectIdentifier(),
1573 }
1574 const name = p.tokSlice(name_tok);
1575
1576 const attr = Attribute.fromString(kind, namespace, name) orelse {
1577 const tag: Diagnostics.Tag = if (kind == .declspec) .declspec_attr_not_supported else .unknown_attribute;
1578 try p.errStr(tag, name_tok, name);
1579 if (p.eatToken(.l_paren)) |_| p.skipTo(.r_paren);
1580 return null;
1581 };
1582
1583 const required_count = Attribute.requiredArgCount(attr);
1584 var arguments = Attribute.initArguments(attr, name_tok);
1585 var arg_idx: u32 = 0;
1586
1587 switch (p.tok_ids[p.tok_i]) {
1588 .comma, .r_paren => {}, // will be consumed in attributeList
1589 .l_paren => blk: {
1590 p.tok_i += 1;
1591 if (p.eatToken(.r_paren)) |_| break :blk;
1592
1593 if (Attribute.wantsIdentEnum(attr)) {
1594 if (try p.eatIdentifier()) |ident| {
1595 if (Attribute.diagnoseIdent(attr, &arguments, p.tokSlice(ident))) |msg| {
1596 try p.errExtra(msg.tag, ident, msg.extra);
1597 p.skipTo(.r_paren);
1598 return error.ParsingFailed;
1599 }
1600 } else {
1601 try p.errExtra(.attribute_requires_identifier, name_tok, .{ .str = name });
1602 return error.ParsingFailed;
1603 }
1604 } else {
1605 const arg_start = p.tok_i;
1606 var first_expr = try p.assignExpr();
1607 try first_expr.expect(p);
1608 if (try p.diagnose(attr, &arguments, arg_idx, first_expr)) |msg| {
1609 try p.errExtra(msg.tag, arg_start, msg.extra);
1610 p.skipTo(.r_paren);
1611 return error.ParsingFailed;
1612 }
1613 }
1614 arg_idx += 1;
1615 while (p.eatToken(.r_paren) == null) : (arg_idx += 1) {
1616 _ = try p.expectToken(.comma);
1617
1618 const arg_start = p.tok_i;
1619 var arg_expr = try p.assignExpr();
1620 try arg_expr.expect(p);
1621 if (try p.diagnose(attr, &arguments, arg_idx, arg_expr)) |msg| {
1622 try p.errExtra(msg.tag, arg_start, msg.extra);
1623 p.skipTo(.r_paren);
1624 return error.ParsingFailed;
1625 }
1626 }
1627 },
1628 else => {},
1629 }
1630 if (arg_idx < required_count) {
1631 try p.errExtra(.attribute_not_enough_args, name_tok, .{ .attr_arg_count = .{ .attribute = attr, .expected = required_count } });
1632 return error.ParsingFailed;
1633 }
1634 return TentativeAttribute{ .attr = .{ .tag = attr, .args = arguments, .syntax = kind.toSyntax() }, .tok = name_tok };
1635}
1636
1637fn diagnose(p: *Parser, attr: Attribute.Tag, arguments: *Attribute.Arguments, arg_idx: u32, res: Result) !?Diagnostics.Message {
1638 if (Attribute.wantsAlignment(attr, arg_idx)) {
1639 return Attribute.diagnoseAlignment(attr, arguments, arg_idx, res, p);
1640 }
1641 const node = p.nodes.get(@intFromEnum(res.node));
1642 return Attribute.diagnose(attr, arguments, arg_idx, res, node, p);
1643}
1644
1645/// attributeList : (attribute (',' attribute)*)?
1646fn gnuAttributeList(p: *Parser) Error!void {
1647 if (p.tok_ids[p.tok_i] == .r_paren) return;
1648
1649 if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
1650 while (p.tok_ids[p.tok_i] != .r_paren) {
1651 _ = try p.expectToken(.comma);
1652 if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
1653 }
1654}
1655
1656fn c23AttributeList(p: *Parser) Error!void {
1657 while (p.tok_ids[p.tok_i] != .r_bracket) {
1658 const namespace_tok = try p.expectIdentifier();
1659 var namespace: ?[]const u8 = null;
1660 if (p.eatToken(.colon_colon)) |_| {
1661 namespace = p.tokSlice(namespace_tok);
1662 } else {
1663 p.tok_i -= 1;
1664 }
1665 if (try p.attribute(.c23, namespace)) |attr| try p.attr_buf.append(p.gpa, attr);
1666 _ = p.eatToken(.comma);
1667 }
1668}
1669
1670fn msvcAttributeList(p: *Parser) Error!void {
1671 while (p.tok_ids[p.tok_i] != .r_paren) {
1672 if (try p.attribute(.declspec, null)) |attr| try p.attr_buf.append(p.gpa, attr);
1673 _ = p.eatToken(.comma);
1674 }
1675}
1676
1677fn c23Attribute(p: *Parser) !bool {
1678 if (!p.comp.langopts.standard.atLeast(.c23)) return false;
1679 const bracket1 = p.eatToken(.l_bracket) orelse return false;
1680 const bracket2 = p.eatToken(.l_bracket) orelse {
1681 p.tok_i -= 1;
1682 return false;
1683 };
1684
1685 try p.c23AttributeList();
1686
1687 _ = try p.expectClosing(bracket2, .r_bracket);
1688 _ = try p.expectClosing(bracket1, .r_bracket);
1689
1690 return true;
1691}
1692
1693fn msvcAttribute(p: *Parser) !bool {
1694 _ = p.eatToken(.keyword_declspec) orelse return false;
1695 const l_paren = try p.expectToken(.l_paren);
1696 try p.msvcAttributeList();
1697 _ = try p.expectClosing(l_paren, .r_paren);
1698
1699 return true;
1700}
1701
1702fn gnuAttribute(p: *Parser) !bool {
1703 switch (p.tok_ids[p.tok_i]) {
1704 .keyword_attribute1, .keyword_attribute2 => p.tok_i += 1,
1705 else => return false,
1706 }
1707 const paren1 = try p.expectToken(.l_paren);
1708 const paren2 = try p.expectToken(.l_paren);
1709
1710 try p.gnuAttributeList();
1711
1712 _ = try p.expectClosing(paren2, .r_paren);
1713 _ = try p.expectClosing(paren1, .r_paren);
1714 return true;
1715}
1716
1717fn attributeSpecifier(p: *Parser) Error!void {
1718 return attributeSpecifierExtra(p, null);
1719}
1720
1721/// attributeSpecifier : (keyword_attribute '( '(' attributeList ')' ')')*
1722fn attributeSpecifierExtra(p: *Parser, declarator_name: ?TokenIndex) Error!void {
1723 while (true) {
1724 if (try p.gnuAttribute()) continue;
1725 if (try p.c23Attribute()) continue;
1726 const maybe_declspec_tok = p.tok_i;
1727 const attr_buf_top = p.attr_buf.len;
1728 if (try p.msvcAttribute()) {
1729 if (declarator_name) |name_tok| {
1730 try p.errTok(.declspec_not_allowed_after_declarator, maybe_declspec_tok);
1731 try p.errTok(.declarator_name_tok, name_tok);
1732 p.attr_buf.len = attr_buf_top;
1733 }
1734 continue;
1735 }
1736 break;
1737 }
1738}
1739
1740/// initDeclarator : declarator assembly? attributeSpecifier? ('=' initializer)?
1741fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?InitDeclarator {
1742 const this_attr_buf_top = p.attr_buf.len;
1743 defer p.attr_buf.len = this_attr_buf_top;
1744
1745 var init_d = InitDeclarator{
1746 .d = (try p.declarator(decl_spec.ty, .normal)) orelse return null,
1747 };
1748
1749 if (decl_spec.ty.is(.c23_auto) and !init_d.d.ty.is(.c23_auto)) {
1750 try p.errTok(.c23_auto_plain_declarator, decl_spec.storage_class.auto);
1751 return error.ParsingFailed;
1752 }
1753
1754 try p.attributeSpecifierExtra(init_d.d.name);
1755 _ = try p.assembly(.decl_label);
1756 try p.attributeSpecifierExtra(init_d.d.name);
1757
1758 var apply_var_attributes = false;
1759 if (decl_spec.storage_class == .typedef) {
1760 if (decl_spec.auto_type) |tok_i| {
1761 try p.errStr(.auto_type_not_allowed, tok_i, "typedef");
1762 return error.ParsingFailed;
1763 }
1764 init_d.d.ty = try Attribute.applyTypeAttributes(p, init_d.d.ty, attr_buf_top, null);
1765 } else if (init_d.d.ty.isFunc()) {
1766 init_d.d.ty = try Attribute.applyFunctionAttributes(p, init_d.d.ty, attr_buf_top);
1767 } else {
1768 apply_var_attributes = true;
1769 }
1770
1771 if (p.eatToken(.equal)) |eq| init: {
1772 if (decl_spec.storage_class == .typedef or
1773 (init_d.d.func_declarator != null and init_d.d.ty.isFunc()))
1774 {
1775 try p.errTok(.illegal_initializer, eq);
1776 } else if (init_d.d.ty.is(.variable_len_array)) {
1777 try p.errTok(.vla_init, eq);
1778 } else if (decl_spec.storage_class == .@"extern") {
1779 try p.err(.extern_initializer);
1780 decl_spec.storage_class = .none;
1781 }
1782
1783 if (init_d.d.ty.hasIncompleteSize() and !init_d.d.ty.is(.incomplete_array)) {
1784 try p.errStr(.variable_incomplete_ty, init_d.d.name, try p.typeStr(init_d.d.ty));
1785 return error.ParsingFailed;
1786 }
1787 if (p.tok_ids[p.tok_i] == .l_brace and init_d.d.ty.is(.c23_auto)) {
1788 try p.errTok(.c23_auto_scalar_init, decl_spec.storage_class.auto);
1789 return error.ParsingFailed;
1790 }
1791
1792 try p.syms.pushScope(p);
1793 defer p.syms.popScope();
1794
1795 const interned_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name));
1796 try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, .none);
1797 var init_list_expr = try p.initializer(init_d.d.ty);
1798 init_d.initializer = init_list_expr;
1799 if (!init_list_expr.ty.isArray()) break :init;
1800 if (init_d.d.ty.specifier == .incomplete_array) {
1801 // Modifying .data is exceptionally allowed for .incomplete_array.
1802 init_d.d.ty.data.array.len = init_list_expr.ty.arrayLen() orelse break :init;
1803 init_d.d.ty.specifier = .array;
1804 }
1805 }
1806
1807 const name = init_d.d.name;
1808 const c23_auto = init_d.d.ty.is(.c23_auto);
1809 if (init_d.d.ty.is(.auto_type) or c23_auto) {
1810 if (init_d.initializer.node == .none) {
1811 init_d.d.ty = Type.invalid;
1812 if (c23_auto) {
1813 try p.errStr(.c32_auto_requires_initializer, decl_spec.storage_class.auto, p.tokSlice(name));
1814 } else {
1815 try p.errStr(.auto_type_requires_initializer, name, p.tokSlice(name));
1816 }
1817 return init_d;
1818 } else {
1819 init_d.d.ty.specifier = init_d.initializer.ty.specifier;
1820 init_d.d.ty.data = init_d.initializer.ty.data;
1821 init_d.d.ty.decayed = init_d.initializer.ty.decayed;
1822 }
1823 }
1824 if (apply_var_attributes) {
1825 init_d.d.ty = try Attribute.applyVariableAttributes(p, init_d.d.ty, attr_buf_top, null);
1826 }
1827 if (decl_spec.storage_class != .typedef and init_d.d.ty.hasIncompleteSize()) incomplete: {
1828 const specifier = init_d.d.ty.canonicalize(.standard).specifier;
1829 if (decl_spec.storage_class == .@"extern") switch (specifier) {
1830 .@"struct", .@"union", .@"enum" => break :incomplete,
1831 .incomplete_array => {
1832 init_d.d.ty.decayArray();
1833 break :incomplete;
1834 },
1835 else => {},
1836 };
1837 // if there was an initializer expression it must have contained an error
1838 if (init_d.initializer.node != .none) break :incomplete;
1839
1840 if (p.func.ty == null) {
1841 if (specifier == .incomplete_array) {
1842 // TODO properly check this after finishing parsing
1843 try p.errStr(.tentative_array, name, try p.typeStr(init_d.d.ty));
1844 break :incomplete;
1845 } else if (init_d.d.ty.getRecord()) |record| {
1846 _ = try p.tentative_defs.getOrPutValue(p.gpa, record.name, init_d.d.name);
1847 break :incomplete;
1848 } else if (init_d.d.ty.get(.@"enum")) |en| {
1849 _ = try p.tentative_defs.getOrPutValue(p.gpa, en.data.@"enum".name, init_d.d.name);
1850 break :incomplete;
1851 }
1852 }
1853 try p.errStr(.variable_incomplete_ty, name, try p.typeStr(init_d.d.ty));
1854 }
1855 return init_d;
1856}
1857
1858/// typeSpec
1859/// : keyword_void
1860/// | keyword_auto_type
1861/// | keyword_char
1862/// | keyword_short
1863/// | keyword_int
1864/// | keyword_long
1865/// | keyword_float
1866/// | keyword_double
1867/// | keyword_signed
1868/// | keyword_unsigned
1869/// | keyword_bool
1870/// | keyword_c23_bool
1871/// | keyword_complex
1872/// | atomicTypeSpec
1873/// | recordSpec
1874/// | enumSpec
1875/// | typedef // IDENTIFIER
1876/// | typeof
1877/// | keyword_bit_int '(' integerConstExpr ')'
1878/// atomicTypeSpec : keyword_atomic '(' typeName ')'
1879/// alignSpec
1880/// : keyword_alignas '(' typeName ')'
1881/// | keyword_alignas '(' integerConstExpr ')'
1882/// | keyword_c23_alignas '(' typeName ')'
1883/// | keyword_c23_alignas '(' integerConstExpr ')'
1884fn typeSpec(p: *Parser, ty: *Type.Builder) Error!bool {
1885 const start = p.tok_i;
1886 while (true) {
1887 try p.attributeSpecifier();
1888
1889 if (try p.typeof()) |inner_ty| {
1890 try ty.combineFromTypeof(p, inner_ty, start);
1891 continue;
1892 }
1893 if (try p.typeQual(&ty.qual)) continue;
1894 switch (p.tok_ids[p.tok_i]) {
1895 .keyword_void => try ty.combine(p, .void, p.tok_i),
1896 .keyword_auto_type => {
1897 try p.errTok(.auto_type_extension, p.tok_i);
1898 try ty.combine(p, .auto_type, p.tok_i);
1899 },
1900 .keyword_bool, .keyword_c23_bool => try ty.combine(p, .bool, p.tok_i),
1901 .keyword_int8, .keyword_int8_2, .keyword_char => try ty.combine(p, .char, p.tok_i),
1902 .keyword_int16, .keyword_int16_2, .keyword_short => try ty.combine(p, .short, p.tok_i),
1903 .keyword_int32, .keyword_int32_2, .keyword_int => try ty.combine(p, .int, p.tok_i),
1904 .keyword_long => try ty.combine(p, .long, p.tok_i),
1905 .keyword_int64, .keyword_int64_2 => try ty.combine(p, .long_long, p.tok_i),
1906 .keyword_int128 => try ty.combine(p, .int128, p.tok_i),
1907 .keyword_signed => try ty.combine(p, .signed, p.tok_i),
1908 .keyword_unsigned => try ty.combine(p, .unsigned, p.tok_i),
1909 .keyword_fp16 => try ty.combine(p, .fp16, p.tok_i),
1910 .keyword_float16 => try ty.combine(p, .float16, p.tok_i),
1911 .keyword_float => try ty.combine(p, .float, p.tok_i),
1912 .keyword_double => try ty.combine(p, .double, p.tok_i),
1913 .keyword_complex => try ty.combine(p, .complex, p.tok_i),
1914 .keyword_float80 => try ty.combine(p, .float80, p.tok_i),
1915 .keyword_float128_1, .keyword_float128_2 => {
1916 if (!p.comp.hasFloat128()) {
1917 try p.errStr(.type_not_supported_on_target, p.tok_i, p.tok_ids[p.tok_i].lexeme().?);
1918 }
1919 try ty.combine(p, .float128, p.tok_i);
1920 },
1921 .keyword_atomic => {
1922 const atomic_tok = p.tok_i;
1923 p.tok_i += 1;
1924 const l_paren = p.eatToken(.l_paren) orelse {
1925 // _Atomic qualifier not _Atomic(typeName)
1926 p.tok_i = atomic_tok;
1927 break;
1928 };
1929 const inner_ty = (try p.typeName()) orelse {
1930 try p.err(.expected_type);
1931 return error.ParsingFailed;
1932 };
1933 try p.expectClosing(l_paren, .r_paren);
1934
1935 const new_spec = Type.Builder.fromType(inner_ty);
1936 try ty.combine(p, new_spec, atomic_tok);
1937
1938 if (ty.qual.atomic != null)
1939 try p.errStr(.duplicate_decl_spec, atomic_tok, "atomic")
1940 else
1941 ty.qual.atomic = atomic_tok;
1942 continue;
1943 },
1944 .keyword_alignas,
1945 .keyword_c23_alignas,
1946 => {
1947 const align_tok = p.tok_i;
1948 p.tok_i += 1;
1949 const l_paren = try p.expectToken(.l_paren);
1950 const typename_start = p.tok_i;
1951 if (try p.typeName()) |inner_ty| {
1952 if (!inner_ty.alignable()) {
1953 try p.errStr(.invalid_alignof, typename_start, try p.typeStr(inner_ty));
1954 }
1955 const alignment = Attribute.Alignment{ .requested = inner_ty.alignof(p.comp) };
1956 try p.attr_buf.append(p.gpa, .{
1957 .attr = .{ .tag = .aligned, .args = .{
1958 .aligned = .{ .alignment = alignment, .__name_tok = align_tok },
1959 }, .syntax = .keyword },
1960 .tok = align_tok,
1961 });
1962 } else {
1963 const arg_start = p.tok_i;
1964 const res = try p.integerConstExpr(.no_const_decl_folding);
1965 if (!res.val.isZero(p.comp)) {
1966 var args = Attribute.initArguments(.aligned, align_tok);
1967 if (try p.diagnose(.aligned, &args, 0, res)) |msg| {
1968 try p.errExtra(msg.tag, arg_start, msg.extra);
1969 p.skipTo(.r_paren);
1970 return error.ParsingFailed;
1971 }
1972 args.aligned.alignment.?.node = res.node;
1973 try p.attr_buf.append(p.gpa, .{
1974 .attr = .{ .tag = .aligned, .args = args, .syntax = .keyword },
1975 .tok = align_tok,
1976 });
1977 }
1978 }
1979 try p.expectClosing(l_paren, .r_paren);
1980 continue;
1981 },
1982 .keyword_stdcall,
1983 .keyword_stdcall2,
1984 .keyword_thiscall,
1985 .keyword_thiscall2,
1986 .keyword_vectorcall,
1987 .keyword_vectorcall2,
1988 => try p.attr_buf.append(p.gpa, .{
1989 .attr = .{ .tag = .calling_convention, .args = .{
1990 .calling_convention = .{ .cc = switch (p.tok_ids[p.tok_i]) {
1991 .keyword_stdcall,
1992 .keyword_stdcall2,
1993 => .stdcall,
1994 .keyword_thiscall,
1995 .keyword_thiscall2,
1996 => .thiscall,
1997 .keyword_vectorcall,
1998 .keyword_vectorcall2,
1999 => .vectorcall,
2000 else => unreachable,
2001 } },
2002 }, .syntax = .keyword },
2003 .tok = p.tok_i,
2004 }),
2005 .keyword_struct, .keyword_union => {
2006 const tag_tok = p.tok_i;
2007 const record_ty = try p.recordSpec();
2008 try ty.combine(p, Type.Builder.fromType(record_ty), tag_tok);
2009 continue;
2010 },
2011 .keyword_enum => {
2012 const tag_tok = p.tok_i;
2013 const enum_ty = try p.enumSpec();
2014 try ty.combine(p, Type.Builder.fromType(enum_ty), tag_tok);
2015 continue;
2016 },
2017 .identifier, .extended_identifier => {
2018 var interned_name = try StrInt.intern(p.comp, p.tokSlice(p.tok_i));
2019 var declspec_found = false;
2020
2021 if (interned_name == p.string_ids.declspec_id) {
2022 try p.errTok(.declspec_not_enabled, p.tok_i);
2023 p.tok_i += 1;
2024 if (p.eatToken(.l_paren)) |_| {
2025 p.skipTo(.r_paren);
2026 continue;
2027 }
2028 declspec_found = true;
2029 }
2030 if (ty.typedef != null) break;
2031 if (declspec_found) {
2032 interned_name = try StrInt.intern(p.comp, p.tokSlice(p.tok_i));
2033 }
2034 const typedef = (try p.syms.findTypedef(p, interned_name, p.tok_i, ty.specifier != .none)) orelse break;
2035 if (!ty.combineTypedef(p, typedef.ty, typedef.tok)) break;
2036 },
2037 .keyword_bit_int => {
2038 try p.err(.bit_int);
2039 const bit_int_tok = p.tok_i;
2040 p.tok_i += 1;
2041 const l_paren = try p.expectToken(.l_paren);
2042 const res = try p.integerConstExpr(.gnu_folding_extension);
2043 try p.expectClosing(l_paren, .r_paren);
2044
2045 var bits: u64 = undefined;
2046 if (res.val.opt_ref == .none) {
2047 try p.errTok(.expected_integer_constant_expr, bit_int_tok);
2048 return error.ParsingFailed;
2049 } else if (res.val.compare(.lte, Value.zero, p.comp)) {
2050 bits = 0;
2051 } else {
2052 bits = res.val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
2053 }
2054
2055 try ty.combine(p, .{ .bit_int = bits }, bit_int_tok);
2056 continue;
2057 },
2058 else => break,
2059 }
2060 // consume single token specifiers here
2061 p.tok_i += 1;
2062 }
2063 return p.tok_i != start;
2064}
2065
2066fn getAnonymousName(p: *Parser, kind_tok: TokenIndex) !StringId {
2067 const loc = p.pp.tokens.items(.loc)[kind_tok];
2068 const source = p.comp.getSource(loc.id);
2069 const line_col = source.lineCol(loc);
2070
2071 const kind_str = switch (p.tok_ids[kind_tok]) {
2072 .keyword_struct, .keyword_union, .keyword_enum => p.tokSlice(kind_tok),
2073 else => "record field",
2074 };
2075
2076 const str = try std.fmt.allocPrint(
2077 p.arena,
2078 "(anonymous {s} at {s}:{d}:{d})",
2079 .{ kind_str, source.path, line_col.line_no, line_col.col },
2080 );
2081 return StrInt.intern(p.comp, str);
2082}
2083
2084/// recordSpec
2085/// : (keyword_struct | keyword_union) IDENTIFIER? { recordDecl* }
2086/// | (keyword_struct | keyword_union) IDENTIFIER
2087fn recordSpec(p: *Parser) Error!Type {
2088 const starting_pragma_pack = p.pragma_pack;
2089 const kind_tok = p.tok_i;
2090 const is_struct = p.tok_ids[kind_tok] == .keyword_struct;
2091 p.tok_i += 1;
2092 const attr_buf_top = p.attr_buf.len;
2093 defer p.attr_buf.len = attr_buf_top;
2094 try p.attributeSpecifier();
2095
2096 const maybe_ident = try p.eatIdentifier();
2097 const l_brace = p.eatToken(.l_brace) orelse {
2098 const ident = maybe_ident orelse {
2099 try p.err(.ident_or_l_brace);
2100 return error.ParsingFailed;
2101 };
2102 // check if this is a reference to a previous type
2103 const interned_name = try StrInt.intern(p.comp, p.tokSlice(ident));
2104 if (try p.syms.findTag(p, interned_name, p.tok_ids[kind_tok], ident, p.tok_ids[p.tok_i])) |prev| {
2105 return prev.ty;
2106 } else {
2107 // this is a forward declaration, create a new record Type.
2108 const record_ty = try Type.Record.create(p.arena, interned_name);
2109 const ty = try Attribute.applyTypeAttributes(p, .{
2110 .specifier = if (is_struct) .@"struct" else .@"union",
2111 .data = .{ .record = record_ty },
2112 }, attr_buf_top, null);
2113 try p.syms.define(p.gpa, .{
2114 .kind = if (is_struct) .@"struct" else .@"union",
2115 .name = interned_name,
2116 .tok = ident,
2117 .ty = ty,
2118 .val = .{},
2119 });
2120 try p.decl_buf.append(try p.addNode(.{
2121 .tag = if (is_struct) .struct_forward_decl else .union_forward_decl,
2122 .ty = ty,
2123 .data = .{ .decl_ref = ident },
2124 }));
2125 return ty;
2126 }
2127 };
2128
2129 var done = false;
2130 errdefer if (!done) p.skipTo(.r_brace);
2131
2132 // Get forward declared type or create a new one
2133 var defined = false;
2134 const record_ty: *Type.Record = if (maybe_ident) |ident| record_ty: {
2135 const ident_str = p.tokSlice(ident);
2136 const interned_name = try StrInt.intern(p.comp, ident_str);
2137 if (try p.syms.defineTag(p, interned_name, p.tok_ids[kind_tok], ident)) |prev| {
2138 if (!prev.ty.hasIncompleteSize()) {
2139 // if the record isn't incomplete, this is a redefinition
2140 try p.errStr(.redefinition, ident, ident_str);
2141 try p.errTok(.previous_definition, prev.tok);
2142 } else {
2143 defined = true;
2144 break :record_ty prev.ty.get(if (is_struct) .@"struct" else .@"union").?.data.record;
2145 }
2146 }
2147 break :record_ty try Type.Record.create(p.arena, interned_name);
2148 } else try Type.Record.create(p.arena, try p.getAnonymousName(kind_tok));
2149
2150 // Initially create ty as a regular non-attributed type, since attributes for a record
2151 // can be specified after the closing rbrace, which we haven't encountered yet.
2152 var ty = Type{
2153 .specifier = if (is_struct) .@"struct" else .@"union",
2154 .data = .{ .record = record_ty },
2155 };
2156
2157 // declare a symbol for the type
2158 // We need to replace the symbol's type if it has attributes
2159 if (maybe_ident != null and !defined) {
2160 try p.syms.define(p.gpa, .{
2161 .kind = if (is_struct) .@"struct" else .@"union",
2162 .name = record_ty.name,
2163 .tok = maybe_ident.?,
2164 .ty = ty,
2165 .val = .{},
2166 });
2167 }
2168
2169 // reserve space for this record
2170 try p.decl_buf.append(.none);
2171 const decl_buf_top = p.decl_buf.items.len;
2172 const record_buf_top = p.record_buf.items.len;
2173 errdefer p.decl_buf.items.len = decl_buf_top - 1;
2174 defer {
2175 p.decl_buf.items.len = decl_buf_top;
2176 p.record_buf.items.len = record_buf_top;
2177 }
2178
2179 const old_record = p.record;
2180 const old_members = p.record_members.items.len;
2181 const old_field_attr_start = p.field_attr_buf.items.len;
2182 p.record = .{
2183 .kind = p.tok_ids[kind_tok],
2184 .start = p.record_members.items.len,
2185 .field_attr_start = p.field_attr_buf.items.len,
2186 };
2187 defer p.record = old_record;
2188 defer p.record_members.items.len = old_members;
2189 defer p.field_attr_buf.items.len = old_field_attr_start;
2190
2191 try p.recordDecls();
2192
2193 if (p.record.flexible_field) |some| {
2194 if (p.record_buf.items[record_buf_top..].len == 1 and is_struct) {
2195 try p.errTok(.flexible_in_empty, some);
2196 }
2197 }
2198
2199 for (p.record_buf.items[record_buf_top..]) |field| {
2200 if (field.ty.hasIncompleteSize() and !field.ty.is(.incomplete_array)) break;
2201 } else {
2202 record_ty.fields = try p.arena.dupe(Type.Record.Field, p.record_buf.items[record_buf_top..]);
2203 }
2204 if (old_field_attr_start < p.field_attr_buf.items.len) {
2205 const field_attr_slice = p.field_attr_buf.items[old_field_attr_start..];
2206 const duped = try p.arena.dupe([]const Attribute, field_attr_slice);
2207 record_ty.field_attributes = duped.ptr;
2208 }
2209
2210 if (p.record_buf.items.len == record_buf_top) {
2211 try p.errStr(.empty_record, kind_tok, p.tokSlice(kind_tok));
2212 try p.errStr(.empty_record_size, kind_tok, p.tokSlice(kind_tok));
2213 }
2214 try p.expectClosing(l_brace, .r_brace);
2215 done = true;
2216 try p.attributeSpecifier();
2217
2218 ty = try Attribute.applyTypeAttributes(p, .{
2219 .specifier = if (is_struct) .@"struct" else .@"union",
2220 .data = .{ .record = record_ty },
2221 }, attr_buf_top, null);
2222 if (ty.specifier == .attributed and maybe_ident != null) {
2223 const ident_str = p.tokSlice(maybe_ident.?);
2224 const interned_name = try StrInt.intern(p.comp, ident_str);
2225 const ptr = p.syms.getPtr(interned_name, .tags);
2226 ptr.ty = ty;
2227 }
2228
2229 if (!ty.hasIncompleteSize()) {
2230 const pragma_pack_value = switch (p.comp.langopts.emulate) {
2231 .clang => starting_pragma_pack,
2232 .gcc => p.pragma_pack,
2233 // TODO: msvc considers `#pragma pack` on a per-field basis
2234 .msvc => p.pragma_pack,
2235 };
2236 record_layout.compute(record_ty, ty, p.comp, pragma_pack_value);
2237 }
2238
2239 // finish by creating a node
2240 var node: Tree.Node = .{
2241 .tag = if (is_struct) .struct_decl_two else .union_decl_two,
2242 .ty = ty,
2243 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
2244 };
2245 const record_decls = p.decl_buf.items[decl_buf_top..];
2246 switch (record_decls.len) {
2247 0 => {},
2248 1 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = .none } },
2249 2 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = record_decls[1] } },
2250 else => {
2251 node.tag = if (is_struct) .struct_decl else .union_decl;
2252 node.data = .{ .range = try p.addList(record_decls) };
2253 },
2254 }
2255 p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
2256 if (p.func.ty == null) {
2257 _ = p.tentative_defs.remove(record_ty.name);
2258 }
2259 return ty;
2260}
2261
2262/// recordDecl
2263/// : specQual (recordDeclarator (',' recordDeclarator)*)? ;
2264/// | staticAssert
2265fn recordDecls(p: *Parser) Error!void {
2266 while (true) {
2267 if (try p.pragma()) continue;
2268 if (try p.parseOrNextDecl(staticAssert)) continue;
2269 if (p.eatToken(.keyword_extension)) |_| {
2270 const saved_extension = p.extension_suppressed;
2271 defer p.extension_suppressed = saved_extension;
2272 p.extension_suppressed = true;
2273
2274 if (try p.parseOrNextDecl(recordDeclarator)) continue;
2275 try p.err(.expected_type);
2276 p.nextExternDecl();
2277 continue;
2278 }
2279 if (try p.parseOrNextDecl(recordDeclarator)) continue;
2280 break;
2281 }
2282}
2283
2284/// recordDeclarator : keyword_extension? declarator (':' integerConstExpr)?
2285fn recordDeclarator(p: *Parser) Error!bool {
2286 const attr_buf_top = p.attr_buf.len;
2287 defer p.attr_buf.len = attr_buf_top;
2288 const base_ty = (try p.specQual()) orelse return false;
2289
2290 try p.attributeSpecifier(); // .record
2291 while (true) {
2292 const this_decl_top = p.attr_buf.len;
2293 defer p.attr_buf.len = this_decl_top;
2294
2295 try p.attributeSpecifier();
2296
2297 // 0 means unnamed
2298 var name_tok: TokenIndex = 0;
2299 var ty = base_ty;
2300 if (ty.is(.auto_type)) {
2301 try p.errStr(.auto_type_not_allowed, p.tok_i, if (p.record.kind == .keyword_struct) "struct member" else "union member");
2302 ty = Type.invalid;
2303 }
2304 var bits_node: NodeIndex = .none;
2305 var bits: ?u32 = null;
2306 const first_tok = p.tok_i;
2307 if (try p.declarator(ty, .record)) |d| {
2308 name_tok = d.name;
2309 ty = d.ty;
2310 }
2311
2312 if (p.eatToken(.colon)) |_| bits: {
2313 const bits_tok = p.tok_i;
2314 const res = try p.integerConstExpr(.gnu_folding_extension);
2315 if (!ty.isInt()) {
2316 try p.errStr(.non_int_bitfield, first_tok, try p.typeStr(ty));
2317 break :bits;
2318 }
2319
2320 if (res.val.opt_ref == .none) {
2321 try p.errTok(.expected_integer_constant_expr, bits_tok);
2322 break :bits;
2323 } else if (res.val.compare(.lt, Value.zero, p.comp)) {
2324 try p.errStr(.negative_bitwidth, first_tok, try res.str(p));
2325 break :bits;
2326 }
2327
2328 // incomplete size error is reported later
2329 const bit_size = ty.bitSizeof(p.comp) orelse break :bits;
2330 const bits_unchecked = res.val.toInt(u32, p.comp) orelse std.math.maxInt(u32);
2331 if (bits_unchecked > bit_size) {
2332 try p.errTok(.bitfield_too_big, name_tok);
2333 break :bits;
2334 } else if (bits_unchecked == 0 and name_tok != 0) {
2335 try p.errTok(.zero_width_named_field, name_tok);
2336 break :bits;
2337 }
2338
2339 bits = bits_unchecked;
2340 bits_node = res.node;
2341 }
2342
2343 try p.attributeSpecifier(); // .record
2344 const to_append = try Attribute.applyFieldAttributes(p, &ty, attr_buf_top);
2345
2346 const any_fields_have_attrs = p.field_attr_buf.items.len > p.record.field_attr_start;
2347
2348 if (any_fields_have_attrs) {
2349 try p.field_attr_buf.append(to_append);
2350 } else {
2351 if (to_append.len > 0) {
2352 const preceding = p.record_members.items.len - p.record.start;
2353 if (preceding > 0) {
2354 try p.field_attr_buf.appendNTimes(&.{}, preceding);
2355 }
2356 try p.field_attr_buf.append(to_append);
2357 }
2358 }
2359
2360 if (name_tok == 0 and bits_node == .none) unnamed: {
2361 if (ty.is(.@"enum") or ty.hasIncompleteSize()) break :unnamed;
2362 if (ty.isAnonymousRecord(p.comp)) {
2363 // An anonymous record appears as indirect fields on the parent
2364 try p.record_buf.append(.{
2365 .name = try p.getAnonymousName(first_tok),
2366 .ty = ty,
2367 });
2368 const node = try p.addNode(.{
2369 .tag = .indirect_record_field_decl,
2370 .ty = ty,
2371 .data = undefined,
2372 });
2373 try p.decl_buf.append(node);
2374 try p.record.addFieldsFromAnonymous(p, ty);
2375 break; // must be followed by a semicolon
2376 }
2377 try p.err(.missing_declaration);
2378 } else {
2379 const interned_name = if (name_tok != 0) try StrInt.intern(p.comp, p.tokSlice(name_tok)) else try p.getAnonymousName(first_tok);
2380 try p.record_buf.append(.{
2381 .name = interned_name,
2382 .ty = ty,
2383 .name_tok = name_tok,
2384 .bit_width = bits,
2385 });
2386 if (name_tok != 0) try p.record.addField(p, interned_name, name_tok);
2387 const node = try p.addNode(.{
2388 .tag = .record_field_decl,
2389 .ty = ty,
2390 .data = .{ .decl = .{ .name = name_tok, .node = bits_node } },
2391 });
2392 try p.decl_buf.append(node);
2393 }
2394
2395 if (ty.isFunc()) {
2396 try p.errTok(.func_field, first_tok);
2397 } else if (ty.is(.variable_len_array)) {
2398 try p.errTok(.vla_field, first_tok);
2399 } else if (ty.is(.incomplete_array)) {
2400 if (p.record.kind == .keyword_union) {
2401 try p.errTok(.flexible_in_union, first_tok);
2402 }
2403 if (p.record.flexible_field) |some| {
2404 if (p.record.kind == .keyword_struct) {
2405 try p.errTok(.flexible_non_final, some);
2406 }
2407 }
2408 p.record.flexible_field = first_tok;
2409 } else if (ty.specifier != .invalid and ty.hasIncompleteSize()) {
2410 try p.errStr(.field_incomplete_ty, first_tok, try p.typeStr(ty));
2411 } else if (p.record.flexible_field) |some| {
2412 if (some != first_tok and p.record.kind == .keyword_struct) try p.errTok(.flexible_non_final, some);
2413 }
2414 if (p.eatToken(.comma) == null) break;
2415 }
2416
2417 if (p.eatToken(.semicolon) == null) {
2418 const tok_id = p.tok_ids[p.tok_i];
2419 if (tok_id == .r_brace) {
2420 try p.err(.missing_semicolon);
2421 } else {
2422 return p.errExpectedToken(.semicolon, tok_id);
2423 }
2424 }
2425
2426 return true;
2427}
2428
2429/// specQual : (typeSpec | typeQual | alignSpec)+
2430fn specQual(p: *Parser) Error!?Type {
2431 var spec: Type.Builder = .{};
2432 if (try p.typeSpec(&spec)) {
2433 return try spec.finish(p);
2434 }
2435 return null;
2436}
2437
2438/// enumSpec
2439/// : keyword_enum IDENTIFIER? (: typeName)? { enumerator (',' enumerator)? ',') }
2440/// | keyword_enum IDENTIFIER (: typeName)?
2441fn enumSpec(p: *Parser) Error!Type {
2442 const enum_tok = p.tok_i;
2443 p.tok_i += 1;
2444 const attr_buf_top = p.attr_buf.len;
2445 defer p.attr_buf.len = attr_buf_top;
2446 try p.attributeSpecifier();
2447
2448 const maybe_ident = try p.eatIdentifier();
2449 const fixed_ty = if (p.eatToken(.colon)) |colon| fixed: {
2450 const fixed = (try p.typeName()) orelse {
2451 if (p.record.kind != .invalid) {
2452 // This is a bit field.
2453 p.tok_i -= 1;
2454 break :fixed null;
2455 }
2456 try p.err(.expected_type);
2457 try p.errTok(.enum_fixed, colon);
2458 break :fixed null;
2459 };
2460 try p.errTok(.enum_fixed, colon);
2461 break :fixed fixed;
2462 } else null;
2463
2464 const l_brace = p.eatToken(.l_brace) orelse {
2465 const ident = maybe_ident orelse {
2466 try p.err(.ident_or_l_brace);
2467 return error.ParsingFailed;
2468 };
2469 // check if this is a reference to a previous type
2470 const interned_name = try StrInt.intern(p.comp, p.tokSlice(ident));
2471 if (try p.syms.findTag(p, interned_name, .keyword_enum, ident, p.tok_ids[p.tok_i])) |prev| {
2472 // only check fixed underlying type in forward declarations and not in references.
2473 if (p.tok_ids[p.tok_i] == .semicolon)
2474 try p.checkEnumFixedTy(fixed_ty, ident, prev);
2475 return prev.ty;
2476 } else {
2477 // this is a forward declaration, create a new enum Type.
2478 const enum_ty = try Type.Enum.create(p.arena, interned_name, fixed_ty);
2479 const ty = try Attribute.applyTypeAttributes(p, .{
2480 .specifier = .@"enum",
2481 .data = .{ .@"enum" = enum_ty },
2482 }, attr_buf_top, null);
2483 try p.syms.define(p.gpa, .{
2484 .kind = .@"enum",
2485 .name = interned_name,
2486 .tok = ident,
2487 .ty = ty,
2488 .val = .{},
2489 });
2490 try p.decl_buf.append(try p.addNode(.{
2491 .tag = .enum_forward_decl,
2492 .ty = ty,
2493 .data = .{ .decl_ref = ident },
2494 }));
2495 return ty;
2496 }
2497 };
2498
2499 var done = false;
2500 errdefer if (!done) p.skipTo(.r_brace);
2501
2502 // Get forward declared type or create a new one
2503 var defined = false;
2504 const enum_ty: *Type.Enum = if (maybe_ident) |ident| enum_ty: {
2505 const ident_str = p.tokSlice(ident);
2506 const interned_name = try StrInt.intern(p.comp, ident_str);
2507 if (try p.syms.defineTag(p, interned_name, .keyword_enum, ident)) |prev| {
2508 const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
2509 if (!enum_ty.isIncomplete() and !enum_ty.fixed) {
2510 // if the enum isn't incomplete, this is a redefinition
2511 try p.errStr(.redefinition, ident, ident_str);
2512 try p.errTok(.previous_definition, prev.tok);
2513 } else {
2514 try p.checkEnumFixedTy(fixed_ty, ident, prev);
2515 defined = true;
2516 break :enum_ty enum_ty;
2517 }
2518 }
2519 break :enum_ty try Type.Enum.create(p.arena, interned_name, fixed_ty);
2520 } else try Type.Enum.create(p.arena, try p.getAnonymousName(enum_tok), fixed_ty);
2521
2522 // reserve space for this enum
2523 try p.decl_buf.append(.none);
2524 const decl_buf_top = p.decl_buf.items.len;
2525 const list_buf_top = p.list_buf.items.len;
2526 const enum_buf_top = p.enum_buf.items.len;
2527 errdefer p.decl_buf.items.len = decl_buf_top - 1;
2528 defer {
2529 p.decl_buf.items.len = decl_buf_top;
2530 p.list_buf.items.len = list_buf_top;
2531 p.enum_buf.items.len = enum_buf_top;
2532 }
2533
2534 var e = Enumerator.init(fixed_ty);
2535 while (try p.enumerator(&e)) |field_and_node| {
2536 try p.enum_buf.append(field_and_node.field);
2537 try p.list_buf.append(field_and_node.node);
2538 if (p.eatToken(.comma) == null) break;
2539 }
2540
2541 if (p.enum_buf.items.len == enum_buf_top) try p.err(.empty_enum);
2542 try p.expectClosing(l_brace, .r_brace);
2543 done = true;
2544 try p.attributeSpecifier();
2545
2546 const ty = try Attribute.applyTypeAttributes(p, .{
2547 .specifier = .@"enum",
2548 .data = .{ .@"enum" = enum_ty },
2549 }, attr_buf_top, null);
2550 if (!enum_ty.fixed) {
2551 const tag_specifier = try e.getTypeSpecifier(p, ty.enumIsPacked(p.comp), maybe_ident orelse enum_tok);
2552 enum_ty.tag_ty = .{ .specifier = tag_specifier };
2553 }
2554
2555 const enum_fields = p.enum_buf.items[enum_buf_top..];
2556 const field_nodes = p.list_buf.items[list_buf_top..];
2557
2558 if (fixed_ty == null) {
2559 for (enum_fields, 0..) |*field, i| {
2560 if (field.ty.eql(Type.int, p.comp, false)) continue;
2561
2562 const sym = p.syms.get(field.name, .vars) orelse continue;
2563
2564 var res = Result{ .node = field.node, .ty = field.ty, .val = sym.val };
2565 const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some|
2566 Type{ .specifier = some }
2567 else if (try res.intFitsInType(p, Type.int))
2568 Type.int
2569 else if (!res.ty.eql(enum_ty.tag_ty, p.comp, false))
2570 enum_ty.tag_ty
2571 else
2572 continue;
2573
2574 const symbol = p.syms.getPtr(field.name, .vars);
2575 try symbol.val.intCast(dest_ty, p.comp);
2576 symbol.ty = dest_ty;
2577 p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty;
2578 field.ty = dest_ty;
2579 res.ty = dest_ty;
2580
2581 if (res.node != .none) {
2582 try res.implicitCast(p, .int_cast);
2583 field.node = res.node;
2584 p.nodes.items(.data)[@intFromEnum(field_nodes[i])].decl.node = res.node;
2585 }
2586 }
2587 }
2588
2589 enum_ty.fields = try p.arena.dupe(Type.Enum.Field, enum_fields);
2590
2591 // declare a symbol for the type
2592 if (maybe_ident != null and !defined) {
2593 try p.syms.define(p.gpa, .{
2594 .kind = .@"enum",
2595 .name = enum_ty.name,
2596 .ty = ty,
2597 .tok = maybe_ident.?,
2598 .val = .{},
2599 });
2600 }
2601
2602 // finish by creating a node
2603 var node: Tree.Node = .{ .tag = .enum_decl_two, .ty = ty, .data = .{
2604 .bin = .{ .lhs = .none, .rhs = .none },
2605 } };
2606 switch (field_nodes.len) {
2607 0 => {},
2608 1 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = .none } },
2609 2 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = field_nodes[1] } },
2610 else => {
2611 node.tag = .enum_decl;
2612 node.data = .{ .range = try p.addList(field_nodes) };
2613 },
2614 }
2615 p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
2616 if (p.func.ty == null) {
2617 _ = p.tentative_defs.remove(enum_ty.name);
2618 }
2619 return ty;
2620}
2621
2622fn checkEnumFixedTy(p: *Parser, fixed_ty: ?Type, ident_tok: TokenIndex, prev: Symbol) !void {
2623 const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
2624 if (fixed_ty) |some| {
2625 if (!enum_ty.fixed) {
2626 try p.errTok(.enum_prev_nonfixed, ident_tok);
2627 try p.errTok(.previous_definition, prev.tok);
2628 return error.ParsingFailed;
2629 }
2630
2631 if (!enum_ty.tag_ty.eql(some, p.comp, false)) {
2632 const str = try p.typePairStrExtra(some, " (was ", enum_ty.tag_ty);
2633 try p.errStr(.enum_different_explicit_ty, ident_tok, str);
2634 try p.errTok(.previous_definition, prev.tok);
2635 return error.ParsingFailed;
2636 }
2637 } else if (enum_ty.fixed) {
2638 try p.errTok(.enum_prev_fixed, ident_tok);
2639 try p.errTok(.previous_definition, prev.tok);
2640 return error.ParsingFailed;
2641 }
2642}
2643
2644const Enumerator = struct {
2645 res: Result,
2646 num_positive_bits: usize = 0,
2647 num_negative_bits: usize = 0,
2648 fixed: bool,
2649
2650 fn init(fixed_ty: ?Type) Enumerator {
2651 return .{
2652 .res = .{ .ty = fixed_ty orelse .{ .specifier = .int } },
2653 .fixed = fixed_ty != null,
2654 };
2655 }
2656
2657 /// Increment enumerator value adjusting type if needed.
2658 fn incr(e: *Enumerator, p: *Parser, tok: TokenIndex) !void {
2659 e.res.node = .none;
2660 const old_val = e.res.val;
2661 if (old_val.opt_ref == .none) {
2662 // First enumerator, set to 0 fits in all types.
2663 e.res.val = Value.zero;
2664 return;
2665 }
2666 if (try e.res.val.add(e.res.val, Value.one, e.res.ty, p.comp)) {
2667 const byte_size = e.res.ty.sizeof(p.comp).?;
2668 const bit_size: u8 = @intCast(if (e.res.ty.isUnsignedInt(p.comp)) byte_size * 8 else byte_size * 8 - 1);
2669 if (e.fixed) {
2670 try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
2671 return;
2672 }
2673 const new_ty = if (p.comp.nextLargestIntSameSign(e.res.ty)) |larger| blk: {
2674 try p.errTok(.enumerator_overflow, tok);
2675 break :blk larger;
2676 } else blk: {
2677 try p.errExtra(.enum_not_representable, tok, .{ .pow_2_as_string = bit_size });
2678 break :blk Type{ .specifier = .ulong_long };
2679 };
2680 e.res.ty = new_ty;
2681 _ = try e.res.val.add(old_val, Value.one, e.res.ty, p.comp);
2682 }
2683 }
2684
2685 /// Set enumerator value to specified value.
2686 fn set(e: *Enumerator, p: *Parser, res: Result, tok: TokenIndex) !void {
2687 if (res.ty.specifier == .invalid) return;
2688 if (e.fixed and !res.ty.eql(e.res.ty, p.comp, false)) {
2689 if (!try res.intFitsInType(p, e.res.ty)) {
2690 try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
2691 return error.ParsingFailed;
2692 }
2693 var copy = res;
2694 copy.ty = e.res.ty;
2695 try copy.implicitCast(p, .int_cast);
2696 e.res = copy;
2697 } else {
2698 e.res = res;
2699 try e.res.intCast(p, e.res.ty.integerPromotion(p.comp), tok);
2700 }
2701 }
2702
2703 fn getTypeSpecifier(e: *const Enumerator, p: *Parser, is_packed: bool, tok: TokenIndex) !Type.Specifier {
2704 if (p.comp.fixedEnumTagSpecifier()) |tag_specifier| return tag_specifier;
2705
2706 const char_width = (Type{ .specifier = .schar }).sizeof(p.comp).? * 8;
2707 const short_width = (Type{ .specifier = .short }).sizeof(p.comp).? * 8;
2708 const int_width = (Type{ .specifier = .int }).sizeof(p.comp).? * 8;
2709 if (e.num_negative_bits > 0) {
2710 if (is_packed and e.num_negative_bits <= char_width and e.num_positive_bits < char_width) {
2711 return .schar;
2712 } else if (is_packed and e.num_negative_bits <= short_width and e.num_positive_bits < short_width) {
2713 return .short;
2714 } else if (e.num_negative_bits <= int_width and e.num_positive_bits < int_width) {
2715 return .int;
2716 }
2717 const long_width = (Type{ .specifier = .long }).sizeof(p.comp).? * 8;
2718 if (e.num_negative_bits <= long_width and e.num_positive_bits < long_width) {
2719 return .long;
2720 }
2721 const long_long_width = (Type{ .specifier = .long_long }).sizeof(p.comp).? * 8;
2722 if (e.num_negative_bits > long_long_width or e.num_positive_bits >= long_long_width) {
2723 try p.errTok(.enum_too_large, tok);
2724 }
2725 return .long_long;
2726 }
2727 if (is_packed and e.num_positive_bits <= char_width) {
2728 return .uchar;
2729 } else if (is_packed and e.num_positive_bits <= short_width) {
2730 return .ushort;
2731 } else if (e.num_positive_bits <= int_width) {
2732 return .uint;
2733 } else if (e.num_positive_bits <= (Type{ .specifier = .long }).sizeof(p.comp).? * 8) {
2734 return .ulong;
2735 }
2736 return .ulong_long;
2737 }
2738};
2739
2740const EnumFieldAndNode = struct { field: Type.Enum.Field, node: NodeIndex };
2741
2742/// enumerator : IDENTIFIER ('=' integerConstExpr)
2743fn enumerator(p: *Parser, e: *Enumerator) Error!?EnumFieldAndNode {
2744 _ = try p.pragma();
2745 const name_tok = (try p.eatIdentifier()) orelse {
2746 if (p.tok_ids[p.tok_i] == .r_brace) return null;
2747 try p.err(.expected_identifier);
2748 p.skipTo(.r_brace);
2749 return error.ParsingFailed;
2750 };
2751 const attr_buf_top = p.attr_buf.len;
2752 defer p.attr_buf.len = attr_buf_top;
2753 try p.attributeSpecifier();
2754
2755 const err_start = p.comp.diagnostics.list.items.len;
2756 if (p.eatToken(.equal)) |_| {
2757 const specified = try p.integerConstExpr(.gnu_folding_extension);
2758 if (specified.val.opt_ref == .none) {
2759 try p.errTok(.enum_val_unavailable, name_tok + 2);
2760 try e.incr(p, name_tok);
2761 } else {
2762 try e.set(p, specified, name_tok);
2763 }
2764 } else {
2765 try e.incr(p, name_tok);
2766 }
2767
2768 var res = e.res;
2769 res.ty = try Attribute.applyEnumeratorAttributes(p, res.ty, attr_buf_top);
2770
2771 if (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, Value.zero, p.comp)) {
2772 e.num_positive_bits = @max(e.num_positive_bits, res.val.minUnsignedBits(p.comp));
2773 } else {
2774 e.num_negative_bits = @max(e.num_negative_bits, res.val.minSignedBits(p.comp));
2775 }
2776
2777 if (err_start == p.comp.diagnostics.list.items.len) {
2778 // only do these warnings if we didn't already warn about overflow or non-representable values
2779 if (e.res.val.compare(.lt, Value.zero, p.comp)) {
2780 const min_int = (Type{ .specifier = .int }).minInt(p.comp);
2781 const min_val = try Value.int(min_int, p.comp);
2782 if (e.res.val.compare(.lt, min_val, p.comp)) {
2783 try p.errStr(.enumerator_too_small, name_tok, try e.res.str(p));
2784 }
2785 } else {
2786 const max_int = (Type{ .specifier = .int }).maxInt(p.comp);
2787 const max_val = try Value.int(max_int, p.comp);
2788 if (e.res.val.compare(.gt, max_val, p.comp)) {
2789 try p.errStr(.enumerator_too_large, name_tok, try e.res.str(p));
2790 }
2791 }
2792 }
2793
2794 const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok));
2795 try p.syms.defineEnumeration(p, interned_name, res.ty, name_tok, e.res.val);
2796 const node = try p.addNode(.{
2797 .tag = .enum_field_decl,
2798 .ty = res.ty,
2799 .data = .{ .decl = .{
2800 .name = name_tok,
2801 .node = res.node,
2802 } },
2803 });
2804 try p.value_map.put(node, e.res.val);
2805 return EnumFieldAndNode{ .field = .{
2806 .name = interned_name,
2807 .ty = res.ty,
2808 .name_tok = name_tok,
2809 .node = res.node,
2810 }, .node = node };
2811}
2812
2813/// typeQual : keyword_const | keyword_restrict | keyword_volatile | keyword_atomic
2814fn typeQual(p: *Parser, b: *Type.Qualifiers.Builder) Error!bool {
2815 var any = false;
2816 while (true) {
2817 switch (p.tok_ids[p.tok_i]) {
2818 .keyword_restrict, .keyword_restrict1, .keyword_restrict2 => {
2819 if (b.restrict != null)
2820 try p.errStr(.duplicate_decl_spec, p.tok_i, "restrict")
2821 else
2822 b.restrict = p.tok_i;
2823 },
2824 .keyword_const, .keyword_const1, .keyword_const2 => {
2825 if (b.@"const" != null)
2826 try p.errStr(.duplicate_decl_spec, p.tok_i, "const")
2827 else
2828 b.@"const" = p.tok_i;
2829 },
2830 .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
2831 if (b.@"volatile" != null)
2832 try p.errStr(.duplicate_decl_spec, p.tok_i, "volatile")
2833 else
2834 b.@"volatile" = p.tok_i;
2835 },
2836 .keyword_atomic => {
2837 // _Atomic(typeName) instead of just _Atomic
2838 if (p.tok_ids[p.tok_i + 1] == .l_paren) break;
2839 if (b.atomic != null)
2840 try p.errStr(.duplicate_decl_spec, p.tok_i, "atomic")
2841 else
2842 b.atomic = p.tok_i;
2843 },
2844 else => break,
2845 }
2846 p.tok_i += 1;
2847 any = true;
2848 }
2849 return any;
2850}
2851
2852const Declarator = struct {
2853 name: TokenIndex,
2854 ty: Type,
2855 func_declarator: ?TokenIndex = null,
2856 old_style_func: ?TokenIndex = null,
2857};
2858const DeclaratorKind = enum { normal, abstract, param, record };
2859
2860/// declarator : pointer? (IDENTIFIER | '(' declarator ')') directDeclarator*
2861/// abstractDeclarator
2862/// : pointer? ('(' abstractDeclarator ')')? directAbstractDeclarator*
2863fn declarator(
2864 p: *Parser,
2865 base_type: Type,
2866 kind: DeclaratorKind,
2867) Error!?Declarator {
2868 const start = p.tok_i;
2869 var d = Declarator{ .name = 0, .ty = try p.pointer(base_type) };
2870 if (base_type.is(.auto_type) and !d.ty.is(.auto_type)) {
2871 try p.errTok(.auto_type_requires_plain_declarator, start);
2872 return error.ParsingFailed;
2873 }
2874
2875 const maybe_ident = p.tok_i;
2876 if (kind != .abstract and (try p.eatIdentifier()) != null) {
2877 d.name = maybe_ident;
2878 const combine_tok = p.tok_i;
2879 d.ty = try p.directDeclarator(d.ty, &d, kind);
2880 try d.ty.validateCombinedType(p, combine_tok);
2881 return d;
2882 } else if (p.eatToken(.l_paren)) |l_paren| blk: {
2883 var res = (try p.declarator(.{ .specifier = .void }, kind)) orelse {
2884 p.tok_i = l_paren;
2885 break :blk;
2886 };
2887 try p.expectClosing(l_paren, .r_paren);
2888 const suffix_start = p.tok_i;
2889 const outer = try p.directDeclarator(d.ty, &d, kind);
2890 try res.ty.combine(outer);
2891 try res.ty.validateCombinedType(p, suffix_start);
2892 res.old_style_func = d.old_style_func;
2893 if (d.func_declarator) |some| res.func_declarator = some;
2894 return res;
2895 }
2896
2897 const expected_ident = p.tok_i;
2898
2899 d.ty = try p.directDeclarator(d.ty, &d, kind);
2900
2901 if (kind == .normal and !d.ty.isEnumOrRecord()) {
2902 try p.errTok(.expected_ident_or_l_paren, expected_ident);
2903 return error.ParsingFailed;
2904 }
2905 try d.ty.validateCombinedType(p, expected_ident);
2906 if (start == p.tok_i) return null;
2907 return d;
2908}
2909
2910/// directDeclarator
2911/// : '[' typeQual* assignExpr? ']' directDeclarator?
2912/// | '[' keyword_static typeQual* assignExpr ']' directDeclarator?
2913/// | '[' typeQual+ keyword_static assignExpr ']' directDeclarator?
2914/// | '[' typeQual* '*' ']' directDeclarator?
2915/// | '(' paramDecls ')' directDeclarator?
2916/// | '(' (IDENTIFIER (',' IDENTIFIER))? ')' directDeclarator?
2917/// directAbstractDeclarator
2918/// : '[' typeQual* assignExpr? ']'
2919/// | '[' keyword_static typeQual* assignExpr ']'
2920/// | '[' typeQual+ keyword_static assignExpr ']'
2921/// | '[' '*' ']'
2922/// | '(' paramDecls? ')'
2923fn directDeclarator(p: *Parser, base_type: Type, d: *Declarator, kind: DeclaratorKind) Error!Type {
2924 if (p.eatToken(.l_bracket)) |l_bracket| {
2925 if (p.tok_ids[p.tok_i] == .l_bracket) {
2926 switch (kind) {
2927 .normal, .record => if (p.comp.langopts.standard.atLeast(.c23)) {
2928 p.tok_i -= 1;
2929 return base_type;
2930 },
2931 .param, .abstract => {},
2932 }
2933 try p.err(.expected_expr);
2934 return error.ParsingFailed;
2935 }
2936 var res_ty = Type{
2937 // so that we can get any restrict type that might be present
2938 .specifier = .pointer,
2939 };
2940 var quals = Type.Qualifiers.Builder{};
2941
2942 var got_quals = try p.typeQual(&quals);
2943 var static = p.eatToken(.keyword_static);
2944 if (static != null and !got_quals) got_quals = try p.typeQual(&quals);
2945 var star = p.eatToken(.asterisk);
2946 const size_tok = p.tok_i;
2947
2948 const const_decl_folding = p.const_decl_folding;
2949 p.const_decl_folding = .gnu_vla_folding_extension;
2950 const size = if (star) |_| Result{} else try p.assignExpr();
2951 p.const_decl_folding = const_decl_folding;
2952
2953 try p.expectClosing(l_bracket, .r_bracket);
2954
2955 if (star != null and static != null) {
2956 try p.errTok(.invalid_static_star, static.?);
2957 static = null;
2958 }
2959 if (kind != .param) {
2960 if (static != null)
2961 try p.errTok(.static_non_param, l_bracket)
2962 else if (got_quals)
2963 try p.errTok(.array_qualifiers, l_bracket);
2964 if (star) |some| try p.errTok(.star_non_param, some);
2965 static = null;
2966 quals = .{};
2967 star = null;
2968 } else {
2969 try quals.finish(p, &res_ty);
2970 }
2971 if (static) |_| try size.expect(p);
2972
2973 if (base_type.is(.auto_type)) {
2974 try p.errStr(.array_of_auto_type, d.name, p.tokSlice(d.name));
2975 return error.ParsingFailed;
2976 }
2977
2978 const outer = try p.directDeclarator(base_type, d, kind);
2979 var max_bits = p.comp.target.ptrBitWidth();
2980 if (max_bits > 61) max_bits = 61;
2981 const max_bytes = (@as(u64, 1) << @truncate(max_bits)) - 1;
2982
2983 if (!size.ty.isInt()) {
2984 try p.errStr(.array_size_non_int, size_tok, try p.typeStr(size.ty));
2985 return error.ParsingFailed;
2986 }
2987 if (base_type.is(.c23_auto)) {
2988 // issue error later
2989 return Type.invalid;
2990 } else if (size.val.opt_ref == .none) {
2991 if (size.node != .none) {
2992 try p.errTok(.vla, size_tok);
2993 if (p.func.ty == null and kind != .param and p.record.kind == .invalid) {
2994 try p.errTok(.variable_len_array_file_scope, d.name);
2995 }
2996 const expr_ty = try p.arena.create(Type.Expr);
2997 expr_ty.ty = .{ .specifier = .void };
2998 expr_ty.node = size.node;
2999 res_ty.data = .{ .expr = expr_ty };
3000 res_ty.specifier = .variable_len_array;
3001
3002 if (static) |some| try p.errTok(.useless_static, some);
3003 } else if (star) |_| {
3004 const elem_ty = try p.arena.create(Type);
3005 elem_ty.* = .{ .specifier = .void };
3006 res_ty.data = .{ .sub_type = elem_ty };
3007 res_ty.specifier = .unspecified_variable_len_array;
3008 } else {
3009 const arr_ty = try p.arena.create(Type.Array);
3010 arr_ty.elem = .{ .specifier = .void };
3011 arr_ty.len = 0;
3012 res_ty.data = .{ .array = arr_ty };
3013 res_ty.specifier = .incomplete_array;
3014 }
3015 } else {
3016 // `outer` is validated later so it may be invalid here
3017 const outer_size = outer.sizeof(p.comp);
3018 const max_elems = max_bytes / @max(1, outer_size orelse 1);
3019
3020 var size_val = size.val;
3021 if (size_val.isZero(p.comp)) {
3022 try p.errTok(.zero_length_array, l_bracket);
3023 } else if (size_val.compare(.lt, Value.zero, p.comp)) {
3024 try p.errTok(.negative_array_size, l_bracket);
3025 return error.ParsingFailed;
3026 }
3027 const arr_ty = try p.arena.create(Type.Array);
3028 arr_ty.elem = .{ .specifier = .void };
3029 arr_ty.len = size_val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
3030 if (arr_ty.len > max_elems) {
3031 try p.errTok(.array_too_large, l_bracket);
3032 arr_ty.len = max_elems;
3033 }
3034 res_ty.data = .{ .array = arr_ty };
3035 res_ty.specifier = .array;
3036 }
3037
3038 try res_ty.combine(outer);
3039 return res_ty;
3040 } else if (p.eatToken(.l_paren)) |l_paren| {
3041 d.func_declarator = l_paren;
3042
3043 const func_ty = try p.arena.create(Type.Func);
3044 func_ty.params = &.{};
3045 func_ty.return_type.specifier = .void;
3046 var specifier: Type.Specifier = .func;
3047
3048 if (p.eatToken(.ellipsis)) |_| {
3049 try p.err(.param_before_var_args);
3050 try p.expectClosing(l_paren, .r_paren);
3051 var res_ty = Type{ .specifier = .func, .data = .{ .func = func_ty } };
3052
3053 const outer = try p.directDeclarator(base_type, d, kind);
3054 try res_ty.combine(outer);
3055 return res_ty;
3056 }
3057
3058 if (try p.paramDecls(d)) |params| {
3059 func_ty.params = params;
3060 if (p.eatToken(.ellipsis)) |_| specifier = .var_args_func;
3061 } else if (p.tok_ids[p.tok_i] == .r_paren) {
3062 specifier = if (p.comp.langopts.standard.atLeast(.c23))
3063 .func
3064 else
3065 .old_style_func;
3066 } else if (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) {
3067 d.old_style_func = p.tok_i;
3068 const param_buf_top = p.param_buf.items.len;
3069 try p.syms.pushScope(p);
3070 defer {
3071 p.param_buf.items.len = param_buf_top;
3072 p.syms.popScope();
3073 }
3074
3075 specifier = .old_style_func;
3076 while (true) {
3077 const name_tok = try p.expectIdentifier();
3078 const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok));
3079 try p.syms.defineParam(p, interned_name, undefined, name_tok);
3080 try p.param_buf.append(.{
3081 .name = interned_name,
3082 .name_tok = name_tok,
3083 .ty = .{ .specifier = .int },
3084 });
3085 if (p.eatToken(.comma) == null) break;
3086 }
3087 func_ty.params = try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
3088 } else {
3089 try p.err(.expected_param_decl);
3090 }
3091
3092 try p.expectClosing(l_paren, .r_paren);
3093 var res_ty = Type{
3094 .specifier = specifier,
3095 .data = .{ .func = func_ty },
3096 };
3097
3098 const outer = try p.directDeclarator(base_type, d, kind);
3099 try res_ty.combine(outer);
3100 return res_ty;
3101 } else return base_type;
3102}
3103
3104/// pointer : '*' typeQual* pointer?
3105fn pointer(p: *Parser, base_ty: Type) Error!Type {
3106 var ty = base_ty;
3107 while (p.eatToken(.asterisk)) |_| {
3108 const elem_ty = try p.arena.create(Type);
3109 elem_ty.* = ty;
3110 ty = Type{
3111 .specifier = .pointer,
3112 .data = .{ .sub_type = elem_ty },
3113 };
3114 var quals = Type.Qualifiers.Builder{};
3115 _ = try p.typeQual(&quals);
3116 try quals.finish(p, &ty);
3117 }
3118 return ty;
3119}
3120
3121/// paramDecls : paramDecl (',' paramDecl)* (',' '...')
3122/// paramDecl : declSpec (declarator | abstractDeclarator)
3123fn paramDecls(p: *Parser, d: *Declarator) Error!?[]Type.Func.Param {
3124 // TODO warn about visibility of types declared here
3125 const param_buf_top = p.param_buf.items.len;
3126 defer p.param_buf.items.len = param_buf_top;
3127 try p.syms.pushScope(p);
3128 defer p.syms.popScope();
3129
3130 while (true) {
3131 const attr_buf_top = p.attr_buf.len;
3132 defer p.attr_buf.len = attr_buf_top;
3133 const param_decl_spec = if (try p.declSpec()) |some|
3134 some
3135 else if (p.comp.langopts.standard.atLeast(.c23) and
3136 (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier))
3137 {
3138 // handle deprecated K&R style parameters
3139 const identifier = try p.expectIdentifier();
3140 try p.errStr(.unknown_type_name, identifier, p.tokSlice(identifier));
3141 if (d.old_style_func == null) d.old_style_func = identifier;
3142
3143 try p.param_buf.append(.{
3144 .name = try StrInt.intern(p.comp, p.tokSlice(identifier)),
3145 .name_tok = identifier,
3146 .ty = .{ .specifier = .int },
3147 });
3148
3149 if (p.eatToken(.comma) == null) break;
3150 if (p.tok_ids[p.tok_i] == .ellipsis) break;
3151 continue;
3152 } else if (p.param_buf.items.len == param_buf_top) {
3153 return null;
3154 } else blk: {
3155 var spec: Type.Builder = .{};
3156 break :blk DeclSpec{ .ty = try spec.finish(p) };
3157 };
3158
3159 var name_tok: TokenIndex = 0;
3160 const first_tok = p.tok_i;
3161 var param_ty = param_decl_spec.ty;
3162 if (try p.declarator(param_decl_spec.ty, .param)) |some| {
3163 if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
3164 try p.attributeSpecifier();
3165
3166 name_tok = some.name;
3167 param_ty = some.ty;
3168 if (some.name != 0) {
3169 const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok));
3170 try p.syms.defineParam(p, interned_name, param_ty, name_tok);
3171 }
3172 }
3173 param_ty = try Attribute.applyParameterAttributes(p, param_ty, attr_buf_top, .alignas_on_param);
3174
3175 if (param_ty.isFunc()) {
3176 // params declared as functions are converted to function pointers
3177 const elem_ty = try p.arena.create(Type);
3178 elem_ty.* = param_ty;
3179 param_ty = Type{
3180 .specifier = .pointer,
3181 .data = .{ .sub_type = elem_ty },
3182 };
3183 } else if (param_ty.isArray()) {
3184 // params declared as arrays are converted to pointers
3185 param_ty.decayArray();
3186 } else if (param_ty.is(.void)) {
3187 // validate void parameters
3188 if (p.param_buf.items.len == param_buf_top) {
3189 if (p.tok_ids[p.tok_i] != .r_paren) {
3190 try p.err(.void_only_param);
3191 if (param_ty.anyQual()) try p.err(.void_param_qualified);
3192 return error.ParsingFailed;
3193 }
3194 return &[0]Type.Func.Param{};
3195 }
3196 try p.err(.void_must_be_first_param);
3197 return error.ParsingFailed;
3198 }
3199
3200 try param_decl_spec.validateParam(p, &param_ty);
3201 try p.param_buf.append(.{
3202 .name = if (name_tok == 0) .empty else try StrInt.intern(p.comp, p.tokSlice(name_tok)),
3203 .name_tok = if (name_tok == 0) first_tok else name_tok,
3204 .ty = param_ty,
3205 });
3206
3207 if (p.eatToken(.comma) == null) break;
3208 if (p.tok_ids[p.tok_i] == .ellipsis) break;
3209 }
3210 return try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
3211}
3212
3213/// typeName : specQual abstractDeclarator
3214fn typeName(p: *Parser) Error!?Type {
3215 const attr_buf_top = p.attr_buf.len;
3216 defer p.attr_buf.len = attr_buf_top;
3217 const ty = (try p.specQual()) orelse return null;
3218 if (try p.declarator(ty, .abstract)) |some| {
3219 if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
3220 return try Attribute.applyTypeAttributes(p, some.ty, attr_buf_top, .align_ignored);
3221 }
3222 return try Attribute.applyTypeAttributes(p, ty, attr_buf_top, .align_ignored);
3223}
3224
3225/// initializer
3226/// : assignExpr
3227/// | '{' initializerItems '}'
3228fn initializer(p: *Parser, init_ty: Type) Error!Result {
3229 // fast path for non-braced initializers
3230 if (p.tok_ids[p.tok_i] != .l_brace) {
3231 const tok = p.tok_i;
3232 var res = try p.assignExpr();
3233 try res.expect(p);
3234 if (try p.coerceArrayInit(&res, tok, init_ty)) return res;
3235 try p.coerceInit(&res, tok, init_ty);
3236 return res;
3237 }
3238 if (init_ty.is(.auto_type)) {
3239 try p.err(.auto_type_with_init_list);
3240 return error.ParsingFailed;
3241 }
3242
3243 var il: InitList = .{};
3244 defer il.deinit(p.gpa);
3245
3246 _ = try p.initializerItem(&il, init_ty);
3247
3248 const res = try p.convertInitList(il, init_ty);
3249 var res_ty = p.nodes.items(.ty)[@intFromEnum(res)];
3250 res_ty.qual = init_ty.qual;
3251 return Result{ .ty = res_ty, .node = res };
3252}
3253
3254/// initializerItems : designation? initializer (',' designation? initializer)* ','?
3255/// designation : designator+ '='
3256/// designator
3257/// : '[' integerConstExpr ']'
3258/// | '.' identifier
3259fn initializerItem(p: *Parser, il: *InitList, init_ty: Type) Error!bool {
3260 const l_brace = p.eatToken(.l_brace) orelse {
3261 const tok = p.tok_i;
3262 var res = try p.assignExpr();
3263 if (res.empty(p)) return false;
3264
3265 const arr = try p.coerceArrayInit(&res, tok, init_ty);
3266 if (!arr) try p.coerceInit(&res, tok, init_ty);
3267 if (il.tok != 0) {
3268 try p.errTok(.initializer_overrides, tok);
3269 try p.errTok(.previous_initializer, il.tok);
3270 }
3271 il.node = res.node;
3272 il.tok = tok;
3273 return true;
3274 };
3275
3276 const is_scalar = init_ty.isScalar();
3277 const is_complex = init_ty.isComplex();
3278 const scalar_inits_needed: usize = if (is_complex) 2 else 1;
3279 if (p.eatToken(.r_brace)) |_| {
3280 if (is_scalar) try p.errTok(.empty_scalar_init, l_brace);
3281 if (il.tok != 0) {
3282 try p.errTok(.initializer_overrides, l_brace);
3283 try p.errTok(.previous_initializer, il.tok);
3284 }
3285 il.node = .none;
3286 il.tok = l_brace;
3287 return true;
3288 }
3289
3290 var count: u64 = 0;
3291 var warned_excess = false;
3292 var is_str_init = false;
3293 var index_hint: ?u64 = null;
3294 while (true) : (count += 1) {
3295 errdefer p.skipTo(.r_brace);
3296
3297 var first_tok = p.tok_i;
3298 var cur_ty = init_ty;
3299 var cur_il = il;
3300 var designation = false;
3301 var cur_index_hint: ?u64 = null;
3302 while (true) {
3303 if (p.eatToken(.l_bracket)) |l_bracket| {
3304 if (!cur_ty.isArray()) {
3305 try p.errStr(.invalid_array_designator, l_bracket, try p.typeStr(cur_ty));
3306 return error.ParsingFailed;
3307 }
3308 const expr_tok = p.tok_i;
3309 const index_res = try p.integerConstExpr(.gnu_folding_extension);
3310 try p.expectClosing(l_bracket, .r_bracket);
3311
3312 if (index_res.val.opt_ref == .none) {
3313 try p.errTok(.expected_integer_constant_expr, expr_tok);
3314 return error.ParsingFailed;
3315 } else if (index_res.val.compare(.lt, Value.zero, p.comp)) {
3316 try p.errStr(.negative_array_designator, l_bracket + 1, try index_res.str(p));
3317 return error.ParsingFailed;
3318 }
3319
3320 const max_len = cur_ty.arrayLen() orelse std.math.maxInt(usize);
3321 const index_int = index_res.val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
3322 if (index_int >= max_len) {
3323 try p.errStr(.oob_array_designator, l_bracket + 1, try index_res.str(p));
3324 return error.ParsingFailed;
3325 }
3326 cur_index_hint = cur_index_hint orelse index_int;
3327
3328 cur_il = try cur_il.find(p.gpa, index_int);
3329 cur_ty = cur_ty.elemType();
3330 designation = true;
3331 } else if (p.eatToken(.period)) |period| {
3332 const field_tok = try p.expectIdentifier();
3333 const field_str = p.tokSlice(field_tok);
3334 const field_name = try StrInt.intern(p.comp, field_str);
3335 cur_ty = cur_ty.canonicalize(.standard);
3336 if (!cur_ty.isRecord()) {
3337 try p.errStr(.invalid_field_designator, period, try p.typeStr(cur_ty));
3338 return error.ParsingFailed;
3339 } else if (!cur_ty.hasField(field_name)) {
3340 try p.errStr(.no_such_field_designator, period, field_str);
3341 return error.ParsingFailed;
3342 }
3343
3344 // TODO check if union already has field set
3345 outer: while (true) {
3346 for (cur_ty.data.record.fields, 0..) |f, i| {
3347 if (f.isAnonymousRecord()) {
3348 // Recurse into anonymous field if it has a field by the name.
3349 if (!f.ty.hasField(field_name)) continue;
3350 cur_ty = f.ty.canonicalize(.standard);
3351 cur_il = try il.find(p.gpa, i);
3352 cur_index_hint = cur_index_hint orelse i;
3353 continue :outer;
3354 }
3355 if (field_name == f.name) {
3356 cur_il = try cur_il.find(p.gpa, i);
3357 cur_ty = f.ty;
3358 cur_index_hint = cur_index_hint orelse i;
3359 break :outer;
3360 }
3361 }
3362 unreachable; // we already checked that the starting type has this field
3363 }
3364 designation = true;
3365 } else break;
3366 }
3367 if (designation) index_hint = null;
3368 defer index_hint = cur_index_hint orelse null;
3369
3370 if (designation) _ = try p.expectToken(.equal);
3371
3372 if (!designation and cur_ty.hasAttribute(.designated_init)) {
3373 try p.err(.designated_init_needed);
3374 }
3375
3376 var saw = false;
3377 if (is_str_init and p.isStringInit(init_ty)) {
3378 // discard further strings
3379 var tmp_il = InitList{};
3380 defer tmp_il.deinit(p.gpa);
3381 saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
3382 } else if (count == 0 and p.isStringInit(init_ty)) {
3383 is_str_init = true;
3384 saw = try p.initializerItem(il, init_ty);
3385 } else if (is_scalar and count >= scalar_inits_needed) {
3386 // discard further scalars
3387 var tmp_il = InitList{};
3388 defer tmp_il.deinit(p.gpa);
3389 saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
3390 } else if (p.tok_ids[p.tok_i] == .l_brace) {
3391 if (designation) {
3392 // designation overrides previous value, let existing mechanism handle it
3393 saw = try p.initializerItem(cur_il, cur_ty);
3394 } else if (try p.findAggregateInitializer(&cur_il, &cur_ty, &index_hint)) {
3395 saw = try p.initializerItem(cur_il, cur_ty);
3396 } else {
3397 // discard further values
3398 var tmp_il = InitList{};
3399 defer tmp_il.deinit(p.gpa);
3400 saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
3401 if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
3402 warned_excess = true;
3403 }
3404 } else single_item: {
3405 first_tok = p.tok_i;
3406 var res = try p.assignExpr();
3407 saw = !res.empty(p);
3408 if (!saw) break :single_item;
3409
3410 excess: {
3411 if (index_hint) |*hint| {
3412 if (try p.findScalarInitializerAt(&cur_il, &cur_ty, &res, first_tok, hint)) break :excess;
3413 } else if (try p.findScalarInitializer(&cur_il, &cur_ty, &res, first_tok)) break :excess;
3414
3415 if (designation) break :excess;
3416 if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
3417 warned_excess = true;
3418
3419 break :single_item;
3420 }
3421
3422 const arr = try p.coerceArrayInit(&res, first_tok, cur_ty);
3423 if (!arr) try p.coerceInit(&res, first_tok, cur_ty);
3424 if (cur_il.tok != 0) {
3425 try p.errTok(.initializer_overrides, first_tok);
3426 try p.errTok(.previous_initializer, cur_il.tok);
3427 }
3428 cur_il.node = res.node;
3429 cur_il.tok = first_tok;
3430 }
3431
3432 if (!saw) {
3433 if (designation) {
3434 try p.err(.expected_expr);
3435 return error.ParsingFailed;
3436 }
3437 break;
3438 } else if (count == 1) {
3439 if (is_str_init) try p.errTok(.excess_str_init, first_tok);
3440 if (is_scalar and !is_complex) try p.errTok(.excess_scalar_init, first_tok);
3441 } else if (count == 2) {
3442 if (is_scalar and is_complex) try p.errTok(.excess_scalar_init, first_tok);
3443 }
3444
3445 if (p.eatToken(.comma) == null) break;
3446 }
3447 try p.expectClosing(l_brace, .r_brace);
3448
3449 if (is_complex and count == 1) { // count of 1 means we saw exactly 2 items in the initializer list
3450 try p.errTok(.complex_component_init, l_brace);
3451 }
3452 if (is_scalar or is_str_init) return true;
3453 if (il.tok != 0) {
3454 try p.errTok(.initializer_overrides, l_brace);
3455 try p.errTok(.previous_initializer, il.tok);
3456 }
3457 il.node = .none;
3458 il.tok = l_brace;
3459 return true;
3460}
3461
3462/// Returns true if the value is unused.
3463fn findScalarInitializerAt(p: *Parser, il: **InitList, ty: *Type, res: *Result, first_tok: TokenIndex, start_index: *u64) Error!bool {
3464 if (ty.isArray()) {
3465 if (il.*.node != .none) return false;
3466 start_index.* += 1;
3467
3468 const arr_ty = ty.*;
3469 const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
3470 if (elem_count == 0) {
3471 try p.errTok(.empty_aggregate_init_braces, first_tok);
3472 return error.ParsingFailed;
3473 }
3474 const elem_ty = arr_ty.elemType();
3475 const arr_il = il.*;
3476 if (start_index.* < elem_count) {
3477 ty.* = elem_ty;
3478 il.* = try arr_il.find(p.gpa, start_index.*);
3479 _ = try p.findScalarInitializer(il, ty, res, first_tok);
3480 return true;
3481 }
3482 return false;
3483 } else if (ty.get(.@"struct")) |struct_ty| {
3484 if (il.*.node != .none) return false;
3485 start_index.* += 1;
3486
3487 const fields = struct_ty.data.record.fields;
3488 if (fields.len == 0) {
3489 try p.errTok(.empty_aggregate_init_braces, first_tok);
3490 return error.ParsingFailed;
3491 }
3492 const struct_il = il.*;
3493 if (start_index.* < fields.len) {
3494 const field = fields[@intCast(start_index.*)];
3495 ty.* = field.ty;
3496 il.* = try struct_il.find(p.gpa, start_index.*);
3497 _ = try p.findScalarInitializer(il, ty, res, first_tok);
3498 return true;
3499 }
3500 return false;
3501 } else if (ty.get(.@"union")) |_| {
3502 return false;
3503 }
3504 return il.*.node == .none;
3505}
3506
3507/// Returns true if the value is unused.
3508fn findScalarInitializer(p: *Parser, il: **InitList, ty: *Type, res: *Result, first_tok: TokenIndex) Error!bool {
3509 const actual_ty = res.ty;
3510 if (ty.isArray() or ty.isComplex()) {
3511 if (il.*.node != .none) return false;
3512 if (try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true;
3513 const start_index = il.*.list.items.len;
3514 var index = if (start_index != 0) il.*.list.items[start_index - 1].index else start_index;
3515
3516 const arr_ty = ty.*;
3517 const elem_count: u64 = arr_ty.expectedInitListSize() orelse std.math.maxInt(u64);
3518 if (elem_count == 0) {
3519 try p.errTok(.empty_aggregate_init_braces, first_tok);
3520 return error.ParsingFailed;
3521 }
3522 const elem_ty = arr_ty.elemType();
3523 const arr_il = il.*;
3524 while (index < elem_count) : (index += 1) {
3525 ty.* = elem_ty;
3526 il.* = try arr_il.find(p.gpa, index);
3527 if (il.*.node == .none and actual_ty.eql(elem_ty, p.comp, false)) return true;
3528 if (try p.findScalarInitializer(il, ty, res, first_tok)) return true;
3529 }
3530 return false;
3531 } else if (ty.get(.@"struct")) |struct_ty| {
3532 if (il.*.node != .none) return false;
3533 if (actual_ty.eql(ty.*, p.comp, false)) return true;
3534 const start_index = il.*.list.items.len;
3535 var index = if (start_index != 0) il.*.list.items[start_index - 1].index + 1 else start_index;
3536
3537 const fields = struct_ty.data.record.fields;
3538 if (fields.len == 0) {
3539 try p.errTok(.empty_aggregate_init_braces, first_tok);
3540 return error.ParsingFailed;
3541 }
3542 const struct_il = il.*;
3543 while (index < fields.len) : (index += 1) {
3544 const field = fields[@intCast(index)];
3545 ty.* = field.ty;
3546 il.* = try struct_il.find(p.gpa, index);
3547 if (il.*.node == .none and actual_ty.eql(field.ty, p.comp, false)) return true;
3548 if (il.*.node == .none and try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true;
3549 if (try p.findScalarInitializer(il, ty, res, first_tok)) return true;
3550 }
3551 return false;
3552 } else if (ty.get(.@"union")) |union_ty| {
3553 if (il.*.node != .none) return false;
3554 if (actual_ty.eql(ty.*, p.comp, false)) return true;
3555 if (union_ty.data.record.fields.len == 0) {
3556 try p.errTok(.empty_aggregate_init_braces, first_tok);
3557 return error.ParsingFailed;
3558 }
3559 ty.* = union_ty.data.record.fields[0].ty;
3560 il.* = try il.*.find(p.gpa, 0);
3561 // if (il.*.node == .none and actual_ty.eql(ty, p.comp, false)) return true;
3562 if (try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true;
3563 if (try p.findScalarInitializer(il, ty, res, first_tok)) return true;
3564 return false;
3565 }
3566 return il.*.node == .none;
3567}
3568
3569fn findAggregateInitializer(p: *Parser, il: **InitList, ty: *Type, start_index: *?u64) Error!bool {
3570 if (ty.isArray()) {
3571 if (il.*.node != .none) return false;
3572 const list_index = il.*.list.items.len;
3573 const index = if (start_index.*) |*some| blk: {
3574 some.* += 1;
3575 break :blk some.*;
3576 } else if (list_index != 0)
3577 il.*.list.items[list_index - 1].index + 1
3578 else
3579 list_index;
3580
3581 const arr_ty = ty.*;
3582 const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
3583 const elem_ty = arr_ty.elemType();
3584 if (index < elem_count) {
3585 ty.* = elem_ty;
3586 il.* = try il.*.find(p.gpa, index);
3587 return true;
3588 }
3589 return false;
3590 } else if (ty.get(.@"struct")) |struct_ty| {
3591 if (il.*.node != .none) return false;
3592 const list_index = il.*.list.items.len;
3593 const index = if (start_index.*) |*some| blk: {
3594 some.* += 1;
3595 break :blk some.*;
3596 } else if (list_index != 0)
3597 il.*.list.items[list_index - 1].index + 1
3598 else
3599 list_index;
3600
3601 const field_count = struct_ty.data.record.fields.len;
3602 if (index < field_count) {
3603 ty.* = struct_ty.data.record.fields[@intCast(index)].ty;
3604 il.* = try il.*.find(p.gpa, index);
3605 return true;
3606 }
3607 return false;
3608 } else if (ty.get(.@"union")) |union_ty| {
3609 if (il.*.node != .none) return false;
3610 if (start_index.*) |_| return false; // overrides
3611 if (union_ty.data.record.fields.len == 0) return false;
3612
3613 ty.* = union_ty.data.record.fields[0].ty;
3614 il.* = try il.*.find(p.gpa, 0);
3615 return true;
3616 } else {
3617 try p.err(.too_many_scalar_init_braces);
3618 return il.*.node == .none;
3619 }
3620}
3621
3622fn coerceArrayInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !bool {
3623 return p.coerceArrayInitExtra(item, tok, target, true);
3624}
3625
3626fn coerceArrayInitExtra(p: *Parser, item: *Result, tok: TokenIndex, target: Type, report_err: bool) !bool {
3627 if (!target.isArray()) return false;
3628
3629 const is_str_lit = p.nodeIs(item.node, .string_literal_expr);
3630 if (!is_str_lit and !p.nodeIsCompoundLiteral(item.node) or !item.ty.isArray()) {
3631 if (!report_err) return false;
3632 try p.errTok(.array_init_str, tok);
3633 return true; // do not do further coercion
3634 }
3635
3636 const target_spec = target.elemType().canonicalize(.standard).specifier;
3637 const item_spec = item.ty.elemType().canonicalize(.standard).specifier;
3638
3639 const compatible = target.elemType().eql(item.ty.elemType(), p.comp, false) or
3640 (is_str_lit and item_spec == .char and (target_spec == .uchar or target_spec == .schar)) or
3641 (is_str_lit and item_spec == .uchar and (target_spec == .uchar or target_spec == .schar or target_spec == .char));
3642 if (!compatible) {
3643 if (!report_err) return false;
3644 const e_msg = " with array of type ";
3645 try p.errStr(.incompatible_array_init, tok, try p.typePairStrExtra(target, e_msg, item.ty));
3646 return true; // do not do further coercion
3647 }
3648
3649 if (target.get(.array)) |arr_ty| {
3650 assert(item.ty.specifier == .array);
3651 const len = item.ty.arrayLen().?;
3652 const array_len = arr_ty.arrayLen().?;
3653 if (is_str_lit) {
3654 // the null byte of a string can be dropped
3655 if (len - 1 > array_len and report_err) {
3656 try p.errTok(.str_init_too_long, tok);
3657 }
3658 } else if (len > array_len and report_err) {
3659 try p.errStr(
3660 .arr_init_too_long,
3661 tok,
3662 try p.typePairStrExtra(target, " with array of type ", item.ty),
3663 );
3664 }
3665 }
3666 return true;
3667}
3668
3669fn coerceInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !void {
3670 if (target.is(.void)) return; // Do not do type coercion on excess items
3671
3672 const node = item.node;
3673 try item.lvalConversion(p);
3674 if (target.is(.auto_type)) {
3675 if (p.getNode(node, .member_access_expr) orelse p.getNode(node, .member_access_ptr_expr)) |member_node| {
3676 if (p.tmpTree().isBitfield(member_node)) try p.errTok(.auto_type_from_bitfield, tok);
3677 }
3678 return;
3679 } else if (target.is(.c23_auto)) {
3680 return;
3681 }
3682
3683 try item.coerce(p, target, tok, .init);
3684}
3685
3686fn isStringInit(p: *Parser, ty: Type) bool {
3687 if (!ty.isArray() or !ty.elemType().isInt()) return false;
3688 var i = p.tok_i;
3689 while (true) : (i += 1) {
3690 switch (p.tok_ids[i]) {
3691 .l_paren => {},
3692 .string_literal,
3693 .string_literal_utf_16,
3694 .string_literal_utf_8,
3695 .string_literal_utf_32,
3696 .string_literal_wide,
3697 => return true,
3698 else => return false,
3699 }
3700 }
3701}
3702
3703/// Convert InitList into an AST
3704fn convertInitList(p: *Parser, il: InitList, init_ty: Type) Error!NodeIndex {
3705 const is_complex = init_ty.isComplex();
3706 if (init_ty.isScalar() and !is_complex) {
3707 if (il.node == .none) {
3708 return p.addNode(.{ .tag = .default_init_expr, .ty = init_ty, .data = undefined });
3709 }
3710 return il.node;
3711 } else if (init_ty.is(.variable_len_array)) {
3712 return error.ParsingFailed; // vla invalid, reported earlier
3713 } else if (init_ty.isArray() or is_complex) {
3714 if (il.node != .none) {
3715 return il.node;
3716 }
3717 const list_buf_top = p.list_buf.items.len;
3718 defer p.list_buf.items.len = list_buf_top;
3719
3720 const elem_ty = init_ty.elemType();
3721
3722 const max_items: u64 = init_ty.expectedInitListSize() orelse std.math.maxInt(usize);
3723 var start: u64 = 0;
3724 for (il.list.items) |*init| {
3725 if (init.index > start) {
3726 const elem = try p.addNode(.{
3727 .tag = .array_filler_expr,
3728 .ty = elem_ty,
3729 .data = .{ .int = init.index - start },
3730 });
3731 try p.list_buf.append(elem);
3732 }
3733 start = init.index + 1;
3734
3735 const elem = try p.convertInitList(init.list, elem_ty);
3736 try p.list_buf.append(elem);
3737 }
3738
3739 var arr_init_node: Tree.Node = .{
3740 .tag = .array_init_expr_two,
3741 .ty = init_ty,
3742 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
3743 };
3744
3745 if (init_ty.specifier == .incomplete_array) {
3746 arr_init_node.ty.specifier = .array;
3747 arr_init_node.ty.data.array.len = start;
3748 } else if (init_ty.is(.incomplete_array)) {
3749 const arr_ty = try p.arena.create(Type.Array);
3750 arr_ty.* = .{ .elem = init_ty.elemType(), .len = start };
3751 arr_init_node.ty = .{
3752 .specifier = .array,
3753 .data = .{ .array = arr_ty },
3754 };
3755 const attrs = init_ty.getAttributes();
3756 arr_init_node.ty = try arr_init_node.ty.withAttributes(p.arena, attrs);
3757 } else if (start < max_items) {
3758 const elem = try p.addNode(.{
3759 .tag = .array_filler_expr,
3760 .ty = elem_ty,
3761 .data = .{ .int = max_items - start },
3762 });
3763 try p.list_buf.append(elem);
3764 }
3765
3766 const items = p.list_buf.items[list_buf_top..];
3767 switch (items.len) {
3768 0 => {},
3769 1 => arr_init_node.data.bin.lhs = items[0],
3770 2 => arr_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
3771 else => {
3772 arr_init_node.tag = .array_init_expr;
3773 arr_init_node.data = .{ .range = try p.addList(items) };
3774 },
3775 }
3776 return try p.addNode(arr_init_node);
3777 } else if (init_ty.get(.@"struct")) |struct_ty| {
3778 assert(!struct_ty.hasIncompleteSize());
3779 if (il.node != .none) {
3780 return il.node;
3781 }
3782
3783 const list_buf_top = p.list_buf.items.len;
3784 defer p.list_buf.items.len = list_buf_top;
3785
3786 var init_index: usize = 0;
3787 for (struct_ty.data.record.fields, 0..) |f, i| {
3788 if (init_index < il.list.items.len and il.list.items[init_index].index == i) {
3789 const item = try p.convertInitList(il.list.items[init_index].list, f.ty);
3790 try p.list_buf.append(item);
3791 init_index += 1;
3792 } else {
3793 const item = try p.addNode(.{ .tag = .default_init_expr, .ty = f.ty, .data = undefined });
3794 try p.list_buf.append(item);
3795 }
3796 }
3797
3798 var struct_init_node: Tree.Node = .{
3799 .tag = .struct_init_expr_two,
3800 .ty = init_ty,
3801 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
3802 };
3803 const items = p.list_buf.items[list_buf_top..];
3804 switch (items.len) {
3805 0 => {},
3806 1 => struct_init_node.data.bin.lhs = items[0],
3807 2 => struct_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
3808 else => {
3809 struct_init_node.tag = .struct_init_expr;
3810 struct_init_node.data = .{ .range = try p.addList(items) };
3811 },
3812 }
3813 return try p.addNode(struct_init_node);
3814 } else if (init_ty.get(.@"union")) |union_ty| {
3815 if (il.node != .none) {
3816 return il.node;
3817 }
3818
3819 var union_init_node: Tree.Node = .{
3820 .tag = .union_init_expr,
3821 .ty = init_ty,
3822 .data = .{ .union_init = .{ .field_index = 0, .node = .none } },
3823 };
3824 if (union_ty.data.record.fields.len == 0) {
3825 // do nothing for empty unions
3826 } else if (il.list.items.len == 0) {
3827 union_init_node.data.union_init.node = try p.addNode(.{
3828 .tag = .default_init_expr,
3829 .ty = init_ty,
3830 .data = undefined,
3831 });
3832 } else {
3833 const init = il.list.items[0];
3834 const index: u32 = @truncate(init.index);
3835 const field_ty = union_ty.data.record.fields[index].ty;
3836 union_init_node.data.union_init = .{
3837 .field_index = index,
3838 .node = try p.convertInitList(init.list, field_ty),
3839 };
3840 }
3841 return try p.addNode(union_init_node);
3842 } else {
3843 return error.ParsingFailed; // initializer target is invalid, reported earlier
3844 }
3845}
3846
3847fn msvcAsmStmt(p: *Parser) Error!?NodeIndex {
3848 return p.todo("MSVC assembly statements");
3849}
3850
3851/// asmOperand : ('[' IDENTIFIER ']')? asmStr '(' expr ')'
3852fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *NodeList, exprs: *NodeList) Error!void {
3853 if (p.eatToken(.l_bracket)) |l_bracket| {
3854 const ident = (try p.eatIdentifier()) orelse {
3855 try p.err(.expected_identifier);
3856 return error.ParsingFailed;
3857 };
3858 try names.append(ident);
3859 try p.expectClosing(l_bracket, .r_bracket);
3860 } else {
3861 try names.append(null);
3862 }
3863 const constraint = try p.asmStr();
3864 try constraints.append(constraint.node);
3865
3866 const l_paren = p.eatToken(.l_paren) orelse {
3867 try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .l_paren } });
3868 return error.ParsingFailed;
3869 };
3870 const res = try p.expr();
3871 try p.expectClosing(l_paren, .r_paren);
3872 try res.expect(p);
3873 try exprs.append(res.node);
3874}
3875
3876/// gnuAsmStmt
3877/// : asmStr
3878/// | asmStr ':' asmOperand*
3879/// | asmStr ':' asmOperand* ':' asmOperand*
3880/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)*
3881/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)* : IDENTIFIER (',' IDENTIFIER)*
3882fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, l_paren: TokenIndex) Error!NodeIndex {
3883 const asm_str = try p.asmStr();
3884 try p.checkAsmStr(asm_str.val, l_paren);
3885
3886 if (p.tok_ids[p.tok_i] == .r_paren) {
3887 return p.addNode(.{
3888 .tag = .gnu_asm_simple,
3889 .ty = .{ .specifier = .void },
3890 .data = .{ .un = asm_str.node },
3891 });
3892 }
3893
3894 const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names
3895 const bytes_needed = expected_items * @sizeOf(?TokenIndex) + expected_items * 3 * @sizeOf(NodeIndex);
3896
3897 var stack_fallback = std.heap.stackFallback(bytes_needed, p.gpa);
3898 const allocator = stack_fallback.get();
3899
3900 // TODO: Consider using a TokenIndex of 0 instead of null if we need to store the names in the tree
3901 var names = std.ArrayList(?TokenIndex).initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
3902 defer names.deinit();
3903 var constraints = NodeList.initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
3904 defer constraints.deinit();
3905 var exprs = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
3906 defer exprs.deinit();
3907 var clobbers = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
3908 defer clobbers.deinit();
3909
3910 // Outputs
3911 var ate_extra_colon = false;
3912 if (p.eatToken(.colon) orelse p.eatToken(.colon_colon)) |tok_i| {
3913 ate_extra_colon = p.tok_ids[tok_i] == .colon_colon;
3914 if (!ate_extra_colon) {
3915 if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
3916 while (true) {
3917 try p.asmOperand(&names, &constraints, &exprs);
3918 if (p.eatToken(.comma) == null) break;
3919 }
3920 }
3921 }
3922 }
3923
3924 const num_outputs = names.items.len;
3925
3926 // Inputs
3927 if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
3928 if (ate_extra_colon) {
3929 ate_extra_colon = false;
3930 } else {
3931 ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
3932 p.tok_i += 1;
3933 }
3934 if (!ate_extra_colon) {
3935 if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
3936 while (true) {
3937 try p.asmOperand(&names, &constraints, &exprs);
3938 if (p.eatToken(.comma) == null) break;
3939 }
3940 }
3941 }
3942 }
3943 std.debug.assert(names.items.len == constraints.items.len and constraints.items.len == exprs.items.len);
3944 const num_inputs = names.items.len - num_outputs;
3945 _ = num_inputs;
3946
3947 // Clobbers
3948 if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
3949 if (ate_extra_colon) {
3950 ate_extra_colon = false;
3951 } else {
3952 ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
3953 p.tok_i += 1;
3954 }
3955 if (!ate_extra_colon and p.tok_ids[p.tok_i].isStringLiteral()) {
3956 while (true) {
3957 const clobber = try p.asmStr();
3958 try clobbers.append(clobber.node);
3959 if (p.eatToken(.comma) == null) break;
3960 }
3961 }
3962 }
3963
3964 if (!quals.goto and (p.tok_ids[p.tok_i] != .r_paren or ate_extra_colon)) {
3965 try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .r_paren } });
3966 return error.ParsingFailed;
3967 }
3968
3969 // Goto labels
3970 var num_labels: u32 = 0;
3971 if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon) {
3972 if (!ate_extra_colon) {
3973 p.tok_i += 1;
3974 }
3975 while (true) {
3976 const ident = (try p.eatIdentifier()) orelse {
3977 try p.err(.expected_identifier);
3978 return error.ParsingFailed;
3979 };
3980 const ident_str = p.tokSlice(ident);
3981 const label = p.findLabel(ident_str) orelse blk: {
3982 try p.labels.append(.{ .unresolved_goto = ident });
3983 break :blk ident;
3984 };
3985 try names.append(ident);
3986
3987 const elem_ty = try p.arena.create(Type);
3988 elem_ty.* = .{ .specifier = .void };
3989 const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
3990
3991 const label_addr_node = try p.addNode(.{
3992 .tag = .addr_of_label,
3993 .data = .{ .decl_ref = label },
3994 .ty = result_ty,
3995 });
3996 try exprs.append(label_addr_node);
3997
3998 num_labels += 1;
3999 if (p.eatToken(.comma) == null) break;
4000 }
4001 } else if (quals.goto) {
4002 try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .colon } });
4003 return error.ParsingFailed;
4004 }
4005
4006 // TODO: validate and insert into AST
4007 return .none;
4008}
4009
4010fn checkAsmStr(p: *Parser, asm_str: Value, tok: TokenIndex) !void {
4011 if (!p.comp.langopts.gnu_asm) {
4012 const str = p.comp.interner.get(asm_str.ref()).bytes;
4013 if (str.len > 1) {
4014 // Empty string (just a NUL byte) is ok because it does not emit any assembly
4015 try p.errTok(.gnu_asm_disabled, tok);
4016 }
4017 }
4018}
4019
4020/// assembly
4021/// : keyword_asm asmQual* '(' asmStr ')'
4022/// | keyword_asm asmQual* '(' gnuAsmStmt ')'
4023/// | keyword_asm msvcAsmStmt
4024fn assembly(p: *Parser, kind: enum { global, decl_label, stmt }) Error!?NodeIndex {
4025 const asm_tok = p.tok_i;
4026 switch (p.tok_ids[p.tok_i]) {
4027 .keyword_asm => {
4028 try p.err(.extension_token_used);
4029 p.tok_i += 1;
4030 },
4031 .keyword_asm1, .keyword_asm2 => p.tok_i += 1,
4032 else => return null,
4033 }
4034
4035 if (!p.tok_ids[p.tok_i].canOpenGCCAsmStmt()) {
4036 return p.msvcAsmStmt();
4037 }
4038
4039 var quals: Tree.GNUAssemblyQualifiers = .{};
4040 while (true) : (p.tok_i += 1) switch (p.tok_ids[p.tok_i]) {
4041 .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
4042 if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "volatile");
4043 if (quals.@"volatile") try p.errStr(.duplicate_asm_qual, p.tok_i, "volatile");
4044 quals.@"volatile" = true;
4045 },
4046 .keyword_inline, .keyword_inline1, .keyword_inline2 => {
4047 if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "inline");
4048 if (quals.@"inline") try p.errStr(.duplicate_asm_qual, p.tok_i, "inline");
4049 quals.@"inline" = true;
4050 },
4051 .keyword_goto => {
4052 if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "goto");
4053 if (quals.goto) try p.errStr(.duplicate_asm_qual, p.tok_i, "goto");
4054 quals.goto = true;
4055 },
4056 else => break,
4057 };
4058
4059 const l_paren = try p.expectToken(.l_paren);
4060 var result_node: NodeIndex = .none;
4061 switch (kind) {
4062 .decl_label => {
4063 const asm_str = try p.asmStr();
4064 const str = try p.removeNull(asm_str.val);
4065
4066 const attr = Attribute{ .tag = .asm_label, .args = .{ .asm_label = .{ .name = str } }, .syntax = .keyword };
4067 try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = asm_tok });
4068 },
4069 .global => {
4070 const asm_str = try p.asmStr();
4071 try p.checkAsmStr(asm_str.val, l_paren);
4072 result_node = try p.addNode(.{
4073 .tag = .file_scope_asm,
4074 .ty = .{ .specifier = .void },
4075 .data = .{ .decl = .{ .name = asm_tok, .node = asm_str.node } },
4076 });
4077 },
4078 .stmt => result_node = try p.gnuAsmStmt(quals, l_paren),
4079 }
4080 try p.expectClosing(l_paren, .r_paren);
4081
4082 if (kind != .decl_label) _ = try p.expectToken(.semicolon);
4083 return result_node;
4084}
4085
4086/// Same as stringLiteral but errors on unicode and wide string literals
4087fn asmStr(p: *Parser) Error!Result {
4088 var i = p.tok_i;
4089 while (true) : (i += 1) switch (p.tok_ids[i]) {
4090 .string_literal, .unterminated_string_literal => {},
4091 .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32 => {
4092 try p.errStr(.invalid_asm_str, p.tok_i, "unicode");
4093 return error.ParsingFailed;
4094 },
4095 .string_literal_wide => {
4096 try p.errStr(.invalid_asm_str, p.tok_i, "wide");
4097 return error.ParsingFailed;
4098 },
4099 else => {
4100 if (i == p.tok_i) {
4101 try p.errStr(.expected_str_literal_in, p.tok_i, "asm");
4102 return error.ParsingFailed;
4103 }
4104 break;
4105 },
4106 };
4107 return try p.stringLiteral();
4108}
4109
4110// ====== statements ======
4111
4112/// stmt
4113/// : labeledStmt
4114/// | compoundStmt
4115/// | keyword_if '(' expr ')' stmt (keyword_else stmt)?
4116/// | keyword_switch '(' expr ')' stmt
4117/// | keyword_while '(' expr ')' stmt
4118/// | keyword_do stmt while '(' expr ')' ';'
4119/// | keyword_for '(' (decl | expr? ';') expr? ';' expr? ')' stmt
4120/// | keyword_goto (IDENTIFIER | ('*' expr)) ';'
4121/// | keyword_continue ';'
4122/// | keyword_break ';'
4123/// | keyword_return expr? ';'
4124/// | assembly ';'
4125/// | expr? ';'
4126fn stmt(p: *Parser) Error!NodeIndex {
4127 if (try p.labeledStmt()) |some| return some;
4128 if (try p.compoundStmt(false, null)) |some| return some;
4129 if (p.eatToken(.keyword_if)) |_| {
4130 const l_paren = try p.expectToken(.l_paren);
4131 const cond_tok = p.tok_i;
4132 var cond = try p.expr();
4133 try cond.expect(p);
4134 try cond.lvalConversion(p);
4135 try cond.usualUnaryConversion(p, cond_tok);
4136 if (!cond.ty.isScalar())
4137 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4138 try cond.saveValue(p);
4139 try p.expectClosing(l_paren, .r_paren);
4140
4141 const then = try p.stmt();
4142 const @"else" = if (p.eatToken(.keyword_else)) |_| try p.stmt() else .none;
4143
4144 if (then != .none and @"else" != .none)
4145 return try p.addNode(.{
4146 .tag = .if_then_else_stmt,
4147 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then, @"else" })).start } },
4148 })
4149 else
4150 return try p.addNode(.{
4151 .tag = .if_then_stmt,
4152 .data = .{ .bin = .{ .lhs = cond.node, .rhs = then } },
4153 });
4154 }
4155 if (p.eatToken(.keyword_switch)) |_| {
4156 const l_paren = try p.expectToken(.l_paren);
4157 const cond_tok = p.tok_i;
4158 var cond = try p.expr();
4159 try cond.expect(p);
4160 try cond.lvalConversion(p);
4161 try cond.usualUnaryConversion(p, cond_tok);
4162
4163 if (!cond.ty.isInt())
4164 try p.errStr(.statement_int, l_paren + 1, try p.typeStr(cond.ty));
4165 try cond.saveValue(p);
4166 try p.expectClosing(l_paren, .r_paren);
4167
4168 const old_switch = p.@"switch";
4169 var @"switch" = Switch{
4170 .ranges = std.ArrayList(Switch.Range).init(p.gpa),
4171 .ty = cond.ty,
4172 .comp = p.comp,
4173 };
4174 p.@"switch" = &@"switch";
4175 defer {
4176 @"switch".ranges.deinit();
4177 p.@"switch" = old_switch;
4178 }
4179
4180 const body = try p.stmt();
4181
4182 return try p.addNode(.{
4183 .tag = .switch_stmt,
4184 .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
4185 });
4186 }
4187 if (p.eatToken(.keyword_while)) |_| {
4188 const l_paren = try p.expectToken(.l_paren);
4189 const cond_tok = p.tok_i;
4190 var cond = try p.expr();
4191 try cond.expect(p);
4192 try cond.lvalConversion(p);
4193 try cond.usualUnaryConversion(p, cond_tok);
4194 if (!cond.ty.isScalar())
4195 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4196 try cond.saveValue(p);
4197 try p.expectClosing(l_paren, .r_paren);
4198
4199 const body = body: {
4200 const old_loop = p.in_loop;
4201 p.in_loop = true;
4202 defer p.in_loop = old_loop;
4203 break :body try p.stmt();
4204 };
4205
4206 return try p.addNode(.{
4207 .tag = .while_stmt,
4208 .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
4209 });
4210 }
4211 if (p.eatToken(.keyword_do)) |_| {
4212 const body = body: {
4213 const old_loop = p.in_loop;
4214 p.in_loop = true;
4215 defer p.in_loop = old_loop;
4216 break :body try p.stmt();
4217 };
4218
4219 _ = try p.expectToken(.keyword_while);
4220 const l_paren = try p.expectToken(.l_paren);
4221 const cond_tok = p.tok_i;
4222 var cond = try p.expr();
4223 try cond.expect(p);
4224 try cond.lvalConversion(p);
4225 try cond.usualUnaryConversion(p, cond_tok);
4226
4227 if (!cond.ty.isScalar())
4228 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4229 try cond.saveValue(p);
4230 try p.expectClosing(l_paren, .r_paren);
4231
4232 _ = try p.expectToken(.semicolon);
4233 return try p.addNode(.{
4234 .tag = .do_while_stmt,
4235 .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
4236 });
4237 }
4238 if (p.eatToken(.keyword_for)) |_| {
4239 try p.syms.pushScope(p);
4240 defer p.syms.popScope();
4241 const decl_buf_top = p.decl_buf.items.len;
4242 defer p.decl_buf.items.len = decl_buf_top;
4243
4244 const l_paren = try p.expectToken(.l_paren);
4245 const got_decl = try p.decl();
4246
4247 // for (init
4248 const init_start = p.tok_i;
4249 var err_start = p.comp.diagnostics.list.items.len;
4250 var init = if (!got_decl) try p.expr() else Result{};
4251 try init.saveValue(p);
4252 try init.maybeWarnUnused(p, init_start, err_start);
4253 if (!got_decl) _ = try p.expectToken(.semicolon);
4254
4255 // for (init; cond
4256 const cond_tok = p.tok_i;
4257 var cond = try p.expr();
4258 if (cond.node != .none) {
4259 try cond.lvalConversion(p);
4260 try cond.usualUnaryConversion(p, cond_tok);
4261 if (!cond.ty.isScalar())
4262 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4263 }
4264 try cond.saveValue(p);
4265 _ = try p.expectToken(.semicolon);
4266
4267 // for (init; cond; incr
4268 const incr_start = p.tok_i;
4269 err_start = p.comp.diagnostics.list.items.len;
4270 var incr = try p.expr();
4271 try incr.maybeWarnUnused(p, incr_start, err_start);
4272 try incr.saveValue(p);
4273 try p.expectClosing(l_paren, .r_paren);
4274
4275 const body = body: {
4276 const old_loop = p.in_loop;
4277 p.in_loop = true;
4278 defer p.in_loop = old_loop;
4279 break :body try p.stmt();
4280 };
4281
4282 if (got_decl) {
4283 const start = (try p.addList(p.decl_buf.items[decl_buf_top..])).start;
4284 const end = (try p.addList(&.{ cond.node, incr.node, body })).end;
4285
4286 return try p.addNode(.{
4287 .tag = .for_decl_stmt,
4288 .data = .{ .range = .{ .start = start, .end = end } },
4289 });
4290 } else if (init.node == .none and cond.node == .none and incr.node == .none) {
4291 return try p.addNode(.{
4292 .tag = .forever_stmt,
4293 .data = .{ .un = body },
4294 });
4295 } else return try p.addNode(.{ .tag = .for_stmt, .data = .{ .if3 = .{
4296 .cond = body,
4297 .body = (try p.addList(&.{ init.node, cond.node, incr.node })).start,
4298 } } });
4299 }
4300 if (p.eatToken(.keyword_goto)) |goto_tok| {
4301 if (p.eatToken(.asterisk)) |_| {
4302 const expr_tok = p.tok_i;
4303 var e = try p.expr();
4304 try e.expect(p);
4305 try e.lvalConversion(p);
4306 p.computed_goto_tok = p.computed_goto_tok orelse goto_tok;
4307 if (!e.ty.isPtr()) {
4308 const elem_ty = try p.arena.create(Type);
4309 elem_ty.* = .{ .specifier = .void, .qual = .{ .@"const" = true } };
4310 const result_ty = Type{
4311 .specifier = .pointer,
4312 .data = .{ .sub_type = elem_ty },
4313 };
4314 if (!e.ty.isInt()) {
4315 try p.errStr(.incompatible_arg, expr_tok, try p.typePairStrExtra(e.ty, " to parameter of incompatible type ", result_ty));
4316 return error.ParsingFailed;
4317 }
4318 if (e.val.isZero(p.comp)) {
4319 try e.nullCast(p, result_ty);
4320 } else {
4321 try p.errStr(.implicit_int_to_ptr, expr_tok, try p.typePairStrExtra(e.ty, " to ", result_ty));
4322 try e.ptrCast(p, result_ty);
4323 }
4324 }
4325
4326 try e.un(p, .computed_goto_stmt);
4327 _ = try p.expectToken(.semicolon);
4328 return e.node;
4329 }
4330 const name_tok = try p.expectIdentifier();
4331 const str = p.tokSlice(name_tok);
4332 if (p.findLabel(str) == null) {
4333 try p.labels.append(.{ .unresolved_goto = name_tok });
4334 }
4335 _ = try p.expectToken(.semicolon);
4336 return try p.addNode(.{
4337 .tag = .goto_stmt,
4338 .data = .{ .decl_ref = name_tok },
4339 });
4340 }
4341 if (p.eatToken(.keyword_continue)) |cont| {
4342 if (!p.in_loop) try p.errTok(.continue_not_in_loop, cont);
4343 _ = try p.expectToken(.semicolon);
4344 return try p.addNode(.{ .tag = .continue_stmt, .data = undefined });
4345 }
4346 if (p.eatToken(.keyword_break)) |br| {
4347 if (!p.in_loop and p.@"switch" == null) try p.errTok(.break_not_in_loop_or_switch, br);
4348 _ = try p.expectToken(.semicolon);
4349 return try p.addNode(.{ .tag = .break_stmt, .data = undefined });
4350 }
4351 if (try p.returnStmt()) |some| return some;
4352 if (try p.assembly(.stmt)) |some| return some;
4353
4354 const expr_start = p.tok_i;
4355 const err_start = p.comp.diagnostics.list.items.len;
4356
4357 const e = try p.expr();
4358 if (e.node != .none) {
4359 _ = try p.expectToken(.semicolon);
4360 try e.maybeWarnUnused(p, expr_start, err_start);
4361 return e.node;
4362 }
4363
4364 const attr_buf_top = p.attr_buf.len;
4365 defer p.attr_buf.len = attr_buf_top;
4366 try p.attributeSpecifier();
4367
4368 if (p.eatToken(.semicolon)) |_| {
4369 var null_node: Tree.Node = .{ .tag = .null_stmt, .data = undefined };
4370 null_node.ty = try Attribute.applyStatementAttributes(p, null_node.ty, expr_start, attr_buf_top);
4371 return p.addNode(null_node);
4372 }
4373
4374 try p.err(.expected_stmt);
4375 return error.ParsingFailed;
4376}
4377
4378/// labeledStmt
4379/// : IDENTIFIER ':' stmt
4380/// | keyword_case integerConstExpr ':' stmt
4381/// | keyword_default ':' stmt
4382fn labeledStmt(p: *Parser) Error!?NodeIndex {
4383 if ((p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) and p.tok_ids[p.tok_i + 1] == .colon) {
4384 const name_tok = try p.expectIdentifier();
4385 const str = p.tokSlice(name_tok);
4386 if (p.findLabel(str)) |some| {
4387 try p.errStr(.duplicate_label, name_tok, str);
4388 try p.errStr(.previous_label, some, str);
4389 } else {
4390 p.label_count += 1;
4391 try p.labels.append(.{ .label = name_tok });
4392 var i: usize = 0;
4393 while (i < p.labels.items.len) {
4394 if (p.labels.items[i] == .unresolved_goto and
4395 mem.eql(u8, p.tokSlice(p.labels.items[i].unresolved_goto), str))
4396 {
4397 _ = p.labels.swapRemove(i);
4398 } else i += 1;
4399 }
4400 }
4401
4402 p.tok_i += 1;
4403 const attr_buf_top = p.attr_buf.len;
4404 defer p.attr_buf.len = attr_buf_top;
4405 try p.attributeSpecifier();
4406
4407 var labeled_stmt = Tree.Node{
4408 .tag = .labeled_stmt,
4409 .data = .{ .decl = .{ .name = name_tok, .node = try p.labelableStmt() } },
4410 };
4411 labeled_stmt.ty = try Attribute.applyLabelAttributes(p, labeled_stmt.ty, attr_buf_top);
4412 return try p.addNode(labeled_stmt);
4413 } else if (p.eatToken(.keyword_case)) |case| {
4414 const first_item = try p.integerConstExpr(.gnu_folding_extension);
4415 const ellipsis = p.tok_i;
4416 const second_item = if (p.eatToken(.ellipsis) != null) blk: {
4417 try p.errTok(.gnu_switch_range, ellipsis);
4418 break :blk try p.integerConstExpr(.gnu_folding_extension);
4419 } else null;
4420 _ = try p.expectToken(.colon);
4421
4422 if (p.@"switch") |some| check: {
4423 if (some.ty.hasIncompleteSize()) break :check; // error already reported for incomplete size
4424
4425 const first = first_item.val;
4426 const last = if (second_item) |second| second.val else first;
4427 if (first.opt_ref == .none) {
4428 try p.errTok(.case_val_unavailable, case + 1);
4429 break :check;
4430 } else if (last.opt_ref == .none) {
4431 try p.errTok(.case_val_unavailable, ellipsis + 1);
4432 break :check;
4433 } else if (last.compare(.lt, first, p.comp)) {
4434 try p.errTok(.empty_case_range, case + 1);
4435 break :check;
4436 }
4437
4438 // TODO cast to target type
4439 const prev = (try some.add(first, last, case + 1)) orelse break :check;
4440
4441 // TODO check which value was already handled
4442 try p.errStr(.duplicate_switch_case, case + 1, try first_item.str(p));
4443 try p.errTok(.previous_case, prev.tok);
4444 } else {
4445 try p.errStr(.case_not_in_switch, case, "case");
4446 }
4447
4448 const s = try p.labelableStmt();
4449 if (second_item) |some| return try p.addNode(.{
4450 .tag = .case_range_stmt,
4451 .data = .{ .if3 = .{ .cond = s, .body = (try p.addList(&.{ first_item.node, some.node })).start } },
4452 }) else return try p.addNode(.{
4453 .tag = .case_stmt,
4454 .data = .{ .bin = .{ .lhs = first_item.node, .rhs = s } },
4455 });
4456 } else if (p.eatToken(.keyword_default)) |default| {
4457 _ = try p.expectToken(.colon);
4458 const s = try p.labelableStmt();
4459 const node = try p.addNode(.{
4460 .tag = .default_stmt,
4461 .data = .{ .un = s },
4462 });
4463 const @"switch" = p.@"switch" orelse {
4464 try p.errStr(.case_not_in_switch, default, "default");
4465 return node;
4466 };
4467 if (@"switch".default) |previous| {
4468 try p.errTok(.multiple_default, default);
4469 try p.errTok(.previous_case, previous);
4470 } else {
4471 @"switch".default = default;
4472 }
4473 return node;
4474 } else return null;
4475}
4476
4477fn labelableStmt(p: *Parser) Error!NodeIndex {
4478 if (p.tok_ids[p.tok_i] == .r_brace) {
4479 try p.err(.label_compound_end);
4480 return p.addNode(.{ .tag = .null_stmt, .data = undefined });
4481 }
4482 return p.stmt();
4483}
4484
4485const StmtExprState = struct {
4486 last_expr_tok: TokenIndex = 0,
4487 last_expr_res: Result = .{ .ty = .{ .specifier = .void } },
4488};
4489
4490/// compoundStmt : '{' ( decl | keyword_extension decl | staticAssert | stmt)* '}'
4491fn compoundStmt(p: *Parser, is_fn_body: bool, stmt_expr_state: ?*StmtExprState) Error!?NodeIndex {
4492 const l_brace = p.eatToken(.l_brace) orelse return null;
4493
4494 const decl_buf_top = p.decl_buf.items.len;
4495 defer p.decl_buf.items.len = decl_buf_top;
4496
4497 // the parameters of a function are in the same scope as the body
4498 if (!is_fn_body) try p.syms.pushScope(p);
4499 defer if (!is_fn_body) p.syms.popScope();
4500
4501 var noreturn_index: ?TokenIndex = null;
4502 var noreturn_label_count: u32 = 0;
4503
4504 while (p.eatToken(.r_brace) == null) : (_ = try p.pragma()) {
4505 if (stmt_expr_state) |state| state.* = .{};
4506 if (try p.parseOrNextStmt(staticAssert, l_brace)) continue;
4507 if (try p.parseOrNextStmt(decl, l_brace)) continue;
4508 if (p.eatToken(.keyword_extension)) |ext| {
4509 const saved_extension = p.extension_suppressed;
4510 defer p.extension_suppressed = saved_extension;
4511 p.extension_suppressed = true;
4512
4513 if (try p.parseOrNextStmt(decl, l_brace)) continue;
4514 p.tok_i = ext;
4515 }
4516 const stmt_tok = p.tok_i;
4517 const s = p.stmt() catch |er| switch (er) {
4518 error.ParsingFailed => {
4519 try p.nextStmt(l_brace);
4520 continue;
4521 },
4522 else => |e| return e,
4523 };
4524 if (s == .none) continue;
4525 if (stmt_expr_state) |state| {
4526 state.* = .{
4527 .last_expr_tok = stmt_tok,
4528 .last_expr_res = .{
4529 .node = s,
4530 .ty = p.nodes.items(.ty)[@intFromEnum(s)],
4531 },
4532 };
4533 }
4534 try p.decl_buf.append(s);
4535
4536 if (noreturn_index == null and p.nodeIsNoreturn(s) == .yes) {
4537 noreturn_index = p.tok_i;
4538 noreturn_label_count = p.label_count;
4539 }
4540 switch (p.nodes.items(.tag)[@intFromEnum(s)]) {
4541 .case_stmt, .default_stmt, .labeled_stmt => noreturn_index = null,
4542 else => {},
4543 }
4544 }
4545
4546 if (noreturn_index) |some| {
4547 // if new labels were defined we cannot be certain that the code is unreachable
4548 if (some != p.tok_i - 1 and noreturn_label_count == p.label_count) try p.errTok(.unreachable_code, some);
4549 }
4550 if (is_fn_body) {
4551 const last_noreturn = if (p.decl_buf.items.len == decl_buf_top)
4552 .no
4553 else
4554 p.nodeIsNoreturn(p.decl_buf.items[p.decl_buf.items.len - 1]);
4555
4556 if (last_noreturn != .yes) {
4557 const ret_ty = p.func.ty.?.returnType();
4558 var return_zero = false;
4559 if (last_noreturn == .no and !ret_ty.is(.void) and !ret_ty.isFunc() and !ret_ty.isArray()) {
4560 const func_name = p.tokSlice(p.func.name);
4561 const interned_name = try StrInt.intern(p.comp, func_name);
4562 if (interned_name == p.string_ids.main_id and ret_ty.is(.int)) {
4563 return_zero = true;
4564 } else {
4565 try p.errStr(.func_does_not_return, p.tok_i - 1, func_name);
4566 }
4567 }
4568 try p.decl_buf.append(try p.addNode(.{ .tag = .implicit_return, .ty = p.func.ty.?.returnType(), .data = .{ .return_zero = return_zero } }));
4569 }
4570 if (p.func.ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
4571 if (p.func.pretty_ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
4572 }
4573
4574 var node: Tree.Node = .{
4575 .tag = .compound_stmt_two,
4576 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
4577 };
4578 const statements = p.decl_buf.items[decl_buf_top..];
4579 switch (statements.len) {
4580 0 => {},
4581 1 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = .none } },
4582 2 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = statements[1] } },
4583 else => {
4584 node.tag = .compound_stmt;
4585 node.data = .{ .range = try p.addList(statements) };
4586 },
4587 }
4588 return try p.addNode(node);
4589}
4590
4591const NoreturnKind = enum { no, yes, complex };
4592
4593fn nodeIsNoreturn(p: *Parser, node: NodeIndex) NoreturnKind {
4594 switch (p.nodes.items(.tag)[@intFromEnum(node)]) {
4595 .break_stmt, .continue_stmt, .return_stmt => return .yes,
4596 .if_then_else_stmt => {
4597 const data = p.data.items[p.nodes.items(.data)[@intFromEnum(node)].if3.body..];
4598 const then_type = p.nodeIsNoreturn(data[0]);
4599 const else_type = p.nodeIsNoreturn(data[1]);
4600 if (then_type == .complex or else_type == .complex) return .complex;
4601 if (then_type == .yes and else_type == .yes) return .yes;
4602 return .no;
4603 },
4604 .compound_stmt_two => {
4605 const data = p.nodes.items(.data)[@intFromEnum(node)];
4606 if (data.bin.rhs != .none) return p.nodeIsNoreturn(data.bin.rhs);
4607 if (data.bin.lhs != .none) return p.nodeIsNoreturn(data.bin.lhs);
4608 return .no;
4609 },
4610 .compound_stmt => {
4611 const data = p.nodes.items(.data)[@intFromEnum(node)];
4612 return p.nodeIsNoreturn(p.data.items[data.range.end - 1]);
4613 },
4614 .labeled_stmt => {
4615 const data = p.nodes.items(.data)[@intFromEnum(node)];
4616 return p.nodeIsNoreturn(data.decl.node);
4617 },
4618 .switch_stmt => {
4619 const data = p.nodes.items(.data)[@intFromEnum(node)];
4620 if (data.bin.rhs == .none) return .complex;
4621 if (p.nodeIsNoreturn(data.bin.rhs) == .yes) return .yes;
4622 return .complex;
4623 },
4624 else => return .no,
4625 }
4626}
4627
4628fn parseOrNextStmt(p: *Parser, comptime func: fn (*Parser) Error!bool, l_brace: TokenIndex) !bool {
4629 return func(p) catch |er| switch (er) {
4630 error.ParsingFailed => {
4631 try p.nextStmt(l_brace);
4632 return true;
4633 },
4634 else => |e| return e,
4635 };
4636}
4637
4638fn nextStmt(p: *Parser, l_brace: TokenIndex) !void {
4639 var parens: u32 = 0;
4640 while (p.tok_i < p.tok_ids.len) : (p.tok_i += 1) {
4641 switch (p.tok_ids[p.tok_i]) {
4642 .l_paren, .l_brace, .l_bracket => parens += 1,
4643 .r_paren, .r_bracket => if (parens != 0) {
4644 parens -= 1;
4645 },
4646 .r_brace => if (parens == 0)
4647 return
4648 else {
4649 parens -= 1;
4650 },
4651 .semicolon => if (parens == 0) {
4652 p.tok_i += 1;
4653 return;
4654 },
4655 .keyword_for,
4656 .keyword_while,
4657 .keyword_do,
4658 .keyword_if,
4659 .keyword_goto,
4660 .keyword_switch,
4661 .keyword_case,
4662 .keyword_default,
4663 .keyword_continue,
4664 .keyword_break,
4665 .keyword_return,
4666 .keyword_typedef,
4667 .keyword_extern,
4668 .keyword_static,
4669 .keyword_auto,
4670 .keyword_register,
4671 .keyword_thread_local,
4672 .keyword_c23_thread_local,
4673 .keyword_inline,
4674 .keyword_inline1,
4675 .keyword_inline2,
4676 .keyword_noreturn,
4677 .keyword_void,
4678 .keyword_bool,
4679 .keyword_c23_bool,
4680 .keyword_char,
4681 .keyword_short,
4682 .keyword_int,
4683 .keyword_long,
4684 .keyword_signed,
4685 .keyword_unsigned,
4686 .keyword_float,
4687 .keyword_double,
4688 .keyword_complex,
4689 .keyword_atomic,
4690 .keyword_enum,
4691 .keyword_struct,
4692 .keyword_union,
4693 .keyword_alignas,
4694 .keyword_c23_alignas,
4695 .keyword_typeof,
4696 .keyword_typeof1,
4697 .keyword_typeof2,
4698 .keyword_typeof_unqual,
4699 .keyword_extension,
4700 => if (parens == 0) return,
4701 .keyword_pragma => p.skipToPragmaSentinel(),
4702 else => {},
4703 }
4704 }
4705 p.tok_i -= 1; // So we can consume EOF
4706 try p.expectClosing(l_brace, .r_brace);
4707 unreachable;
4708}
4709
4710fn returnStmt(p: *Parser) Error!?NodeIndex {
4711 const ret_tok = p.eatToken(.keyword_return) orelse return null;
4712
4713 const e_tok = p.tok_i;
4714 var e = try p.expr();
4715 _ = try p.expectToken(.semicolon);
4716 const ret_ty = p.func.ty.?.returnType();
4717
4718 if (p.func.ty.?.hasAttribute(.noreturn)) {
4719 try p.errStr(.invalid_noreturn, e_tok, p.tokSlice(p.func.name));
4720 }
4721
4722 if (e.node == .none) {
4723 if (!ret_ty.is(.void)) try p.errStr(.func_should_return, ret_tok, p.tokSlice(p.func.name));
4724 return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
4725 } else if (ret_ty.is(.void)) {
4726 try p.errStr(.void_func_returns_value, e_tok, p.tokSlice(p.func.name));
4727 return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
4728 }
4729
4730 try e.lvalConversion(p);
4731 try e.coerce(p, ret_ty, e_tok, .ret);
4732
4733 try e.saveValue(p);
4734 return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
4735}
4736
4737// ====== expressions ======
4738
4739pub fn macroExpr(p: *Parser) Compilation.Error!bool {
4740 const res = p.condExpr() catch |e| switch (e) {
4741 error.OutOfMemory => return error.OutOfMemory,
4742 error.FatalError => return error.FatalError,
4743 error.ParsingFailed => return false,
4744 };
4745 if (res.val.opt_ref == .none) {
4746 try p.errTok(.expected_expr, p.tok_i);
4747 return false;
4748 }
4749 return res.val.toBool(p.comp);
4750}
4751
4752const CallExpr = union(enum) {
4753 standard: NodeIndex,
4754 builtin: struct {
4755 node: NodeIndex,
4756 tag: Builtin.Tag,
4757 },
4758
4759 fn init(p: *Parser, call_node: NodeIndex, func_node: NodeIndex) CallExpr {
4760 if (p.getNode(call_node, .builtin_call_expr_one)) |node| {
4761 const data = p.nodes.items(.data)[@intFromEnum(node)];
4762 const name = p.tokSlice(data.decl.name);
4763 const builtin_ty = p.comp.builtins.lookup(name);
4764 return .{ .builtin = .{ .node = node, .tag = builtin_ty.builtin.tag } };
4765 }
4766 return .{ .standard = func_node };
4767 }
4768
4769 fn shouldPerformLvalConversion(self: CallExpr, arg_idx: u32) bool {
4770 return switch (self) {
4771 .standard => true,
4772 .builtin => |builtin| switch (builtin.tag) {
4773 Builtin.tagFromName("__builtin_va_start").?,
4774 Builtin.tagFromName("__va_start").?,
4775 Builtin.tagFromName("va_start").?,
4776 => arg_idx != 1,
4777 else => true,
4778 },
4779 };
4780 }
4781
4782 fn shouldPromoteVarArg(self: CallExpr, arg_idx: u32) bool {
4783 return switch (self) {
4784 .standard => true,
4785 .builtin => |builtin| switch (builtin.tag) {
4786 Builtin.tagFromName("__builtin_va_start").?,
4787 Builtin.tagFromName("__va_start").?,
4788 Builtin.tagFromName("va_start").?,
4789 => arg_idx != 1,
4790 Builtin.tagFromName("__builtin_complex").? => false,
4791 else => true,
4792 },
4793 };
4794 }
4795
4796 fn shouldCoerceArg(self: CallExpr, arg_idx: u32) bool {
4797 _ = self;
4798 _ = arg_idx;
4799 return true;
4800 }
4801
4802 fn checkVarArg(self: CallExpr, p: *Parser, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32) !void {
4803 if (self == .standard) return;
4804
4805 const builtin_tok = p.nodes.items(.data)[@intFromEnum(self.builtin.node)].decl.name;
4806 switch (self.builtin.tag) {
4807 Builtin.tagFromName("__builtin_va_start").?,
4808 Builtin.tagFromName("__va_start").?,
4809 Builtin.tagFromName("va_start").?,
4810 => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx),
4811 Builtin.tagFromName("__builtin_complex").? => return p.checkComplexArg(builtin_tok, first_after, param_tok, arg, arg_idx),
4812 else => {},
4813 }
4814 }
4815
4816 /// Some functions cannot be expressed as standard C prototypes. For example `__builtin_complex` requires
4817 /// two arguments of the same real floating point type (e.g. two doubles or two floats). These functions are
4818 /// encoded as varargs functions with custom typechecking. Since varargs functions do not have a fixed number
4819 /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for
4820 /// these custom-typechecked functions.
4821 fn paramCountOverride(self: CallExpr) ?u32 {
4822 @setEvalBranchQuota(10_000);
4823 return switch (self) {
4824 .standard => null,
4825 .builtin => |builtin| switch (builtin.tag) {
4826 Builtin.tagFromName("__builtin_complex").? => 2,
4827
4828 Builtin.tagFromName("__atomic_fetch_add").?,
4829 Builtin.tagFromName("__atomic_fetch_sub").?,
4830 Builtin.tagFromName("__atomic_fetch_and").?,
4831 Builtin.tagFromName("__atomic_fetch_xor").?,
4832 Builtin.tagFromName("__atomic_fetch_or").?,
4833 Builtin.tagFromName("__atomic_fetch_nand").?,
4834 => 3,
4835
4836 Builtin.tagFromName("__atomic_compare_exchange").?,
4837 Builtin.tagFromName("__atomic_compare_exchange_n").?,
4838 => 6,
4839 else => null,
4840 },
4841 };
4842 }
4843
4844 fn returnType(self: CallExpr, p: *Parser, callable_ty: Type) Type {
4845 return switch (self) {
4846 .standard => callable_ty.returnType(),
4847 .builtin => |builtin| switch (builtin.tag) {
4848 Builtin.tagFromName("__atomic_fetch_add").?,
4849 Builtin.tagFromName("__atomic_fetch_sub").?,
4850 Builtin.tagFromName("__atomic_fetch_and").?,
4851 Builtin.tagFromName("__atomic_fetch_xor").?,
4852 Builtin.tagFromName("__atomic_fetch_or").?,
4853 Builtin.tagFromName("__atomic_fetch_nand").?,
4854 => {
4855 if (p.list_buf.items.len < 2) return Type.invalid; // not enough arguments; already an error
4856 const second_param = p.list_buf.items[p.list_buf.items.len - 2];
4857 return p.nodes.items(.ty)[@intFromEnum(second_param)];
4858 },
4859 Builtin.tagFromName("__builtin_complex").? => {
4860 if (p.list_buf.items.len < 1) return Type.invalid; // not enough arguments; already an error
4861 const last_param = p.list_buf.items[p.list_buf.items.len - 1];
4862 return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex();
4863 },
4864 Builtin.tagFromName("__atomic_compare_exchange").?,
4865 Builtin.tagFromName("__atomic_compare_exchange_n").?,
4866 => .{ .specifier = .bool },
4867 else => callable_ty.returnType(),
4868 },
4869 };
4870 }
4871
4872 fn finish(self: CallExpr, p: *Parser, ty: Type, list_buf_top: usize, arg_count: u32) Error!Result {
4873 const ret_ty = self.returnType(p, ty);
4874 switch (self) {
4875 .standard => |func_node| {
4876 var call_node: Tree.Node = .{
4877 .tag = .call_expr_one,
4878 .ty = ret_ty,
4879 .data = .{ .bin = .{ .lhs = func_node, .rhs = .none } },
4880 };
4881 const args = p.list_buf.items[list_buf_top..];
4882 switch (arg_count) {
4883 0 => {},
4884 1 => call_node.data.bin.rhs = args[1], // args[0] == func.node
4885 else => {
4886 call_node.tag = .call_expr;
4887 call_node.data = .{ .range = try p.addList(args) };
4888 },
4889 }
4890 return Result{ .node = try p.addNode(call_node), .ty = ret_ty };
4891 },
4892 .builtin => |builtin| {
4893 const index = @intFromEnum(builtin.node);
4894 var call_node = p.nodes.get(index);
4895 defer p.nodes.set(index, call_node);
4896 call_node.ty = ret_ty;
4897 const args = p.list_buf.items[list_buf_top..];
4898 switch (arg_count) {
4899 0 => {},
4900 1 => call_node.data.decl.node = args[1], // args[0] == func.node
4901 else => {
4902 call_node.tag = .builtin_call_expr;
4903 args[0] = @enumFromInt(call_node.data.decl.name);
4904 call_node.data = .{ .range = try p.addList(args) };
4905 },
4906 }
4907 return Result{ .node = builtin.node, .ty = ret_ty };
4908 },
4909 }
4910 }
4911};
4912
4913pub const Result = struct {
4914 node: NodeIndex = .none,
4915 ty: Type = .{ .specifier = .int },
4916 val: Value = .{},
4917
4918 pub fn str(res: Result, p: *Parser) ![]const u8 {
4919 switch (res.val.opt_ref) {
4920 .none => return "(none)",
4921 .null => return "nullptr_t",
4922 else => {},
4923 }
4924 const strings_top = p.strings.items.len;
4925 defer p.strings.items.len = strings_top;
4926
4927 try res.val.print(res.ty, p.comp, p.strings.writer());
4928 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
4929 }
4930
4931 fn expect(res: Result, p: *Parser) Error!void {
4932 if (p.in_macro) {
4933 if (res.val.opt_ref == .none) {
4934 try p.errTok(.expected_expr, p.tok_i);
4935 return error.ParsingFailed;
4936 }
4937 return;
4938 }
4939 if (res.node == .none) {
4940 try p.errTok(.expected_expr, p.tok_i);
4941 return error.ParsingFailed;
4942 }
4943 }
4944
4945 fn empty(res: Result, p: *Parser) bool {
4946 if (p.in_macro) return res.val.opt_ref == .none;
4947 return res.node == .none;
4948 }
4949
4950 fn maybeWarnUnused(res: Result, p: *Parser, expr_start: TokenIndex, err_start: usize) Error!void {
4951 if (res.ty.is(.void) or res.node == .none) return;
4952 // don't warn about unused result if the expression contained errors besides other unused results
4953 for (p.comp.diagnostics.list.items[err_start..]) |err_item| {
4954 if (err_item.tag != .unused_value) return;
4955 }
4956 var cur_node = res.node;
4957 while (true) switch (p.nodes.items(.tag)[@intFromEnum(cur_node)]) {
4958 .invalid, // So that we don't need to check for node == 0
4959 .assign_expr,
4960 .mul_assign_expr,
4961 .div_assign_expr,
4962 .mod_assign_expr,
4963 .add_assign_expr,
4964 .sub_assign_expr,
4965 .shl_assign_expr,
4966 .shr_assign_expr,
4967 .bit_and_assign_expr,
4968 .bit_xor_assign_expr,
4969 .bit_or_assign_expr,
4970 .pre_inc_expr,
4971 .pre_dec_expr,
4972 .post_inc_expr,
4973 .post_dec_expr,
4974 => return,
4975 .call_expr_one => {
4976 const fn_ptr = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.lhs;
4977 const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
4978 if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
4979 if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
4980 return;
4981 },
4982 .call_expr => {
4983 const fn_ptr = p.data.items[p.nodes.items(.data)[@intFromEnum(cur_node)].range.start];
4984 const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
4985 if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
4986 if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
4987 return;
4988 },
4989 .stmt_expr => {
4990 const body = p.nodes.items(.data)[@intFromEnum(cur_node)].un;
4991 switch (p.nodes.items(.tag)[@intFromEnum(body)]) {
4992 .compound_stmt_two => {
4993 const body_stmt = p.nodes.items(.data)[@intFromEnum(body)].bin;
4994 cur_node = if (body_stmt.rhs != .none) body_stmt.rhs else body_stmt.lhs;
4995 },
4996 .compound_stmt => {
4997 const data = p.nodes.items(.data)[@intFromEnum(body)];
4998 cur_node = p.data.items[data.range.end - 1];
4999 },
5000 else => unreachable,
5001 }
5002 },
5003 .comma_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.rhs,
5004 .paren_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].un,
5005 else => break,
5006 };
5007 try p.errTok(.unused_value, expr_start);
5008 }
5009
5010 fn boolRes(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
5011 if (lhs.val.opt_ref == .null) {
5012 lhs.val = Value.zero;
5013 }
5014 if (lhs.ty.specifier != .invalid) {
5015 lhs.ty = Type.int;
5016 }
5017 return lhs.bin(p, tag, rhs);
5018 }
5019
5020 fn bin(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
5021 lhs.node = try p.addNode(.{
5022 .tag = tag,
5023 .ty = lhs.ty,
5024 .data = .{ .bin = .{ .lhs = lhs.node, .rhs = rhs.node } },
5025 });
5026 }
5027
5028 fn un(operand: *Result, p: *Parser, tag: Tree.Tag) Error!void {
5029 operand.node = try p.addNode(.{
5030 .tag = tag,
5031 .ty = operand.ty,
5032 .data = .{ .un = operand.node },
5033 });
5034 }
5035
5036 fn implicitCast(operand: *Result, p: *Parser, kind: Tree.CastKind) Error!void {
5037 operand.node = try p.addNode(.{
5038 .tag = .implicit_cast,
5039 .ty = operand.ty,
5040 .data = .{ .cast = .{ .operand = operand.node, .kind = kind } },
5041 });
5042 }
5043
5044 fn adjustCondExprPtrs(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) !bool {
5045 assert(a.ty.isPtr() and b.ty.isPtr());
5046
5047 const a_elem = a.ty.elemType();
5048 const b_elem = b.ty.elemType();
5049 if (a_elem.eql(b_elem, p.comp, true)) return true;
5050
5051 var adjusted_elem_ty = try p.arena.create(Type);
5052 adjusted_elem_ty.* = a_elem;
5053
5054 const has_void_star_branch = a.ty.isVoidStar() or b.ty.isVoidStar();
5055 const only_quals_differ = a_elem.eql(b_elem, p.comp, false);
5056 const pointers_compatible = only_quals_differ or has_void_star_branch;
5057
5058 if (!pointers_compatible or has_void_star_branch) {
5059 if (!pointers_compatible) {
5060 try p.errStr(.pointer_mismatch, tok, try p.typePairStrExtra(a.ty, " and ", b.ty));
5061 }
5062 adjusted_elem_ty.* = .{ .specifier = .void };
5063 }
5064 if (pointers_compatible) {
5065 adjusted_elem_ty.qual = a_elem.qual.mergeCV(b_elem.qual);
5066 }
5067 if (!adjusted_elem_ty.eql(a_elem, p.comp, true)) {
5068 a.ty = .{
5069 .data = .{ .sub_type = adjusted_elem_ty },
5070 .specifier = .pointer,
5071 };
5072 try a.implicitCast(p, .bitcast);
5073 }
5074 if (!adjusted_elem_ty.eql(b_elem, p.comp, true)) {
5075 b.ty = .{
5076 .data = .{ .sub_type = adjusted_elem_ty },
5077 .specifier = .pointer,
5078 };
5079 try b.implicitCast(p, .bitcast);
5080 }
5081 return true;
5082 }
5083
5084 /// Adjust types for binary operation, returns true if the result can and should be evaluated.
5085 fn adjustTypes(a: *Result, tok: TokenIndex, b: *Result, p: *Parser, kind: enum {
5086 integer,
5087 arithmetic,
5088 boolean_logic,
5089 relational,
5090 equality,
5091 conditional,
5092 add,
5093 sub,
5094 }) !bool {
5095 if (b.ty.specifier == .invalid) {
5096 try a.saveValue(p);
5097 a.ty = Type.invalid;
5098 }
5099 if (a.ty.specifier == .invalid) {
5100 return false;
5101 }
5102 try a.lvalConversion(p);
5103 try b.lvalConversion(p);
5104
5105 const a_vec = a.ty.is(.vector);
5106 const b_vec = b.ty.is(.vector);
5107 if (a_vec and b_vec) {
5108 if (a.ty.eql(b.ty, p.comp, false)) {
5109 return a.shouldEval(b, p);
5110 }
5111 return a.invalidBinTy(tok, b, p);
5112 } else if (a_vec) {
5113 if (b.coerceExtra(p, a.ty.elemType(), tok, .test_coerce)) {
5114 try b.saveValue(p);
5115 try b.implicitCast(p, .vector_splat);
5116 return a.shouldEval(b, p);
5117 } else |er| switch (er) {
5118 error.CoercionFailed => return a.invalidBinTy(tok, b, p),
5119 else => |e| return e,
5120 }
5121 } else if (b_vec) {
5122 if (a.coerceExtra(p, b.ty.elemType(), tok, .test_coerce)) {
5123 try a.saveValue(p);
5124 try a.implicitCast(p, .vector_splat);
5125 return a.shouldEval(b, p);
5126 } else |er| switch (er) {
5127 error.CoercionFailed => return a.invalidBinTy(tok, b, p),
5128 else => |e| return e,
5129 }
5130 }
5131
5132 const a_int = a.ty.isInt();
5133 const b_int = b.ty.isInt();
5134 if (a_int and b_int) {
5135 try a.usualArithmeticConversion(b, p, tok);
5136 return a.shouldEval(b, p);
5137 }
5138 if (kind == .integer) return a.invalidBinTy(tok, b, p);
5139
5140 const a_float = a.ty.isFloat();
5141 const b_float = b.ty.isFloat();
5142 const a_arithmetic = a_int or a_float;
5143 const b_arithmetic = b_int or b_float;
5144 if (a_arithmetic and b_arithmetic) {
5145 // <, <=, >, >= only work on real types
5146 if (kind == .relational and (!a.ty.isReal() or !b.ty.isReal()))
5147 return a.invalidBinTy(tok, b, p);
5148
5149 try a.usualArithmeticConversion(b, p, tok);
5150 return a.shouldEval(b, p);
5151 }
5152 if (kind == .arithmetic) return a.invalidBinTy(tok, b, p);
5153
5154 const a_nullptr = a.ty.is(.nullptr_t);
5155 const b_nullptr = b.ty.is(.nullptr_t);
5156 const a_ptr = a.ty.isPtr();
5157 const b_ptr = b.ty.isPtr();
5158 const a_scalar = a_arithmetic or a_ptr;
5159 const b_scalar = b_arithmetic or b_ptr;
5160 switch (kind) {
5161 .boolean_logic => {
5162 if (!(a_scalar or a_nullptr) or !(b_scalar or b_nullptr)) return a.invalidBinTy(tok, b, p);
5163
5164 // Do integer promotions but nothing else
5165 if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
5166 if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
5167 return a.shouldEval(b, p);
5168 },
5169 .relational, .equality => {
5170 if (kind == .equality and (a_nullptr or b_nullptr)) {
5171 if (a_nullptr and b_nullptr) return a.shouldEval(b, p);
5172 const nullptr_res = if (a_nullptr) a else b;
5173 const other_res = if (a_nullptr) b else a;
5174 if (other_res.ty.isPtr()) {
5175 try nullptr_res.nullCast(p, other_res.ty);
5176 return other_res.shouldEval(nullptr_res, p);
5177 } else if (other_res.val.isZero(p.comp)) {
5178 other_res.val = Value.null;
5179 try other_res.nullCast(p, nullptr_res.ty);
5180 return other_res.shouldEval(nullptr_res, p);
5181 }
5182 return a.invalidBinTy(tok, b, p);
5183 }
5184 // comparisons between floats and pointes not allowed
5185 if (!a_scalar or !b_scalar or (a_float and b_ptr) or (b_float and a_ptr))
5186 return a.invalidBinTy(tok, b, p);
5187
5188 if ((a_int or b_int) and !(a.val.isZero(p.comp) or b.val.isZero(p.comp))) {
5189 try p.errStr(.comparison_ptr_int, tok, try p.typePairStr(a.ty, b.ty));
5190 } else if (a_ptr and b_ptr) {
5191 if (!a.ty.isVoidStar() and !b.ty.isVoidStar() and !a.ty.eql(b.ty, p.comp, false))
5192 try p.errStr(.comparison_distinct_ptr, tok, try p.typePairStr(a.ty, b.ty));
5193 } else if (a_ptr) {
5194 try b.ptrCast(p, a.ty);
5195 } else {
5196 assert(b_ptr);
5197 try a.ptrCast(p, b.ty);
5198 }
5199
5200 return a.shouldEval(b, p);
5201 },
5202 .conditional => {
5203 // doesn't matter what we return here, as the result is ignored
5204 if (a.ty.is(.void) or b.ty.is(.void)) {
5205 try a.toVoid(p);
5206 try b.toVoid(p);
5207 return true;
5208 }
5209 if (a_nullptr and b_nullptr) return true;
5210 if ((a_ptr and b_int) or (a_int and b_ptr)) {
5211 if (a.val.isZero(p.comp) or b.val.isZero(p.comp)) {
5212 try a.nullCast(p, b.ty);
5213 try b.nullCast(p, a.ty);
5214 return true;
5215 }
5216 const int_ty = if (a_int) a else b;
5217 const ptr_ty = if (a_ptr) a else b;
5218 try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(int_ty.ty, " to ", ptr_ty.ty));
5219 try int_ty.ptrCast(p, ptr_ty.ty);
5220
5221 return true;
5222 }
5223 if (a_ptr and b_ptr) return a.adjustCondExprPtrs(tok, b, p);
5224 if ((a_ptr and b_nullptr) or (a_nullptr and b_ptr)) {
5225 const nullptr_res = if (a_nullptr) a else b;
5226 const ptr_res = if (a_nullptr) b else a;
5227 try nullptr_res.nullCast(p, ptr_res.ty);
5228 return true;
5229 }
5230 if (a.ty.isRecord() and b.ty.isRecord() and a.ty.eql(b.ty, p.comp, false)) {
5231 return true;
5232 }
5233 return a.invalidBinTy(tok, b, p);
5234 },
5235 .add => {
5236 // if both aren't arithmetic one should be pointer and the other an integer
5237 if (a_ptr == b_ptr or a_int == b_int) return a.invalidBinTy(tok, b, p);
5238
5239 // Do integer promotions but nothing else
5240 if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
5241 if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
5242
5243 // The result type is the type of the pointer operand
5244 if (a_int) a.ty = b.ty else b.ty = a.ty;
5245 return a.shouldEval(b, p);
5246 },
5247 .sub => {
5248 // if both aren't arithmetic then either both should be pointers or just a
5249 if (!a_ptr or !(b_ptr or b_int)) return a.invalidBinTy(tok, b, p);
5250
5251 if (a_ptr and b_ptr) {
5252 if (!a.ty.eql(b.ty, p.comp, false)) try p.errStr(.incompatible_pointers, tok, try p.typePairStr(a.ty, b.ty));
5253 a.ty = p.comp.types.ptrdiff;
5254 }
5255
5256 // Do integer promotion on b if needed
5257 if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
5258 return a.shouldEval(b, p);
5259 },
5260 else => return a.invalidBinTy(tok, b, p),
5261 }
5262 }
5263
5264 fn lvalConversion(res: *Result, p: *Parser) Error!void {
5265 if (res.ty.isFunc()) {
5266 const elem_ty = try p.arena.create(Type);
5267 elem_ty.* = res.ty;
5268 res.ty.specifier = .pointer;
5269 res.ty.data = .{ .sub_type = elem_ty };
5270 try res.implicitCast(p, .function_to_pointer);
5271 } else if (res.ty.isArray()) {
5272 res.val = .{};
5273 res.ty.decayArray();
5274 try res.implicitCast(p, .array_to_pointer);
5275 } else if (!p.in_macro and p.tmpTree().isLval(res.node)) {
5276 res.ty.qual = .{};
5277 try res.implicitCast(p, .lval_to_rval);
5278 }
5279 }
5280
5281 fn boolCast(res: *Result, p: *Parser, bool_ty: Type, tok: TokenIndex) Error!void {
5282 if (res.ty.isArray()) {
5283 if (res.val.is(.bytes, p.comp)) {
5284 try p.errStr(.string_literal_to_bool, tok, try p.typePairStrExtra(res.ty, " to ", bool_ty));
5285 } else {
5286 try p.errStr(.array_address_to_bool, tok, p.tokSlice(tok));
5287 }
5288 try res.lvalConversion(p);
5289 res.val = Value.one;
5290 res.ty = bool_ty;
5291 try res.implicitCast(p, .pointer_to_bool);
5292 } else if (res.ty.isPtr()) {
5293 res.val.boolCast(p.comp);
5294 res.ty = bool_ty;
5295 try res.implicitCast(p, .pointer_to_bool);
5296 } else if (res.ty.isInt() and !res.ty.is(.bool)) {
5297 res.val.boolCast(p.comp);
5298 res.ty = bool_ty;
5299 try res.implicitCast(p, .int_to_bool);
5300 } else if (res.ty.isFloat()) {
5301 const old_value = res.val;
5302 const value_change_kind = try res.val.floatToInt(bool_ty, p.comp);
5303 try res.floatToIntWarning(p, bool_ty, old_value, value_change_kind, tok);
5304 if (!res.ty.isReal()) {
5305 res.ty = res.ty.makeReal();
5306 try res.implicitCast(p, .complex_float_to_real);
5307 }
5308 res.ty = bool_ty;
5309 try res.implicitCast(p, .float_to_bool);
5310 }
5311 }
5312
5313 fn intCast(res: *Result, p: *Parser, int_ty: Type, tok: TokenIndex) Error!void {
5314 if (int_ty.hasIncompleteSize()) return error.ParsingFailed; // Diagnostic already issued
5315 if (res.ty.is(.bool)) {
5316 res.ty = int_ty.makeReal();
5317 try res.implicitCast(p, .bool_to_int);
5318 if (!int_ty.isReal()) {
5319 res.ty = int_ty;
5320 try res.implicitCast(p, .real_to_complex_int);
5321 }
5322 } else if (res.ty.isPtr()) {
5323 res.ty = int_ty.makeReal();
5324 try res.implicitCast(p, .pointer_to_int);
5325 if (!int_ty.isReal()) {
5326 res.ty = int_ty;
5327 try res.implicitCast(p, .real_to_complex_int);
5328 }
5329 } else if (res.ty.isFloat()) {
5330 const old_value = res.val;
5331 const value_change_kind = try res.val.floatToInt(int_ty, p.comp);
5332 try res.floatToIntWarning(p, int_ty, old_value, value_change_kind, tok);
5333 const old_real = res.ty.isReal();
5334 const new_real = int_ty.isReal();
5335 if (old_real and new_real) {
5336 res.ty = int_ty;
5337 try res.implicitCast(p, .float_to_int);
5338 } else if (old_real) {
5339 res.ty = int_ty.makeReal();
5340 try res.implicitCast(p, .float_to_int);
5341 res.ty = int_ty;
5342 try res.implicitCast(p, .real_to_complex_int);
5343 } else if (new_real) {
5344 res.ty = res.ty.makeReal();
5345 try res.implicitCast(p, .complex_float_to_real);
5346 res.ty = int_ty;
5347 try res.implicitCast(p, .float_to_int);
5348 } else {
5349 res.ty = int_ty;
5350 try res.implicitCast(p, .complex_float_to_complex_int);
5351 }
5352 } else if (!res.ty.eql(int_ty, p.comp, true)) {
5353 try res.val.intCast(int_ty, p.comp);
5354 const old_real = res.ty.isReal();
5355 const new_real = int_ty.isReal();
5356 if (old_real and new_real) {
5357 res.ty = int_ty;
5358 try res.implicitCast(p, .int_cast);
5359 } else if (old_real) {
5360 const real_int_ty = int_ty.makeReal();
5361 if (!res.ty.eql(real_int_ty, p.comp, false)) {
5362 res.ty = real_int_ty;
5363 try res.implicitCast(p, .int_cast);
5364 }
5365 res.ty = int_ty;
5366 try res.implicitCast(p, .real_to_complex_int);
5367 } else if (new_real) {
5368 res.ty = res.ty.makeReal();
5369 try res.implicitCast(p, .complex_int_to_real);
5370 res.ty = int_ty;
5371 try res.implicitCast(p, .int_cast);
5372 } else {
5373 res.ty = int_ty;
5374 try res.implicitCast(p, .complex_int_cast);
5375 }
5376 }
5377 }
5378
5379 fn floatToIntWarning(res: *Result, p: *Parser, int_ty: Type, old_value: Value, change_kind: Value.FloatToIntChangeKind, tok: TokenIndex) !void {
5380 switch (change_kind) {
5381 .none => return p.errStr(.float_to_int, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
5382 .out_of_range => return p.errStr(.float_out_of_range, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
5383 .overflow => return p.errStr(.float_overflow_conversion, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
5384 .nonzero_to_zero => return p.errStr(.float_zero_conversion, tok, try p.floatValueChangedStr(res, old_value, int_ty)),
5385 .value_changed => return p.errStr(.float_value_changed, tok, try p.floatValueChangedStr(res, old_value, int_ty)),
5386 }
5387 }
5388
5389 fn floatCast(res: *Result, p: *Parser, float_ty: Type) Error!void {
5390 if (res.ty.is(.bool)) {
5391 try res.val.intToFloat(float_ty, p.comp);
5392 res.ty = float_ty.makeReal();
5393 try res.implicitCast(p, .bool_to_float);
5394 if (!float_ty.isReal()) {
5395 res.ty = float_ty;
5396 try res.implicitCast(p, .real_to_complex_float);
5397 }
5398 } else if (res.ty.isInt()) {
5399 try res.val.intToFloat(float_ty, p.comp);
5400 const old_real = res.ty.isReal();
5401 const new_real = float_ty.isReal();
5402 if (old_real and new_real) {
5403 res.ty = float_ty;
5404 try res.implicitCast(p, .int_to_float);
5405 } else if (old_real) {
5406 res.ty = float_ty.makeReal();
5407 try res.implicitCast(p, .int_to_float);
5408 res.ty = float_ty;
5409 try res.implicitCast(p, .real_to_complex_float);
5410 } else if (new_real) {
5411 res.ty = res.ty.makeReal();
5412 try res.implicitCast(p, .complex_int_to_real);
5413 res.ty = float_ty;
5414 try res.implicitCast(p, .int_to_float);
5415 } else {
5416 res.ty = float_ty;
5417 try res.implicitCast(p, .complex_int_to_complex_float);
5418 }
5419 } else if (!res.ty.eql(float_ty, p.comp, true)) {
5420 try res.val.floatCast(float_ty, p.comp);
5421 const old_real = res.ty.isReal();
5422 const new_real = float_ty.isReal();
5423 if (old_real and new_real) {
5424 res.ty = float_ty;
5425 try res.implicitCast(p, .float_cast);
5426 } else if (old_real) {
5427 if (res.ty.floatRank() != float_ty.floatRank()) {
5428 res.ty = float_ty.makeReal();
5429 try res.implicitCast(p, .float_cast);
5430 }
5431 res.ty = float_ty;
5432 try res.implicitCast(p, .real_to_complex_float);
5433 } else if (new_real) {
5434 res.ty = res.ty.makeReal();
5435 try res.implicitCast(p, .complex_float_to_real);
5436 if (res.ty.floatRank() != float_ty.floatRank()) {
5437 res.ty = float_ty;
5438 try res.implicitCast(p, .float_cast);
5439 }
5440 } else {
5441 res.ty = float_ty;
5442 try res.implicitCast(p, .complex_float_cast);
5443 }
5444 }
5445 }
5446
5447 /// Converts a bool or integer to a pointer
5448 fn ptrCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
5449 if (res.ty.is(.bool)) {
5450 res.ty = ptr_ty;
5451 try res.implicitCast(p, .bool_to_pointer);
5452 } else if (res.ty.isInt()) {
5453 try res.val.intCast(ptr_ty, p.comp);
5454 res.ty = ptr_ty;
5455 try res.implicitCast(p, .int_to_pointer);
5456 }
5457 }
5458
5459 /// Convert pointer to one with a different child type
5460 fn ptrChildTypeCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
5461 res.ty = ptr_ty;
5462 return res.implicitCast(p, .bitcast);
5463 }
5464
5465 fn toVoid(res: *Result, p: *Parser) Error!void {
5466 if (!res.ty.is(.void)) {
5467 res.ty = .{ .specifier = .void };
5468 try res.implicitCast(p, .to_void);
5469 }
5470 }
5471
5472 fn nullCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
5473 if (!res.ty.is(.nullptr_t) and !res.val.isZero(p.comp)) return;
5474 res.ty = ptr_ty;
5475 try res.implicitCast(p, .null_to_pointer);
5476 }
5477
5478 fn usualUnaryConversion(res: *Result, p: *Parser, tok: TokenIndex) Error!void {
5479 if (res.ty.isFloat()) fp_eval: {
5480 const eval_method = p.comp.langopts.fp_eval_method orelse break :fp_eval;
5481 switch (eval_method) {
5482 .source => {},
5483 .indeterminate => unreachable,
5484 .double => {
5485 if (res.ty.floatRank() < (Type{ .specifier = .double }).floatRank()) {
5486 const spec: Type.Specifier = if (res.ty.isReal()) .double else .complex_double;
5487 return res.floatCast(p, .{ .specifier = spec });
5488 }
5489 },
5490 .extended => {
5491 if (res.ty.floatRank() < (Type{ .specifier = .long_double }).floatRank()) {
5492 const spec: Type.Specifier = if (res.ty.isReal()) .long_double else .complex_long_double;
5493 return res.floatCast(p, .{ .specifier = spec });
5494 }
5495 },
5496 }
5497 }
5498
5499 if (res.ty.is(.fp16) and !p.comp.langopts.use_native_half_type) {
5500 return res.floatCast(p, .{ .specifier = .float });
5501 }
5502 if (res.ty.isInt()) {
5503 if (p.tmpTree().bitfieldWidth(res.node, true)) |width| {
5504 if (res.ty.bitfieldPromotion(p.comp, width)) |promotion_ty| {
5505 return res.intCast(p, promotion_ty, tok);
5506 }
5507 }
5508 return res.intCast(p, res.ty.integerPromotion(p.comp), tok);
5509 }
5510 }
5511
5512 fn usualArithmeticConversion(a: *Result, b: *Result, p: *Parser, tok: TokenIndex) Error!void {
5513 try a.usualUnaryConversion(p, tok);
5514 try b.usualUnaryConversion(p, tok);
5515
5516 // if either is a float cast to that type
5517 if (a.ty.isFloat() or b.ty.isFloat()) {
5518 const float_types = [7][2]Type.Specifier{
5519 .{ .complex_long_double, .long_double },
5520 .{ .complex_float128, .float128 },
5521 .{ .complex_float80, .float80 },
5522 .{ .complex_double, .double },
5523 .{ .complex_float, .float },
5524 // No `_Complex __fp16` type
5525 .{ .invalid, .fp16 },
5526 // No `_Complex _Float16`
5527 .{ .invalid, .float16 },
5528 };
5529 const a_spec = a.ty.canonicalize(.standard).specifier;
5530 const b_spec = b.ty.canonicalize(.standard).specifier;
5531 if (p.comp.target.c_type_bit_size(.longdouble) == 128) {
5532 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
5533 }
5534 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[1])) return;
5535 if (p.comp.target.c_type_bit_size(.longdouble) == 80) {
5536 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
5537 }
5538 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[2])) return;
5539 if (p.comp.target.c_type_bit_size(.longdouble) == 64) {
5540 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
5541 }
5542 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[3])) return;
5543 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[4])) return;
5544 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[5])) return;
5545 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[6])) return;
5546 }
5547
5548 if (a.ty.eql(b.ty, p.comp, true)) {
5549 // cast to promoted type
5550 try a.intCast(p, a.ty, tok);
5551 try b.intCast(p, b.ty, tok);
5552 return;
5553 }
5554
5555 const target = a.ty.integerConversion(b.ty, p.comp);
5556 if (!target.isReal()) {
5557 try a.saveValue(p);
5558 try b.saveValue(p);
5559 }
5560 try a.intCast(p, target, tok);
5561 try b.intCast(p, target, tok);
5562 }
5563
5564 fn floatConversion(a: *Result, b: *Result, a_spec: Type.Specifier, b_spec: Type.Specifier, p: *Parser, pair: [2]Type.Specifier) !bool {
5565 if (a_spec == pair[0] or a_spec == pair[1] or
5566 b_spec == pair[0] or b_spec == pair[1])
5567 {
5568 const both_real = a.ty.isReal() and b.ty.isReal();
5569 const res_spec = pair[@intFromBool(both_real)];
5570 const ty = Type{ .specifier = res_spec };
5571 try a.floatCast(p, ty);
5572 try b.floatCast(p, ty);
5573 return true;
5574 }
5575 return false;
5576 }
5577
5578 fn invalidBinTy(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) Error!bool {
5579 try p.errStr(.invalid_bin_types, tok, try p.typePairStr(a.ty, b.ty));
5580 a.val = .{};
5581 b.val = .{};
5582 a.ty = Type.invalid;
5583 return false;
5584 }
5585
5586 fn shouldEval(a: *Result, b: *Result, p: *Parser) Error!bool {
5587 if (p.no_eval) return false;
5588 if (a.val.opt_ref != .none and b.val.opt_ref != .none)
5589 return true;
5590
5591 try a.saveValue(p);
5592 try b.saveValue(p);
5593 return p.no_eval;
5594 }
5595
5596 /// Saves value and replaces it with `.unavailable`.
5597 fn saveValue(res: *Result, p: *Parser) !void {
5598 assert(!p.in_macro);
5599 if (res.val.opt_ref == .none or res.val.opt_ref == .null) return;
5600 if (!p.in_macro) try p.value_map.put(res.node, res.val);
5601 res.val = .{};
5602 }
5603
5604 fn castType(res: *Result, p: *Parser, to: Type, operand_tok: TokenIndex, l_paren: TokenIndex) !void {
5605 var cast_kind: Tree.CastKind = undefined;
5606
5607 if (to.is(.void)) {
5608 // everything can cast to void
5609 cast_kind = .to_void;
5610 res.val = .{};
5611 } else if (to.is(.nullptr_t)) {
5612 if (res.ty.is(.nullptr_t)) {
5613 cast_kind = .no_op;
5614 } else {
5615 try p.errStr(.invalid_object_cast, l_paren, try p.typePairStrExtra(res.ty, " to ", to));
5616 return error.ParsingFailed;
5617 }
5618 } else if (res.ty.is(.nullptr_t)) {
5619 if (to.is(.bool)) {
5620 try res.nullCast(p, res.ty);
5621 res.val.boolCast(p.comp);
5622 res.ty = .{ .specifier = .bool };
5623 try res.implicitCast(p, .pointer_to_bool);
5624 try res.saveValue(p);
5625 } else if (to.isPtr()) {
5626 try res.nullCast(p, to);
5627 } else {
5628 try p.errStr(.invalid_object_cast, l_paren, try p.typePairStrExtra(res.ty, " to ", to));
5629 return error.ParsingFailed;
5630 }
5631 cast_kind = .no_op;
5632 } else if (res.val.isZero(p.comp) and to.isPtr()) {
5633 cast_kind = .null_to_pointer;
5634 } else if (to.isScalar()) cast: {
5635 const old_float = res.ty.isFloat();
5636 const new_float = to.isFloat();
5637
5638 if (new_float and res.ty.isPtr()) {
5639 try p.errStr(.invalid_cast_to_float, l_paren, try p.typeStr(to));
5640 return error.ParsingFailed;
5641 } else if (old_float and to.isPtr()) {
5642 try p.errStr(.invalid_cast_to_pointer, l_paren, try p.typeStr(res.ty));
5643 return error.ParsingFailed;
5644 }
5645 const old_real = res.ty.isReal();
5646 const new_real = to.isReal();
5647
5648 if (to.eql(res.ty, p.comp, false)) {
5649 cast_kind = .no_op;
5650 } else if (to.is(.bool)) {
5651 if (res.ty.isPtr()) {
5652 cast_kind = .pointer_to_bool;
5653 } else if (res.ty.isInt()) {
5654 if (!old_real) {
5655 res.ty = res.ty.makeReal();
5656 try res.implicitCast(p, .complex_int_to_real);
5657 }
5658 cast_kind = .int_to_bool;
5659 } else if (old_float) {
5660 if (!old_real) {
5661 res.ty = res.ty.makeReal();
5662 try res.implicitCast(p, .complex_float_to_real);
5663 }
5664 cast_kind = .float_to_bool;
5665 }
5666 } else if (to.isInt()) {
5667 if (res.ty.is(.bool)) {
5668 if (!new_real) {
5669 res.ty = to.makeReal();
5670 try res.implicitCast(p, .bool_to_int);
5671 cast_kind = .real_to_complex_int;
5672 } else {
5673 cast_kind = .bool_to_int;
5674 }
5675 } else if (res.ty.isInt()) {
5676 if (old_real and new_real) {
5677 cast_kind = .int_cast;
5678 } else if (old_real) {
5679 res.ty = to.makeReal();
5680 try res.implicitCast(p, .int_cast);
5681 cast_kind = .real_to_complex_int;
5682 } else if (new_real) {
5683 res.ty = res.ty.makeReal();
5684 try res.implicitCast(p, .complex_int_to_real);
5685 cast_kind = .int_cast;
5686 } else {
5687 cast_kind = .complex_int_cast;
5688 }
5689 } else if (res.ty.isPtr()) {
5690 if (!new_real) {
5691 res.ty = to.makeReal();
5692 try res.implicitCast(p, .pointer_to_int);
5693 cast_kind = .real_to_complex_int;
5694 } else {
5695 cast_kind = .pointer_to_int;
5696 }
5697 } else if (old_real and new_real) {
5698 cast_kind = .float_to_int;
5699 } else if (old_real) {
5700 res.ty = to.makeReal();
5701 try res.implicitCast(p, .float_to_int);
5702 cast_kind = .real_to_complex_int;
5703 } else if (new_real) {
5704 res.ty = res.ty.makeReal();
5705 try res.implicitCast(p, .complex_float_to_real);
5706 cast_kind = .float_to_int;
5707 } else {
5708 cast_kind = .complex_float_to_complex_int;
5709 }
5710 } else if (to.isPtr()) {
5711 if (res.ty.isArray())
5712 cast_kind = .array_to_pointer
5713 else if (res.ty.isPtr())
5714 cast_kind = .bitcast
5715 else if (res.ty.isFunc())
5716 cast_kind = .function_to_pointer
5717 else if (res.ty.is(.bool))
5718 cast_kind = .bool_to_pointer
5719 else if (res.ty.isInt()) {
5720 if (!old_real) {
5721 res.ty = res.ty.makeReal();
5722 try res.implicitCast(p, .complex_int_to_real);
5723 }
5724 cast_kind = .int_to_pointer;
5725 } else {
5726 try p.errStr(.cond_expr_type, operand_tok, try p.typeStr(res.ty));
5727 return error.ParsingFailed;
5728 }
5729 } else if (new_float) {
5730 if (res.ty.is(.bool)) {
5731 if (!new_real) {
5732 res.ty = to.makeReal();
5733 try res.implicitCast(p, .bool_to_float);
5734 cast_kind = .real_to_complex_float;
5735 } else {
5736 cast_kind = .bool_to_float;
5737 }
5738 } else if (res.ty.isInt()) {
5739 if (old_real and new_real) {
5740 cast_kind = .int_to_float;
5741 } else if (old_real) {
5742 res.ty = to.makeReal();
5743 try res.implicitCast(p, .int_to_float);
5744 cast_kind = .real_to_complex_float;
5745 } else if (new_real) {
5746 res.ty = res.ty.makeReal();
5747 try res.implicitCast(p, .complex_int_to_real);
5748 cast_kind = .int_to_float;
5749 } else {
5750 cast_kind = .complex_int_to_complex_float;
5751 }
5752 } else if (old_real and new_real) {
5753 cast_kind = .float_cast;
5754 } else if (old_real) {
5755 res.ty = to.makeReal();
5756 try res.implicitCast(p, .float_cast);
5757 cast_kind = .real_to_complex_float;
5758 } else if (new_real) {
5759 res.ty = res.ty.makeReal();
5760 try res.implicitCast(p, .complex_float_to_real);
5761 cast_kind = .float_cast;
5762 } else {
5763 cast_kind = .complex_float_cast;
5764 }
5765 }
5766 if (res.val.opt_ref == .none) break :cast;
5767
5768 const old_int = res.ty.isInt() or res.ty.isPtr();
5769 const new_int = to.isInt() or to.isPtr();
5770 if (to.is(.bool)) {
5771 res.val.boolCast(p.comp);
5772 } else if (old_float and new_int) {
5773 // Explicit cast, no conversion warning
5774 _ = try res.val.floatToInt(to, p.comp);
5775 } else if (new_float and old_int) {
5776 try res.val.intToFloat(to, p.comp);
5777 } else if (new_float and old_float) {
5778 try res.val.floatCast(to, p.comp);
5779 } else if (old_int and new_int) {
5780 if (to.hasIncompleteSize()) {
5781 try p.errStr(.cast_to_incomplete_type, l_paren, try p.typeStr(to));
5782 return error.ParsingFailed;
5783 }
5784 try res.val.intCast(to, p.comp);
5785 }
5786 } else if (to.get(.@"union")) |union_ty| {
5787 if (union_ty.data.record.hasFieldOfType(res.ty, p.comp)) {
5788 cast_kind = .union_cast;
5789 try p.errTok(.gnu_union_cast, l_paren);
5790 } else {
5791 if (union_ty.data.record.isIncomplete()) {
5792 try p.errStr(.cast_to_incomplete_type, l_paren, try p.typeStr(to));
5793 } else {
5794 try p.errStr(.invalid_union_cast, l_paren, try p.typeStr(res.ty));
5795 }
5796 return error.ParsingFailed;
5797 }
5798 } else {
5799 if (to.is(.auto_type)) {
5800 try p.errTok(.invalid_cast_to_auto_type, l_paren);
5801 } else {
5802 try p.errStr(.invalid_cast_type, l_paren, try p.typeStr(to));
5803 }
5804 return error.ParsingFailed;
5805 }
5806 if (to.anyQual()) try p.errStr(.qual_cast, l_paren, try p.typeStr(to));
5807 if (to.isInt() and res.ty.isPtr() and to.sizeCompare(res.ty, p.comp) == .lt) {
5808 try p.errStr(.cast_to_smaller_int, l_paren, try p.typePairStrExtra(to, " from ", res.ty));
5809 }
5810 res.ty = to;
5811 res.ty.qual = .{};
5812 res.node = try p.addNode(.{
5813 .tag = .explicit_cast,
5814 .ty = res.ty,
5815 .data = .{ .cast = .{ .operand = res.node, .kind = cast_kind } },
5816 });
5817 }
5818
5819 fn intFitsInType(res: Result, p: *Parser, ty: Type) !bool {
5820 const max_int = try Value.int(ty.maxInt(p.comp), p.comp);
5821 const min_int = try Value.int(ty.minInt(p.comp), p.comp);
5822 return res.val.compare(.lte, max_int, p.comp) and
5823 (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, min_int, p.comp));
5824 }
5825
5826 const CoerceContext = union(enum) {
5827 assign,
5828 init,
5829 ret,
5830 arg: TokenIndex,
5831 test_coerce,
5832
5833 fn note(c: CoerceContext, p: *Parser) !void {
5834 switch (c) {
5835 .arg => |tok| try p.errTok(.parameter_here, tok),
5836 .test_coerce => unreachable,
5837 else => {},
5838 }
5839 }
5840
5841 fn typePairStr(c: CoerceContext, p: *Parser, dest_ty: Type, src_ty: Type) ![]const u8 {
5842 switch (c) {
5843 .assign, .init => return p.typePairStrExtra(dest_ty, " from incompatible type ", src_ty),
5844 .ret => return p.typePairStrExtra(src_ty, " from a function with incompatible result type ", dest_ty),
5845 .arg => return p.typePairStrExtra(src_ty, " to parameter of incompatible type ", dest_ty),
5846 .test_coerce => unreachable,
5847 }
5848 }
5849 };
5850
5851 /// Perform assignment-like coercion to `dest_ty`.
5852 fn coerce(res: *Result, p: *Parser, dest_ty: Type, tok: TokenIndex, c: CoerceContext) Error!void {
5853 if (res.ty.specifier == .invalid or dest_ty.specifier == .invalid) {
5854 res.ty = Type.invalid;
5855 return;
5856 }
5857 return res.coerceExtra(p, dest_ty, tok, c) catch |er| switch (er) {
5858 error.CoercionFailed => unreachable,
5859 else => |e| return e,
5860 };
5861 }
5862
5863 fn coerceExtra(
5864 res: *Result,
5865 p: *Parser,
5866 dest_ty: Type,
5867 tok: TokenIndex,
5868 c: CoerceContext,
5869 ) (Error || error{CoercionFailed})!void {
5870 // Subject of the coercion does not need to be qualified.
5871 var unqual_ty = dest_ty.canonicalize(.standard);
5872 unqual_ty.qual = .{};
5873 if (unqual_ty.is(.nullptr_t)) {
5874 if (res.ty.is(.nullptr_t)) return;
5875 } else if (unqual_ty.is(.bool)) {
5876 if (res.ty.isScalar() and !res.ty.is(.nullptr_t)) {
5877 // this is ridiculous but it's what clang does
5878 try res.boolCast(p, unqual_ty, tok);
5879 return;
5880 }
5881 } else if (unqual_ty.isInt()) {
5882 if (res.ty.isInt() or res.ty.isFloat()) {
5883 try res.intCast(p, unqual_ty, tok);
5884 return;
5885 } else if (res.ty.isPtr()) {
5886 if (c == .test_coerce) return error.CoercionFailed;
5887 try p.errStr(.implicit_ptr_to_int, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
5888 try c.note(p);
5889 try res.intCast(p, unqual_ty, tok);
5890 return;
5891 }
5892 } else if (unqual_ty.isFloat()) {
5893 if (res.ty.isInt() or res.ty.isFloat()) {
5894 try res.floatCast(p, unqual_ty);
5895 return;
5896 }
5897 } else if (unqual_ty.isPtr()) {
5898 if (res.ty.is(.nullptr_t) or res.val.isZero(p.comp)) {
5899 try res.nullCast(p, dest_ty);
5900 return;
5901 } else if (res.ty.isInt() and res.ty.isReal()) {
5902 if (c == .test_coerce) return error.CoercionFailed;
5903 try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
5904 try c.note(p);
5905 try res.ptrCast(p, unqual_ty);
5906 return;
5907 } else if (res.ty.isVoidStar() or unqual_ty.eql(res.ty, p.comp, true)) {
5908 return; // ok
5909 } else if (unqual_ty.isVoidStar() and res.ty.isPtr() or (res.ty.isInt() and res.ty.isReal())) {
5910 return; // ok
5911 } else if (unqual_ty.eql(res.ty, p.comp, false)) {
5912 if (!unqual_ty.elemType().qual.hasQuals(res.ty.elemType().qual)) {
5913 try p.errStr(switch (c) {
5914 .assign => .ptr_assign_discards_quals,
5915 .init => .ptr_init_discards_quals,
5916 .ret => .ptr_ret_discards_quals,
5917 .arg => .ptr_arg_discards_quals,
5918 .test_coerce => return error.CoercionFailed,
5919 }, tok, try c.typePairStr(p, dest_ty, res.ty));
5920 }
5921 try res.ptrCast(p, unqual_ty);
5922 return;
5923 } else if (res.ty.isPtr()) {
5924 const different_sign_only = unqual_ty.elemType().sameRankDifferentSign(res.ty.elemType(), p.comp);
5925 try p.errStr(switch (c) {
5926 .assign => ([2]Diagnostics.Tag{ .incompatible_ptr_assign, .incompatible_ptr_assign_sign })[@intFromBool(different_sign_only)],
5927 .init => ([2]Diagnostics.Tag{ .incompatible_ptr_init, .incompatible_ptr_init_sign })[@intFromBool(different_sign_only)],
5928 .ret => ([2]Diagnostics.Tag{ .incompatible_return, .incompatible_return_sign })[@intFromBool(different_sign_only)],
5929 .arg => ([2]Diagnostics.Tag{ .incompatible_ptr_arg, .incompatible_ptr_arg_sign })[@intFromBool(different_sign_only)],
5930 .test_coerce => return error.CoercionFailed,
5931 }, tok, try c.typePairStr(p, dest_ty, res.ty));
5932 try c.note(p);
5933 try res.ptrChildTypeCast(p, unqual_ty);
5934 return;
5935 }
5936 } else if (unqual_ty.isRecord()) {
5937 if (unqual_ty.eql(res.ty, p.comp, false)) {
5938 return; // ok
5939 }
5940
5941 if (c == .arg) if (unqual_ty.get(.@"union")) |union_ty| {
5942 if (dest_ty.hasAttribute(.transparent_union)) transparent_union: {
5943 res.coerceExtra(p, union_ty.data.record.fields[0].ty, tok, .test_coerce) catch |er| switch (er) {
5944 error.CoercionFailed => break :transparent_union,
5945 else => |e| return e,
5946 };
5947 res.node = try p.addNode(.{
5948 .tag = .union_init_expr,
5949 .ty = dest_ty,
5950 .data = .{ .union_init = .{ .field_index = 0, .node = res.node } },
5951 });
5952 res.ty = dest_ty;
5953 return;
5954 }
5955 };
5956 } else if (unqual_ty.is(.vector)) {
5957 if (unqual_ty.eql(res.ty, p.comp, false)) {
5958 return; // ok
5959 }
5960 } else {
5961 if (c == .assign and (unqual_ty.isArray() or unqual_ty.isFunc())) {
5962 try p.errTok(.not_assignable, tok);
5963 return;
5964 } else if (c == .test_coerce) {
5965 return error.CoercionFailed;
5966 }
5967 // This case should not be possible and an error should have already been emitted but we
5968 // might still have attempted to parse further so return error.ParsingFailed here to stop.
5969 return error.ParsingFailed;
5970 }
5971
5972 try p.errStr(switch (c) {
5973 .assign => .incompatible_assign,
5974 .init => .incompatible_init,
5975 .ret => .incompatible_return,
5976 .arg => .incompatible_arg,
5977 .test_coerce => return error.CoercionFailed,
5978 }, tok, try c.typePairStr(p, dest_ty, res.ty));
5979 try c.note(p);
5980 }
5981};
5982
5983/// expr : assignExpr (',' assignExpr)*
5984fn expr(p: *Parser) Error!Result {
5985 var expr_start = p.tok_i;
5986 var err_start = p.comp.diagnostics.list.items.len;
5987 var lhs = try p.assignExpr();
5988 if (p.tok_ids[p.tok_i] == .comma) try lhs.expect(p);
5989 while (p.eatToken(.comma)) |_| {
5990 try lhs.maybeWarnUnused(p, expr_start, err_start);
5991 expr_start = p.tok_i;
5992 err_start = p.comp.diagnostics.list.items.len;
5993
5994 var rhs = try p.assignExpr();
5995 try rhs.expect(p);
5996 try rhs.lvalConversion(p);
5997 lhs.val = rhs.val;
5998 lhs.ty = rhs.ty;
5999 try lhs.bin(p, .comma_expr, rhs);
6000 }
6001 return lhs;
6002}
6003
6004fn tokToTag(p: *Parser, tok: TokenIndex) Tree.Tag {
6005 return switch (p.tok_ids[tok]) {
6006 .equal => .assign_expr,
6007 .asterisk_equal => .mul_assign_expr,
6008 .slash_equal => .div_assign_expr,
6009 .percent_equal => .mod_assign_expr,
6010 .plus_equal => .add_assign_expr,
6011 .minus_equal => .sub_assign_expr,
6012 .angle_bracket_angle_bracket_left_equal => .shl_assign_expr,
6013 .angle_bracket_angle_bracket_right_equal => .shr_assign_expr,
6014 .ampersand_equal => .bit_and_assign_expr,
6015 .caret_equal => .bit_xor_assign_expr,
6016 .pipe_equal => .bit_or_assign_expr,
6017 .equal_equal => .equal_expr,
6018 .bang_equal => .not_equal_expr,
6019 .angle_bracket_left => .less_than_expr,
6020 .angle_bracket_left_equal => .less_than_equal_expr,
6021 .angle_bracket_right => .greater_than_expr,
6022 .angle_bracket_right_equal => .greater_than_equal_expr,
6023 .angle_bracket_angle_bracket_left => .shl_expr,
6024 .angle_bracket_angle_bracket_right => .shr_expr,
6025 .plus => .add_expr,
6026 .minus => .sub_expr,
6027 .asterisk => .mul_expr,
6028 .slash => .div_expr,
6029 .percent => .mod_expr,
6030 else => unreachable,
6031 };
6032}
6033
6034/// assignExpr
6035/// : condExpr
6036/// | unExpr ('=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=') assignExpr
6037fn assignExpr(p: *Parser) Error!Result {
6038 var lhs = try p.condExpr();
6039 if (lhs.empty(p)) return lhs;
6040
6041 const tok = p.tok_i;
6042 const eq = p.eatToken(.equal);
6043 const mul = eq orelse p.eatToken(.asterisk_equal);
6044 const div = mul orelse p.eatToken(.slash_equal);
6045 const mod = div orelse p.eatToken(.percent_equal);
6046 const add = mod orelse p.eatToken(.plus_equal);
6047 const sub = add orelse p.eatToken(.minus_equal);
6048 const shl = sub orelse p.eatToken(.angle_bracket_angle_bracket_left_equal);
6049 const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right_equal);
6050 const bit_and = shr orelse p.eatToken(.ampersand_equal);
6051 const bit_xor = bit_and orelse p.eatToken(.caret_equal);
6052 const bit_or = bit_xor orelse p.eatToken(.pipe_equal);
6053
6054 const tag = p.tokToTag(bit_or orelse return lhs);
6055 var rhs = try p.assignExpr();
6056 try rhs.expect(p);
6057 try rhs.lvalConversion(p);
6058
6059 var is_const: bool = undefined;
6060 if (!p.tmpTree().isLvalExtra(lhs.node, &is_const) or is_const) {
6061 try p.errTok(.not_assignable, tok);
6062 return error.ParsingFailed;
6063 }
6064
6065 // adjustTypes will do do lvalue conversion but we do not want that
6066 var lhs_copy = lhs;
6067 switch (tag) {
6068 .assign_expr => {}, // handle plain assignment separately
6069 .mul_assign_expr,
6070 .div_assign_expr,
6071 .mod_assign_expr,
6072 => {
6073 if (rhs.val.isZero(p.comp) and lhs.ty.isInt() and rhs.ty.isInt()) {
6074 switch (tag) {
6075 .div_assign_expr => try p.errStr(.division_by_zero, div.?, "division"),
6076 .mod_assign_expr => try p.errStr(.division_by_zero, mod.?, "remainder"),
6077 else => {},
6078 }
6079 }
6080 _ = try lhs_copy.adjustTypes(tok, &rhs, p, if (tag == .mod_assign_expr) .integer else .arithmetic);
6081 try lhs.bin(p, tag, rhs);
6082 return lhs;
6083 },
6084 .sub_assign_expr,
6085 .add_assign_expr,
6086 => {
6087 if (lhs.ty.isPtr() and rhs.ty.isInt()) {
6088 try rhs.ptrCast(p, lhs.ty);
6089 } else {
6090 _ = try lhs_copy.adjustTypes(tok, &rhs, p, .arithmetic);
6091 }
6092 try lhs.bin(p, tag, rhs);
6093 return lhs;
6094 },
6095 .shl_assign_expr,
6096 .shr_assign_expr,
6097 .bit_and_assign_expr,
6098 .bit_xor_assign_expr,
6099 .bit_or_assign_expr,
6100 => {
6101 _ = try lhs_copy.adjustTypes(tok, &rhs, p, .integer);
6102 try lhs.bin(p, tag, rhs);
6103 return lhs;
6104 },
6105 else => unreachable,
6106 }
6107
6108 try rhs.coerce(p, lhs.ty, tok, .assign);
6109
6110 try lhs.bin(p, tag, rhs);
6111 return lhs;
6112}
6113
6114/// Returns a parse error if the expression is not an integer constant
6115/// integerConstExpr : constExpr
6116fn integerConstExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
6117 const start = p.tok_i;
6118 const res = try p.constExpr(decl_folding);
6119 if (!res.ty.isInt() and res.ty.specifier != .invalid) {
6120 try p.errTok(.expected_integer_constant_expr, start);
6121 return error.ParsingFailed;
6122 }
6123 return res;
6124}
6125
6126/// Caller is responsible for issuing a diagnostic if result is invalid/unavailable
6127/// constExpr : condExpr
6128fn constExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
6129 const const_decl_folding = p.const_decl_folding;
6130 defer p.const_decl_folding = const_decl_folding;
6131 p.const_decl_folding = decl_folding;
6132
6133 const res = try p.condExpr();
6134 try res.expect(p);
6135
6136 if (res.ty.specifier == .invalid or res.val.opt_ref == .none) return res;
6137
6138 // saveValue sets val to unavailable
6139 var copy = res;
6140 try copy.saveValue(p);
6141 return res;
6142}
6143
6144/// condExpr : lorExpr ('?' expression? ':' condExpr)?
6145fn condExpr(p: *Parser) Error!Result {
6146 const cond_tok = p.tok_i;
6147 var cond = try p.lorExpr();
6148 if (cond.empty(p) or p.eatToken(.question_mark) == null) return cond;
6149 try cond.lvalConversion(p);
6150 const saved_eval = p.no_eval;
6151
6152 if (!cond.ty.isScalar()) {
6153 try p.errStr(.cond_expr_type, cond_tok, try p.typeStr(cond.ty));
6154 return error.ParsingFailed;
6155 }
6156
6157 // Prepare for possible binary conditional expression.
6158 const maybe_colon = p.eatToken(.colon);
6159
6160 // Depending on the value of the condition, avoid evaluating unreachable branches.
6161 var then_expr = blk: {
6162 defer p.no_eval = saved_eval;
6163 if (cond.val.opt_ref != .none and !cond.val.toBool(p.comp)) p.no_eval = true;
6164 break :blk try p.expr();
6165 };
6166 try then_expr.expect(p);
6167
6168 // If we saw a colon then this is a binary conditional expression.
6169 if (maybe_colon) |colon| {
6170 var cond_then = cond;
6171 cond_then.node = try p.addNode(.{ .tag = .cond_dummy_expr, .ty = cond.ty, .data = .{ .un = cond.node } });
6172 _ = try cond_then.adjustTypes(colon, &then_expr, p, .conditional);
6173 cond.ty = then_expr.ty;
6174 cond.node = try p.addNode(.{
6175 .tag = .binary_cond_expr,
6176 .ty = cond.ty,
6177 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ cond_then.node, then_expr.node })).start } },
6178 });
6179 return cond;
6180 }
6181
6182 const colon = try p.expectToken(.colon);
6183 var else_expr = blk: {
6184 defer p.no_eval = saved_eval;
6185 if (cond.val.opt_ref != .none and cond.val.toBool(p.comp)) p.no_eval = true;
6186 break :blk try p.condExpr();
6187 };
6188 try else_expr.expect(p);
6189
6190 _ = try then_expr.adjustTypes(colon, &else_expr, p, .conditional);
6191
6192 if (cond.val.opt_ref != .none) {
6193 cond.val = if (cond.val.toBool(p.comp)) then_expr.val else else_expr.val;
6194 } else {
6195 try then_expr.saveValue(p);
6196 try else_expr.saveValue(p);
6197 }
6198 cond.ty = then_expr.ty;
6199 cond.node = try p.addNode(.{
6200 .tag = .cond_expr,
6201 .ty = cond.ty,
6202 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
6203 });
6204 return cond;
6205}
6206
6207/// lorExpr : landExpr ('||' landExpr)*
6208fn lorExpr(p: *Parser) Error!Result {
6209 var lhs = try p.landExpr();
6210 if (lhs.empty(p)) return lhs;
6211 const saved_eval = p.no_eval;
6212 defer p.no_eval = saved_eval;
6213
6214 while (p.eatToken(.pipe_pipe)) |tok| {
6215 if (lhs.val.opt_ref != .none and lhs.val.toBool(p.comp)) p.no_eval = true;
6216 var rhs = try p.landExpr();
6217 try rhs.expect(p);
6218
6219 if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
6220 const res = lhs.val.toBool(p.comp) or rhs.val.toBool(p.comp);
6221 lhs.val = Value.fromBool(res);
6222 }
6223 try lhs.boolRes(p, .bool_or_expr, rhs);
6224 }
6225 return lhs;
6226}
6227
6228/// landExpr : orExpr ('&&' orExpr)*
6229fn landExpr(p: *Parser) Error!Result {
6230 var lhs = try p.orExpr();
6231 if (lhs.empty(p)) return lhs;
6232 const saved_eval = p.no_eval;
6233 defer p.no_eval = saved_eval;
6234
6235 while (p.eatToken(.ampersand_ampersand)) |tok| {
6236 if (lhs.val.opt_ref != .none and !lhs.val.toBool(p.comp)) p.no_eval = true;
6237 var rhs = try p.orExpr();
6238 try rhs.expect(p);
6239
6240 if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
6241 const res = lhs.val.toBool(p.comp) and rhs.val.toBool(p.comp);
6242 lhs.val = Value.fromBool(res);
6243 }
6244 try lhs.boolRes(p, .bool_and_expr, rhs);
6245 }
6246 return lhs;
6247}
6248
6249/// orExpr : xorExpr ('|' xorExpr)*
6250fn orExpr(p: *Parser) Error!Result {
6251 var lhs = try p.xorExpr();
6252 if (lhs.empty(p)) return lhs;
6253 while (p.eatToken(.pipe)) |tok| {
6254 var rhs = try p.xorExpr();
6255 try rhs.expect(p);
6256
6257 if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
6258 lhs.val = try lhs.val.bitOr(rhs.val, p.comp);
6259 }
6260 try lhs.bin(p, .bit_or_expr, rhs);
6261 }
6262 return lhs;
6263}
6264
6265/// xorExpr : andExpr ('^' andExpr)*
6266fn xorExpr(p: *Parser) Error!Result {
6267 var lhs = try p.andExpr();
6268 if (lhs.empty(p)) return lhs;
6269 while (p.eatToken(.caret)) |tok| {
6270 var rhs = try p.andExpr();
6271 try rhs.expect(p);
6272
6273 if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
6274 lhs.val = try lhs.val.bitXor(rhs.val, p.comp);
6275 }
6276 try lhs.bin(p, .bit_xor_expr, rhs);
6277 }
6278 return lhs;
6279}
6280
6281/// andExpr : eqExpr ('&' eqExpr)*
6282fn andExpr(p: *Parser) Error!Result {
6283 var lhs = try p.eqExpr();
6284 if (lhs.empty(p)) return lhs;
6285 while (p.eatToken(.ampersand)) |tok| {
6286 var rhs = try p.eqExpr();
6287 try rhs.expect(p);
6288
6289 if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
6290 lhs.val = try lhs.val.bitAnd(rhs.val, p.comp);
6291 }
6292 try lhs.bin(p, .bit_and_expr, rhs);
6293 }
6294 return lhs;
6295}
6296
6297/// eqExpr : compExpr (('==' | '!=') compExpr)*
6298fn eqExpr(p: *Parser) Error!Result {
6299 var lhs = try p.compExpr();
6300 if (lhs.empty(p)) return lhs;
6301 while (true) {
6302 const eq = p.eatToken(.equal_equal);
6303 const ne = eq orelse p.eatToken(.bang_equal);
6304 const tag = p.tokToTag(ne orelse break);
6305 var rhs = try p.compExpr();
6306 try rhs.expect(p);
6307
6308 if (try lhs.adjustTypes(ne.?, &rhs, p, .equality)) {
6309 const op: std.math.CompareOperator = if (tag == .equal_expr) .eq else .neq;
6310 const res = lhs.val.compare(op, rhs.val, p.comp);
6311 lhs.val = Value.fromBool(res);
6312 }
6313 try lhs.boolRes(p, tag, rhs);
6314 }
6315 return lhs;
6316}
6317
6318/// compExpr : shiftExpr (('<' | '<=' | '>' | '>=') shiftExpr)*
6319fn compExpr(p: *Parser) Error!Result {
6320 var lhs = try p.shiftExpr();
6321 if (lhs.empty(p)) return lhs;
6322 while (true) {
6323 const lt = p.eatToken(.angle_bracket_left);
6324 const le = lt orelse p.eatToken(.angle_bracket_left_equal);
6325 const gt = le orelse p.eatToken(.angle_bracket_right);
6326 const ge = gt orelse p.eatToken(.angle_bracket_right_equal);
6327 const tag = p.tokToTag(ge orelse break);
6328 var rhs = try p.shiftExpr();
6329 try rhs.expect(p);
6330
6331 if (try lhs.adjustTypes(ge.?, &rhs, p, .relational)) {
6332 const op: std.math.CompareOperator = switch (tag) {
6333 .less_than_expr => .lt,
6334 .less_than_equal_expr => .lte,
6335 .greater_than_expr => .gt,
6336 .greater_than_equal_expr => .gte,
6337 else => unreachable,
6338 };
6339 const res = lhs.val.compare(op, rhs.val, p.comp);
6340 lhs.val = Value.fromBool(res);
6341 }
6342 try lhs.boolRes(p, tag, rhs);
6343 }
6344 return lhs;
6345}
6346
6347/// shiftExpr : addExpr (('<<' | '>>') addExpr)*
6348fn shiftExpr(p: *Parser) Error!Result {
6349 var lhs = try p.addExpr();
6350 if (lhs.empty(p)) return lhs;
6351 while (true) {
6352 const shl = p.eatToken(.angle_bracket_angle_bracket_left);
6353 const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right);
6354 const tag = p.tokToTag(shr orelse break);
6355 var rhs = try p.addExpr();
6356 try rhs.expect(p);
6357
6358 if (try lhs.adjustTypes(shr.?, &rhs, p, .integer)) {
6359 if (shl != null) {
6360 if (try lhs.val.shl(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(shl.?, lhs);
6361 } else {
6362 lhs.val = try lhs.val.shr(rhs.val, lhs.ty, p.comp);
6363 }
6364 }
6365 try lhs.bin(p, tag, rhs);
6366 }
6367 return lhs;
6368}
6369
6370/// addExpr : mulExpr (('+' | '-') mulExpr)*
6371fn addExpr(p: *Parser) Error!Result {
6372 var lhs = try p.mulExpr();
6373 if (lhs.empty(p)) return lhs;
6374 while (true) {
6375 const plus = p.eatToken(.plus);
6376 const minus = plus orelse p.eatToken(.minus);
6377 const tag = p.tokToTag(minus orelse break);
6378 var rhs = try p.mulExpr();
6379 try rhs.expect(p);
6380
6381 const lhs_ty = lhs.ty;
6382 if (try lhs.adjustTypes(minus.?, &rhs, p, if (plus != null) .add else .sub)) {
6383 if (plus != null) {
6384 if (try lhs.val.add(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(plus.?, lhs);
6385 } else {
6386 if (try lhs.val.sub(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(minus.?, lhs);
6387 }
6388 }
6389 if (lhs.ty.specifier != .invalid and lhs_ty.isPtr() and !lhs_ty.isVoidStar() and lhs_ty.elemType().hasIncompleteSize()) {
6390 try p.errStr(.ptr_arithmetic_incomplete, minus.?, try p.typeStr(lhs_ty.elemType()));
6391 lhs.ty = Type.invalid;
6392 }
6393 try lhs.bin(p, tag, rhs);
6394 }
6395 return lhs;
6396}
6397
6398/// mulExpr : castExpr (('*' | '/' | '%') castExpr)*´
6399fn mulExpr(p: *Parser) Error!Result {
6400 var lhs = try p.castExpr();
6401 if (lhs.empty(p)) return lhs;
6402 while (true) {
6403 const mul = p.eatToken(.asterisk);
6404 const div = mul orelse p.eatToken(.slash);
6405 const percent = div orelse p.eatToken(.percent);
6406 const tag = p.tokToTag(percent orelse break);
6407 var rhs = try p.castExpr();
6408 try rhs.expect(p);
6409
6410 if (rhs.val.isZero(p.comp) and mul == null and !p.no_eval and lhs.ty.isInt() and rhs.ty.isInt()) {
6411 const err_tag: Diagnostics.Tag = if (p.in_macro) .division_by_zero_macro else .division_by_zero;
6412 lhs.val = .{};
6413 if (div != null) {
6414 try p.errStr(err_tag, div.?, "division");
6415 } else {
6416 try p.errStr(err_tag, percent.?, "remainder");
6417 }
6418 if (p.in_macro) return error.ParsingFailed;
6419 }
6420
6421 if (try lhs.adjustTypes(percent.?, &rhs, p, if (tag == .mod_expr) .integer else .arithmetic)) {
6422 if (mul != null) {
6423 if (try lhs.val.mul(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs);
6424 } else if (div != null) {
6425 if (try lhs.val.div(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs);
6426 } else {
6427 var res = try Value.rem(lhs.val, rhs.val, lhs.ty, p.comp);
6428 if (res.opt_ref == .none) {
6429 if (p.in_macro) {
6430 // match clang behavior by defining invalid remainder to be zero in macros
6431 res = Value.zero;
6432 } else {
6433 try lhs.saveValue(p);
6434 try rhs.saveValue(p);
6435 }
6436 }
6437 lhs.val = res;
6438 }
6439 }
6440
6441 try lhs.bin(p, tag, rhs);
6442 }
6443 return lhs;
6444}
6445
6446/// This will always be the last message, if present
6447fn removeUnusedWarningForTok(p: *Parser, last_expr_tok: TokenIndex) void {
6448 if (last_expr_tok == 0) return;
6449 if (p.comp.diagnostics.list.items.len == 0) return;
6450
6451 const last_expr_loc = p.pp.tokens.items(.loc)[last_expr_tok];
6452 const last_msg = p.comp.diagnostics.list.items[p.comp.diagnostics.list.items.len - 1];
6453
6454 if (last_msg.tag == .unused_value and last_msg.loc.eql(last_expr_loc)) {
6455 p.comp.diagnostics.list.items.len = p.comp.diagnostics.list.items.len - 1;
6456 }
6457}
6458
6459/// castExpr
6460/// : '(' compoundStmt ')'
6461/// | '(' typeName ')' castExpr
6462/// | '(' typeName ')' '{' initializerItems '}'
6463/// | __builtin_choose_expr '(' integerConstExpr ',' assignExpr ',' assignExpr ')'
6464/// | __builtin_va_arg '(' assignExpr ',' typeName ')'
6465/// | __builtin_offsetof '(' typeName ',' offsetofMemberDesignator ')'
6466/// | __builtin_bitoffsetof '(' typeName ',' offsetofMemberDesignator ')'
6467/// | unExpr
6468fn castExpr(p: *Parser) Error!Result {
6469 if (p.eatToken(.l_paren)) |l_paren| cast_expr: {
6470 if (p.tok_ids[p.tok_i] == .l_brace) {
6471 try p.err(.gnu_statement_expression);
6472 if (p.func.ty == null) {
6473 try p.err(.stmt_expr_not_allowed_file_scope);
6474 return error.ParsingFailed;
6475 }
6476 var stmt_expr_state: StmtExprState = .{};
6477 const body_node = (try p.compoundStmt(false, &stmt_expr_state)).?; // compoundStmt only returns null if .l_brace isn't the first token
6478 p.removeUnusedWarningForTok(stmt_expr_state.last_expr_tok);
6479
6480 var res = Result{
6481 .node = body_node,
6482 .ty = stmt_expr_state.last_expr_res.ty,
6483 .val = stmt_expr_state.last_expr_res.val,
6484 };
6485 try p.expectClosing(l_paren, .r_paren);
6486 try res.un(p, .stmt_expr);
6487 return res;
6488 }
6489 const ty = (try p.typeName()) orelse {
6490 p.tok_i -= 1;
6491 break :cast_expr;
6492 };
6493 try p.expectClosing(l_paren, .r_paren);
6494
6495 if (p.tok_ids[p.tok_i] == .l_brace) {
6496 // Compound literal; handled in unExpr
6497 p.tok_i = l_paren;
6498 break :cast_expr;
6499 }
6500
6501 const operand_tok = p.tok_i;
6502 var operand = try p.castExpr();
6503 try operand.expect(p);
6504 try operand.lvalConversion(p);
6505 try operand.castType(p, ty, operand_tok, l_paren);
6506 return operand;
6507 }
6508 switch (p.tok_ids[p.tok_i]) {
6509 .builtin_choose_expr => return p.builtinChooseExpr(),
6510 .builtin_va_arg => return p.builtinVaArg(),
6511 .builtin_offsetof => return p.builtinOffsetof(false),
6512 .builtin_bitoffsetof => return p.builtinOffsetof(true),
6513 .builtin_types_compatible_p => return p.typesCompatible(),
6514 // TODO: other special-cased builtins
6515 else => {},
6516 }
6517 return p.unExpr();
6518}
6519
6520fn typesCompatible(p: *Parser) Error!Result {
6521 p.tok_i += 1;
6522 const l_paren = try p.expectToken(.l_paren);
6523
6524 const first = (try p.typeName()) orelse {
6525 try p.err(.expected_type);
6526 p.skipTo(.r_paren);
6527 return error.ParsingFailed;
6528 };
6529 const lhs = try p.addNode(.{ .tag = .invalid, .ty = first, .data = undefined });
6530 _ = try p.expectToken(.comma);
6531
6532 const second = (try p.typeName()) orelse {
6533 try p.err(.expected_type);
6534 p.skipTo(.r_paren);
6535 return error.ParsingFailed;
6536 };
6537 const rhs = try p.addNode(.{ .tag = .invalid, .ty = second, .data = undefined });
6538
6539 try p.expectClosing(l_paren, .r_paren);
6540
6541 var first_unqual = first.canonicalize(.standard);
6542 first_unqual.qual.@"const" = false;
6543 first_unqual.qual.@"volatile" = false;
6544 var second_unqual = second.canonicalize(.standard);
6545 second_unqual.qual.@"const" = false;
6546 second_unqual.qual.@"volatile" = false;
6547
6548 const compatible = first_unqual.eql(second_unqual, p.comp, true);
6549
6550 const res = Result{
6551 .val = Value.fromBool(compatible),
6552 .node = try p.addNode(.{ .tag = .builtin_types_compatible_p, .ty = Type.int, .data = .{ .bin = .{
6553 .lhs = lhs,
6554 .rhs = rhs,
6555 } } }),
6556 };
6557 try p.value_map.put(res.node, res.val);
6558 return res;
6559}
6560
6561fn builtinChooseExpr(p: *Parser) Error!Result {
6562 p.tok_i += 1;
6563 const l_paren = try p.expectToken(.l_paren);
6564 const cond_tok = p.tok_i;
6565 var cond = try p.integerConstExpr(.no_const_decl_folding);
6566 if (cond.val.opt_ref == .none) {
6567 try p.errTok(.builtin_choose_cond, cond_tok);
6568 return error.ParsingFailed;
6569 }
6570
6571 _ = try p.expectToken(.comma);
6572
6573 var then_expr = if (cond.val.toBool(p.comp)) try p.assignExpr() else try p.parseNoEval(assignExpr);
6574 try then_expr.expect(p);
6575
6576 _ = try p.expectToken(.comma);
6577
6578 var else_expr = if (!cond.val.toBool(p.comp)) try p.assignExpr() else try p.parseNoEval(assignExpr);
6579 try else_expr.expect(p);
6580
6581 try p.expectClosing(l_paren, .r_paren);
6582
6583 if (cond.val.toBool(p.comp)) {
6584 cond.val = then_expr.val;
6585 cond.ty = then_expr.ty;
6586 } else {
6587 cond.val = else_expr.val;
6588 cond.ty = else_expr.ty;
6589 }
6590 cond.node = try p.addNode(.{
6591 .tag = .builtin_choose_expr,
6592 .ty = cond.ty,
6593 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
6594 });
6595 return cond;
6596}
6597
6598fn builtinVaArg(p: *Parser) Error!Result {
6599 const builtin_tok = p.tok_i;
6600 p.tok_i += 1;
6601
6602 const l_paren = try p.expectToken(.l_paren);
6603 const va_list_tok = p.tok_i;
6604 var va_list = try p.assignExpr();
6605 try va_list.expect(p);
6606 try va_list.lvalConversion(p);
6607
6608 _ = try p.expectToken(.comma);
6609
6610 const ty = (try p.typeName()) orelse {
6611 try p.err(.expected_type);
6612 return error.ParsingFailed;
6613 };
6614 try p.expectClosing(l_paren, .r_paren);
6615
6616 if (!va_list.ty.eql(p.comp.types.va_list, p.comp, true)) {
6617 try p.errStr(.incompatible_va_arg, va_list_tok, try p.typeStr(va_list.ty));
6618 return error.ParsingFailed;
6619 }
6620
6621 return Result{ .ty = ty, .node = try p.addNode(.{
6622 .tag = .special_builtin_call_one,
6623 .ty = ty,
6624 .data = .{ .decl = .{ .name = builtin_tok, .node = va_list.node } },
6625 }) };
6626}
6627
6628fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result {
6629 const builtin_tok = p.tok_i;
6630 p.tok_i += 1;
6631
6632 const l_paren = try p.expectToken(.l_paren);
6633 const ty_tok = p.tok_i;
6634
6635 const ty = (try p.typeName()) orelse {
6636 try p.err(.expected_type);
6637 p.skipTo(.r_paren);
6638 return error.ParsingFailed;
6639 };
6640
6641 if (!ty.isRecord()) {
6642 try p.errStr(.offsetof_ty, ty_tok, try p.typeStr(ty));
6643 p.skipTo(.r_paren);
6644 return error.ParsingFailed;
6645 } else if (ty.hasIncompleteSize()) {
6646 try p.errStr(.offsetof_incomplete, ty_tok, try p.typeStr(ty));
6647 p.skipTo(.r_paren);
6648 return error.ParsingFailed;
6649 }
6650
6651 _ = try p.expectToken(.comma);
6652
6653 const offsetof_expr = try p.offsetofMemberDesignator(ty, want_bits);
6654
6655 try p.expectClosing(l_paren, .r_paren);
6656
6657 return Result{
6658 .ty = p.comp.types.size,
6659 .val = offsetof_expr.val,
6660 .node = try p.addNode(.{
6661 .tag = .special_builtin_call_one,
6662 .ty = p.comp.types.size,
6663 .data = .{ .decl = .{ .name = builtin_tok, .node = offsetof_expr.node } },
6664 }),
6665 };
6666}
6667
6668/// offsetofMemberDesignator: IDENTIFIER ('.' IDENTIFIER | '[' expr ']' )*
6669fn offsetofMemberDesignator(p: *Parser, base_ty: Type, want_bits: bool) Error!Result {
6670 errdefer p.skipTo(.r_paren);
6671 const base_field_name_tok = try p.expectIdentifier();
6672 const base_field_name = try StrInt.intern(p.comp, p.tokSlice(base_field_name_tok));
6673 try p.validateFieldAccess(base_ty, base_ty, base_field_name_tok, base_field_name);
6674 const base_node = try p.addNode(.{ .tag = .default_init_expr, .ty = base_ty, .data = undefined });
6675
6676 var cur_offset: u64 = 0;
6677 const base_record_ty = base_ty.canonicalize(.standard);
6678 var lhs = try p.fieldAccessExtra(base_node, base_record_ty, base_field_name, false, &cur_offset);
6679
6680 var total_offset = cur_offset;
6681 while (true) switch (p.tok_ids[p.tok_i]) {
6682 .period => {
6683 p.tok_i += 1;
6684 const field_name_tok = try p.expectIdentifier();
6685 const field_name = try StrInt.intern(p.comp, p.tokSlice(field_name_tok));
6686
6687 if (!lhs.ty.isRecord()) {
6688 try p.errStr(.offsetof_ty, field_name_tok, try p.typeStr(lhs.ty));
6689 return error.ParsingFailed;
6690 }
6691 try p.validateFieldAccess(lhs.ty, lhs.ty, field_name_tok, field_name);
6692 const record_ty = lhs.ty.canonicalize(.standard);
6693 lhs = try p.fieldAccessExtra(lhs.node, record_ty, field_name, false, &cur_offset);
6694 total_offset += cur_offset;
6695 },
6696 .l_bracket => {
6697 const l_bracket_tok = p.tok_i;
6698 p.tok_i += 1;
6699 var index = try p.expr();
6700 try index.expect(p);
6701 _ = try p.expectClosing(l_bracket_tok, .r_bracket);
6702
6703 if (!lhs.ty.isArray()) {
6704 try p.errStr(.offsetof_array, l_bracket_tok, try p.typeStr(lhs.ty));
6705 return error.ParsingFailed;
6706 }
6707 var ptr = lhs;
6708 try ptr.lvalConversion(p);
6709 try index.lvalConversion(p);
6710
6711 if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket_tok);
6712 try p.checkArrayBounds(index, lhs, l_bracket_tok);
6713
6714 try index.saveValue(p);
6715 try ptr.bin(p, .array_access_expr, index);
6716 lhs = ptr;
6717 },
6718 else => break,
6719 };
6720 const val = try Value.int(if (want_bits) total_offset else total_offset / 8, p.comp);
6721 return Result{ .ty = base_ty, .val = val, .node = lhs.node };
6722}
6723
6724/// unExpr
6725/// : (compoundLiteral | primaryExpr) suffixExpr*
6726/// | '&&' IDENTIFIER
6727/// | ('&' | '*' | '+' | '-' | '~' | '!' | '++' | '--' | keyword_extension | keyword_imag | keyword_real) castExpr
6728/// | keyword_sizeof unExpr
6729/// | keyword_sizeof '(' typeName ')'
6730/// | keyword_alignof '(' typeName ')'
6731/// | keyword_c23_alignof '(' typeName ')'
6732fn unExpr(p: *Parser) Error!Result {
6733 const tok = p.tok_i;
6734 switch (p.tok_ids[tok]) {
6735 .ampersand_ampersand => {
6736 const address_tok = p.tok_i;
6737 p.tok_i += 1;
6738 const name_tok = try p.expectIdentifier();
6739 try p.errTok(.gnu_label_as_value, address_tok);
6740 p.contains_address_of_label = true;
6741
6742 const str = p.tokSlice(name_tok);
6743 if (p.findLabel(str) == null) {
6744 try p.labels.append(.{ .unresolved_goto = name_tok });
6745 }
6746 const elem_ty = try p.arena.create(Type);
6747 elem_ty.* = .{ .specifier = .void };
6748 const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
6749 return Result{
6750 .node = try p.addNode(.{
6751 .tag = .addr_of_label,
6752 .data = .{ .decl_ref = name_tok },
6753 .ty = result_ty,
6754 }),
6755 .ty = result_ty,
6756 };
6757 },
6758 .ampersand => {
6759 if (p.in_macro) {
6760 try p.err(.invalid_preproc_operator);
6761 return error.ParsingFailed;
6762 }
6763 p.tok_i += 1;
6764 var operand = try p.castExpr();
6765 try operand.expect(p);
6766
6767 const tree = p.tmpTree();
6768 if (p.getNode(operand.node, .member_access_expr) orelse
6769 p.getNode(operand.node, .member_access_ptr_expr)) |member_node|
6770 {
6771 if (tree.isBitfield(member_node)) try p.errTok(.addr_of_bitfield, tok);
6772 }
6773 if (!tree.isLval(operand.node)) {
6774 try p.errTok(.addr_of_rvalue, tok);
6775 }
6776 if (operand.ty.qual.register) try p.errTok(.addr_of_register, tok);
6777
6778 const elem_ty = try p.arena.create(Type);
6779 elem_ty.* = operand.ty;
6780 operand.ty = Type{
6781 .specifier = .pointer,
6782 .data = .{ .sub_type = elem_ty },
6783 };
6784 try operand.saveValue(p);
6785 try operand.un(p, .addr_of_expr);
6786 return operand;
6787 },
6788 .asterisk => {
6789 const asterisk_loc = p.tok_i;
6790 p.tok_i += 1;
6791 var operand = try p.castExpr();
6792 try operand.expect(p);
6793
6794 if (operand.ty.isArray() or operand.ty.isPtr() or operand.ty.isFunc()) {
6795 try operand.lvalConversion(p);
6796 operand.ty = operand.ty.elemType();
6797 } else {
6798 try p.errTok(.indirection_ptr, tok);
6799 }
6800 if (operand.ty.hasIncompleteSize() and !operand.ty.is(.void)) {
6801 try p.errStr(.deref_incomplete_ty_ptr, asterisk_loc, try p.typeStr(operand.ty));
6802 }
6803 operand.ty.qual = .{};
6804 try operand.un(p, .deref_expr);
6805 return operand;
6806 },
6807 .plus => {
6808 p.tok_i += 1;
6809
6810 var operand = try p.castExpr();
6811 try operand.expect(p);
6812 try operand.lvalConversion(p);
6813 if (!operand.ty.isInt() and !operand.ty.isFloat())
6814 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6815
6816 try operand.usualUnaryConversion(p, tok);
6817
6818 return operand;
6819 },
6820 .minus => {
6821 p.tok_i += 1;
6822
6823 var operand = try p.castExpr();
6824 try operand.expect(p);
6825 try operand.lvalConversion(p);
6826 if (!operand.ty.isInt() and !operand.ty.isFloat())
6827 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6828
6829 try operand.usualUnaryConversion(p, tok);
6830 if (operand.val.is(.int, p.comp)) {
6831 _ = try operand.val.sub(Value.zero, operand.val, operand.ty, p.comp);
6832 } else {
6833 operand.val = .{};
6834 }
6835 try operand.un(p, .negate_expr);
6836 return operand;
6837 },
6838 .plus_plus => {
6839 p.tok_i += 1;
6840
6841 var operand = try p.castExpr();
6842 try operand.expect(p);
6843 if (!operand.ty.isScalar())
6844 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6845 if (operand.ty.isComplex())
6846 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
6847
6848 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
6849 try p.errTok(.not_assignable, tok);
6850 return error.ParsingFailed;
6851 }
6852 try operand.usualUnaryConversion(p, tok);
6853
6854 if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) {
6855 if (try operand.val.add(operand.val, Value.one, operand.ty, p.comp))
6856 try p.errOverflow(tok, operand);
6857 } else {
6858 operand.val = .{};
6859 }
6860
6861 try operand.un(p, .pre_inc_expr);
6862 return operand;
6863 },
6864 .minus_minus => {
6865 p.tok_i += 1;
6866
6867 var operand = try p.castExpr();
6868 try operand.expect(p);
6869 if (!operand.ty.isScalar())
6870 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6871 if (operand.ty.isComplex())
6872 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
6873
6874 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
6875 try p.errTok(.not_assignable, tok);
6876 return error.ParsingFailed;
6877 }
6878 try operand.usualUnaryConversion(p, tok);
6879
6880 if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) {
6881 if (try operand.val.sub(operand.val, Value.one, operand.ty, p.comp))
6882 try p.errOverflow(tok, operand);
6883 } else {
6884 operand.val = .{};
6885 }
6886
6887 try operand.un(p, .pre_dec_expr);
6888 return operand;
6889 },
6890 .tilde => {
6891 p.tok_i += 1;
6892
6893 var operand = try p.castExpr();
6894 try operand.expect(p);
6895 try operand.lvalConversion(p);
6896 try operand.usualUnaryConversion(p, tok);
6897 if (operand.ty.isInt()) {
6898 if (operand.val.is(.int, p.comp)) {
6899 operand.val = try operand.val.bitNot(operand.ty, p.comp);
6900 }
6901 } else {
6902 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6903 operand.val = .{};
6904 }
6905 try operand.un(p, .bit_not_expr);
6906 return operand;
6907 },
6908 .bang => {
6909 p.tok_i += 1;
6910
6911 var operand = try p.castExpr();
6912 try operand.expect(p);
6913 try operand.lvalConversion(p);
6914 if (!operand.ty.isScalar())
6915 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6916
6917 try operand.usualUnaryConversion(p, tok);
6918 if (operand.val.is(.int, p.comp)) {
6919 operand.val = Value.fromBool(!operand.val.toBool(p.comp));
6920 } else if (operand.val.opt_ref == .null) {
6921 operand.val = Value.one;
6922 } else {
6923 if (operand.ty.isDecayed()) {
6924 operand.val = Value.zero;
6925 } else {
6926 operand.val = .{};
6927 }
6928 }
6929 operand.ty = .{ .specifier = .int };
6930 try operand.un(p, .bool_not_expr);
6931 return operand;
6932 },
6933 .keyword_sizeof => {
6934 p.tok_i += 1;
6935 const expected_paren = p.tok_i;
6936 var res = Result{};
6937 if (try p.typeName()) |ty| {
6938 res.ty = ty;
6939 try p.errTok(.expected_parens_around_typename, expected_paren);
6940 } else if (p.eatToken(.l_paren)) |l_paren| {
6941 if (try p.typeName()) |ty| {
6942 res.ty = ty;
6943 try p.expectClosing(l_paren, .r_paren);
6944 } else {
6945 p.tok_i = expected_paren;
6946 res = try p.parseNoEval(unExpr);
6947 }
6948 } else {
6949 res = try p.parseNoEval(unExpr);
6950 }
6951
6952 if (res.ty.is(.void)) {
6953 try p.errStr(.pointer_arith_void, tok, "sizeof");
6954 } else if (res.ty.isDecayed()) {
6955 const array_ty = res.ty.originalTypeOfDecayedArray();
6956 const err_str = try p.typePairStrExtra(res.ty, " instead of ", array_ty);
6957 try p.errStr(.sizeof_array_arg, tok, err_str);
6958 }
6959 if (res.ty.sizeof(p.comp)) |size| {
6960 if (size == 0) {
6961 try p.errTok(.sizeof_returns_zero, tok);
6962 }
6963 res.val = try Value.int(size, p.comp);
6964 res.ty = p.comp.types.size;
6965 } else {
6966 res.val = .{};
6967 if (res.ty.hasIncompleteSize()) {
6968 try p.errStr(.invalid_sizeof, expected_paren - 1, try p.typeStr(res.ty));
6969 res.ty = Type.invalid;
6970 } else {
6971 res.ty = p.comp.types.size;
6972 }
6973 }
6974 try res.un(p, .sizeof_expr);
6975 return res;
6976 },
6977 .keyword_alignof,
6978 .keyword_alignof1,
6979 .keyword_alignof2,
6980 .keyword_c23_alignof,
6981 => {
6982 p.tok_i += 1;
6983 const expected_paren = p.tok_i;
6984 var res = Result{};
6985 if (try p.typeName()) |ty| {
6986 res.ty = ty;
6987 try p.errTok(.expected_parens_around_typename, expected_paren);
6988 } else if (p.eatToken(.l_paren)) |l_paren| {
6989 if (try p.typeName()) |ty| {
6990 res.ty = ty;
6991 try p.expectClosing(l_paren, .r_paren);
6992 } else {
6993 p.tok_i = expected_paren;
6994 res = try p.parseNoEval(unExpr);
6995 try p.errTok(.alignof_expr, expected_paren);
6996 }
6997 } else {
6998 res = try p.parseNoEval(unExpr);
6999 try p.errTok(.alignof_expr, expected_paren);
7000 }
7001
7002 if (res.ty.is(.void)) {
7003 try p.errStr(.pointer_arith_void, tok, "alignof");
7004 }
7005 if (res.ty.alignable()) {
7006 res.val = try Value.int(res.ty.alignof(p.comp), p.comp);
7007 res.ty = p.comp.types.size;
7008 } else {
7009 try p.errStr(.invalid_alignof, expected_paren, try p.typeStr(res.ty));
7010 res.ty = Type.invalid;
7011 }
7012 try res.un(p, .alignof_expr);
7013 return res;
7014 },
7015 .keyword_extension => {
7016 p.tok_i += 1;
7017 const saved_extension = p.extension_suppressed;
7018 defer p.extension_suppressed = saved_extension;
7019 p.extension_suppressed = true;
7020
7021 var child = try p.castExpr();
7022 try child.expect(p);
7023 return child;
7024 },
7025 .keyword_imag1, .keyword_imag2 => {
7026 const imag_tok = p.tok_i;
7027 p.tok_i += 1;
7028
7029 var operand = try p.castExpr();
7030 try operand.expect(p);
7031 try operand.lvalConversion(p);
7032 if (!operand.ty.isInt() and !operand.ty.isFloat()) {
7033 try p.errStr(.invalid_imag, imag_tok, try p.typeStr(operand.ty));
7034 }
7035 if (operand.ty.isReal()) {
7036 switch (p.comp.langopts.emulate) {
7037 .msvc => {}, // Doesn't support `_Complex` or `__imag` in the first place
7038 .gcc => operand.val = Value.zero,
7039 .clang => {
7040 if (operand.val.is(.int, p.comp)) {
7041 operand.val = Value.zero;
7042 } else {
7043 operand.val = .{};
7044 }
7045 },
7046 }
7047 }
7048 // convert _Complex T to T
7049 operand.ty = operand.ty.makeReal();
7050 try operand.un(p, .imag_expr);
7051 return operand;
7052 },
7053 .keyword_real1, .keyword_real2 => {
7054 const real_tok = p.tok_i;
7055 p.tok_i += 1;
7056
7057 var operand = try p.castExpr();
7058 try operand.expect(p);
7059 try operand.lvalConversion(p);
7060 if (!operand.ty.isInt() and !operand.ty.isFloat()) {
7061 try p.errStr(.invalid_real, real_tok, try p.typeStr(operand.ty));
7062 }
7063 // convert _Complex T to T
7064 operand.ty = operand.ty.makeReal();
7065 try operand.un(p, .real_expr);
7066 return operand;
7067 },
7068 else => {
7069 var lhs = try p.compoundLiteral();
7070 if (lhs.empty(p)) {
7071 lhs = try p.primaryExpr();
7072 if (lhs.empty(p)) return lhs;
7073 }
7074 while (true) {
7075 const suffix = try p.suffixExpr(lhs);
7076 if (suffix.empty(p)) break;
7077 lhs = suffix;
7078 }
7079 return lhs;
7080 },
7081 }
7082}
7083
7084/// compoundLiteral
7085/// : '(' storageClassSpec* type_name ')' '{' initializer_list '}'
7086/// | '(' storageClassSpec* type_name ')' '{' initializer_list ',' '}'
7087fn compoundLiteral(p: *Parser) Error!Result {
7088 const l_paren = p.eatToken(.l_paren) orelse return Result{};
7089
7090 var d: DeclSpec = .{ .ty = .{ .specifier = undefined } };
7091 const any = if (p.comp.langopts.standard.atLeast(.c23))
7092 try p.storageClassSpec(&d)
7093 else
7094 false;
7095
7096 const tag: Tree.Tag = switch (d.storage_class) {
7097 .static => if (d.thread_local != null)
7098 .static_thread_local_compound_literal_expr
7099 else
7100 .static_compound_literal_expr,
7101 .register, .none => if (d.thread_local != null)
7102 .thread_local_compound_literal_expr
7103 else
7104 .compound_literal_expr,
7105 .auto, .@"extern", .typedef => |tok| blk: {
7106 try p.errStr(.invalid_compound_literal_storage_class, tok, @tagName(d.storage_class));
7107 d.storage_class = .none;
7108 break :blk if (d.thread_local != null)
7109 .thread_local_compound_literal_expr
7110 else
7111 .compound_literal_expr;
7112 },
7113 };
7114
7115 var ty = (try p.typeName()) orelse {
7116 p.tok_i = l_paren;
7117 if (any) {
7118 try p.err(.expected_type);
7119 return error.ParsingFailed;
7120 }
7121 return Result{};
7122 };
7123 if (d.storage_class == .register) ty.qual.register = true;
7124 try p.expectClosing(l_paren, .r_paren);
7125
7126 if (ty.isFunc()) {
7127 try p.err(.func_init);
7128 } else if (ty.is(.variable_len_array)) {
7129 try p.err(.vla_init);
7130 } else if (ty.hasIncompleteSize() and !ty.is(.incomplete_array)) {
7131 try p.errStr(.variable_incomplete_ty, p.tok_i, try p.typeStr(ty));
7132 return error.ParsingFailed;
7133 }
7134 var init_list_expr = try p.initializer(ty);
7135 if (d.constexpr) |_| {
7136 // TODO error if not constexpr
7137 }
7138 try init_list_expr.un(p, tag);
7139 return init_list_expr;
7140}
7141
7142/// suffixExpr
7143/// : '[' expr ']'
7144/// | '(' argumentExprList? ')'
7145/// | '.' IDENTIFIER
7146/// | '->' IDENTIFIER
7147/// | '++'
7148/// | '--'
7149/// argumentExprList : assignExpr (',' assignExpr)*
7150fn suffixExpr(p: *Parser, lhs: Result) Error!Result {
7151 assert(!lhs.empty(p));
7152 switch (p.tok_ids[p.tok_i]) {
7153 .l_paren => return p.callExpr(lhs),
7154 .plus_plus => {
7155 defer p.tok_i += 1;
7156
7157 var operand = lhs;
7158 if (!operand.ty.isScalar())
7159 try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
7160 if (operand.ty.isComplex())
7161 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
7162
7163 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
7164 try p.err(.not_assignable);
7165 return error.ParsingFailed;
7166 }
7167 try operand.usualUnaryConversion(p, p.tok_i);
7168
7169 try operand.un(p, .post_inc_expr);
7170 return operand;
7171 },
7172 .minus_minus => {
7173 defer p.tok_i += 1;
7174
7175 var operand = lhs;
7176 if (!operand.ty.isScalar())
7177 try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
7178 if (operand.ty.isComplex())
7179 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
7180
7181 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
7182 try p.err(.not_assignable);
7183 return error.ParsingFailed;
7184 }
7185 try operand.usualUnaryConversion(p, p.tok_i);
7186
7187 try operand.un(p, .post_dec_expr);
7188 return operand;
7189 },
7190 .l_bracket => {
7191 const l_bracket = p.tok_i;
7192 p.tok_i += 1;
7193 var index = try p.expr();
7194 try index.expect(p);
7195 try p.expectClosing(l_bracket, .r_bracket);
7196
7197 const array_before_conversion = lhs;
7198 const index_before_conversion = index;
7199 var ptr = lhs;
7200 try ptr.lvalConversion(p);
7201 try index.lvalConversion(p);
7202 if (ptr.ty.isPtr()) {
7203 ptr.ty = ptr.ty.elemType();
7204 if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
7205 try p.checkArrayBounds(index_before_conversion, array_before_conversion, l_bracket);
7206 } else if (index.ty.isPtr()) {
7207 index.ty = index.ty.elemType();
7208 if (!ptr.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
7209 try p.checkArrayBounds(array_before_conversion, index_before_conversion, l_bracket);
7210 std.mem.swap(Result, &ptr, &index);
7211 } else {
7212 try p.errTok(.invalid_subscript, l_bracket);
7213 }
7214
7215 try ptr.saveValue(p);
7216 try index.saveValue(p);
7217 try ptr.bin(p, .array_access_expr, index);
7218 return ptr;
7219 },
7220 .period => {
7221 p.tok_i += 1;
7222 const name = try p.expectIdentifier();
7223 return p.fieldAccess(lhs, name, false);
7224 },
7225 .arrow => {
7226 p.tok_i += 1;
7227 const name = try p.expectIdentifier();
7228 if (lhs.ty.isArray()) {
7229 var copy = lhs;
7230 copy.ty.decayArray();
7231 try copy.implicitCast(p, .array_to_pointer);
7232 return p.fieldAccess(copy, name, true);
7233 }
7234 return p.fieldAccess(lhs, name, true);
7235 },
7236 else => return Result{},
7237 }
7238}
7239
7240fn fieldAccess(
7241 p: *Parser,
7242 lhs: Result,
7243 field_name_tok: TokenIndex,
7244 is_arrow: bool,
7245) !Result {
7246 const expr_ty = lhs.ty;
7247 const is_ptr = expr_ty.isPtr();
7248 const expr_base_ty = if (is_ptr) expr_ty.elemType() else expr_ty;
7249 const record_ty = expr_base_ty.canonicalize(.standard);
7250
7251 switch (record_ty.specifier) {
7252 .@"struct", .@"union" => {},
7253 else => {
7254 try p.errStr(.expected_record_ty, field_name_tok, try p.typeStr(expr_ty));
7255 return error.ParsingFailed;
7256 },
7257 }
7258 if (record_ty.hasIncompleteSize()) {
7259 try p.errStr(.deref_incomplete_ty_ptr, field_name_tok - 2, try p.typeStr(expr_base_ty));
7260 return error.ParsingFailed;
7261 }
7262 if (is_arrow and !is_ptr) try p.errStr(.member_expr_not_ptr, field_name_tok, try p.typeStr(expr_ty));
7263 if (!is_arrow and is_ptr) try p.errStr(.member_expr_ptr, field_name_tok, try p.typeStr(expr_ty));
7264
7265 const field_name = try StrInt.intern(p.comp, p.tokSlice(field_name_tok));
7266 try p.validateFieldAccess(record_ty, expr_ty, field_name_tok, field_name);
7267 var discard: u64 = 0;
7268 return p.fieldAccessExtra(lhs.node, record_ty, field_name, is_arrow, &discard);
7269}
7270
7271fn validateFieldAccess(p: *Parser, record_ty: Type, expr_ty: Type, field_name_tok: TokenIndex, field_name: StringId) Error!void {
7272 if (record_ty.hasField(field_name)) return;
7273
7274 p.strings.items.len = 0;
7275
7276 try p.strings.writer().print("'{s}' in '", .{p.tokSlice(field_name_tok)});
7277 const mapper = p.comp.string_interner.getSlowTypeMapper();
7278 try expr_ty.print(mapper, p.comp.langopts, p.strings.writer());
7279 try p.strings.append('\'');
7280
7281 const duped = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items);
7282 try p.errStr(.no_such_member, field_name_tok, duped);
7283 return error.ParsingFailed;
7284}
7285
7286fn fieldAccessExtra(p: *Parser, lhs: NodeIndex, record_ty: Type, field_name: StringId, is_arrow: bool, offset_bits: *u64) Error!Result {
7287 for (record_ty.data.record.fields, 0..) |f, i| {
7288 if (f.isAnonymousRecord()) {
7289 if (!f.ty.hasField(field_name)) continue;
7290 const inner = try p.addNode(.{
7291 .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
7292 .ty = f.ty,
7293 .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
7294 });
7295 const ret = p.fieldAccessExtra(inner, f.ty, field_name, false, offset_bits);
7296 offset_bits.* = f.layout.offset_bits;
7297 return ret;
7298 }
7299 if (field_name == f.name) {
7300 offset_bits.* = f.layout.offset_bits;
7301 return Result{
7302 .ty = f.ty,
7303 .node = try p.addNode(.{
7304 .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
7305 .ty = f.ty,
7306 .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
7307 }),
7308 };
7309 }
7310 }
7311 // We already checked that this container has a field by the name.
7312 unreachable;
7313}
7314
7315fn checkVaStartArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
7316 assert(idx != 0);
7317 if (idx > 1) {
7318 try p.errTok(.closing_paren, first_after);
7319 return error.ParsingFailed;
7320 }
7321
7322 var func_ty = p.func.ty orelse {
7323 try p.errTok(.va_start_not_in_func, builtin_tok);
7324 return;
7325 };
7326 const func_params = func_ty.params();
7327 if (func_ty.specifier != .var_args_func or func_params.len == 0) {
7328 return p.errTok(.va_start_fixed_args, builtin_tok);
7329 }
7330 const last_param_name = func_params[func_params.len - 1].name;
7331 const decl_ref = p.getNode(arg.node, .decl_ref_expr);
7332 if (decl_ref == null or last_param_name != try StrInt.intern(p.comp, p.tokSlice(p.nodes.items(.data)[@intFromEnum(decl_ref.?)].decl_ref))) {
7333 try p.errTok(.va_start_not_last_param, param_tok);
7334 }
7335}
7336
7337fn checkComplexArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
7338 _ = builtin_tok;
7339 _ = first_after;
7340 if (idx <= 1 and !arg.ty.isFloat()) {
7341 try p.errStr(.not_floating_type, param_tok, try p.typeStr(arg.ty));
7342 } else if (idx == 1) {
7343 const prev_idx = p.list_buf.items[p.list_buf.items.len - 1];
7344 const prev_ty = p.nodes.items(.ty)[@intFromEnum(prev_idx)];
7345 if (!prev_ty.eql(arg.ty, p.comp, false)) {
7346 try p.errStr(.argument_types_differ, param_tok, try p.typePairStrExtra(prev_ty, " vs ", arg.ty));
7347 }
7348 }
7349}
7350
7351fn callExpr(p: *Parser, lhs: Result) Error!Result {
7352 const l_paren = p.tok_i;
7353 p.tok_i += 1;
7354 const ty = lhs.ty.isCallable() orelse {
7355 try p.errStr(.not_callable, l_paren, try p.typeStr(lhs.ty));
7356 return error.ParsingFailed;
7357 };
7358 const params = ty.params();
7359 var func = lhs;
7360 try func.lvalConversion(p);
7361
7362 const list_buf_top = p.list_buf.items.len;
7363 defer p.list_buf.items.len = list_buf_top;
7364 try p.list_buf.append(func.node);
7365 var arg_count: u32 = 0;
7366 var first_after = l_paren;
7367
7368 const call_expr = CallExpr.init(p, lhs.node, func.node);
7369
7370 while (p.eatToken(.r_paren) == null) {
7371 const param_tok = p.tok_i;
7372 if (arg_count == params.len) first_after = p.tok_i;
7373 var arg = try p.assignExpr();
7374 try arg.expect(p);
7375
7376 if (call_expr.shouldPerformLvalConversion(arg_count)) {
7377 try arg.lvalConversion(p);
7378 }
7379 if (arg.ty.hasIncompleteSize() and !arg.ty.is(.void)) return error.ParsingFailed;
7380
7381 if (arg_count >= params.len) {
7382 if (call_expr.shouldPromoteVarArg(arg_count)) {
7383 if (arg.ty.isInt()) try arg.intCast(p, arg.ty.integerPromotion(p.comp), param_tok);
7384 if (arg.ty.is(.float)) try arg.floatCast(p, .{ .specifier = .double });
7385 }
7386 try call_expr.checkVarArg(p, first_after, param_tok, &arg, arg_count);
7387 try arg.saveValue(p);
7388 try p.list_buf.append(arg.node);
7389 arg_count += 1;
7390
7391 _ = p.eatToken(.comma) orelse {
7392 try p.expectClosing(l_paren, .r_paren);
7393 break;
7394 };
7395 continue;
7396 }
7397 const p_ty = params[arg_count].ty;
7398 if (call_expr.shouldCoerceArg(arg_count)) {
7399 try arg.coerce(p, p_ty, param_tok, .{ .arg = params[arg_count].name_tok });
7400 }
7401 try arg.saveValue(p);
7402 try p.list_buf.append(arg.node);
7403 arg_count += 1;
7404
7405 _ = p.eatToken(.comma) orelse {
7406 try p.expectClosing(l_paren, .r_paren);
7407 break;
7408 };
7409 }
7410
7411 const actual: u32 = @intCast(arg_count);
7412 const extra = Diagnostics.Message.Extra{ .arguments = .{
7413 .expected = @intCast(params.len),
7414 .actual = actual,
7415 } };
7416 if (call_expr.paramCountOverride()) |expected| {
7417 if (expected != actual) {
7418 try p.errExtra(.expected_arguments, first_after, .{ .arguments = .{ .expected = expected, .actual = actual } });
7419 }
7420 } else if (ty.is(.func) and params.len != arg_count) {
7421 try p.errExtra(.expected_arguments, first_after, extra);
7422 } else if (ty.is(.old_style_func) and params.len != arg_count) {
7423 if (params.len == 0)
7424 try p.errTok(.passing_args_to_kr, first_after)
7425 else
7426 try p.errExtra(.expected_arguments_old, first_after, extra);
7427 } else if (ty.is(.var_args_func) and arg_count < params.len) {
7428 try p.errExtra(.expected_at_least_arguments, first_after, extra);
7429 }
7430
7431 return call_expr.finish(p, ty, list_buf_top, arg_count);
7432}
7433
7434fn checkArrayBounds(p: *Parser, index: Result, array: Result, tok: TokenIndex) !void {
7435 if (index.val.opt_ref == .none) return;
7436
7437 const array_len = array.ty.arrayLen() orelse return;
7438 if (array_len == 0) return;
7439
7440 if (array_len == 1) {
7441 if (p.getNode(array.node, .member_access_expr) orelse p.getNode(array.node, .member_access_ptr_expr)) |node| {
7442 const data = p.nodes.items(.data)[@intFromEnum(node)];
7443 var lhs = p.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
7444 if (lhs.get(.pointer)) |ptr| {
7445 lhs = ptr.data.sub_type.*;
7446 }
7447 if (lhs.is(.@"struct")) {
7448 const record = lhs.getRecord().?;
7449 if (data.member.index + 1 == record.fields.len) {
7450 if (!index.val.isZero(p.comp)) {
7451 try p.errStr(.old_style_flexible_struct, tok, try index.str(p));
7452 }
7453 return;
7454 }
7455 }
7456 }
7457 }
7458 const index_int = index.val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
7459 if (index.ty.isUnsignedInt(p.comp)) {
7460 if (index_int >= array_len) {
7461 try p.errStr(.array_after, tok, try index.str(p));
7462 }
7463 } else {
7464 if (index.val.compare(.lt, Value.zero, p.comp)) {
7465 try p.errStr(.array_before, tok, try index.str(p));
7466 } else if (index_int >= array_len) {
7467 try p.errStr(.array_after, tok, try index.str(p));
7468 }
7469 }
7470}
7471
7472/// primaryExpr
7473/// : IDENTIFIER
7474/// | keyword_true
7475/// | keyword_false
7476/// | keyword_nullptr
7477/// | INTEGER_LITERAL
7478/// | FLOAT_LITERAL
7479/// | IMAGINARY_LITERAL
7480/// | CHAR_LITERAL
7481/// | STRING_LITERAL
7482/// | '(' expr ')'
7483/// | genericSelection
7484fn primaryExpr(p: *Parser) Error!Result {
7485 if (p.eatToken(.l_paren)) |l_paren| {
7486 var e = try p.expr();
7487 try e.expect(p);
7488 try p.expectClosing(l_paren, .r_paren);
7489 try e.un(p, .paren_expr);
7490 return e;
7491 }
7492 switch (p.tok_ids[p.tok_i]) {
7493 .identifier, .extended_identifier => {
7494 const name_tok = try p.expectIdentifier();
7495 const name = p.tokSlice(name_tok);
7496 const interned_name = try StrInt.intern(p.comp, name);
7497 if (p.syms.findSymbol(interned_name)) |sym| {
7498 try p.checkDeprecatedUnavailable(sym.ty, name_tok, sym.tok);
7499 if (sym.kind == .constexpr) {
7500 return Result{
7501 .val = sym.val,
7502 .ty = sym.ty,
7503 .node = try p.addNode(.{
7504 .tag = .decl_ref_expr,
7505 .ty = sym.ty,
7506 .data = .{ .decl_ref = name_tok },
7507 }),
7508 };
7509 }
7510 if (sym.val.is(.int, p.comp)) {
7511 switch (p.const_decl_folding) {
7512 .gnu_folding_extension => try p.errTok(.const_decl_folded, name_tok),
7513 .gnu_vla_folding_extension => try p.errTok(.const_decl_folded_vla, name_tok),
7514 else => {},
7515 }
7516 }
7517 return Result{
7518 .val = if (p.const_decl_folding == .no_const_decl_folding and sym.kind != .enumeration) Value{} else sym.val,
7519 .ty = sym.ty,
7520 .node = try p.addNode(.{
7521 .tag = if (sym.kind == .enumeration) .enumeration_ref else .decl_ref_expr,
7522 .ty = sym.ty,
7523 .data = .{ .decl_ref = name_tok },
7524 }),
7525 };
7526 }
7527 if (try p.comp.builtins.getOrCreate(p.comp, name, p.arena)) |some| {
7528 for (p.tok_ids[p.tok_i..]) |id| switch (id) {
7529 .r_paren => {}, // closing grouped expr
7530 .l_paren => break, // beginning of a call
7531 else => {
7532 try p.errTok(.builtin_must_be_called, name_tok);
7533 return error.ParsingFailed;
7534 },
7535 };
7536 if (some.builtin.properties.header != .none) {
7537 try p.errStr(.implicit_builtin, name_tok, name);
7538 try p.errExtra(.implicit_builtin_header_note, name_tok, .{ .builtin_with_header = .{
7539 .builtin = some.builtin.tag,
7540 .header = some.builtin.properties.header,
7541 } });
7542 }
7543
7544 return Result{
7545 .ty = some.ty,
7546 .node = try p.addNode(.{
7547 .tag = .builtin_call_expr_one,
7548 .ty = some.ty,
7549 .data = .{ .decl = .{ .name = name_tok, .node = .none } },
7550 }),
7551 };
7552 }
7553 if (p.tok_ids[p.tok_i] == .l_paren and !p.comp.langopts.standard.atLeast(.c23)) {
7554 // allow implicitly declaring functions before C99 like `puts("foo")`
7555 if (mem.startsWith(u8, name, "__builtin_"))
7556 try p.errStr(.unknown_builtin, name_tok, name)
7557 else
7558 try p.errStr(.implicit_func_decl, name_tok, name);
7559
7560 const func_ty = try p.arena.create(Type.Func);
7561 func_ty.* = .{ .return_type = .{ .specifier = .int }, .params = &.{} };
7562 const ty: Type = .{ .specifier = .old_style_func, .data = .{ .func = func_ty } };
7563 const node = try p.addNode(.{
7564 .ty = ty,
7565 .tag = .fn_proto,
7566 .data = .{ .decl = .{ .name = name_tok } },
7567 });
7568
7569 try p.decl_buf.append(node);
7570 try p.syms.declareSymbol(p, interned_name, ty, name_tok, node);
7571
7572 return Result{
7573 .ty = ty,
7574 .node = try p.addNode(.{
7575 .tag = .decl_ref_expr,
7576 .ty = ty,
7577 .data = .{ .decl_ref = name_tok },
7578 }),
7579 };
7580 }
7581 try p.errStr(.undeclared_identifier, name_tok, p.tokSlice(name_tok));
7582 return error.ParsingFailed;
7583 },
7584 .keyword_true, .keyword_false => |id| {
7585 p.tok_i += 1;
7586 const res = Result{
7587 .val = Value.fromBool(id == .keyword_true),
7588 .ty = .{ .specifier = .bool },
7589 .node = try p.addNode(.{ .tag = .bool_literal, .ty = .{ .specifier = .bool }, .data = undefined }),
7590 };
7591 std.debug.assert(!p.in_macro); // Should have been replaced with .one / .zero
7592 try p.value_map.put(res.node, res.val);
7593 return res;
7594 },
7595 .keyword_nullptr => {
7596 defer p.tok_i += 1;
7597 try p.errStr(.pre_c23_compat, p.tok_i, "'nullptr'");
7598 return Result{
7599 .val = Value.null,
7600 .ty = .{ .specifier = .nullptr_t },
7601 .node = try p.addNode(.{
7602 .tag = .nullptr_literal,
7603 .ty = .{ .specifier = .nullptr_t },
7604 .data = undefined,
7605 }),
7606 };
7607 },
7608 .macro_func, .macro_function => {
7609 defer p.tok_i += 1;
7610 var ty: Type = undefined;
7611 var tok = p.tok_i;
7612 if (p.func.ident) |some| {
7613 ty = some.ty;
7614 tok = p.nodes.items(.data)[@intFromEnum(some.node)].decl.name;
7615 } else if (p.func.ty) |_| {
7616 const strings_top = p.strings.items.len;
7617 defer p.strings.items.len = strings_top;
7618
7619 try p.strings.appendSlice(p.tokSlice(p.func.name));
7620 try p.strings.append(0);
7621 const predef = try p.makePredefinedIdentifier(strings_top);
7622 ty = predef.ty;
7623 p.func.ident = predef;
7624 } else {
7625 const strings_top = p.strings.items.len;
7626 defer p.strings.items.len = strings_top;
7627
7628 try p.strings.append(0);
7629 const predef = try p.makePredefinedIdentifier(strings_top);
7630 ty = predef.ty;
7631 p.func.ident = predef;
7632 try p.decl_buf.append(predef.node);
7633 }
7634 if (p.func.ty == null) try p.err(.predefined_top_level);
7635 return Result{
7636 .ty = ty,
7637 .node = try p.addNode(.{
7638 .tag = .decl_ref_expr,
7639 .ty = ty,
7640 .data = .{ .decl_ref = tok },
7641 }),
7642 };
7643 },
7644 .macro_pretty_func => {
7645 defer p.tok_i += 1;
7646 var ty: Type = undefined;
7647 if (p.func.pretty_ident) |some| {
7648 ty = some.ty;
7649 } else if (p.func.ty) |func_ty| {
7650 const strings_top = p.strings.items.len;
7651 defer p.strings.items.len = strings_top;
7652
7653 const mapper = p.comp.string_interner.getSlowTypeMapper();
7654 try Type.printNamed(func_ty, p.tokSlice(p.func.name), mapper, p.comp.langopts, p.strings.writer());
7655 try p.strings.append(0);
7656 const predef = try p.makePredefinedIdentifier(strings_top);
7657 ty = predef.ty;
7658 p.func.pretty_ident = predef;
7659 } else {
7660 const strings_top = p.strings.items.len;
7661 defer p.strings.items.len = strings_top;
7662
7663 try p.strings.appendSlice("top level\x00");
7664 const predef = try p.makePredefinedIdentifier(strings_top);
7665 ty = predef.ty;
7666 p.func.pretty_ident = predef;
7667 try p.decl_buf.append(predef.node);
7668 }
7669 if (p.func.ty == null) try p.err(.predefined_top_level);
7670 return Result{
7671 .ty = ty,
7672 .node = try p.addNode(.{
7673 .tag = .decl_ref_expr,
7674 .ty = ty,
7675 .data = .{ .decl_ref = p.tok_i },
7676 }),
7677 };
7678 },
7679 .string_literal,
7680 .string_literal_utf_16,
7681 .string_literal_utf_8,
7682 .string_literal_utf_32,
7683 .string_literal_wide,
7684 .unterminated_string_literal,
7685 => return p.stringLiteral(),
7686 .char_literal,
7687 .char_literal_utf_8,
7688 .char_literal_utf_16,
7689 .char_literal_utf_32,
7690 .char_literal_wide,
7691 .empty_char_literal,
7692 .unterminated_char_literal,
7693 => return p.charLiteral(),
7694 .zero => {
7695 p.tok_i += 1;
7696 var res: Result = .{ .val = Value.zero, .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
7697 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
7698 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7699 return res;
7700 },
7701 .one => {
7702 p.tok_i += 1;
7703 var res: Result = .{ .val = Value.one, .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
7704 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
7705 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7706 return res;
7707 },
7708 .pp_num => return p.ppNum(),
7709 .embed_byte => {
7710 assert(!p.in_macro);
7711 const loc = p.pp.tokens.items(.loc)[p.tok_i];
7712 p.tok_i += 1;
7713 const buf = p.comp.getSource(.generated).buf[loc.byte_offset..];
7714 var byte: u8 = buf[0] - '0';
7715 for (buf[1..]) |c| {
7716 if (!std.ascii.isDigit(c)) break;
7717 byte *= 10;
7718 byte += c - '0';
7719 }
7720 var res: Result = .{ .val = try Value.int(byte, p.comp) };
7721 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
7722 try p.value_map.put(res.node, res.val);
7723 return res;
7724 },
7725 .keyword_generic => return p.genericSelection(),
7726 else => return Result{},
7727 }
7728}
7729
7730fn makePredefinedIdentifier(p: *Parser, strings_top: usize) !Result {
7731 const end: u32 = @intCast(p.strings.items.len);
7732 const elem_ty = .{ .specifier = .char, .qual = .{ .@"const" = true } };
7733 const arr_ty = try p.arena.create(Type.Array);
7734 arr_ty.* = .{ .elem = elem_ty, .len = end - strings_top };
7735 const ty: Type = .{ .specifier = .array, .data = .{ .array = arr_ty } };
7736
7737 const slice = p.strings.items[strings_top..];
7738 const val = try Value.intern(p.comp, .{ .bytes = slice });
7739
7740 const str_lit = try p.addNode(.{ .tag = .string_literal_expr, .ty = ty, .data = undefined });
7741 if (!p.in_macro) try p.value_map.put(str_lit, val);
7742
7743 return Result{ .ty = ty, .node = try p.addNode(.{
7744 .tag = .implicit_static_var,
7745 .ty = ty,
7746 .data = .{ .decl = .{ .name = p.tok_i, .node = str_lit } },
7747 }) };
7748}
7749
7750fn stringLiteral(p: *Parser) Error!Result {
7751 var string_end = p.tok_i;
7752 var string_kind: text_literal.Kind = .char;
7753 while (text_literal.Kind.classify(p.tok_ids[string_end], .string_literal)) |next| : (string_end += 1) {
7754 string_kind = string_kind.concat(next) catch {
7755 try p.errTok(.unsupported_str_cat, string_end);
7756 while (p.tok_ids[p.tok_i].isStringLiteral()) : (p.tok_i += 1) {}
7757 return error.ParsingFailed;
7758 };
7759 if (string_kind == .unterminated) {
7760 try p.errTok(.unterminated_string_literal_error, string_end);
7761 p.tok_i = string_end + 1;
7762 return error.ParsingFailed;
7763 }
7764 }
7765 assert(string_end > p.tok_i);
7766
7767 const char_width = string_kind.charUnitSize(p.comp);
7768
7769 const strings_top = p.strings.items.len;
7770 defer p.strings.items.len = strings_top;
7771
7772 while (p.tok_i < string_end) : (p.tok_i += 1) {
7773 const this_kind = text_literal.Kind.classify(p.tok_ids[p.tok_i], .string_literal).?;
7774 const slice = this_kind.contentSlice(p.tokSlice(p.tok_i));
7775 var char_literal_parser = text_literal.Parser.init(slice, this_kind, 0x10ffff, p.comp);
7776
7777 try p.strings.ensureUnusedCapacity((slice.len + 1) * @intFromEnum(char_width)); // +1 for null terminator
7778 while (char_literal_parser.next()) |item| switch (item) {
7779 .value => |v| {
7780 switch (char_width) {
7781 .@"1" => p.strings.appendAssumeCapacity(@intCast(v)),
7782 .@"2" => {
7783 const word: u16 = @intCast(v);
7784 p.strings.appendSliceAssumeCapacity(mem.asBytes(&word));
7785 },
7786 .@"4" => p.strings.appendSliceAssumeCapacity(mem.asBytes(&v)),
7787 }
7788 },
7789 .codepoint => |c| {
7790 switch (char_width) {
7791 .@"1" => {
7792 var buf: [4]u8 = undefined;
7793 const written = std.unicode.utf8Encode(c, &buf) catch unreachable;
7794 const encoded = buf[0..written];
7795 p.strings.appendSliceAssumeCapacity(encoded);
7796 },
7797 .@"2" => {
7798 var utf16_buf: [2]u16 = undefined;
7799 var utf8_buf: [4]u8 = undefined;
7800 const utf8_written = std.unicode.utf8Encode(c, &utf8_buf) catch unreachable;
7801 const utf16_written = std.unicode.utf8ToUtf16Le(&utf16_buf, utf8_buf[0..utf8_written]) catch unreachable;
7802 const bytes = std.mem.sliceAsBytes(utf16_buf[0..utf16_written]);
7803 p.strings.appendSliceAssumeCapacity(bytes);
7804 },
7805 .@"4" => {
7806 const val: u32 = c;
7807 p.strings.appendSliceAssumeCapacity(mem.asBytes(&val));
7808 },
7809 }
7810 },
7811 .improperly_encoded => |bytes| p.strings.appendSliceAssumeCapacity(bytes),
7812 .utf8_text => |view| {
7813 switch (char_width) {
7814 .@"1" => p.strings.appendSliceAssumeCapacity(view.bytes),
7815 .@"2" => {
7816 const capacity_slice: []align(@alignOf(u16)) u8 = @alignCast(p.strings.unusedCapacitySlice());
7817 const dest_len = std.mem.alignBackward(usize, capacity_slice.len, 2);
7818 const dest = std.mem.bytesAsSlice(u16, capacity_slice[0..dest_len]);
7819 const words_written = std.unicode.utf8ToUtf16Le(dest, view.bytes) catch unreachable;
7820 p.strings.resize(p.strings.items.len + words_written * 2) catch unreachable;
7821 },
7822 .@"4" => {
7823 var it = view.iterator();
7824 while (it.nextCodepoint()) |codepoint| {
7825 const val: u32 = codepoint;
7826 p.strings.appendSliceAssumeCapacity(mem.asBytes(&val));
7827 }
7828 },
7829 }
7830 },
7831 };
7832 for (char_literal_parser.errors()) |item| {
7833 try p.errExtra(item.tag, p.tok_i, item.extra);
7834 }
7835 }
7836 p.strings.appendNTimesAssumeCapacity(0, @intFromEnum(char_width));
7837 const slice = p.strings.items[strings_top..];
7838
7839 // TODO this won't do anything if there is a cache hit
7840 const interned_align = mem.alignForward(
7841 usize,
7842 p.comp.interner.strings.items.len,
7843 string_kind.internalStorageAlignment(p.comp),
7844 );
7845 try p.comp.interner.strings.resize(p.gpa, interned_align);
7846
7847 const val = try Value.intern(p.comp, .{ .bytes = slice });
7848
7849 const arr_ty = try p.arena.create(Type.Array);
7850 arr_ty.* = .{ .elem = string_kind.elementType(p.comp), .len = @divExact(slice.len, @intFromEnum(char_width)) };
7851 var res: Result = .{
7852 .ty = .{
7853 .specifier = .array,
7854 .data = .{ .array = arr_ty },
7855 },
7856 .val = val,
7857 };
7858 res.node = try p.addNode(.{ .tag = .string_literal_expr, .ty = res.ty, .data = undefined });
7859 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7860 return res;
7861}
7862
7863fn charLiteral(p: *Parser) Error!Result {
7864 defer p.tok_i += 1;
7865 const tok_id = p.tok_ids[p.tok_i];
7866 const char_kind = text_literal.Kind.classify(tok_id, .char_literal) orelse {
7867 if (tok_id == .empty_char_literal) {
7868 try p.err(.empty_char_literal_error);
7869 } else if (tok_id == .unterminated_char_literal) {
7870 try p.err(.unterminated_char_literal_error);
7871 } else unreachable;
7872 return .{
7873 .ty = Type.int,
7874 .val = Value.zero,
7875 .node = try p.addNode(.{ .tag = .char_literal, .ty = Type.int, .data = undefined }),
7876 };
7877 };
7878 if (char_kind == .utf_8) try p.err(.u8_char_lit);
7879 var val: u32 = 0;
7880
7881 const slice = char_kind.contentSlice(p.tokSlice(p.tok_i));
7882
7883 if (slice.len == 1 and std.ascii.isASCII(slice[0])) {
7884 // fast path: single unescaped ASCII char
7885 val = slice[0];
7886 } else {
7887 const max_codepoint = char_kind.maxCodepoint(p.comp);
7888 var char_literal_parser = text_literal.Parser.init(slice, char_kind, max_codepoint, p.comp);
7889
7890 const max_chars_expected = 4;
7891 var stack_fallback = std.heap.stackFallback(max_chars_expected * @sizeOf(u32), p.comp.gpa);
7892 var chars = std.ArrayList(u32).initCapacity(stack_fallback.get(), max_chars_expected) catch unreachable; // stack allocation already succeeded
7893 defer chars.deinit();
7894
7895 while (char_literal_parser.next()) |item| switch (item) {
7896 .value => |v| try chars.append(v),
7897 .codepoint => |c| try chars.append(c),
7898 .improperly_encoded => |s| {
7899 try chars.ensureUnusedCapacity(s.len);
7900 for (s) |c| chars.appendAssumeCapacity(c);
7901 },
7902 .utf8_text => |view| {
7903 var it = view.iterator();
7904 var max_codepoint_seen: u21 = 0;
7905 try chars.ensureUnusedCapacity(view.bytes.len);
7906 while (it.nextCodepoint()) |c| {
7907 max_codepoint_seen = @max(max_codepoint_seen, c);
7908 chars.appendAssumeCapacity(c);
7909 }
7910 if (max_codepoint_seen > max_codepoint) {
7911 char_literal_parser.err(.char_too_large, .{ .none = {} });
7912 }
7913 },
7914 };
7915
7916 const is_multichar = chars.items.len > 1;
7917 if (is_multichar) {
7918 if (char_kind == .char and chars.items.len == 4) {
7919 char_literal_parser.warn(.four_char_char_literal, .{ .none = {} });
7920 } else if (char_kind == .char) {
7921 char_literal_parser.warn(.multichar_literal_warning, .{ .none = {} });
7922 } else {
7923 const kind = switch (char_kind) {
7924 .wide => "wide",
7925 .utf_8, .utf_16, .utf_32 => "Unicode",
7926 else => unreachable,
7927 };
7928 char_literal_parser.err(.invalid_multichar_literal, .{ .str = kind });
7929 }
7930 }
7931
7932 var multichar_overflow = false;
7933 if (char_kind == .char and is_multichar) {
7934 for (chars.items) |item| {
7935 val, const overflowed = @shlWithOverflow(val, 8);
7936 multichar_overflow = multichar_overflow or overflowed != 0;
7937 val += @as(u8, @truncate(item));
7938 }
7939 } else if (chars.items.len > 0) {
7940 val = chars.items[chars.items.len - 1];
7941 }
7942
7943 if (multichar_overflow) {
7944 char_literal_parser.err(.char_lit_too_wide, .{ .none = {} });
7945 }
7946
7947 for (char_literal_parser.errors()) |item| {
7948 try p.errExtra(item.tag, p.tok_i, item.extra);
7949 }
7950 }
7951
7952 const ty = char_kind.charLiteralType(p.comp);
7953 // This is the type the literal will have if we're in a macro; macros always operate on intmax_t/uintmax_t values
7954 const macro_ty = if (ty.isUnsignedInt(p.comp) or (char_kind == .char and p.comp.getCharSignedness() == .unsigned))
7955 p.comp.types.intmax.makeIntegerUnsigned()
7956 else
7957 p.comp.types.intmax;
7958
7959 const res = Result{
7960 .ty = if (p.in_macro) macro_ty else ty,
7961 .val = try Value.int(val, p.comp),
7962 .node = try p.addNode(.{ .tag = .char_literal, .ty = ty, .data = undefined }),
7963 };
7964 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7965 return res;
7966}
7967
7968fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
7969 const ty = Type{ .specifier = switch (suffix) {
7970 .None, .I => .double,
7971 .F, .IF => .float,
7972 .F16 => .float16,
7973 .L, .IL => .long_double,
7974 .W, .IW => .float80,
7975 .Q, .IQ, .F128, .IF128 => .float128,
7976 else => unreachable,
7977 } };
7978 const val = try Value.intern(p.comp, key: {
7979 try p.strings.ensureUnusedCapacity(buf.len);
7980
7981 const strings_top = p.strings.items.len;
7982 defer p.strings.items.len = strings_top;
7983 for (buf) |c| {
7984 if (c != '\'') p.strings.appendAssumeCapacity(c);
7985 }
7986
7987 const float = std.fmt.parseFloat(f128, p.strings.items[strings_top..]) catch unreachable;
7988 const bits = ty.bitSizeof(p.comp).?;
7989 break :key switch (bits) {
7990 16 => .{ .float = .{ .f16 = @floatCast(float) } },
7991 32 => .{ .float = .{ .f32 = @floatCast(float) } },
7992 64 => .{ .float = .{ .f64 = @floatCast(float) } },
7993 80 => .{ .float = .{ .f80 = @floatCast(float) } },
7994 128 => .{ .float = .{ .f128 = @floatCast(float) } },
7995 else => unreachable,
7996 };
7997 });
7998 var res = Result{
7999 .ty = ty,
8000 .node = try p.addNode(.{ .tag = .float_literal, .ty = ty, .data = undefined }),
8001 .val = val,
8002 };
8003 if (suffix.isImaginary()) {
8004 try p.err(.gnu_imaginary_constant);
8005 res.ty = .{ .specifier = switch (suffix) {
8006 .I => .complex_double,
8007 .IF => .complex_float,
8008 .IL => .complex_long_double,
8009 .IW => .complex_float80,
8010 .IQ, .IF128 => .complex_float128,
8011 else => unreachable,
8012 } };
8013 res.val = .{}; // TODO add complex values
8014 try res.un(p, .imaginary_literal);
8015 }
8016 return res;
8017}
8018
8019fn getIntegerPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
8020 if (buf[0] == '.') return "";
8021
8022 if (!prefix.digitAllowed(buf[0])) {
8023 switch (prefix) {
8024 .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
8025 .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
8026 .hex => try p.errStr(.invalid_int_suffix, tok_i, buf),
8027 .decimal => unreachable,
8028 }
8029 return error.ParsingFailed;
8030 }
8031
8032 for (buf, 0..) |c, idx| {
8033 if (idx == 0) continue;
8034 switch (c) {
8035 '.' => return buf[0..idx],
8036 'p', 'P' => return if (prefix == .hex) buf[0..idx] else {
8037 try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]);
8038 return error.ParsingFailed;
8039 },
8040 'e', 'E' => {
8041 switch (prefix) {
8042 .hex => continue,
8043 .decimal => return buf[0..idx],
8044 .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
8045 .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
8046 }
8047 return error.ParsingFailed;
8048 },
8049 '0'...'9', 'a'...'d', 'A'...'D', 'f', 'F' => {
8050 if (!prefix.digitAllowed(c)) {
8051 switch (prefix) {
8052 .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
8053 .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
8054 .decimal, .hex => try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]),
8055 }
8056 return error.ParsingFailed;
8057 }
8058 },
8059 '\'' => {},
8060 else => return buf[0..idx],
8061 }
8062 }
8063 return buf;
8064}
8065
8066fn fixedSizeInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
8067 var val: u64 = 0;
8068 var overflow = false;
8069 for (buf) |c| {
8070 const digit: u64 = switch (c) {
8071 '0'...'9' => c - '0',
8072 'A'...'Z' => c - 'A' + 10,
8073 'a'...'z' => c - 'a' + 10,
8074 '\'' => continue,
8075 else => unreachable,
8076 };
8077
8078 if (val != 0) {
8079 const product, const overflowed = @mulWithOverflow(val, base);
8080 if (overflowed != 0) {
8081 overflow = true;
8082 }
8083 val = product;
8084 }
8085 const sum, const overflowed = @addWithOverflow(val, digit);
8086 if (overflowed != 0) overflow = true;
8087 val = sum;
8088 }
8089 var res: Result = .{ .val = try Value.int(val, p.comp) };
8090 if (overflow) {
8091 try p.errTok(.int_literal_too_big, tok_i);
8092 res.ty = .{ .specifier = .ulong_long };
8093 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
8094 if (!p.in_macro) try p.value_map.put(res.node, res.val);
8095 return res;
8096 }
8097 if (suffix.isSignedInteger()) {
8098 if (val > p.comp.types.intmax.maxInt(p.comp)) {
8099 try p.errTok(.implicitly_unsigned_literal, tok_i);
8100 }
8101 }
8102
8103 const signed_specs = .{ .int, .long, .long_long };
8104 const unsigned_specs = .{ .uint, .ulong, .ulong_long };
8105 const signed_oct_hex_specs = .{ .int, .uint, .long, .ulong, .long_long, .ulong_long };
8106 const specs: []const Type.Specifier = if (suffix.signedness() == .unsigned)
8107 &unsigned_specs
8108 else if (base == 10)
8109 &signed_specs
8110 else
8111 &signed_oct_hex_specs;
8112
8113 const suffix_ty: Type = .{ .specifier = switch (suffix) {
8114 .None, .I => .int,
8115 .U, .IU => .uint,
8116 .UL, .IUL => .ulong,
8117 .ULL, .IULL => .ulong_long,
8118 .L, .IL => .long,
8119 .LL, .ILL => .long_long,
8120 else => unreachable,
8121 } };
8122
8123 for (specs) |spec| {
8124 res.ty = Type{ .specifier = spec };
8125 if (res.ty.compareIntegerRanks(suffix_ty, p.comp).compare(.lt)) continue;
8126 const max_int = res.ty.maxInt(p.comp);
8127 if (val <= max_int) break;
8128 } else {
8129 res.ty = .{ .specifier = .ulong_long };
8130 }
8131
8132 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
8133 if (!p.in_macro) try p.value_map.put(res.node, res.val);
8134 return res;
8135}
8136
8137fn parseInt(p: *Parser, prefix: NumberPrefix, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
8138 if (prefix == .binary) {
8139 try p.errTok(.binary_integer_literal, tok_i);
8140 }
8141 const base = @intFromEnum(prefix);
8142 var res = if (suffix.isBitInt())
8143 try p.bitInt(base, buf, suffix, tok_i)
8144 else
8145 try p.fixedSizeInt(base, buf, suffix, tok_i);
8146
8147 if (suffix.isImaginary()) {
8148 try p.errTok(.gnu_imaginary_constant, tok_i);
8149 res.ty = res.ty.makeComplex();
8150 res.val = .{};
8151 try res.un(p, .imaginary_literal);
8152 }
8153 return res;
8154}
8155
8156fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) Error!Result {
8157 try p.errStr(.pre_c23_compat, tok_i, "'_BitInt' suffix for literals");
8158 try p.errTok(.bitint_suffix, tok_i);
8159
8160 var managed = try big.int.Managed.init(p.gpa);
8161 defer managed.deinit();
8162
8163 {
8164 try p.strings.ensureUnusedCapacity(buf.len);
8165
8166 const strings_top = p.strings.items.len;
8167 defer p.strings.items.len = strings_top;
8168 for (buf) |c| {
8169 if (c != '\'') p.strings.appendAssumeCapacity(c);
8170 }
8171
8172 managed.setString(base, p.strings.items[strings_top..]) catch |e| switch (e) {
8173 error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16
8174 error.InvalidCharacter => unreachable, // digits validated by Tokenizer
8175 else => |er| return er,
8176 };
8177 }
8178 const c = managed.toConst();
8179 const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: {
8180 // Literal `0` requires at least 1 bit
8181 const count = @max(1, c.bitCountTwosComp());
8182 // The wb suffix results in a _BitInt that includes space for the sign bit even if the
8183 // value of the constant is positive or was specified in hexadecimal or octal notation.
8184 const sign_bits = @intFromBool(suffix.isSignedInteger());
8185 const bits_needed = count + sign_bits;
8186 if (bits_needed > Compilation.bit_int_max_bits) {
8187 const specifier: Type.Builder.Specifier = switch (suffix) {
8188 .WB => .{ .bit_int = 0 },
8189 .UWB => .{ .ubit_int = 0 },
8190 .IWB => .{ .complex_bit_int = 0 },
8191 .IUWB => .{ .complex_ubit_int = 0 },
8192 else => unreachable,
8193 };
8194 try p.errStr(.bit_int_too_big, tok_i, specifier.str(p.comp.langopts).?);
8195 return error.ParsingFailed;
8196 }
8197 break :blk @intCast(bits_needed);
8198 };
8199
8200 var res: Result = .{
8201 .val = try Value.intern(p.comp, .{ .int = .{ .big_int = c } }),
8202 .ty = .{
8203 .specifier = .bit_int,
8204 .data = .{ .int = .{ .bits = bits_needed, .signedness = suffix.signedness() } },
8205 },
8206 };
8207 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
8208 if (!p.in_macro) try p.value_map.put(res.node, res.val);
8209 return res;
8210}
8211
8212fn getFracPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
8213 if (buf.len == 0 or buf[0] != '.') return "";
8214 assert(prefix != .octal);
8215 if (prefix == .binary) {
8216 try p.errStr(.invalid_int_suffix, tok_i, buf);
8217 return error.ParsingFailed;
8218 }
8219 for (buf, 0..) |c, idx| {
8220 if (idx == 0) continue;
8221 if (c == '\'') continue;
8222 if (!prefix.digitAllowed(c)) return buf[0..idx];
8223 }
8224 return buf;
8225}
8226
8227fn getExponent(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
8228 if (buf.len == 0) return "";
8229
8230 switch (buf[0]) {
8231 'e', 'E' => assert(prefix == .decimal),
8232 'p', 'P' => if (prefix != .hex) {
8233 try p.errStr(.invalid_float_suffix, tok_i, buf);
8234 return error.ParsingFailed;
8235 },
8236 else => return "",
8237 }
8238 const end = for (buf, 0..) |c, idx| {
8239 if (idx == 0) continue;
8240 if (idx == 1 and (c == '+' or c == '-')) continue;
8241 switch (c) {
8242 '0'...'9' => {},
8243 '\'' => continue,
8244 else => break idx,
8245 }
8246 } else buf.len;
8247 const exponent = buf[0..end];
8248 if (std.mem.indexOfAny(u8, exponent, "0123456789") == null) {
8249 try p.errTok(.exponent_has_no_digits, tok_i);
8250 return error.ParsingFailed;
8251 }
8252 return exponent;
8253}
8254
8255/// Using an explicit `tok_i` parameter instead of `p.tok_i` makes it easier
8256/// to parse numbers in pragma handlers.
8257pub fn parseNumberToken(p: *Parser, tok_i: TokenIndex) !Result {
8258 const buf = p.tokSlice(tok_i);
8259 const prefix = NumberPrefix.fromString(buf);
8260 const after_prefix = buf[prefix.stringLen()..];
8261
8262 const int_part = try p.getIntegerPart(after_prefix, prefix, tok_i);
8263
8264 const after_int = after_prefix[int_part.len..];
8265
8266 const frac = try p.getFracPart(after_int, prefix, tok_i);
8267 const after_frac = after_int[frac.len..];
8268
8269 const exponent = try p.getExponent(after_frac, prefix, tok_i);
8270 const suffix_str = after_frac[exponent.len..];
8271 const is_float = (exponent.len > 0 or frac.len > 0);
8272 const suffix = NumberSuffix.fromString(suffix_str, if (is_float) .float else .int) orelse {
8273 if (is_float) {
8274 try p.errStr(.invalid_float_suffix, tok_i, suffix_str);
8275 } else {
8276 try p.errStr(.invalid_int_suffix, tok_i, suffix_str);
8277 }
8278 return error.ParsingFailed;
8279 };
8280
8281 if (is_float) {
8282 assert(prefix == .hex or prefix == .decimal);
8283 if (prefix == .hex and exponent.len == 0) {
8284 try p.errTok(.hex_floating_constant_requires_exponent, tok_i);
8285 return error.ParsingFailed;
8286 }
8287 const number = buf[0 .. buf.len - suffix_str.len];
8288 return p.parseFloat(number, suffix);
8289 } else {
8290 return p.parseInt(prefix, int_part, suffix, tok_i);
8291 }
8292}
8293
8294fn ppNum(p: *Parser) Error!Result {
8295 defer p.tok_i += 1;
8296 var res = try p.parseNumberToken(p.tok_i);
8297 if (p.in_macro) {
8298 if (res.ty.isFloat() or !res.ty.isReal()) {
8299 try p.errTok(.float_literal_in_pp_expr, p.tok_i);
8300 return error.ParsingFailed;
8301 }
8302 res.ty = if (res.ty.isUnsignedInt(p.comp)) p.comp.types.intmax.makeIntegerUnsigned() else p.comp.types.intmax;
8303 } else if (res.val.opt_ref != .none) {
8304 // TODO add complex values
8305 try p.value_map.put(res.node, res.val);
8306 }
8307 return res;
8308}
8309
8310/// Run a parser function but do not evaluate the result
8311fn parseNoEval(p: *Parser, comptime func: fn (*Parser) Error!Result) Error!Result {
8312 const no_eval = p.no_eval;
8313 defer p.no_eval = no_eval;
8314 p.no_eval = true;
8315 const parsed = try func(p);
8316 try parsed.expect(p);
8317 return parsed;
8318}
8319
8320/// genericSelection : keyword_generic '(' assignExpr ',' genericAssoc (',' genericAssoc)* ')'
8321/// genericAssoc
8322/// : typeName ':' assignExpr
8323/// | keyword_default ':' assignExpr
8324fn genericSelection(p: *Parser) Error!Result {
8325 p.tok_i += 1;
8326 const l_paren = try p.expectToken(.l_paren);
8327 const controlling_tok = p.tok_i;
8328 const controlling = try p.parseNoEval(assignExpr);
8329 _ = try p.expectToken(.comma);
8330 var controlling_ty = controlling.ty;
8331 if (controlling_ty.isArray()) controlling_ty.decayArray();
8332
8333 const list_buf_top = p.list_buf.items.len;
8334 defer p.list_buf.items.len = list_buf_top;
8335 try p.list_buf.append(controlling.node);
8336
8337 // Use decl_buf to store the token indexes of previous cases
8338 const decl_buf_top = p.decl_buf.items.len;
8339 defer p.decl_buf.items.len = decl_buf_top;
8340
8341 var default_tok: ?TokenIndex = null;
8342 var default: Result = undefined;
8343 var chosen_tok: TokenIndex = undefined;
8344 var chosen: Result = .{};
8345 while (true) {
8346 const start = p.tok_i;
8347 if (try p.typeName()) |ty| blk: {
8348 if (ty.isArray()) {
8349 try p.errTok(.generic_array_type, start);
8350 } else if (ty.isFunc()) {
8351 try p.errTok(.generic_func_type, start);
8352 } else if (ty.anyQual()) {
8353 try p.errTok(.generic_qual_type, start);
8354 }
8355 _ = try p.expectToken(.colon);
8356 const node = try p.assignExpr();
8357 try node.expect(p);
8358
8359 if (ty.eql(controlling_ty, p.comp, false)) {
8360 if (chosen.node == .none) {
8361 chosen = node;
8362 chosen_tok = start;
8363 break :blk;
8364 }
8365 try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
8366 try p.errStr(.generic_duplicate_here, chosen_tok, try p.typeStr(ty));
8367 }
8368 for (p.list_buf.items[list_buf_top + 1 ..], p.decl_buf.items[decl_buf_top..]) |item, prev_tok| {
8369 const prev_ty = p.nodes.items(.ty)[@intFromEnum(item)];
8370 if (prev_ty.eql(ty, p.comp, true)) {
8371 try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
8372 try p.errStr(.generic_duplicate_here, @intFromEnum(prev_tok), try p.typeStr(ty));
8373 }
8374 }
8375 try p.list_buf.append(try p.addNode(.{
8376 .tag = .generic_association_expr,
8377 .ty = ty,
8378 .data = .{ .un = node.node },
8379 }));
8380 try p.decl_buf.append(@enumFromInt(start));
8381 } else if (p.eatToken(.keyword_default)) |tok| {
8382 if (default_tok) |prev| {
8383 try p.errTok(.generic_duplicate_default, tok);
8384 try p.errTok(.previous_case, prev);
8385 }
8386 default_tok = tok;
8387 _ = try p.expectToken(.colon);
8388 default = try p.assignExpr();
8389 try default.expect(p);
8390 } else {
8391 if (p.list_buf.items.len == list_buf_top + 1) {
8392 try p.err(.expected_type);
8393 return error.ParsingFailed;
8394 }
8395 break;
8396 }
8397 if (p.eatToken(.comma) == null) break;
8398 }
8399 try p.expectClosing(l_paren, .r_paren);
8400
8401 if (chosen.node == .none) {
8402 if (default_tok != null) {
8403 try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
8404 .tag = .generic_default_expr,
8405 .data = .{ .un = default.node },
8406 }));
8407 chosen = default;
8408 } else {
8409 try p.errStr(.generic_no_match, controlling_tok, try p.typeStr(controlling_ty));
8410 return error.ParsingFailed;
8411 }
8412 } else {
8413 try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
8414 .tag = .generic_association_expr,
8415 .data = .{ .un = chosen.node },
8416 }));
8417 if (default_tok != null) {
8418 try p.list_buf.append(try p.addNode(.{
8419 .tag = .generic_default_expr,
8420 .data = .{ .un = chosen.node },
8421 }));
8422 }
8423 }
8424
8425 var generic_node: Tree.Node = .{
8426 .tag = .generic_expr_one,
8427 .ty = chosen.ty,
8428 .data = .{ .bin = .{ .lhs = controlling.node, .rhs = chosen.node } },
8429 };
8430 const associations = p.list_buf.items[list_buf_top..];
8431 if (associations.len > 2) { // associations[0] == controlling.node
8432 generic_node.tag = .generic_expr;
8433 generic_node.data = .{ .range = try p.addList(associations) };
8434 }
8435 chosen.node = try p.addNode(generic_node);
8436 return chosen;
8437}
deps/aro/aro/Pragma.zig deleted-83
......@@ -1,83 +0,0 @@
1const std = @import("std");
2const Compilation = @import("Compilation.zig");
3const Preprocessor = @import("Preprocessor.zig");
4const Parser = @import("Parser.zig");
5const TokenIndex = @import("Tree.zig").TokenIndex;
6
7pub const Error = Compilation.Error || error{ UnknownPragma, StopPreprocessing };
8
9const Pragma = @This();
10
11/// Called during Preprocessor.init
12beforePreprocess: ?*const fn (*Pragma, *Compilation) void = null,
13
14/// Called at the beginning of Parser.parse
15beforeParse: ?*const fn (*Pragma, *Compilation) void = null,
16
17/// Called at the end of Parser.parse if a Tree was successfully parsed
18afterParse: ?*const fn (*Pragma, *Compilation) void = null,
19
20/// Called during Compilation.deinit
21deinit: *const fn (*Pragma, *Compilation) void,
22
23/// Called whenever the preprocessor encounters this pragma. `start_idx` is the index
24/// within `pp.tokens` of the pragma name token. The pragma end is indicated by a
25/// .nl token (which may be generated if the source ends with a pragma with no newline)
26/// As an example, given the following line:
27/// #pragma GCC diagnostic error "-Wnewline-eof" \n
28/// Then pp.tokens.get(start_idx) will return the `GCC` token.
29/// Return error.UnknownPragma to emit an `unknown_pragma` diagnostic
30/// Return error.StopPreprocessing to stop preprocessing the current file (see once.zig)
31preprocessorHandler: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) Error!void = null,
32
33/// Called during token pretty-printing (`-E` option). If this returns true, the pragma will
34/// be printed; otherwise it will be omitted. start_idx is the index of the pragma name token
35preserveTokens: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) bool = null,
36
37/// Same as preprocessorHandler except called during parsing
38/// The parser's `p.tok_i` field must not be changed
39parserHandler: ?*const fn (*Pragma, *Parser, start_idx: TokenIndex) Compilation.Error!void = null,
40
41pub fn pasteTokens(pp: *Preprocessor, start_idx: TokenIndex) ![]const u8 {
42 if (pp.tokens.get(start_idx).id == .nl) return error.ExpectedStringLiteral;
43
44 const char_top = pp.char_buf.items.len;
45 defer pp.char_buf.items.len = char_top;
46 var i: usize = 0;
47 var lparen_count: u32 = 0;
48 var rparen_count: u32 = 0;
49 while (true) : (i += 1) {
50 const tok = pp.tokens.get(start_idx + i);
51 if (tok.id == .nl) break;
52 switch (tok.id) {
53 .l_paren => {
54 if (lparen_count != i) return error.ExpectedStringLiteral;
55 lparen_count += 1;
56 },
57 .r_paren => rparen_count += 1,
58 .string_literal => {
59 if (rparen_count != 0) return error.ExpectedStringLiteral;
60 const str = pp.expandedSlice(tok);
61 try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
62 },
63 else => return error.ExpectedStringLiteral,
64 }
65 }
66 if (lparen_count != rparen_count) return error.ExpectedStringLiteral;
67 return pp.char_buf.items[char_top..];
68}
69
70pub fn shouldPreserveTokens(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
71 if (self.preserveTokens) |func| return func(self, pp, start_idx);
72 return false;
73}
74
75pub fn preprocessorCB(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Error!void {
76 if (self.preprocessorHandler) |func| return func(self, pp, start_idx);
77}
78
79pub fn parserCB(self: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
80 const tok_index = p.tok_i;
81 defer std.debug.assert(tok_index == p.tok_i);
82 if (self.parserHandler) |func| return func(self, p, start_idx);
83}
deps/aro/aro/Preprocessor.zig deleted-3421
......@@ -1,3421 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const assert = std.debug.assert;
5const Compilation = @import("Compilation.zig");
6const Error = Compilation.Error;
7const Source = @import("Source.zig");
8const Tokenizer = @import("Tokenizer.zig");
9const RawToken = Tokenizer.Token;
10const Parser = @import("Parser.zig");
11const Diagnostics = @import("Diagnostics.zig");
12const Token = @import("Tree.zig").Token;
13const Attribute = @import("Attribute.zig");
14const features = @import("features.zig");
15
16const DefineMap = std.StringHashMapUnmanaged(Macro);
17const RawTokenList = std.ArrayList(RawToken);
18const max_include_depth = 200;
19
20/// Errors that can be returned when expanding a macro.
21/// error.UnknownPragma can occur within Preprocessor.pragma() but
22/// it is handled there and doesn't escape that function
23const MacroError = Error || error{StopPreprocessing};
24
25const Macro = struct {
26 /// Parameters of the function type macro
27 params: []const []const u8,
28
29 /// Token constituting the macro body
30 tokens: []const RawToken,
31
32 /// If the function type macro has variable number of arguments
33 var_args: bool,
34
35 /// Is a function type macro
36 is_func: bool,
37
38 /// Is a predefined macro
39 is_builtin: bool = false,
40
41 /// Location of macro in the source
42 loc: Source.Location,
43 start: u32,
44 end: u32,
45
46 fn eql(a: Macro, b: Macro, pp: *Preprocessor) bool {
47 if (a.tokens.len != b.tokens.len) return false;
48 if (a.is_builtin != b.is_builtin) return false;
49 for (a.tokens, b.tokens) |a_tok, b_tok| if (!tokEql(pp, a_tok, b_tok)) return false;
50
51 if (a.is_func and b.is_func) {
52 if (a.var_args != b.var_args) return false;
53 if (a.params.len != b.params.len) return false;
54 for (a.params, b.params) |a_param, b_param| if (!mem.eql(u8, a_param, b_param)) return false;
55 }
56
57 return true;
58 }
59
60 fn tokEql(pp: *Preprocessor, a: RawToken, b: RawToken) bool {
61 return mem.eql(u8, pp.tokSlice(a), pp.tokSlice(b));
62 }
63};
64
65const Preprocessor = @This();
66
67comp: *Compilation,
68gpa: mem.Allocator,
69arena: std.heap.ArenaAllocator,
70defines: DefineMap = .{},
71tokens: Token.List = .{},
72token_buf: RawTokenList,
73char_buf: std.ArrayList(u8),
74/// Counter that is incremented each time preprocess() is called
75/// Can be used to distinguish multiple preprocessings of the same file
76preprocess_count: u32 = 0,
77generated_line: u32 = 1,
78add_expansion_nl: u32 = 0,
79include_depth: u8 = 0,
80counter: u32 = 0,
81expansion_source_loc: Source.Location = undefined,
82poisoned_identifiers: std.StringHashMap(void),
83/// Map from Source.Id to macro name in the `#ifndef` condition which guards the source, if any
84include_guards: std.AutoHashMapUnmanaged(Source.Id, []const u8) = .{},
85
86/// Memory is retained to avoid allocation on every single token.
87top_expansion_buf: ExpandBuf,
88
89/// Dump current state to stderr.
90verbose: bool = false,
91preserve_whitespace: bool = false,
92
93/// linemarker tokens. Must be .none unless in -E mode (parser does not handle linemarkers)
94linemarkers: Linemarkers = .none,
95
96pub const parse = Parser.parse;
97
98pub const Linemarkers = enum {
99 /// No linemarker tokens. Required setting if parser will run
100 none,
101 /// #line <num> "filename"
102 line_directives,
103 /// # <num> "filename" flags
104 numeric_directives,
105};
106
107pub fn init(comp: *Compilation) Preprocessor {
108 const pp = Preprocessor{
109 .comp = comp,
110 .gpa = comp.gpa,
111 .arena = std.heap.ArenaAllocator.init(comp.gpa),
112 .token_buf = RawTokenList.init(comp.gpa),
113 .char_buf = std.ArrayList(u8).init(comp.gpa),
114 .poisoned_identifiers = std.StringHashMap(void).init(comp.gpa),
115 .top_expansion_buf = ExpandBuf.init(comp.gpa),
116 };
117 comp.pragmaEvent(.before_preprocess);
118 return pp;
119}
120
121/// Initialize Preprocessor with builtin macros.
122pub fn initDefault(comp: *Compilation) !Preprocessor {
123 var pp = init(comp);
124 errdefer pp.deinit();
125 try pp.addBuiltinMacros();
126 return pp;
127}
128
129const builtin_macros = struct {
130 const args = [1][]const u8{"X"};
131
132 const has_attribute = [1]RawToken{.{
133 .id = .macro_param_has_attribute,
134 .source = .generated,
135 }};
136 const has_c_attribute = [1]RawToken{.{
137 .id = .macro_param_has_c_attribute,
138 .source = .generated,
139 }};
140 const has_declspec_attribute = [1]RawToken{.{
141 .id = .macro_param_has_declspec_attribute,
142 .source = .generated,
143 }};
144 const has_warning = [1]RawToken{.{
145 .id = .macro_param_has_warning,
146 .source = .generated,
147 }};
148 const has_feature = [1]RawToken{.{
149 .id = .macro_param_has_feature,
150 .source = .generated,
151 }};
152 const has_extension = [1]RawToken{.{
153 .id = .macro_param_has_extension,
154 .source = .generated,
155 }};
156 const has_builtin = [1]RawToken{.{
157 .id = .macro_param_has_builtin,
158 .source = .generated,
159 }};
160 const has_include = [1]RawToken{.{
161 .id = .macro_param_has_include,
162 .source = .generated,
163 }};
164 const has_include_next = [1]RawToken{.{
165 .id = .macro_param_has_include_next,
166 .source = .generated,
167 }};
168 const has_embed = [1]RawToken{.{
169 .id = .macro_param_has_embed,
170 .source = .generated,
171 }};
172
173 const is_identifier = [1]RawToken{.{
174 .id = .macro_param_is_identifier,
175 .source = .generated,
176 }};
177
178 const pragma_operator = [1]RawToken{.{
179 .id = .macro_param_pragma_operator,
180 .source = .generated,
181 }};
182
183 const file = [1]RawToken{.{
184 .id = .macro_file,
185 .source = .generated,
186 }};
187 const line = [1]RawToken{.{
188 .id = .macro_line,
189 .source = .generated,
190 }};
191 const counter = [1]RawToken{.{
192 .id = .macro_counter,
193 .source = .generated,
194 }};
195};
196
197fn addBuiltinMacro(pp: *Preprocessor, name: []const u8, is_func: bool, tokens: []const RawToken) !void {
198 try pp.defines.putNoClobber(pp.gpa, name, .{
199 .params = &builtin_macros.args,
200 .tokens = tokens,
201 .var_args = false,
202 .is_func = is_func,
203 .loc = .{ .id = .generated },
204 .start = 0,
205 .end = 0,
206 .is_builtin = true,
207 });
208}
209
210pub fn addBuiltinMacros(pp: *Preprocessor) !void {
211 try pp.addBuiltinMacro("__has_attribute", true, &builtin_macros.has_attribute);
212 try pp.addBuiltinMacro("__has_c_attribute", true, &builtin_macros.has_c_attribute);
213 try pp.addBuiltinMacro("__has_declspec_attribute", true, &builtin_macros.has_declspec_attribute);
214 try pp.addBuiltinMacro("__has_warning", true, &builtin_macros.has_warning);
215 try pp.addBuiltinMacro("__has_feature", true, &builtin_macros.has_feature);
216 try pp.addBuiltinMacro("__has_extension", true, &builtin_macros.has_extension);
217 try pp.addBuiltinMacro("__has_builtin", true, &builtin_macros.has_builtin);
218 try pp.addBuiltinMacro("__has_include", true, &builtin_macros.has_include);
219 try pp.addBuiltinMacro("__has_include_next", true, &builtin_macros.has_include_next);
220 try pp.addBuiltinMacro("__has_embed", true, &builtin_macros.has_embed);
221 try pp.addBuiltinMacro("__is_identifier", true, &builtin_macros.is_identifier);
222 try pp.addBuiltinMacro("_Pragma", true, &builtin_macros.pragma_operator);
223
224 try pp.addBuiltinMacro("__FILE__", false, &builtin_macros.file);
225 try pp.addBuiltinMacro("__LINE__", false, &builtin_macros.line);
226 try pp.addBuiltinMacro("__COUNTER__", false, &builtin_macros.counter);
227}
228
229pub fn deinit(pp: *Preprocessor) void {
230 pp.defines.deinit(pp.gpa);
231 for (pp.tokens.items(.expansion_locs)) |loc| Token.free(loc, pp.gpa);
232 pp.tokens.deinit(pp.gpa);
233 pp.arena.deinit();
234 pp.token_buf.deinit();
235 pp.char_buf.deinit();
236 pp.poisoned_identifiers.deinit();
237 pp.include_guards.deinit(pp.gpa);
238 pp.top_expansion_buf.deinit();
239}
240
241/// Preprocess a compilation unit of sources into a parsable list of tokens.
242pub fn preprocessSources(pp: *Preprocessor, sources: []const Source) Error!void {
243 assert(sources.len > 1);
244 const first = sources[0];
245 try pp.addIncludeStart(first);
246 for (sources[1..]) |header| {
247 try pp.addIncludeStart(header);
248 _ = try pp.preprocess(header);
249 }
250 try pp.addIncludeResume(first.id, 0, 0);
251 const eof = try pp.preprocess(first);
252 try pp.tokens.append(pp.comp.gpa, eof);
253}
254
255/// Preprocess a source file, returns eof token.
256pub fn preprocess(pp: *Preprocessor, source: Source) Error!Token {
257 const eof = pp.preprocessExtra(source) catch |er| switch (er) {
258 // This cannot occur in the main file and is handled in `include`.
259 error.StopPreprocessing => unreachable,
260 else => |e| return e,
261 };
262 try eof.checkMsEof(source, pp.comp);
263 return eof;
264}
265
266/// Tokenize a file without any preprocessing, returns eof token.
267pub fn tokenize(pp: *Preprocessor, source: Source) Error!Token {
268 assert(pp.linemarkers == .none);
269 assert(pp.preserve_whitespace == false);
270 var tokenizer = Tokenizer{
271 .buf = source.buf,
272 .comp = pp.comp,
273 .source = source.id,
274 };
275
276 // Estimate how many new tokens this source will contain.
277 const estimated_token_count = source.buf.len / 8;
278 try pp.tokens.ensureTotalCapacity(pp.gpa, pp.tokens.len + estimated_token_count);
279
280 while (true) {
281 const tok = tokenizer.next();
282 if (tok.id == .eof) return tokFromRaw(tok);
283 try pp.tokens.append(pp.gpa, tokFromRaw(tok));
284 }
285}
286
287pub fn addIncludeStart(pp: *Preprocessor, source: Source) !void {
288 if (pp.linemarkers == .none) return;
289 try pp.tokens.append(pp.gpa, .{ .id = .include_start, .loc = .{
290 .id = source.id,
291 .byte_offset = std.math.maxInt(u32),
292 .line = 0,
293 } });
294}
295
296pub fn addIncludeResume(pp: *Preprocessor, source: Source.Id, offset: u32, line: u32) !void {
297 if (pp.linemarkers == .none) return;
298 try pp.tokens.append(pp.gpa, .{ .id = .include_resume, .loc = .{
299 .id = source,
300 .byte_offset = offset,
301 .line = line,
302 } });
303}
304
305fn invalidTokenDiagnostic(tok_id: Token.Id) Diagnostics.Tag {
306 return switch (tok_id) {
307 .unterminated_string_literal => .unterminated_string_literal_warning,
308 .empty_char_literal => .empty_char_literal_warning,
309 .unterminated_char_literal => .unterminated_char_literal_warning,
310 else => unreachable,
311 };
312}
313
314/// Return the name of the #ifndef guard macro that starts a source, if any.
315fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 {
316 var tokenizer = Tokenizer{
317 .buf = source.buf,
318 .langopts = pp.comp.langopts,
319 .source = source.id,
320 };
321 var hash = tokenizer.nextNoWS();
322 while (hash.id == .nl) hash = tokenizer.nextNoWS();
323 if (hash.id != .hash) return null;
324 const ifndef = tokenizer.nextNoWS();
325 if (ifndef.id != .keyword_ifndef) return null;
326 const guard = tokenizer.nextNoWS();
327 if (guard.id != .identifier) return null;
328 return pp.tokSlice(guard);
329}
330
331fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token {
332 var guard_name = pp.findIncludeGuard(source);
333
334 pp.preprocess_count += 1;
335 var tokenizer = Tokenizer{
336 .buf = source.buf,
337 .langopts = pp.comp.langopts,
338 .source = source.id,
339 };
340
341 // Estimate how many new tokens this source will contain.
342 const estimated_token_count = source.buf.len / 8;
343 try pp.tokens.ensureTotalCapacity(pp.gpa, pp.tokens.len + estimated_token_count);
344
345 var if_level: u8 = 0;
346 var if_kind = std.PackedIntArray(u2, 256).init([1]u2{0} ** 256);
347 const until_else = 0;
348 const until_endif = 1;
349 const until_endif_seen_else = 2;
350
351 var start_of_line = true;
352 while (true) {
353 var tok = tokenizer.next();
354 switch (tok.id) {
355 .hash => if (!start_of_line) try pp.tokens.append(pp.gpa, tokFromRaw(tok)) else {
356 const directive = tokenizer.nextNoWS();
357 switch (directive.id) {
358 .keyword_error, .keyword_warning => {
359 // #error tokens..
360 pp.top_expansion_buf.items.len = 0;
361 const char_top = pp.char_buf.items.len;
362 defer pp.char_buf.items.len = char_top;
363
364 while (true) {
365 tok = tokenizer.next();
366 if (tok.id == .nl or tok.id == .eof) break;
367 if (tok.id == .whitespace) tok.id = .macro_ws;
368 try pp.top_expansion_buf.append(tokFromRaw(tok));
369 }
370 try pp.stringify(pp.top_expansion_buf.items);
371 const slice = pp.char_buf.items[char_top + 1 .. pp.char_buf.items.len - 2];
372 const duped = try pp.comp.diagnostics.arena.allocator().dupe(u8, slice);
373
374 try pp.comp.addDiagnostic(.{
375 .tag = if (directive.id == .keyword_error) .error_directive else .warning_directive,
376 .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
377 .extra = .{ .str = duped },
378 }, &.{});
379 },
380 .keyword_if => {
381 const sum, const overflowed = @addWithOverflow(if_level, 1);
382 if (overflowed != 0)
383 return pp.fatal(directive, "too many #if nestings", .{});
384 if_level = sum;
385
386 if (try pp.expr(&tokenizer)) {
387 if_kind.set(if_level, until_endif);
388 if (pp.verbose) {
389 pp.verboseLog(directive, "entering then branch of #if", .{});
390 }
391 } else {
392 if_kind.set(if_level, until_else);
393 try pp.skip(&tokenizer, .until_else);
394 if (pp.verbose) {
395 pp.verboseLog(directive, "entering else branch of #if", .{});
396 }
397 }
398 },
399 .keyword_ifdef => {
400 const sum, const overflowed = @addWithOverflow(if_level, 1);
401 if (overflowed != 0)
402 return pp.fatal(directive, "too many #if nestings", .{});
403 if_level = sum;
404
405 const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
406 try pp.expectNl(&tokenizer);
407 if (pp.defines.get(macro_name) != null) {
408 if_kind.set(if_level, until_endif);
409 if (pp.verbose) {
410 pp.verboseLog(directive, "entering then branch of #ifdef", .{});
411 }
412 } else {
413 if_kind.set(if_level, until_else);
414 try pp.skip(&tokenizer, .until_else);
415 if (pp.verbose) {
416 pp.verboseLog(directive, "entering else branch of #ifdef", .{});
417 }
418 }
419 },
420 .keyword_ifndef => {
421 const sum, const overflowed = @addWithOverflow(if_level, 1);
422 if (overflowed != 0)
423 return pp.fatal(directive, "too many #if nestings", .{});
424 if_level = sum;
425
426 const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
427 try pp.expectNl(&tokenizer);
428 if (pp.defines.get(macro_name) == null) {
429 if_kind.set(if_level, until_endif);
430 } else {
431 if_kind.set(if_level, until_else);
432 try pp.skip(&tokenizer, .until_else);
433 }
434 },
435 .keyword_elif => {
436 if (if_level == 0) {
437 try pp.err(directive, .elif_without_if);
438 if_level += 1;
439 if_kind.set(if_level, until_else);
440 } else if (if_level == 1) {
441 guard_name = null;
442 }
443 switch (if_kind.get(if_level)) {
444 until_else => if (try pp.expr(&tokenizer)) {
445 if_kind.set(if_level, until_endif);
446 if (pp.verbose) {
447 pp.verboseLog(directive, "entering then branch of #elif", .{});
448 }
449 } else {
450 try pp.skip(&tokenizer, .until_else);
451 if (pp.verbose) {
452 pp.verboseLog(directive, "entering else branch of #elif", .{});
453 }
454 },
455 until_endif => try pp.skip(&tokenizer, .until_endif),
456 until_endif_seen_else => {
457 try pp.err(directive, .elif_after_else);
458 skipToNl(&tokenizer);
459 },
460 else => unreachable,
461 }
462 },
463 .keyword_elifdef => {
464 if (if_level == 0) {
465 try pp.err(directive, .elifdef_without_if);
466 if_level += 1;
467 if_kind.set(if_level, until_else);
468 } else if (if_level == 1) {
469 guard_name = null;
470 }
471 switch (if_kind.get(if_level)) {
472 until_else => {
473 const macro_name = try pp.expectMacroName(&tokenizer);
474 if (macro_name == null) {
475 if_kind.set(if_level, until_else);
476 try pp.skip(&tokenizer, .until_else);
477 if (pp.verbose) {
478 pp.verboseLog(directive, "entering else branch of #elifdef", .{});
479 }
480 } else {
481 try pp.expectNl(&tokenizer);
482 if (pp.defines.get(macro_name.?) != null) {
483 if_kind.set(if_level, until_endif);
484 if (pp.verbose) {
485 pp.verboseLog(directive, "entering then branch of #elifdef", .{});
486 }
487 } else {
488 if_kind.set(if_level, until_else);
489 try pp.skip(&tokenizer, .until_else);
490 if (pp.verbose) {
491 pp.verboseLog(directive, "entering else branch of #elifdef", .{});
492 }
493 }
494 }
495 },
496 until_endif => try pp.skip(&tokenizer, .until_endif),
497 until_endif_seen_else => {
498 try pp.err(directive, .elifdef_after_else);
499 skipToNl(&tokenizer);
500 },
501 else => unreachable,
502 }
503 },
504 .keyword_elifndef => {
505 if (if_level == 0) {
506 try pp.err(directive, .elifdef_without_if);
507 if_level += 1;
508 if_kind.set(if_level, until_else);
509 } else if (if_level == 1) {
510 guard_name = null;
511 }
512 switch (if_kind.get(if_level)) {
513 until_else => {
514 const macro_name = try pp.expectMacroName(&tokenizer);
515 if (macro_name == null) {
516 if_kind.set(if_level, until_else);
517 try pp.skip(&tokenizer, .until_else);
518 if (pp.verbose) {
519 pp.verboseLog(directive, "entering else branch of #elifndef", .{});
520 }
521 } else {
522 try pp.expectNl(&tokenizer);
523 if (pp.defines.get(macro_name.?) == null) {
524 if_kind.set(if_level, until_endif);
525 if (pp.verbose) {
526 pp.verboseLog(directive, "entering then branch of #elifndef", .{});
527 }
528 } else {
529 if_kind.set(if_level, until_else);
530 try pp.skip(&tokenizer, .until_else);
531 if (pp.verbose) {
532 pp.verboseLog(directive, "entering else branch of #elifndef", .{});
533 }
534 }
535 }
536 },
537 until_endif => try pp.skip(&tokenizer, .until_endif),
538 until_endif_seen_else => {
539 try pp.err(directive, .elifdef_after_else);
540 skipToNl(&tokenizer);
541 },
542 else => unreachable,
543 }
544 },
545 .keyword_else => {
546 try pp.expectNl(&tokenizer);
547 if (if_level == 0) {
548 try pp.err(directive, .else_without_if);
549 continue;
550 } else if (if_level == 1) {
551 guard_name = null;
552 }
553 switch (if_kind.get(if_level)) {
554 until_else => {
555 if_kind.set(if_level, until_endif_seen_else);
556 if (pp.verbose) {
557 pp.verboseLog(directive, "#else branch here", .{});
558 }
559 },
560 until_endif => try pp.skip(&tokenizer, .until_endif_seen_else),
561 until_endif_seen_else => {
562 try pp.err(directive, .else_after_else);
563 skipToNl(&tokenizer);
564 },
565 else => unreachable,
566 }
567 },
568 .keyword_endif => {
569 try pp.expectNl(&tokenizer);
570 if (if_level == 0) {
571 guard_name = null;
572 try pp.err(directive, .endif_without_if);
573 continue;
574 } else if (if_level == 1) {
575 const saved_tokenizer = tokenizer;
576 defer tokenizer = saved_tokenizer;
577
578 var next = tokenizer.nextNoWS();
579 while (next.id == .nl) : (next = tokenizer.nextNoWS()) {}
580 if (next.id != .eof) guard_name = null;
581 }
582 if_level -= 1;
583 },
584 .keyword_define => try pp.define(&tokenizer),
585 .keyword_undef => {
586 const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
587
588 _ = pp.defines.remove(macro_name);
589 try pp.expectNl(&tokenizer);
590 },
591 .keyword_include => {
592 try pp.include(&tokenizer, .first);
593 continue;
594 },
595 .keyword_include_next => {
596 try pp.comp.addDiagnostic(.{
597 .tag = .include_next,
598 .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
599 }, &.{});
600 if (pp.include_depth == 0) {
601 try pp.comp.addDiagnostic(.{
602 .tag = .include_next_outside_header,
603 .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
604 }, &.{});
605 try pp.include(&tokenizer, .first);
606 } else {
607 try pp.include(&tokenizer, .next);
608 }
609 },
610 .keyword_embed => try pp.embed(&tokenizer),
611 .keyword_pragma => {
612 try pp.pragma(&tokenizer, directive, null, &.{});
613 continue;
614 },
615 .keyword_line => {
616 // #line number "file"
617 const digits = tokenizer.nextNoWS();
618 if (digits.id != .pp_num) try pp.err(digits, .line_simple_digit);
619 // TODO: validate that the pp_num token is solely digits
620
621 if (digits.id == .eof or digits.id == .nl) continue;
622 const name = tokenizer.nextNoWS();
623 if (name.id == .eof or name.id == .nl) continue;
624 if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
625 try pp.expectNl(&tokenizer);
626 },
627 .pp_num => {
628 // # number "file" flags
629 // TODO: validate that the pp_num token is solely digits
630 // if not, emit `GNU line marker directive requires a simple digit sequence`
631 const name = tokenizer.nextNoWS();
632 if (name.id == .eof or name.id == .nl) continue;
633 if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
634
635 const flag_1 = tokenizer.nextNoWS();
636 if (flag_1.id == .eof or flag_1.id == .nl) continue;
637 const flag_2 = tokenizer.nextNoWS();
638 if (flag_2.id == .eof or flag_2.id == .nl) continue;
639 const flag_3 = tokenizer.nextNoWS();
640 if (flag_3.id == .eof or flag_3.id == .nl) continue;
641 const flag_4 = tokenizer.nextNoWS();
642 if (flag_4.id == .eof or flag_4.id == .nl) continue;
643 try pp.expectNl(&tokenizer);
644 },
645 .nl => {},
646 .eof => {
647 if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
648 return tokFromRaw(directive);
649 },
650 else => {
651 try pp.err(tok, .invalid_preprocessing_directive);
652 skipToNl(&tokenizer);
653 },
654 }
655 if (pp.preserve_whitespace) {
656 tok.id = .nl;
657 try pp.tokens.append(pp.gpa, tokFromRaw(tok));
658 }
659 },
660 .whitespace => if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok)),
661 .nl => {
662 start_of_line = true;
663 if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok));
664 },
665 .eof => {
666 if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
667 // The following check needs to occur here and not at the top of the function
668 // because a pragma may change the level during preprocessing
669 if (source.buf.len > 0 and source.buf[source.buf.len - 1] != '\n') {
670 try pp.err(tok, .newline_eof);
671 }
672 if (guard_name) |name| {
673 if (try pp.include_guards.fetchPut(pp.gpa, source.id, name)) |prev| {
674 assert(mem.eql(u8, name, prev.value));
675 }
676 }
677 return tokFromRaw(tok);
678 },
679 .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| {
680 start_of_line = false;
681 try pp.err(tok, invalidTokenDiagnostic(tag));
682 try pp.expandMacro(&tokenizer, tok);
683 },
684 .unterminated_comment => try pp.err(tok, .unterminated_comment),
685 else => {
686 if (tok.id.isMacroIdentifier() and pp.poisoned_identifiers.get(pp.tokSlice(tok)) != null) {
687 try pp.err(tok, .poisoned_identifier);
688 }
689 // Add the token to the buffer doing any necessary expansions.
690 start_of_line = false;
691 try pp.expandMacro(&tokenizer, tok);
692 },
693 }
694 }
695}
696
697/// Get raw token source string.
698/// Returned slice is invalidated when comp.generated_buf is updated.
699pub fn tokSlice(pp: *Preprocessor, token: RawToken) []const u8 {
700 if (token.id.lexeme()) |some| return some;
701 const source = pp.comp.getSource(token.source);
702 return source.buf[token.start..token.end];
703}
704
705/// Convert a token from the Tokenizer into a token used by the parser.
706fn tokFromRaw(raw: RawToken) Token {
707 return .{
708 .id = raw.id,
709 .loc = .{
710 .id = raw.source,
711 .byte_offset = raw.start,
712 .line = raw.line,
713 },
714 };
715}
716
717fn err(pp: *Preprocessor, raw: RawToken, tag: Diagnostics.Tag) !void {
718 try pp.comp.addDiagnostic(.{
719 .tag = tag,
720 .loc = .{
721 .id = raw.source,
722 .byte_offset = raw.start,
723 .line = raw.line,
724 },
725 }, &.{});
726}
727
728fn errStr(pp: *Preprocessor, tok: Token, tag: Diagnostics.Tag, str: []const u8) !void {
729 try pp.comp.addDiagnostic(.{
730 .tag = tag,
731 .loc = tok.loc,
732 .extra = .{ .str = str },
733 }, tok.expansionSlice());
734}
735
736fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) Compilation.Error {
737 try pp.comp.diagnostics.list.append(pp.gpa, .{
738 .tag = .cli_error,
739 .kind = .@"fatal error",
740 .extra = .{ .str = try std.fmt.allocPrint(pp.comp.diagnostics.arena.allocator(), fmt, args) },
741 .loc = .{
742 .id = raw.source,
743 .byte_offset = raw.start,
744 .line = raw.line,
745 },
746 });
747 return error.FatalError;
748}
749
750fn fatalNotFound(pp: *Preprocessor, tok: Token, filename: []const u8) Compilation.Error {
751 const old = pp.comp.diagnostics.fatal_errors;
752 pp.comp.diagnostics.fatal_errors = true;
753 defer pp.comp.diagnostics.fatal_errors = old;
754
755 try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ .tag = .cli_error, .loc = tok.loc, .extra = .{
756 .str = try std.fmt.allocPrint(pp.comp.diagnostics.arena.allocator(), "'{s}' not found", .{filename}),
757 } }, tok.expansionSlice(), false);
758 unreachable; // addExtra should've returned FatalError
759}
760
761fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void {
762 const source = pp.comp.getSource(raw.source);
763 const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start });
764
765 const stderr = std.io.getStdErr().writer();
766 var buf_writer = std.io.bufferedWriter(stderr);
767 const writer = buf_writer.writer();
768 defer buf_writer.flush() catch {};
769 writer.print("{s}:{d}:{d}: ", .{ source.path, line_col.line_no, line_col.col }) catch return;
770 writer.print(fmt, args) catch return;
771 writer.writeByte('\n') catch return;
772 writer.writeAll(line_col.line) catch return;
773 writer.writeByte('\n') catch return;
774}
775
776/// Consume next token, error if it is not an identifier.
777fn expectMacroName(pp: *Preprocessor, tokenizer: *Tokenizer) Error!?[]const u8 {
778 const macro_name = tokenizer.nextNoWS();
779 if (!macro_name.id.isMacroIdentifier()) {
780 try pp.err(macro_name, .macro_name_missing);
781 skipToNl(tokenizer);
782 return null;
783 }
784 return pp.tokSlice(macro_name);
785}
786
787/// Skip until after a newline, error if extra tokens before it.
788fn expectNl(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
789 var sent_err = false;
790 while (true) {
791 const tok = tokenizer.next();
792 if (tok.id == .nl or tok.id == .eof) return;
793 if (tok.id == .whitespace) continue;
794 if (!sent_err) {
795 sent_err = true;
796 try pp.err(tok, .extra_tokens_directive_end);
797 }
798 }
799}
800
801/// Consume all tokens until a newline and parse the result into a boolean.
802fn expr(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!bool {
803 const start = pp.tokens.len;
804 defer {
805 for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
806 pp.tokens.len = start;
807 }
808
809 pp.top_expansion_buf.items.len = 0;
810 const eof = while (true) {
811 const tok = tokenizer.next();
812 switch (tok.id) {
813 .nl, .eof => break tok,
814 .whitespace => if (pp.top_expansion_buf.items.len == 0) continue,
815 else => {},
816 }
817 try pp.top_expansion_buf.append(tokFromRaw(tok));
818 } else unreachable;
819 if (pp.top_expansion_buf.items.len != 0) {
820 pp.expansion_source_loc = pp.top_expansion_buf.items[0].loc;
821 try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, pp.top_expansion_buf.items.len, false, .expr);
822 }
823 for (pp.top_expansion_buf.items) |tok| {
824 if (tok.id == .macro_ws) continue;
825 if (!tok.id.validPreprocessorExprStart()) {
826 try pp.comp.addDiagnostic(.{
827 .tag = .invalid_preproc_expr_start,
828 .loc = tok.loc,
829 }, tok.expansionSlice());
830 return false;
831 }
832 break;
833 } else {
834 try pp.err(eof, .expected_value_in_expr);
835 return false;
836 }
837
838 // validate the tokens in the expression
839 try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
840 var i: usize = 0;
841 const items = pp.top_expansion_buf.items;
842 while (i < items.len) : (i += 1) {
843 var tok = items[i];
844 switch (tok.id) {
845 .string_literal,
846 .string_literal_utf_16,
847 .string_literal_utf_8,
848 .string_literal_utf_32,
849 .string_literal_wide,
850 => {
851 try pp.comp.addDiagnostic(.{
852 .tag = .string_literal_in_pp_expr,
853 .loc = tok.loc,
854 }, tok.expansionSlice());
855 return false;
856 },
857 .plus_plus,
858 .minus_minus,
859 .plus_equal,
860 .minus_equal,
861 .asterisk_equal,
862 .slash_equal,
863 .percent_equal,
864 .angle_bracket_angle_bracket_left_equal,
865 .angle_bracket_angle_bracket_right_equal,
866 .ampersand_equal,
867 .caret_equal,
868 .pipe_equal,
869 .l_bracket,
870 .r_bracket,
871 .l_brace,
872 .r_brace,
873 .ellipsis,
874 .semicolon,
875 .hash,
876 .hash_hash,
877 .equal,
878 .arrow,
879 .period,
880 => {
881 try pp.comp.addDiagnostic(.{
882 .tag = .invalid_preproc_operator,
883 .loc = tok.loc,
884 }, tok.expansionSlice());
885 return false;
886 },
887 .macro_ws, .whitespace => continue,
888 .keyword_false => tok.id = .zero,
889 .keyword_true => tok.id = .one,
890 else => if (tok.id.isMacroIdentifier()) {
891 if (tok.id == .keyword_defined) {
892 const tokens_consumed = try pp.handleKeywordDefined(&tok, items[i + 1 ..], eof);
893 i += tokens_consumed;
894 } else {
895 try pp.errStr(tok, .undefined_macro, pp.expandedSlice(tok));
896
897 if (i + 1 < pp.top_expansion_buf.items.len and
898 pp.top_expansion_buf.items[i + 1].id == .l_paren)
899 {
900 try pp.errStr(tok, .fn_macro_undefined, pp.expandedSlice(tok));
901 return false;
902 }
903
904 tok.id = .zero; // undefined macro
905 }
906 },
907 }
908 pp.tokens.appendAssumeCapacity(tok);
909 }
910 try pp.tokens.append(pp.gpa, .{
911 .id = .eof,
912 .loc = tokFromRaw(eof).loc,
913 });
914
915 // Actually parse it.
916 var parser = Parser{
917 .pp = pp,
918 .comp = pp.comp,
919 .gpa = pp.gpa,
920 .tok_ids = pp.tokens.items(.id),
921 .tok_i = @intCast(start),
922 .arena = pp.arena.allocator(),
923 .in_macro = true,
924 .strings = std.ArrayList(u8).init(pp.comp.gpa),
925
926 .data = undefined,
927 .value_map = undefined,
928 .labels = undefined,
929 .decl_buf = undefined,
930 .list_buf = undefined,
931 .param_buf = undefined,
932 .enum_buf = undefined,
933 .record_buf = undefined,
934 .attr_buf = undefined,
935 .field_attr_buf = undefined,
936 .string_ids = undefined,
937 };
938 defer parser.strings.deinit();
939 return parser.macroExpr();
940}
941
942/// Turns macro_tok from .keyword_defined into .zero or .one depending on whether the argument is defined
943/// Returns the number of tokens consumed
944fn handleKeywordDefined(pp: *Preprocessor, macro_tok: *Token, tokens: []const Token, eof: RawToken) !usize {
945 std.debug.assert(macro_tok.id == .keyword_defined);
946 var it = TokenIterator.init(tokens);
947 const first = it.nextNoWS() orelse {
948 try pp.err(eof, .macro_name_missing);
949 return it.i;
950 };
951 switch (first.id) {
952 .l_paren => {},
953 else => {
954 if (!first.id.isMacroIdentifier()) {
955 try pp.errStr(first, .macro_name_must_be_identifier, pp.expandedSlice(first));
956 }
957 macro_tok.id = if (pp.defines.contains(pp.expandedSlice(first))) .one else .zero;
958 return it.i;
959 },
960 }
961 const second = it.nextNoWS() orelse {
962 try pp.err(eof, .macro_name_missing);
963 return it.i;
964 };
965 if (!second.id.isMacroIdentifier()) {
966 try pp.comp.addDiagnostic(.{
967 .tag = .macro_name_must_be_identifier,
968 .loc = second.loc,
969 }, second.expansionSlice());
970 return it.i;
971 }
972 macro_tok.id = if (pp.defines.contains(pp.expandedSlice(second))) .one else .zero;
973
974 const last = it.nextNoWS();
975 if (last == null or last.?.id != .r_paren) {
976 const tok = last orelse tokFromRaw(eof);
977 try pp.comp.addDiagnostic(.{
978 .tag = .closing_paren,
979 .loc = tok.loc,
980 }, tok.expansionSlice());
981 try pp.comp.addDiagnostic(.{
982 .tag = .to_match_paren,
983 .loc = first.loc,
984 }, first.expansionSlice());
985 }
986
987 return it.i;
988}
989
990/// Skip until #else #elif #endif, return last directive token id.
991/// Also skips nested #if ... #endifs.
992fn skip(
993 pp: *Preprocessor,
994 tokenizer: *Tokenizer,
995 cont: enum { until_else, until_endif, until_endif_seen_else },
996) Error!void {
997 var ifs_seen: u32 = 0;
998 var line_start = true;
999 while (tokenizer.index < tokenizer.buf.len) {
1000 if (line_start) {
1001 const saved_tokenizer = tokenizer.*;
1002 const hash = tokenizer.nextNoWS();
1003 if (hash.id == .nl) continue;
1004 line_start = false;
1005 if (hash.id != .hash) continue;
1006 const directive = tokenizer.nextNoWS();
1007 switch (directive.id) {
1008 .keyword_else => {
1009 if (ifs_seen != 0) continue;
1010 if (cont == .until_endif_seen_else) {
1011 try pp.err(directive, .else_after_else);
1012 continue;
1013 }
1014 tokenizer.* = saved_tokenizer;
1015 return;
1016 },
1017 .keyword_elif => {
1018 if (ifs_seen != 0 or cont == .until_endif) continue;
1019 if (cont == .until_endif_seen_else) {
1020 try pp.err(directive, .elif_after_else);
1021 continue;
1022 }
1023 tokenizer.* = saved_tokenizer;
1024 return;
1025 },
1026 .keyword_elifdef => {
1027 if (ifs_seen != 0 or cont == .until_endif) continue;
1028 if (cont == .until_endif_seen_else) {
1029 try pp.err(directive, .elifdef_after_else);
1030 continue;
1031 }
1032 tokenizer.* = saved_tokenizer;
1033 return;
1034 },
1035 .keyword_elifndef => {
1036 if (ifs_seen != 0 or cont == .until_endif) continue;
1037 if (cont == .until_endif_seen_else) {
1038 try pp.err(directive, .elifndef_after_else);
1039 continue;
1040 }
1041 tokenizer.* = saved_tokenizer;
1042 return;
1043 },
1044 .keyword_endif => {
1045 if (ifs_seen == 0) {
1046 tokenizer.* = saved_tokenizer;
1047 return;
1048 }
1049 ifs_seen -= 1;
1050 },
1051 .keyword_if, .keyword_ifdef, .keyword_ifndef => ifs_seen += 1,
1052 else => {},
1053 }
1054 } else if (tokenizer.buf[tokenizer.index] == '\n') {
1055 line_start = true;
1056 tokenizer.index += 1;
1057 tokenizer.line += 1;
1058 if (pp.preserve_whitespace) {
1059 try pp.tokens.append(pp.gpa, .{ .id = .nl, .loc = .{
1060 .id = tokenizer.source,
1061 .line = tokenizer.line,
1062 } });
1063 }
1064 } else {
1065 line_start = false;
1066 tokenizer.index += 1;
1067 }
1068 } else {
1069 const eof = tokenizer.next();
1070 return pp.err(eof, .unterminated_conditional_directive);
1071 }
1072}
1073
1074// Skip until newline, ignore other tokens.
1075fn skipToNl(tokenizer: *Tokenizer) void {
1076 while (true) {
1077 const tok = tokenizer.next();
1078 if (tok.id == .nl or tok.id == .eof) return;
1079 }
1080}
1081
1082const ExpandBuf = std.ArrayList(Token);
1083fn removePlacemarkers(buf: *ExpandBuf) void {
1084 var i: usize = buf.items.len -% 1;
1085 while (i < buf.items.len) : (i -%= 1) {
1086 if (buf.items[i].id == .placemarker) {
1087 const placemarker = buf.orderedRemove(i);
1088 Token.free(placemarker.expansion_locs, buf.allocator);
1089 }
1090 }
1091}
1092
1093const MacroArguments = std.ArrayList([]const Token);
1094fn deinitMacroArguments(allocator: Allocator, args: *const MacroArguments) void {
1095 for (args.items) |item| {
1096 for (item) |tok| Token.free(tok.expansion_locs, allocator);
1097 allocator.free(item);
1098 }
1099 args.deinit();
1100}
1101
1102fn expandObjMacro(pp: *Preprocessor, simple_macro: *const Macro) Error!ExpandBuf {
1103 var buf = ExpandBuf.init(pp.gpa);
1104 errdefer buf.deinit();
1105 try buf.ensureTotalCapacity(simple_macro.tokens.len);
1106
1107 // Add all of the simple_macros tokens to the new buffer handling any concats.
1108 var i: usize = 0;
1109 while (i < simple_macro.tokens.len) : (i += 1) {
1110 const raw = simple_macro.tokens[i];
1111 const tok = tokFromRaw(raw);
1112 switch (raw.id) {
1113 .hash_hash => {
1114 var rhs = tokFromRaw(simple_macro.tokens[i + 1]);
1115 i += 1;
1116 while (true) {
1117 if (rhs.id == .whitespace) {
1118 rhs = tokFromRaw(simple_macro.tokens[i + 1]);
1119 i += 1;
1120 } else if (rhs.id == .comment and !pp.comp.langopts.preserve_comments_in_macros) {
1121 rhs = tokFromRaw(simple_macro.tokens[i + 1]);
1122 i += 1;
1123 } else break;
1124 }
1125 try pp.pasteTokens(&buf, &.{rhs});
1126 },
1127 .whitespace => if (pp.preserve_whitespace) buf.appendAssumeCapacity(tok),
1128 .macro_file => {
1129 const start = pp.comp.generated_buf.items.len;
1130 const source = pp.comp.getSource(pp.expansion_source_loc.id);
1131 const w = pp.comp.generated_buf.writer(pp.gpa);
1132 try w.print("\"{s}\"\n", .{source.path});
1133
1134 buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .string_literal, tok));
1135 },
1136 .macro_line => {
1137 const start = pp.comp.generated_buf.items.len;
1138 const source = pp.comp.getSource(pp.expansion_source_loc.id);
1139 const w = pp.comp.generated_buf.writer(pp.gpa);
1140 try w.print("{d}\n", .{source.physicalLine(pp.expansion_source_loc)});
1141
1142 buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
1143 },
1144 .macro_counter => {
1145 defer pp.counter += 1;
1146 const start = pp.comp.generated_buf.items.len;
1147 const w = pp.comp.generated_buf.writer(pp.gpa);
1148 try w.print("{d}\n", .{pp.counter});
1149
1150 buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
1151 },
1152 else => buf.appendAssumeCapacity(tok),
1153 }
1154 }
1155
1156 return buf;
1157}
1158
1159/// Join a possibly-parenthesized series of string literal tokens into a single string without
1160/// leading or trailing quotes. The returned slice is invalidated if pp.char_buf changes.
1161/// Returns error.ExpectedStringLiteral if parentheses are not balanced, a non-string-literal
1162/// is encountered, or if no string literals are encountered
1163/// TODO: destringize (replace all '\\' with a single `\` and all '\"' with a '"')
1164fn pasteStringsUnsafe(pp: *Preprocessor, toks: []const Token) ![]const u8 {
1165 const char_top = pp.char_buf.items.len;
1166 defer pp.char_buf.items.len = char_top;
1167 var unwrapped = toks;
1168 if (toks.len >= 2 and toks[0].id == .l_paren and toks[toks.len - 1].id == .r_paren) {
1169 unwrapped = toks[1 .. toks.len - 1];
1170 }
1171 if (unwrapped.len == 0) return error.ExpectedStringLiteral;
1172
1173 for (unwrapped) |tok| {
1174 if (tok.id == .macro_ws) continue;
1175 if (tok.id != .string_literal) return error.ExpectedStringLiteral;
1176 const str = pp.expandedSlice(tok);
1177 try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
1178 }
1179 return pp.char_buf.items[char_top..];
1180}
1181
1182/// Handle the _Pragma operator (implemented as a builtin macro)
1183fn pragmaOperator(pp: *Preprocessor, arg_tok: Token, operator_loc: Source.Location) !void {
1184 const arg_slice = pp.expandedSlice(arg_tok);
1185 const content = arg_slice[1 .. arg_slice.len - 1];
1186 const directive = "#pragma ";
1187
1188 pp.char_buf.clearRetainingCapacity();
1189 const total_len = directive.len + content.len + 1; // destringify can never grow the string, + 1 for newline
1190 try pp.char_buf.ensureUnusedCapacity(total_len);
1191 pp.char_buf.appendSliceAssumeCapacity(directive);
1192 pp.destringify(content);
1193 pp.char_buf.appendAssumeCapacity('\n');
1194
1195 const start = pp.comp.generated_buf.items.len;
1196 try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items);
1197 var tmp_tokenizer = Tokenizer{
1198 .buf = pp.comp.generated_buf.items,
1199 .langopts = pp.comp.langopts,
1200 .index = @intCast(start),
1201 .source = .generated,
1202 .line = pp.generated_line,
1203 };
1204 pp.generated_line += 1;
1205 const hash_tok = tmp_tokenizer.next();
1206 assert(hash_tok.id == .hash);
1207 const pragma_tok = tmp_tokenizer.next();
1208 assert(pragma_tok.id == .keyword_pragma);
1209 try pp.pragma(&tmp_tokenizer, pragma_tok, operator_loc, arg_tok.expansionSlice());
1210}
1211
1212/// Inverts the output of the preprocessor stringify (#) operation
1213/// (except all whitespace is condensed to a single space)
1214/// writes output to pp.char_buf; assumes capacity is sufficient
1215/// backslash backslash -> backslash
1216/// backslash doublequote -> doublequote
1217/// All other characters remain the same
1218fn destringify(pp: *Preprocessor, str: []const u8) void {
1219 var state: enum { start, backslash_seen } = .start;
1220 for (str) |c| {
1221 switch (c) {
1222 '\\' => {
1223 if (state == .backslash_seen) pp.char_buf.appendAssumeCapacity(c);
1224 state = if (state == .start) .backslash_seen else .start;
1225 },
1226 else => {
1227 if (state == .backslash_seen and c != '"') pp.char_buf.appendAssumeCapacity('\\');
1228 pp.char_buf.appendAssumeCapacity(c);
1229 state = .start;
1230 },
1231 }
1232 }
1233}
1234
1235/// Stringify `tokens` into pp.char_buf.
1236/// See https://gcc.gnu.org/onlinedocs/gcc-11.2.0/cpp/Stringizing.html#Stringizing
1237fn stringify(pp: *Preprocessor, tokens: []const Token) !void {
1238 try pp.char_buf.append('"');
1239 var ws_state: enum { start, need, not_needed } = .start;
1240 for (tokens) |tok| {
1241 if (tok.id == .macro_ws) {
1242 if (ws_state == .start) continue;
1243 ws_state = .need;
1244 continue;
1245 }
1246 if (ws_state == .need) try pp.char_buf.append(' ');
1247 ws_state = .not_needed;
1248
1249 // backslashes not inside strings are not escaped
1250 const is_str = switch (tok.id) {
1251 .string_literal,
1252 .string_literal_utf_16,
1253 .string_literal_utf_8,
1254 .string_literal_utf_32,
1255 .string_literal_wide,
1256 .char_literal,
1257 .char_literal_utf_16,
1258 .char_literal_utf_32,
1259 .char_literal_wide,
1260 => true,
1261 else => false,
1262 };
1263
1264 for (pp.expandedSlice(tok)) |c| {
1265 if (c == '"')
1266 try pp.char_buf.appendSlice("\\\"")
1267 else if (c == '\\' and is_str)
1268 try pp.char_buf.appendSlice("\\\\")
1269 else
1270 try pp.char_buf.append(c);
1271 }
1272 }
1273 if (pp.char_buf.items[pp.char_buf.items.len - 1] == '\\') {
1274 const tok = tokens[tokens.len - 1];
1275 try pp.comp.addDiagnostic(.{
1276 .tag = .invalid_pp_stringify_escape,
1277 .loc = tok.loc,
1278 }, tok.expansionSlice());
1279 pp.char_buf.items.len -= 1;
1280 }
1281 try pp.char_buf.appendSlice("\"\n");
1282}
1283
1284fn reconstructIncludeString(pp: *Preprocessor, param_toks: []const Token, embed_args: ?*[]const Token) !?[]const u8 {
1285 const char_top = pp.char_buf.items.len;
1286 defer pp.char_buf.items.len = char_top;
1287
1288 // Trim leading/trailing whitespace
1289 var begin: usize = 0;
1290 var end: usize = param_toks.len;
1291 while (begin < end and param_toks[begin].id == .macro_ws) : (begin += 1) {}
1292 while (end > begin and param_toks[end - 1].id == .macro_ws) : (end -= 1) {}
1293 const params = param_toks[begin..end];
1294
1295 if (params.len == 0) {
1296 try pp.comp.addDiagnostic(.{
1297 .tag = .expected_filename,
1298 .loc = param_toks[0].loc,
1299 }, param_toks[0].expansionSlice());
1300 return null;
1301 }
1302 // no string pasting
1303 if (embed_args == null and params[0].id == .string_literal and params.len > 1) {
1304 try pp.comp.addDiagnostic(.{
1305 .tag = .closing_paren,
1306 .loc = params[1].loc,
1307 }, params[1].expansionSlice());
1308 return null;
1309 }
1310
1311 for (params, 0..) |tok, i| {
1312 const str = pp.expandedSliceExtra(tok, .preserve_macro_ws);
1313 try pp.char_buf.appendSlice(str);
1314 if (embed_args) |some| {
1315 if ((i == 0 and tok.id == .string_literal) or tok.id == .angle_bracket_right) {
1316 some.* = params[i + 1 ..];
1317 break;
1318 }
1319 }
1320 }
1321
1322 const include_str = pp.char_buf.items[char_top..];
1323 if (include_str.len < 3) {
1324 try pp.comp.addDiagnostic(.{
1325 .tag = .empty_filename,
1326 .loc = params[0].loc,
1327 }, params[0].expansionSlice());
1328 return null;
1329 }
1330
1331 switch (include_str[0]) {
1332 '<' => {
1333 if (include_str[include_str.len - 1] != '>') {
1334 // Ugly hack to find out where the '>' should go, since we don't have the closing ')' location
1335 const start = params[0].loc;
1336 try pp.comp.addDiagnostic(.{
1337 .tag = .header_str_closing,
1338 .loc = .{ .id = start.id, .byte_offset = start.byte_offset + @as(u32, @intCast(include_str.len)) + 1, .line = start.line },
1339 }, params[0].expansionSlice());
1340 try pp.comp.addDiagnostic(.{
1341 .tag = .header_str_match,
1342 .loc = params[0].loc,
1343 }, params[0].expansionSlice());
1344 return null;
1345 }
1346 return include_str;
1347 },
1348 '"' => return include_str,
1349 else => {
1350 try pp.comp.addDiagnostic(.{
1351 .tag = .expected_filename,
1352 .loc = params[0].loc,
1353 }, params[0].expansionSlice());
1354 return null;
1355 },
1356 }
1357}
1358
1359fn handleBuiltinMacro(pp: *Preprocessor, builtin: RawToken.Id, param_toks: []const Token, src_loc: Source.Location) Error!bool {
1360 switch (builtin) {
1361 .macro_param_has_attribute,
1362 .macro_param_has_declspec_attribute,
1363 .macro_param_has_feature,
1364 .macro_param_has_extension,
1365 .macro_param_has_builtin,
1366 => {
1367 var invalid: ?Token = null;
1368 var identifier: ?Token = null;
1369 for (param_toks) |tok| {
1370 if (tok.id == .macro_ws) continue;
1371 if (tok.id == .comment) continue;
1372 if (!tok.id.isMacroIdentifier()) {
1373 invalid = tok;
1374 break;
1375 }
1376 if (identifier) |_| invalid = tok else identifier = tok;
1377 }
1378 if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
1379 if (invalid) |some| {
1380 try pp.comp.addDiagnostic(
1381 .{ .tag = .feature_check_requires_identifier, .loc = some.loc },
1382 some.expansionSlice(),
1383 );
1384 return false;
1385 }
1386
1387 const ident_str = pp.expandedSlice(identifier.?);
1388 return switch (builtin) {
1389 .macro_param_has_attribute => Attribute.fromString(.gnu, null, ident_str) != null,
1390 .macro_param_has_declspec_attribute => {
1391 return if (pp.comp.langopts.declspec_attrs)
1392 Attribute.fromString(.declspec, null, ident_str) != null
1393 else
1394 false;
1395 },
1396 .macro_param_has_feature => features.hasFeature(pp.comp, ident_str),
1397 .macro_param_has_extension => features.hasExtension(pp.comp, ident_str),
1398 .macro_param_has_builtin => pp.comp.hasBuiltin(ident_str),
1399 else => unreachable,
1400 };
1401 },
1402 .macro_param_has_warning => {
1403 const actual_param = pp.pasteStringsUnsafe(param_toks) catch |er| switch (er) {
1404 error.ExpectedStringLiteral => {
1405 try pp.errStr(param_toks[0], .expected_str_literal_in, "__has_warning");
1406 return false;
1407 },
1408 else => |e| return e,
1409 };
1410 if (!mem.startsWith(u8, actual_param, "-W")) {
1411 try pp.errStr(param_toks[0], .malformed_warning_check, "__has_warning");
1412 return false;
1413 }
1414 const warning_name = actual_param[2..];
1415 return Diagnostics.warningExists(warning_name);
1416 },
1417 .macro_param_is_identifier => {
1418 var invalid: ?Token = null;
1419 var identifier: ?Token = null;
1420 for (param_toks) |tok| switch (tok.id) {
1421 .macro_ws => continue,
1422 .comment => continue,
1423 else => {
1424 if (identifier) |_| invalid = tok else identifier = tok;
1425 },
1426 };
1427 if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
1428 if (invalid) |some| {
1429 try pp.comp.addDiagnostic(.{
1430 .tag = .missing_tok_builtin,
1431 .loc = some.loc,
1432 .extra = .{ .tok_id_expected = .r_paren },
1433 }, some.expansionSlice());
1434 return false;
1435 }
1436
1437 const id = identifier.?.id;
1438 return id == .identifier or id == .extended_identifier;
1439 },
1440 .macro_param_has_include, .macro_param_has_include_next => {
1441 const include_str = (try pp.reconstructIncludeString(param_toks, null)) orelse return false;
1442 const include_type: Compilation.IncludeType = switch (include_str[0]) {
1443 '"' => .quotes,
1444 '<' => .angle_brackets,
1445 else => unreachable,
1446 };
1447 const filename = include_str[1 .. include_str.len - 1];
1448 if (builtin == .macro_param_has_include or pp.include_depth == 0) {
1449 if (builtin == .macro_param_has_include_next) {
1450 try pp.comp.addDiagnostic(.{
1451 .tag = .include_next_outside_header,
1452 .loc = src_loc,
1453 }, &.{});
1454 }
1455 return pp.comp.hasInclude(filename, src_loc.id, include_type, .first);
1456 }
1457 return pp.comp.hasInclude(filename, src_loc.id, include_type, .next);
1458 },
1459 else => unreachable,
1460 }
1461}
1462
1463fn expandFuncMacro(
1464 pp: *Preprocessor,
1465 loc: Source.Location,
1466 func_macro: *const Macro,
1467 args: *const MacroArguments,
1468 expanded_args: *const MacroArguments,
1469) MacroError!ExpandBuf {
1470 var buf = ExpandBuf.init(pp.gpa);
1471 try buf.ensureTotalCapacity(func_macro.tokens.len);
1472 errdefer buf.deinit();
1473
1474 var expanded_variable_arguments = ExpandBuf.init(pp.gpa);
1475 defer expanded_variable_arguments.deinit();
1476 var variable_arguments = ExpandBuf.init(pp.gpa);
1477 defer variable_arguments.deinit();
1478
1479 if (func_macro.var_args) {
1480 var i: usize = func_macro.params.len;
1481 while (i < expanded_args.items.len) : (i += 1) {
1482 try variable_arguments.appendSlice(args.items[i]);
1483 try expanded_variable_arguments.appendSlice(expanded_args.items[i]);
1484 if (i != expanded_args.items.len - 1) {
1485 const comma = Token{ .id = .comma, .loc = .{ .id = .generated } };
1486 try variable_arguments.append(comma);
1487 try expanded_variable_arguments.append(comma);
1488 }
1489 }
1490 }
1491
1492 // token concatenation and expansion phase
1493 var tok_i: usize = 0;
1494 while (tok_i < func_macro.tokens.len) : (tok_i += 1) {
1495 const raw = func_macro.tokens[tok_i];
1496 switch (raw.id) {
1497 .hash_hash => while (tok_i + 1 < func_macro.tokens.len) {
1498 const raw_next = func_macro.tokens[tok_i + 1];
1499 tok_i += 1;
1500
1501 var va_opt_buf = ExpandBuf.init(pp.gpa);
1502 defer va_opt_buf.deinit();
1503
1504 const next = switch (raw_next.id) {
1505 .macro_ws => continue,
1506 .hash_hash => continue,
1507 .comment => if (!pp.comp.langopts.preserve_comments_in_macros)
1508 continue
1509 else
1510 &[1]Token{tokFromRaw(raw_next)},
1511 .macro_param, .macro_param_no_expand => if (args.items[raw_next.end].len > 0)
1512 args.items[raw_next.end]
1513 else
1514 &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })},
1515 .keyword_va_args => variable_arguments.items,
1516 .keyword_va_opt => blk: {
1517 try pp.expandVaOpt(&va_opt_buf, raw_next, variable_arguments.items.len != 0);
1518 if (va_opt_buf.items.len == 0) break;
1519 break :blk va_opt_buf.items;
1520 },
1521 else => &[1]Token{tokFromRaw(raw_next)},
1522 };
1523
1524 try pp.pasteTokens(&buf, next);
1525 if (next.len != 0) break;
1526 },
1527 .macro_param_no_expand => {
1528 const slice = if (args.items[raw.end].len > 0)
1529 args.items[raw.end]
1530 else
1531 &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })};
1532 const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
1533 try bufCopyTokens(&buf, slice, &.{raw_loc});
1534 },
1535 .macro_param => {
1536 const arg = expanded_args.items[raw.end];
1537 const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
1538 try bufCopyTokens(&buf, arg, &.{raw_loc});
1539 },
1540 .keyword_va_args => {
1541 const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
1542 try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
1543 },
1544 .keyword_va_opt => {
1545 try pp.expandVaOpt(&buf, raw, variable_arguments.items.len != 0);
1546 },
1547 .stringify_param, .stringify_va_args => {
1548 const arg = if (raw.id == .stringify_va_args)
1549 variable_arguments.items
1550 else
1551 args.items[raw.end];
1552
1553 pp.char_buf.clearRetainingCapacity();
1554 try pp.stringify(arg);
1555
1556 const start = pp.comp.generated_buf.items.len;
1557 try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items);
1558
1559 try buf.append(try pp.makeGeneratedToken(start, .string_literal, tokFromRaw(raw)));
1560 },
1561 .macro_param_has_attribute,
1562 .macro_param_has_declspec_attribute,
1563 .macro_param_has_warning,
1564 .macro_param_has_feature,
1565 .macro_param_has_extension,
1566 .macro_param_has_builtin,
1567 .macro_param_has_include,
1568 .macro_param_has_include_next,
1569 .macro_param_is_identifier,
1570 => {
1571 const arg = expanded_args.items[0];
1572 const result = if (arg.len == 0) blk: {
1573 const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
1574 try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
1575 break :blk false;
1576 } else try pp.handleBuiltinMacro(raw.id, arg, loc);
1577 const start = pp.comp.generated_buf.items.len;
1578 const w = pp.comp.generated_buf.writer(pp.gpa);
1579 try w.print("{}\n", .{@intFromBool(result)});
1580 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1581 },
1582 .macro_param_has_c_attribute => {
1583 const arg = expanded_args.items[0];
1584 const not_found = "0\n";
1585 const result = if (arg.len == 0) blk: {
1586 const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
1587 try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
1588 break :blk not_found;
1589 } else res: {
1590 var invalid: ?Token = null;
1591 var vendor_ident: ?Token = null;
1592 var colon_colon: ?Token = null;
1593 var attr_ident: ?Token = null;
1594 for (arg) |tok| {
1595 if (tok.id == .macro_ws) continue;
1596 if (tok.id == .comment) continue;
1597 if (tok.id == .colon_colon) {
1598 if (colon_colon != null or attr_ident == null) {
1599 invalid = tok;
1600 break;
1601 }
1602 vendor_ident = attr_ident;
1603 attr_ident = null;
1604 colon_colon = tok;
1605 continue;
1606 }
1607 if (!tok.id.isMacroIdentifier()) {
1608 invalid = tok;
1609 break;
1610 }
1611 if (attr_ident) |_| {
1612 invalid = tok;
1613 break;
1614 } else attr_ident = tok;
1615 }
1616 if (vendor_ident != null and attr_ident == null) {
1617 invalid = vendor_ident;
1618 } else if (attr_ident == null and invalid == null) {
1619 invalid = .{ .id = .eof, .loc = loc };
1620 }
1621 if (invalid) |some| {
1622 try pp.comp.addDiagnostic(
1623 .{ .tag = .feature_check_requires_identifier, .loc = some.loc },
1624 some.expansionSlice(),
1625 );
1626 break :res not_found;
1627 }
1628 if (vendor_ident) |some| {
1629 const vendor_str = pp.expandedSlice(some);
1630 const attr_str = pp.expandedSlice(attr_ident.?);
1631 const exists = Attribute.fromString(.gnu, vendor_str, attr_str) != null;
1632
1633 const start = pp.comp.generated_buf.items.len;
1634 try pp.comp.generated_buf.appendSlice(pp.gpa, if (exists) "1\n" else "0\n");
1635 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1636 continue;
1637 }
1638 if (!pp.comp.langopts.standard.atLeast(.c23)) break :res not_found;
1639
1640 const attrs = std.ComptimeStringMap([]const u8, .{
1641 .{ "deprecated", "201904L\n" },
1642 .{ "fallthrough", "201904L\n" },
1643 .{ "maybe_unused", "201904L\n" },
1644 .{ "nodiscard", "202003L\n" },
1645 .{ "noreturn", "202202L\n" },
1646 .{ "_Noreturn", "202202L\n" },
1647 .{ "unsequenced", "202207L\n" },
1648 .{ "reproducible", "202207L\n" },
1649 });
1650
1651 const attr_str = Attribute.normalize(pp.expandedSlice(attr_ident.?));
1652 break :res attrs.get(attr_str) orelse not_found;
1653 };
1654 const start = pp.comp.generated_buf.items.len;
1655 try pp.comp.generated_buf.appendSlice(pp.gpa, result);
1656 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1657 },
1658 .macro_param_has_embed => {
1659 const arg = expanded_args.items[0];
1660 const not_found = "0\n";
1661 const result = if (arg.len == 0) blk: {
1662 const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
1663 try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
1664 break :blk not_found;
1665 } else res: {
1666 var embed_args: []const Token = &.{};
1667 const include_str = (try pp.reconstructIncludeString(arg, &embed_args)) orelse
1668 break :res not_found;
1669
1670 var prev = tokFromRaw(raw);
1671 prev.id = .eof;
1672 var it: struct {
1673 i: u32 = 0,
1674 slice: []const Token,
1675 prev: Token,
1676 fn next(it: *@This()) Token {
1677 while (it.i < it.slice.len) switch (it.slice[it.i].id) {
1678 .macro_ws, .whitespace => it.i += 1,
1679 else => break,
1680 } else return it.prev;
1681 defer it.i += 1;
1682 it.prev = it.slice[it.i];
1683 it.prev.id = .eof;
1684 return it.slice[it.i];
1685 }
1686 } = .{ .slice = embed_args, .prev = prev };
1687
1688 while (true) {
1689 const param_first = it.next();
1690 if (param_first.id == .eof) break;
1691 if (param_first.id != .identifier) {
1692 try pp.comp.addDiagnostic(
1693 .{ .tag = .malformed_embed_param, .loc = param_first.loc },
1694 param_first.expansionSlice(),
1695 );
1696 continue;
1697 }
1698
1699 const char_top = pp.char_buf.items.len;
1700 defer pp.char_buf.items.len = char_top;
1701
1702 const maybe_colon = it.next();
1703 const param = switch (maybe_colon.id) {
1704 .colon_colon => blk: {
1705 // vendor::param
1706 const param = it.next();
1707 if (param.id != .identifier) {
1708 try pp.comp.addDiagnostic(
1709 .{ .tag = .malformed_embed_param, .loc = param.loc },
1710 param.expansionSlice(),
1711 );
1712 continue;
1713 }
1714 const l_paren = it.next();
1715 if (l_paren.id != .l_paren) {
1716 try pp.comp.addDiagnostic(
1717 .{ .tag = .malformed_embed_param, .loc = l_paren.loc },
1718 l_paren.expansionSlice(),
1719 );
1720 continue;
1721 }
1722 break :blk "doesn't exist";
1723 },
1724 .l_paren => Attribute.normalize(pp.expandedSlice(param_first)),
1725 else => {
1726 try pp.comp.addDiagnostic(
1727 .{ .tag = .malformed_embed_param, .loc = maybe_colon.loc },
1728 maybe_colon.expansionSlice(),
1729 );
1730 continue;
1731 },
1732 };
1733
1734 var arg_count: u32 = 0;
1735 var first_arg: Token = undefined;
1736 while (true) {
1737 const next = it.next();
1738 if (next.id == .eof) {
1739 try pp.comp.addDiagnostic(
1740 .{ .tag = .malformed_embed_limit, .loc = param_first.loc },
1741 param_first.expansionSlice(),
1742 );
1743 break;
1744 }
1745 if (next.id == .r_paren) break;
1746 arg_count += 1;
1747 if (arg_count == 1) first_arg = next;
1748 }
1749
1750 if (std.mem.eql(u8, param, "limit")) {
1751 if (arg_count != 1) {
1752 try pp.comp.addDiagnostic(
1753 .{ .tag = .malformed_embed_limit, .loc = param_first.loc },
1754 param_first.expansionSlice(),
1755 );
1756 continue;
1757 }
1758 if (first_arg.id != .pp_num) {
1759 try pp.comp.addDiagnostic(
1760 .{ .tag = .malformed_embed_limit, .loc = param_first.loc },
1761 param_first.expansionSlice(),
1762 );
1763 continue;
1764 }
1765 _ = std.fmt.parseInt(u32, pp.expandedSlice(first_arg), 10) catch {
1766 break :res not_found;
1767 };
1768 } else if (!std.mem.eql(u8, param, "prefix") and !std.mem.eql(u8, param, "suffix") and
1769 !std.mem.eql(u8, param, "if_empty"))
1770 {
1771 break :res not_found;
1772 }
1773 }
1774
1775 const include_type: Compilation.IncludeType = switch (include_str[0]) {
1776 '"' => .quotes,
1777 '<' => .angle_brackets,
1778 else => unreachable,
1779 };
1780 const filename = include_str[1 .. include_str.len - 1];
1781 const contents = (try pp.comp.findEmbed(filename, arg[0].loc.id, include_type, 1)) orelse
1782 break :res not_found;
1783
1784 defer pp.comp.gpa.free(contents);
1785 break :res if (contents.len != 0) "1\n" else "2\n";
1786 };
1787 const start = pp.comp.generated_buf.items.len;
1788 try pp.comp.generated_buf.appendSlice(pp.comp.gpa, result);
1789 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1790 },
1791 .macro_param_pragma_operator => {
1792 const param_toks = expanded_args.items[0];
1793 // Clang and GCC require exactly one token (so, no parentheses or string pasting)
1794 // even though their error messages indicate otherwise. Ours is slightly more
1795 // descriptive.
1796 var invalid: ?Token = null;
1797 var string: ?Token = null;
1798 for (param_toks) |tok| switch (tok.id) {
1799 .string_literal => {
1800 if (string) |_| invalid = tok else string = tok;
1801 },
1802 .macro_ws => continue,
1803 .comment => continue,
1804 else => {
1805 invalid = tok;
1806 break;
1807 },
1808 };
1809 if (string == null and invalid == null) invalid = .{ .loc = loc, .id = .eof };
1810 if (invalid) |some| try pp.comp.addDiagnostic(
1811 .{ .tag = .pragma_operator_string_literal, .loc = some.loc },
1812 some.expansionSlice(),
1813 ) else try pp.pragmaOperator(string.?, loc);
1814 },
1815 .comma => {
1816 if (tok_i + 2 < func_macro.tokens.len and func_macro.tokens[tok_i + 1].id == .hash_hash) {
1817 const hash_hash = func_macro.tokens[tok_i + 1];
1818 var maybe_va_args = func_macro.tokens[tok_i + 2];
1819 var consumed: usize = 2;
1820 if (maybe_va_args.id == .macro_ws and tok_i + 3 < func_macro.tokens.len) {
1821 consumed = 3;
1822 maybe_va_args = func_macro.tokens[tok_i + 3];
1823 }
1824 if (maybe_va_args.id == .keyword_va_args) {
1825 // GNU extension: `, ##__VA_ARGS__` deletes the comma if __VA_ARGS__ is empty
1826 tok_i += consumed;
1827 if (func_macro.params.len == expanded_args.items.len) {
1828 // Empty __VA_ARGS__, drop the comma
1829 try pp.err(hash_hash, .comma_deletion_va_args);
1830 } else if (func_macro.params.len == 0 and expanded_args.items.len == 1 and expanded_args.items[0].len == 0) {
1831 // Ambiguous whether this is "empty __VA_ARGS__" or "__VA_ARGS__ omitted"
1832 if (pp.comp.langopts.standard.isGNU()) {
1833 // GNU standard, drop the comma
1834 try pp.err(hash_hash, .comma_deletion_va_args);
1835 } else {
1836 // C standard, retain the comma
1837 try buf.append(tokFromRaw(raw));
1838 }
1839 } else {
1840 try buf.append(tokFromRaw(raw));
1841 if (expanded_variable_arguments.items.len > 0 or variable_arguments.items.len == func_macro.params.len) {
1842 try pp.err(hash_hash, .comma_deletion_va_args);
1843 }
1844 const raw_loc = Source.Location{
1845 .id = maybe_va_args.source,
1846 .byte_offset = maybe_va_args.start,
1847 .line = maybe_va_args.line,
1848 };
1849 try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
1850 }
1851 continue;
1852 }
1853 }
1854 // Regular comma, no token pasting with __VA_ARGS__
1855 try buf.append(tokFromRaw(raw));
1856 },
1857 else => try buf.append(tokFromRaw(raw)),
1858 }
1859 }
1860 removePlacemarkers(&buf);
1861
1862 return buf;
1863}
1864
1865fn expandVaOpt(
1866 pp: *Preprocessor,
1867 buf: *ExpandBuf,
1868 raw: RawToken,
1869 should_expand: bool,
1870) !void {
1871 if (!should_expand) return;
1872
1873 const source = pp.comp.getSource(raw.source);
1874 var tokenizer: Tokenizer = .{
1875 .buf = source.buf,
1876 .index = raw.start,
1877 .source = raw.source,
1878 .langopts = pp.comp.langopts,
1879 .line = raw.line,
1880 };
1881 while (tokenizer.index < raw.end) {
1882 const tok = tokenizer.next();
1883 try buf.append(tokFromRaw(tok));
1884 }
1885}
1886
1887fn shouldExpand(tok: Token, macro: *Macro) bool {
1888 if (tok.loc.id == macro.loc.id and
1889 tok.loc.byte_offset >= macro.start and
1890 tok.loc.byte_offset <= macro.end)
1891 return false;
1892 for (tok.expansionSlice()) |loc| {
1893 if (loc.id == macro.loc.id and
1894 loc.byte_offset >= macro.start and
1895 loc.byte_offset <= macro.end)
1896 return false;
1897 }
1898 if (tok.flags.expansion_disabled) return false;
1899
1900 return true;
1901}
1902
1903fn bufCopyTokens(buf: *ExpandBuf, tokens: []const Token, src: []const Source.Location) !void {
1904 try buf.ensureUnusedCapacity(tokens.len);
1905 for (tokens) |tok| {
1906 var copy = try tok.dupe(buf.allocator);
1907 errdefer Token.free(copy.expansion_locs, buf.allocator);
1908 try copy.addExpansionLocation(buf.allocator, src);
1909 buf.appendAssumeCapacity(copy);
1910 }
1911}
1912
1913fn nextBufToken(
1914 pp: *Preprocessor,
1915 tokenizer: *Tokenizer,
1916 buf: *ExpandBuf,
1917 start_idx: *usize,
1918 end_idx: *usize,
1919 extend_buf: bool,
1920) Error!Token {
1921 start_idx.* += 1;
1922 if (start_idx.* == buf.items.len and start_idx.* >= end_idx.*) {
1923 if (extend_buf) {
1924 const raw_tok = tokenizer.next();
1925 if (raw_tok.id.isMacroIdentifier() and
1926 pp.poisoned_identifiers.get(pp.tokSlice(raw_tok)) != null)
1927 try pp.err(raw_tok, .poisoned_identifier);
1928
1929 if (raw_tok.id == .nl) pp.add_expansion_nl += 1;
1930
1931 const new_tok = tokFromRaw(raw_tok);
1932 end_idx.* += 1;
1933 try buf.append(new_tok);
1934 return new_tok;
1935 } else {
1936 return Token{ .id = .eof, .loc = .{ .id = .generated } };
1937 }
1938 } else {
1939 return buf.items[start_idx.*];
1940 }
1941}
1942
1943fn collectMacroFuncArguments(
1944 pp: *Preprocessor,
1945 tokenizer: *Tokenizer,
1946 buf: *ExpandBuf,
1947 start_idx: *usize,
1948 end_idx: *usize,
1949 extend_buf: bool,
1950 is_builtin: bool,
1951) !MacroArguments {
1952 const name_tok = buf.items[start_idx.*];
1953 const saved_tokenizer = tokenizer.*;
1954 const old_end = end_idx.*;
1955
1956 while (true) {
1957 const tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
1958 switch (tok.id) {
1959 .nl, .whitespace, .macro_ws => {},
1960 .l_paren => break,
1961 else => {
1962 if (is_builtin) {
1963 try pp.errStr(name_tok, .missing_lparen_after_builtin, pp.expandedSlice(name_tok));
1964 }
1965 // Not a macro function call, go over normal identifier, rewind
1966 tokenizer.* = saved_tokenizer;
1967 end_idx.* = old_end;
1968 return error.MissingLParen;
1969 },
1970 }
1971 }
1972
1973 // collect the arguments.
1974 var parens: u32 = 0;
1975 var args = MacroArguments.init(pp.gpa);
1976 errdefer deinitMacroArguments(pp.gpa, &args);
1977 var curArgument = std.ArrayList(Token).init(pp.gpa);
1978 defer curArgument.deinit();
1979 while (true) {
1980 var tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
1981 tok.flags.is_macro_arg = true;
1982 switch (tok.id) {
1983 .comma => {
1984 if (parens == 0) {
1985 const owned = try curArgument.toOwnedSlice();
1986 errdefer pp.gpa.free(owned);
1987 try args.append(owned);
1988 } else {
1989 const duped = try tok.dupe(pp.gpa);
1990 errdefer Token.free(duped.expansion_locs, pp.gpa);
1991 try curArgument.append(duped);
1992 }
1993 },
1994 .l_paren => {
1995 const duped = try tok.dupe(pp.gpa);
1996 errdefer Token.free(duped.expansion_locs, pp.gpa);
1997 try curArgument.append(duped);
1998 parens += 1;
1999 },
2000 .r_paren => {
2001 if (parens == 0) {
2002 const owned = try curArgument.toOwnedSlice();
2003 errdefer pp.gpa.free(owned);
2004 try args.append(owned);
2005 break;
2006 } else {
2007 const duped = try tok.dupe(pp.gpa);
2008 errdefer Token.free(duped.expansion_locs, pp.gpa);
2009 try curArgument.append(duped);
2010 parens -= 1;
2011 }
2012 },
2013 .eof => {
2014 {
2015 const owned = try curArgument.toOwnedSlice();
2016 errdefer pp.gpa.free(owned);
2017 try args.append(owned);
2018 }
2019 tokenizer.* = saved_tokenizer;
2020 try pp.comp.addDiagnostic(
2021 .{ .tag = .unterminated_macro_arg_list, .loc = name_tok.loc },
2022 name_tok.expansionSlice(),
2023 );
2024 return error.Unterminated;
2025 },
2026 .nl, .whitespace => {
2027 try curArgument.append(.{ .id = .macro_ws, .loc = tok.loc });
2028 },
2029 else => {
2030 const duped = try tok.dupe(pp.gpa);
2031 errdefer Token.free(duped.expansion_locs, pp.gpa);
2032 try curArgument.append(duped);
2033 },
2034 }
2035 }
2036
2037 return args;
2038}
2039
2040fn removeExpandedTokens(pp: *Preprocessor, buf: *ExpandBuf, start: usize, len: usize, moving_end_idx: *usize) !void {
2041 for (buf.items[start .. start + len]) |tok| Token.free(tok.expansion_locs, pp.gpa);
2042 try buf.replaceRange(start, len, &.{});
2043 moving_end_idx.* -|= len;
2044}
2045
2046/// The behavior of `defined` depends on whether we are in a preprocessor
2047/// expression context (#if or #elif) or not.
2048/// In a non-expression context it's just an identifier. Within a preprocessor
2049/// expression it is a unary operator or one-argument function.
2050const EvalContext = enum {
2051 expr,
2052 non_expr,
2053};
2054
2055/// Helper for safely iterating over a slice of tokens while skipping whitespace
2056const TokenIterator = struct {
2057 toks: []const Token,
2058 i: usize,
2059
2060 fn init(toks: []const Token) TokenIterator {
2061 return .{ .toks = toks, .i = 0 };
2062 }
2063
2064 fn nextNoWS(self: *TokenIterator) ?Token {
2065 while (self.i < self.toks.len) : (self.i += 1) {
2066 const tok = self.toks[self.i];
2067 if (tok.id == .whitespace or tok.id == .macro_ws) continue;
2068
2069 self.i += 1;
2070 return tok;
2071 }
2072 return null;
2073 }
2074};
2075
2076fn expandMacroExhaustive(
2077 pp: *Preprocessor,
2078 tokenizer: *Tokenizer,
2079 buf: *ExpandBuf,
2080 start_idx: usize,
2081 end_idx: usize,
2082 extend_buf: bool,
2083 eval_ctx: EvalContext,
2084) MacroError!void {
2085 var moving_end_idx = end_idx;
2086 var advance_index: usize = 0;
2087 // rescan loop
2088 var do_rescan = true;
2089 while (do_rescan) {
2090 do_rescan = false;
2091 // expansion loop
2092 var idx: usize = start_idx + advance_index;
2093 while (idx < moving_end_idx) {
2094 const macro_tok = buf.items[idx];
2095 if (macro_tok.id == .keyword_defined and eval_ctx == .expr) {
2096 idx += 1;
2097 var it = TokenIterator.init(buf.items[idx..moving_end_idx]);
2098 if (it.nextNoWS()) |tok| {
2099 switch (tok.id) {
2100 .l_paren => {
2101 _ = it.nextNoWS(); // eat (what should be) identifier
2102 _ = it.nextNoWS(); // eat (what should be) r paren
2103 },
2104 .identifier, .extended_identifier => {},
2105 else => {},
2106 }
2107 }
2108 idx += it.i;
2109 continue;
2110 }
2111 const macro_entry = pp.defines.getPtr(pp.expandedSlice(macro_tok));
2112 if (macro_entry == null or !shouldExpand(buf.items[idx], macro_entry.?)) {
2113 idx += 1;
2114 continue;
2115 }
2116 if (macro_entry) |macro| macro_handler: {
2117 if (macro.is_func) {
2118 var macro_scan_idx = idx;
2119 // to be saved in case this doesn't turn out to be a call
2120 const args = pp.collectMacroFuncArguments(
2121 tokenizer,
2122 buf,
2123 &macro_scan_idx,
2124 &moving_end_idx,
2125 extend_buf,
2126 macro.is_builtin,
2127 ) catch |er| switch (er) {
2128 error.MissingLParen => {
2129 if (!buf.items[idx].flags.is_macro_arg) buf.items[idx].flags.expansion_disabled = true;
2130 idx += 1;
2131 break :macro_handler;
2132 },
2133 error.Unterminated => {
2134 if (pp.comp.langopts.emulate == .gcc) idx += 1;
2135 try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx, &moving_end_idx);
2136 break :macro_handler;
2137 },
2138 else => |e| return e,
2139 };
2140 defer {
2141 for (args.items) |item| {
2142 pp.gpa.free(item);
2143 }
2144 args.deinit();
2145 }
2146
2147 var args_count: u32 = @intCast(args.items.len);
2148 // if the macro has zero arguments g() args_count is still 1
2149 // an empty token list g() and a whitespace-only token list g( )
2150 // counts as zero arguments for the purposes of argument-count validation
2151 if (args_count == 1 and macro.params.len == 0) {
2152 for (args.items[0]) |tok| {
2153 if (tok.id != .macro_ws) break;
2154 } else {
2155 args_count = 0;
2156 }
2157 }
2158
2159 // Validate argument count.
2160 const extra = Diagnostics.Message.Extra{
2161 .arguments = .{ .expected = @intCast(macro.params.len), .actual = args_count },
2162 };
2163 if (macro.var_args and args_count < macro.params.len) {
2164 try pp.comp.addDiagnostic(
2165 .{ .tag = .expected_at_least_arguments, .loc = buf.items[idx].loc, .extra = extra },
2166 buf.items[idx].expansionSlice(),
2167 );
2168 idx += 1;
2169 try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
2170 continue;
2171 }
2172 if (!macro.var_args and args_count != macro.params.len) {
2173 try pp.comp.addDiagnostic(
2174 .{ .tag = .expected_arguments, .loc = buf.items[idx].loc, .extra = extra },
2175 buf.items[idx].expansionSlice(),
2176 );
2177 idx += 1;
2178 try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
2179 continue;
2180 }
2181 var expanded_args = MacroArguments.init(pp.gpa);
2182 defer deinitMacroArguments(pp.gpa, &expanded_args);
2183 try expanded_args.ensureTotalCapacity(args.items.len);
2184 for (args.items) |arg| {
2185 var expand_buf = ExpandBuf.init(pp.gpa);
2186 errdefer expand_buf.deinit();
2187 try expand_buf.appendSlice(arg);
2188
2189 try pp.expandMacroExhaustive(tokenizer, &expand_buf, 0, expand_buf.items.len, false, eval_ctx);
2190
2191 expanded_args.appendAssumeCapacity(try expand_buf.toOwnedSlice());
2192 }
2193
2194 var res = try pp.expandFuncMacro(macro_tok.loc, macro, &args, &expanded_args);
2195 defer res.deinit();
2196 const tokens_added = res.items.len;
2197
2198 const macro_expansion_locs = macro_tok.expansionSlice();
2199 for (res.items) |*tok| {
2200 try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
2201 try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
2202 }
2203
2204 const tokens_removed = macro_scan_idx - idx + 1;
2205 for (buf.items[idx .. idx + tokens_removed]) |tok| Token.free(tok.expansion_locs, pp.gpa);
2206 try buf.replaceRange(idx, tokens_removed, res.items);
2207
2208 moving_end_idx += tokens_added;
2209 // Overflow here means that we encountered an unterminated argument list
2210 // while expanding the body of this macro.
2211 moving_end_idx -|= tokens_removed;
2212 idx += tokens_added;
2213 do_rescan = true;
2214 } else {
2215 const res = try pp.expandObjMacro(macro);
2216 defer res.deinit();
2217
2218 const macro_expansion_locs = macro_tok.expansionSlice();
2219 var increment_idx_by = res.items.len;
2220 for (res.items, 0..) |*tok, i| {
2221 tok.flags.is_macro_arg = macro_tok.flags.is_macro_arg;
2222 try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
2223 try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
2224 if (tok.id == .keyword_defined and eval_ctx == .expr) {
2225 try pp.comp.addDiagnostic(.{
2226 .tag = .expansion_to_defined,
2227 .loc = tok.loc,
2228 }, tok.expansionSlice());
2229 }
2230
2231 if (i < increment_idx_by and (tok.id == .keyword_defined or pp.defines.contains(pp.expandedSlice(tok.*)))) {
2232 increment_idx_by = i;
2233 }
2234 }
2235
2236 Token.free(buf.items[idx].expansion_locs, pp.gpa);
2237 try buf.replaceRange(idx, 1, res.items);
2238 idx += increment_idx_by;
2239 moving_end_idx = moving_end_idx + res.items.len - 1;
2240 do_rescan = true;
2241 }
2242 }
2243 if (idx - start_idx == advance_index + 1 and !do_rescan) {
2244 advance_index += 1;
2245 }
2246 } // end of replacement phase
2247 }
2248 // end of scanning phase
2249
2250 // trim excess buffer
2251 for (buf.items[moving_end_idx..]) |item| {
2252 Token.free(item.expansion_locs, pp.gpa);
2253 }
2254 buf.items.len = moving_end_idx;
2255}
2256
2257/// Try to expand a macro after a possible candidate has been read from the `tokenizer`
2258/// into the `raw` token passed as argument
2259fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroError!void {
2260 var source_tok = tokFromRaw(raw);
2261 if (!raw.id.isMacroIdentifier()) {
2262 source_tok.id.simplifyMacroKeyword();
2263 return pp.tokens.append(pp.gpa, source_tok);
2264 }
2265 pp.top_expansion_buf.items.len = 0;
2266 try pp.top_expansion_buf.append(source_tok);
2267 pp.expansion_source_loc = source_tok.loc;
2268
2269 try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr);
2270 try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
2271 for (pp.top_expansion_buf.items) |*tok| {
2272 if (tok.id == .macro_ws and !pp.preserve_whitespace) {
2273 Token.free(tok.expansion_locs, pp.gpa);
2274 continue;
2275 }
2276 if (tok.id == .comment and !pp.comp.langopts.preserve_comments_in_macros) {
2277 Token.free(tok.expansion_locs, pp.gpa);
2278 continue;
2279 }
2280 tok.id.simplifyMacroKeywordExtra(true);
2281 pp.tokens.appendAssumeCapacity(tok.*);
2282 }
2283 if (pp.preserve_whitespace) {
2284 try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.add_expansion_nl);
2285 while (pp.add_expansion_nl > 0) : (pp.add_expansion_nl -= 1) {
2286 pp.tokens.appendAssumeCapacity(.{ .id = .nl, .loc = .{
2287 .id = tokenizer.source,
2288 .line = tokenizer.line,
2289 } });
2290 }
2291 }
2292}
2293
2294fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 {
2295 if (tok.id.lexeme()) |some| {
2296 if (!tok.id.allowsDigraphs(pp.comp.langopts) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some;
2297 }
2298 var tmp_tokenizer = Tokenizer{
2299 .buf = pp.comp.getSource(tok.loc.id).buf,
2300 .langopts = pp.comp.langopts,
2301 .index = tok.loc.byte_offset,
2302 .source = .generated,
2303 };
2304 if (tok.id == .macro_string) {
2305 while (true) : (tmp_tokenizer.index += 1) {
2306 if (tmp_tokenizer.buf[tmp_tokenizer.index] == '>') break;
2307 }
2308 return tmp_tokenizer.buf[tok.loc.byte_offset .. tmp_tokenizer.index + 1];
2309 }
2310 const res = tmp_tokenizer.next();
2311 return tmp_tokenizer.buf[res.start..res.end];
2312}
2313
2314/// Get expanded token source string.
2315pub fn expandedSlice(pp: *Preprocessor, tok: Token) []const u8 {
2316 return pp.expandedSliceExtra(tok, .single_macro_ws);
2317}
2318
2319/// Concat two tokens and add the result to pp.generated
2320fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token) Error!void {
2321 const lhs = while (lhs_toks.popOrNull()) |lhs| {
2322 if ((pp.comp.langopts.preserve_comments_in_macros and lhs.id == .comment) or
2323 (lhs.id != .macro_ws and lhs.id != .comment))
2324 break lhs;
2325
2326 Token.free(lhs.expansion_locs, pp.gpa);
2327 } else {
2328 return bufCopyTokens(lhs_toks, rhs_toks, &.{});
2329 };
2330
2331 var rhs_rest: u32 = 1;
2332 const rhs = for (rhs_toks) |rhs| {
2333 if ((pp.comp.langopts.preserve_comments_in_macros and rhs.id == .comment) or
2334 (rhs.id != .macro_ws and rhs.id != .comment))
2335 break rhs;
2336
2337 rhs_rest += 1;
2338 } else {
2339 return lhs_toks.appendAssumeCapacity(lhs);
2340 };
2341 defer Token.free(lhs.expansion_locs, pp.gpa);
2342
2343 const start = pp.comp.generated_buf.items.len;
2344 const end = start + pp.expandedSlice(lhs).len + pp.expandedSlice(rhs).len;
2345 try pp.comp.generated_buf.ensureTotalCapacity(pp.gpa, end + 1); // +1 for a newline
2346 // We cannot use the same slices here since they might be invalidated by `ensureCapacity`
2347 pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(lhs));
2348 pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(rhs));
2349 pp.comp.generated_buf.appendAssumeCapacity('\n');
2350
2351 // Try to tokenize the result.
2352 var tmp_tokenizer = Tokenizer{
2353 .buf = pp.comp.generated_buf.items,
2354 .langopts = pp.comp.langopts,
2355 .index = @intCast(start),
2356 .source = .generated,
2357 };
2358 const pasted_token = tmp_tokenizer.nextNoWSComments();
2359 const next = tmp_tokenizer.nextNoWSComments();
2360 const pasted_id = if (lhs.id == .placemarker and rhs.id == .placemarker)
2361 .placemarker
2362 else
2363 pasted_token.id;
2364 try lhs_toks.append(try pp.makeGeneratedToken(start, pasted_id, lhs));
2365
2366 if (next.id != .nl and next.id != .eof) {
2367 try pp.errStr(
2368 lhs,
2369 .pasting_formed_invalid,
2370 try pp.comp.diagnostics.arena.allocator().dupe(u8, pp.comp.generated_buf.items[start..end]),
2371 );
2372 try lhs_toks.append(tokFromRaw(next));
2373 }
2374
2375 try bufCopyTokens(lhs_toks, rhs_toks[rhs_rest..], &.{});
2376}
2377
2378fn makeGeneratedToken(pp: *Preprocessor, start: usize, id: Token.Id, source: Token) !Token {
2379 var pasted_token = Token{ .id = id, .loc = .{
2380 .id = .generated,
2381 .byte_offset = @intCast(start),
2382 .line = pp.generated_line,
2383 } };
2384 pp.generated_line += 1;
2385 try pasted_token.addExpansionLocation(pp.gpa, &.{source.loc});
2386 try pasted_token.addExpansionLocation(pp.gpa, source.expansionSlice());
2387 return pasted_token;
2388}
2389
2390/// Defines a new macro and warns if it is a duplicate
2391fn defineMacro(pp: *Preprocessor, name_tok: RawToken, macro: Macro) Error!void {
2392 const name_str = pp.tokSlice(name_tok);
2393 const gop = try pp.defines.getOrPut(pp.gpa, name_str);
2394 if (gop.found_existing and !gop.value_ptr.eql(macro, pp)) {
2395 const tag: Diagnostics.Tag = if (gop.value_ptr.is_builtin) .builtin_macro_redefined else .macro_redefined;
2396 const start = pp.comp.diagnostics.list.items.len;
2397 try pp.comp.addDiagnostic(.{
2398 .tag = tag,
2399 .loc = .{ .id = name_tok.source, .byte_offset = name_tok.start, .line = name_tok.line },
2400 .extra = .{ .str = name_str },
2401 }, &.{});
2402 if (!gop.value_ptr.is_builtin and pp.comp.diagnostics.list.items.len != start) {
2403 try pp.comp.addDiagnostic(.{
2404 .tag = .previous_definition,
2405 .loc = gop.value_ptr.loc,
2406 }, &.{});
2407 }
2408 }
2409 if (pp.verbose) {
2410 pp.verboseLog(name_tok, "macro {s} defined", .{name_str});
2411 }
2412 gop.value_ptr.* = macro;
2413}
2414
2415/// Handle a #define directive.
2416fn define(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
2417 // Get macro name and validate it.
2418 const macro_name = tokenizer.nextNoWS();
2419 if (macro_name.id == .keyword_defined) {
2420 try pp.err(macro_name, .defined_as_macro_name);
2421 return skipToNl(tokenizer);
2422 }
2423 if (!macro_name.id.isMacroIdentifier()) {
2424 try pp.err(macro_name, .macro_name_must_be_identifier);
2425 return skipToNl(tokenizer);
2426 }
2427 var macro_name_token_id = macro_name.id;
2428 macro_name_token_id.simplifyMacroKeyword();
2429 switch (macro_name_token_id) {
2430 .identifier, .extended_identifier => {},
2431 else => if (macro_name_token_id.isMacroIdentifier()) {
2432 try pp.err(macro_name, .keyword_macro);
2433 },
2434 }
2435
2436 // Check for function macros and empty defines.
2437 var first = tokenizer.next();
2438 switch (first.id) {
2439 .nl, .eof => return pp.defineMacro(macro_name, .{
2440 .params = &.{},
2441 .tokens = &.{},
2442 .var_args = false,
2443 .loc = tokFromRaw(macro_name).loc,
2444 .start = 0,
2445 .end = 0,
2446 .is_func = false,
2447 }),
2448 .whitespace => first = tokenizer.next(),
2449 .l_paren => return pp.defineFn(tokenizer, macro_name, first),
2450 else => try pp.err(first, .whitespace_after_macro_name),
2451 }
2452 if (first.id == .hash_hash) {
2453 try pp.err(first, .hash_hash_at_start);
2454 return skipToNl(tokenizer);
2455 }
2456 first.id.simplifyMacroKeyword();
2457
2458 pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
2459
2460 var need_ws = false;
2461 // Collect the token body and validate any ## found.
2462 var tok = first;
2463 const end_index = while (true) {
2464 tok.id.simplifyMacroKeyword();
2465 switch (tok.id) {
2466 .hash_hash => {
2467 const next = tokenizer.nextNoWSComments();
2468 switch (next.id) {
2469 .nl, .eof => {
2470 try pp.err(tok, .hash_hash_at_end);
2471 return;
2472 },
2473 .hash_hash => {
2474 try pp.err(next, .hash_hash_at_end);
2475 return;
2476 },
2477 else => {},
2478 }
2479 try pp.token_buf.append(tok);
2480 try pp.token_buf.append(next);
2481 },
2482 .nl, .eof => break tok.start,
2483 .comment => if (pp.comp.langopts.preserve_comments_in_macros) {
2484 if (need_ws) {
2485 need_ws = false;
2486 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2487 }
2488 try pp.token_buf.append(tok);
2489 },
2490 .whitespace => need_ws = true,
2491 .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| {
2492 try pp.err(tok, invalidTokenDiagnostic(tag));
2493 try pp.token_buf.append(tok);
2494 },
2495 .unterminated_comment => try pp.err(tok, .unterminated_comment),
2496 else => {
2497 if (tok.id != .whitespace and need_ws) {
2498 need_ws = false;
2499 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2500 }
2501 try pp.token_buf.append(tok);
2502 },
2503 }
2504 tok = tokenizer.next();
2505 } else unreachable;
2506
2507 const list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
2508 try pp.defineMacro(macro_name, .{
2509 .loc = tokFromRaw(macro_name).loc,
2510 .start = first.start,
2511 .end = end_index,
2512 .tokens = list,
2513 .params = undefined,
2514 .is_func = false,
2515 .var_args = false,
2516 });
2517}
2518
2519/// Handle a function like #define directive.
2520fn defineFn(pp: *Preprocessor, tokenizer: *Tokenizer, macro_name: RawToken, l_paren: RawToken) Error!void {
2521 assert(macro_name.id.isMacroIdentifier());
2522 var params = std.ArrayList([]const u8).init(pp.gpa);
2523 defer params.deinit();
2524
2525 // Parse the parameter list.
2526 var gnu_var_args: []const u8 = "";
2527 var var_args = false;
2528 const start_index = while (true) {
2529 var tok = tokenizer.nextNoWS();
2530 if (tok.id == .r_paren) break tok.end;
2531 if (tok.id == .eof) return pp.err(tok, .unterminated_macro_param_list);
2532 if (tok.id == .ellipsis) {
2533 var_args = true;
2534 const r_paren = tokenizer.nextNoWS();
2535 if (r_paren.id != .r_paren) {
2536 try pp.err(r_paren, .missing_paren_param_list);
2537 try pp.err(l_paren, .to_match_paren);
2538 return skipToNl(tokenizer);
2539 }
2540 break r_paren.end;
2541 }
2542 if (!tok.id.isMacroIdentifier()) {
2543 try pp.err(tok, .invalid_token_param_list);
2544 return skipToNl(tokenizer);
2545 }
2546
2547 try params.append(pp.tokSlice(tok));
2548
2549 tok = tokenizer.nextNoWS();
2550 if (tok.id == .ellipsis) {
2551 try pp.err(tok, .gnu_va_macro);
2552 gnu_var_args = params.pop();
2553 const r_paren = tokenizer.nextNoWS();
2554 if (r_paren.id != .r_paren) {
2555 try pp.err(r_paren, .missing_paren_param_list);
2556 try pp.err(l_paren, .to_match_paren);
2557 return skipToNl(tokenizer);
2558 }
2559 break r_paren.end;
2560 } else if (tok.id == .r_paren) {
2561 break tok.end;
2562 } else if (tok.id != .comma) {
2563 try pp.err(tok, .expected_comma_param_list);
2564 return skipToNl(tokenizer);
2565 }
2566 } else unreachable;
2567
2568 var need_ws = false;
2569 // Collect the body tokens and validate # and ##'s found.
2570 pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
2571 const end_index = tok_loop: while (true) {
2572 var tok = tokenizer.next();
2573 switch (tok.id) {
2574 .nl, .eof => break tok.start,
2575 .whitespace => need_ws = pp.token_buf.items.len != 0,
2576 .comment => if (!pp.comp.langopts.preserve_comments_in_macros) continue else {
2577 if (need_ws) {
2578 need_ws = false;
2579 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2580 }
2581 try pp.token_buf.append(tok);
2582 },
2583 .hash => {
2584 if (tok.id != .whitespace and need_ws) {
2585 need_ws = false;
2586 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2587 }
2588 const param = tokenizer.nextNoWS();
2589 blk: {
2590 if (var_args and param.id == .keyword_va_args) {
2591 tok.id = .stringify_va_args;
2592 try pp.token_buf.append(tok);
2593 continue :tok_loop;
2594 }
2595 if (!param.id.isMacroIdentifier()) break :blk;
2596 const s = pp.tokSlice(param);
2597 if (mem.eql(u8, s, gnu_var_args)) {
2598 tok.id = .stringify_va_args;
2599 try pp.token_buf.append(tok);
2600 continue :tok_loop;
2601 }
2602 for (params.items, 0..) |p, i| {
2603 if (mem.eql(u8, p, s)) {
2604 tok.id = .stringify_param;
2605 tok.end = @intCast(i);
2606 try pp.token_buf.append(tok);
2607 continue :tok_loop;
2608 }
2609 }
2610 }
2611 try pp.err(param, .hash_not_followed_param);
2612 return skipToNl(tokenizer);
2613 },
2614 .hash_hash => {
2615 need_ws = false;
2616 // if ## appears at the beginning, the token buf is still empty
2617 // in this case, error out
2618 if (pp.token_buf.items.len == 0) {
2619 try pp.err(tok, .hash_hash_at_start);
2620 return skipToNl(tokenizer);
2621 }
2622 const saved_tokenizer = tokenizer.*;
2623 const next = tokenizer.nextNoWSComments();
2624 if (next.id == .nl or next.id == .eof) {
2625 try pp.err(tok, .hash_hash_at_end);
2626 return;
2627 }
2628 tokenizer.* = saved_tokenizer;
2629 // convert the previous token to .macro_param_no_expand if it was .macro_param
2630 if (pp.token_buf.items[pp.token_buf.items.len - 1].id == .macro_param) {
2631 pp.token_buf.items[pp.token_buf.items.len - 1].id = .macro_param_no_expand;
2632 }
2633 try pp.token_buf.append(tok);
2634 },
2635 .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| {
2636 try pp.err(tok, invalidTokenDiagnostic(tag));
2637 try pp.token_buf.append(tok);
2638 },
2639 .unterminated_comment => try pp.err(tok, .unterminated_comment),
2640 else => {
2641 if (tok.id != .whitespace and need_ws) {
2642 need_ws = false;
2643 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2644 }
2645 if (var_args and tok.id == .keyword_va_args) {
2646 // do nothing
2647 } else if (var_args and tok.id == .keyword_va_opt) {
2648 const opt_l_paren = tokenizer.next();
2649 if (opt_l_paren.id != .l_paren) {
2650 try pp.err(opt_l_paren, .va_opt_lparen);
2651 return skipToNl(tokenizer);
2652 }
2653 tok.start = opt_l_paren.end;
2654
2655 var parens: u32 = 0;
2656 while (true) {
2657 const opt_tok = tokenizer.next();
2658 switch (opt_tok.id) {
2659 .l_paren => parens += 1,
2660 .r_paren => if (parens == 0) {
2661 break;
2662 } else {
2663 parens -= 1;
2664 },
2665 .nl, .eof => {
2666 try pp.err(opt_tok, .va_opt_rparen);
2667 try pp.err(opt_l_paren, .to_match_paren);
2668 return skipToNl(tokenizer);
2669 },
2670 .whitespace => {},
2671 else => tok.end = opt_tok.end,
2672 }
2673 }
2674 } else if (tok.id.isMacroIdentifier()) {
2675 tok.id.simplifyMacroKeyword();
2676 const s = pp.tokSlice(tok);
2677 if (mem.eql(u8, gnu_var_args, s)) {
2678 tok.id = .keyword_va_args;
2679 } else for (params.items, 0..) |param, i| {
2680 if (mem.eql(u8, param, s)) {
2681 // NOTE: it doesn't matter to assign .macro_param_no_expand
2682 // here in case a ## was the previous token, because
2683 // ## processing will eat this token with the same semantics
2684 tok.id = .macro_param;
2685 tok.end = @intCast(i);
2686 break;
2687 }
2688 }
2689 }
2690 try pp.token_buf.append(tok);
2691 },
2692 }
2693 } else unreachable;
2694
2695 const param_list = try pp.arena.allocator().dupe([]const u8, params.items);
2696 const token_list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
2697 try pp.defineMacro(macro_name, .{
2698 .is_func = true,
2699 .params = param_list,
2700 .var_args = var_args or gnu_var_args.len != 0,
2701 .tokens = token_list,
2702 .loc = tokFromRaw(macro_name).loc,
2703 .start = start_index,
2704 .end = end_index,
2705 });
2706}
2707
2708/// Handle an #embed directive
2709/// embedDirective : ("FILENAME" | <FILENAME>) embedParam*
2710/// embedParam : IDENTIFIER (:: IDENTIFIER)? '(' <tokens> ')'
2711fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
2712 const first = tokenizer.nextNoWS();
2713 const filename_tok = pp.findIncludeFilenameToken(first, tokenizer, .ignore_trailing_tokens) catch |er| switch (er) {
2714 error.InvalidInclude => return,
2715 else => |e| return e,
2716 };
2717 defer Token.free(filename_tok.expansion_locs, pp.gpa);
2718
2719 // Check for empty filename.
2720 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
2721 if (tok_slice.len < 3) {
2722 try pp.err(first, .empty_filename);
2723 return;
2724 }
2725 const filename = tok_slice[1 .. tok_slice.len - 1];
2726 const include_type: Compilation.IncludeType = switch (filename_tok.id) {
2727 .string_literal => .quotes,
2728 .macro_string => .angle_brackets,
2729 else => unreachable,
2730 };
2731
2732 // Index into `token_buf`
2733 const Range = struct {
2734 start: u32,
2735 end: u32,
2736
2737 fn expand(opt_range: ?@This(), pp_: *Preprocessor, tokenizer_: *Tokenizer) !void {
2738 const range = opt_range orelse return;
2739 const slice = pp_.token_buf.items[range.start..range.end];
2740 for (slice) |tok| {
2741 try pp_.expandMacro(tokenizer_, tok);
2742 }
2743 }
2744 };
2745 pp.token_buf.items.len = 0;
2746
2747 var limit: ?u32 = null;
2748 var prefix: ?Range = null;
2749 var suffix: ?Range = null;
2750 var if_empty: ?Range = null;
2751 while (true) {
2752 const param_first = tokenizer.nextNoWS();
2753 switch (param_first.id) {
2754 .nl, .eof => break,
2755 .identifier => {},
2756 else => {
2757 try pp.err(param_first, .malformed_embed_param);
2758 continue;
2759 },
2760 }
2761
2762 const char_top = pp.char_buf.items.len;
2763 defer pp.char_buf.items.len = char_top;
2764
2765 const maybe_colon = tokenizer.colonColon();
2766 const param = switch (maybe_colon.id) {
2767 .colon_colon => blk: {
2768 // vendor::param
2769 const param = tokenizer.nextNoWS();
2770 if (param.id != .identifier) {
2771 try pp.err(param, .malformed_embed_param);
2772 continue;
2773 }
2774 const l_paren = tokenizer.nextNoWS();
2775 if (l_paren.id != .l_paren) {
2776 try pp.err(l_paren, .malformed_embed_param);
2777 continue;
2778 }
2779 try pp.char_buf.appendSlice(Attribute.normalize(pp.tokSlice(param_first)));
2780 try pp.char_buf.appendSlice("::");
2781 try pp.char_buf.appendSlice(Attribute.normalize(pp.tokSlice(param)));
2782 break :blk pp.char_buf.items;
2783 },
2784 .l_paren => Attribute.normalize(pp.tokSlice(param_first)),
2785 else => {
2786 try pp.err(maybe_colon, .malformed_embed_param);
2787 continue;
2788 },
2789 };
2790
2791 const start: u32 = @intCast(pp.token_buf.items.len);
2792 while (true) {
2793 const next = tokenizer.nextNoWS();
2794 if (next.id == .r_paren) break;
2795 if (next.id == .eof) {
2796 try pp.err(maybe_colon, .malformed_embed_param);
2797 break;
2798 }
2799 try pp.token_buf.append(next);
2800 }
2801 const end: u32 = @intCast(pp.token_buf.items.len);
2802
2803 if (std.mem.eql(u8, param, "limit")) {
2804 if (limit != null) {
2805 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "limit");
2806 continue;
2807 }
2808 if (start + 1 != end) {
2809 try pp.err(param_first, .malformed_embed_limit);
2810 continue;
2811 }
2812 const limit_tok = pp.token_buf.items[start];
2813 if (limit_tok.id != .pp_num) {
2814 try pp.err(param_first, .malformed_embed_limit);
2815 continue;
2816 }
2817 limit = std.fmt.parseInt(u32, pp.tokSlice(limit_tok), 10) catch {
2818 try pp.err(limit_tok, .malformed_embed_limit);
2819 continue;
2820 };
2821 pp.token_buf.items.len = start;
2822 } else if (std.mem.eql(u8, param, "prefix")) {
2823 if (prefix != null) {
2824 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "prefix");
2825 continue;
2826 }
2827 prefix = .{ .start = start, .end = end };
2828 } else if (std.mem.eql(u8, param, "suffix")) {
2829 if (suffix != null) {
2830 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "suffix");
2831 continue;
2832 }
2833 suffix = .{ .start = start, .end = end };
2834 } else if (std.mem.eql(u8, param, "if_empty")) {
2835 if (if_empty != null) {
2836 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "if_empty");
2837 continue;
2838 }
2839 if_empty = .{ .start = start, .end = end };
2840 } else {
2841 try pp.errStr(
2842 tokFromRaw(param_first),
2843 .unsupported_embed_param,
2844 try pp.comp.diagnostics.arena.allocator().dupe(u8, param),
2845 );
2846 pp.token_buf.items.len = start;
2847 }
2848 }
2849
2850 const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type, limit)) orelse
2851 return pp.fatalNotFound(filename_tok, filename);
2852 defer pp.comp.gpa.free(embed_bytes);
2853
2854 try Range.expand(prefix, pp, tokenizer);
2855
2856 if (embed_bytes.len == 0) {
2857 try Range.expand(if_empty, pp, tokenizer);
2858 try Range.expand(suffix, pp, tokenizer);
2859 return;
2860 }
2861
2862 try pp.tokens.ensureUnusedCapacity(pp.comp.gpa, 2 * embed_bytes.len - 1); // N bytes and N-1 commas
2863
2864 // TODO: We currently only support systems with CHAR_BIT == 8
2865 // If the target's CHAR_BIT is not 8, we need to write out correctly-sized embed_bytes
2866 // and correctly account for the target's endianness
2867 const writer = pp.comp.generated_buf.writer(pp.gpa);
2868
2869 {
2870 const byte = embed_bytes[0];
2871 const start = pp.comp.generated_buf.items.len;
2872 try writer.print("{d}", .{byte});
2873 pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start, .embed_byte, filename_tok));
2874 }
2875
2876 for (embed_bytes[1..]) |byte| {
2877 const start = pp.comp.generated_buf.items.len;
2878 try writer.print(",{d}", .{byte});
2879 pp.tokens.appendAssumeCapacity(.{ .id = .comma, .loc = .{ .id = .generated, .byte_offset = @intCast(start) } });
2880 pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start + 1, .embed_byte, filename_tok));
2881 }
2882 try pp.comp.generated_buf.append(pp.gpa, '\n');
2883
2884 try Range.expand(suffix, pp, tokenizer);
2885}
2886
2887// Handle a #include directive.
2888fn include(pp: *Preprocessor, tokenizer: *Tokenizer, which: Compilation.WhichInclude) MacroError!void {
2889 const first = tokenizer.nextNoWS();
2890 const new_source = findIncludeSource(pp, tokenizer, first, which) catch |er| switch (er) {
2891 error.InvalidInclude => return,
2892 else => |e| return e,
2893 };
2894
2895 // Prevent stack overflow
2896 pp.include_depth += 1;
2897 defer pp.include_depth -= 1;
2898 if (pp.include_depth > max_include_depth) {
2899 try pp.comp.addDiagnostic(.{
2900 .tag = .too_many_includes,
2901 .loc = .{ .id = first.source, .byte_offset = first.start, .line = first.line },
2902 }, &.{});
2903 return error.StopPreprocessing;
2904 }
2905
2906 if (pp.include_guards.get(new_source.id)) |guard| {
2907 if (pp.defines.contains(guard)) return;
2908 }
2909
2910 if (pp.verbose) {
2911 pp.verboseLog(first, "include file {s}", .{new_source.path});
2912 }
2913
2914 const tokens_start = pp.tokens.len;
2915 try pp.addIncludeStart(new_source);
2916 const eof = pp.preprocessExtra(new_source) catch |er| switch (er) {
2917 error.StopPreprocessing => {
2918 for (pp.tokens.items(.expansion_locs)[tokens_start..]) |loc| Token.free(loc, pp.gpa);
2919 pp.tokens.len = tokens_start;
2920 return;
2921 },
2922 else => |e| return e,
2923 };
2924 try eof.checkMsEof(new_source, pp.comp);
2925 if (pp.preserve_whitespace and pp.tokens.items(.id)[pp.tokens.len - 1] != .nl) {
2926 try pp.tokens.append(pp.gpa, .{ .id = .nl, .loc = .{
2927 .id = tokenizer.source,
2928 .line = tokenizer.line,
2929 } });
2930 }
2931 if (pp.linemarkers == .none) return;
2932 var next = first;
2933 while (true) {
2934 var tmp = tokenizer.*;
2935 next = tmp.nextNoWS();
2936 if (next.id != .nl) break;
2937 tokenizer.* = tmp;
2938 }
2939 try pp.addIncludeResume(next.source, next.end, next.line);
2940}
2941
2942/// tokens that are part of a pragma directive can happen in 3 ways:
2943/// 1. directly in the text via `#pragma ...`
2944/// 2. Via a string literal argument to `_Pragma`
2945/// 3. Via a stringified macro argument which is used as an argument to `_Pragma`
2946/// operator_loc: Location of `_Pragma`; null if this is from #pragma
2947/// arg_locs: expansion locations of the argument to _Pragma. empty if #pragma or a raw string literal was used
2948fn makePragmaToken(pp: *Preprocessor, raw: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !Token {
2949 var tok = tokFromRaw(raw);
2950 if (operator_loc) |loc| {
2951 try tok.addExpansionLocation(pp.gpa, &.{loc});
2952 }
2953 try tok.addExpansionLocation(pp.gpa, arg_locs);
2954 return tok;
2955}
2956
2957/// Handle a pragma directive
2958fn pragma(pp: *Preprocessor, tokenizer: *Tokenizer, pragma_tok: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !void {
2959 const name_tok = tokenizer.nextNoWS();
2960 if (name_tok.id == .nl or name_tok.id == .eof) return;
2961
2962 const name = pp.tokSlice(name_tok);
2963 try pp.tokens.append(pp.gpa, try pp.makePragmaToken(pragma_tok, operator_loc, arg_locs));
2964 const pragma_start: u32 = @intCast(pp.tokens.len);
2965
2966 const pragma_name_tok = try pp.makePragmaToken(name_tok, operator_loc, arg_locs);
2967 try pp.tokens.append(pp.gpa, pragma_name_tok);
2968 while (true) {
2969 const next_tok = tokenizer.next();
2970 if (next_tok.id == .whitespace) continue;
2971 if (next_tok.id == .eof) {
2972 try pp.tokens.append(pp.gpa, .{
2973 .id = .nl,
2974 .loc = .{ .id = .generated },
2975 });
2976 break;
2977 }
2978 try pp.tokens.append(pp.gpa, try pp.makePragmaToken(next_tok, operator_loc, arg_locs));
2979 if (next_tok.id == .nl) break;
2980 }
2981 if (pp.comp.getPragma(name)) |prag| unknown: {
2982 return prag.preprocessorCB(pp, pragma_start) catch |er| switch (er) {
2983 error.UnknownPragma => break :unknown,
2984 else => |e| return e,
2985 };
2986 }
2987 return pp.comp.addDiagnostic(.{
2988 .tag = .unknown_pragma,
2989 .loc = pragma_name_tok.loc,
2990 }, pragma_name_tok.expansionSlice());
2991}
2992
2993fn findIncludeFilenameToken(
2994 pp: *Preprocessor,
2995 first_token: RawToken,
2996 tokenizer: *Tokenizer,
2997 trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof },
2998) !Token {
2999 var first = first_token;
3000
3001 if (first.id == .angle_bracket_left) to_end: {
3002 // The tokenizer does not handle <foo> include strings so do it here.
3003 while (tokenizer.index < tokenizer.buf.len) : (tokenizer.index += 1) {
3004 switch (tokenizer.buf[tokenizer.index]) {
3005 '>' => {
3006 tokenizer.index += 1;
3007 first.end = tokenizer.index;
3008 first.id = .macro_string;
3009 break :to_end;
3010 },
3011 '\n' => break,
3012 else => {},
3013 }
3014 }
3015 try pp.comp.addDiagnostic(.{
3016 .tag = .header_str_closing,
3017 .loc = .{ .id = first.source, .byte_offset = tokenizer.index, .line = first.line },
3018 }, &.{});
3019 try pp.err(first, .header_str_match);
3020 }
3021
3022 const source_tok = tokFromRaw(first);
3023 const filename_tok, const expanded_trailing = switch (source_tok.id) {
3024 .string_literal, .macro_string => .{ source_tok, false },
3025 else => expanded: {
3026 // Try to expand if the argument is a macro.
3027 pp.top_expansion_buf.items.len = 0;
3028 defer for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
3029 try pp.top_expansion_buf.append(source_tok);
3030 pp.expansion_source_loc = source_tok.loc;
3031
3032 try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr);
3033 var trailing_toks: []const Token = &.{};
3034 const include_str = (try pp.reconstructIncludeString(pp.top_expansion_buf.items, &trailing_toks)) orelse {
3035 try pp.err(first, .expected_filename);
3036 try pp.expectNl(tokenizer);
3037 return error.InvalidInclude;
3038 };
3039 const start = pp.comp.generated_buf.items.len;
3040 try pp.comp.generated_buf.appendSlice(pp.gpa, include_str);
3041
3042 break :expanded .{ try pp.makeGeneratedToken(start, switch (include_str[0]) {
3043 '"' => .string_literal,
3044 '<' => .macro_string,
3045 else => unreachable,
3046 }, pp.top_expansion_buf.items[0]), trailing_toks.len != 0 };
3047 },
3048 };
3049
3050 switch (trailing_token_behavior) {
3051 .expect_nl_eof => {
3052 // Error on extra tokens.
3053 const nl = tokenizer.nextNoWS();
3054 if ((nl.id != .nl and nl.id != .eof) or expanded_trailing) {
3055 skipToNl(tokenizer);
3056 try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{
3057 .tag = .extra_tokens_directive_end,
3058 .loc = filename_tok.loc,
3059 }, filename_tok.expansionSlice(), false);
3060 }
3061 },
3062 .ignore_trailing_tokens => if (expanded_trailing) {
3063 try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{
3064 .tag = .extra_tokens_directive_end,
3065 .loc = filename_tok.loc,
3066 }, filename_tok.expansionSlice(), false);
3067 },
3068 }
3069 return filename_tok;
3070}
3071
3072fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source {
3073 const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof);
3074 defer Token.free(filename_tok.expansion_locs, pp.gpa);
3075
3076 // Check for empty filename.
3077 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
3078 if (tok_slice.len < 3) {
3079 try pp.err(first, .empty_filename);
3080 return error.InvalidInclude;
3081 }
3082
3083 // Find the file.
3084 const filename = tok_slice[1 .. tok_slice.len - 1];
3085 const include_type: Compilation.IncludeType = switch (filename_tok.id) {
3086 .string_literal => .quotes,
3087 .macro_string => .angle_brackets,
3088 else => unreachable,
3089 };
3090
3091 return (try pp.comp.findInclude(filename, first, include_type, which)) orelse
3092 return pp.fatalNotFound(filename_tok, filename);
3093}
3094
3095fn printLinemarker(
3096 pp: *Preprocessor,
3097 w: anytype,
3098 line_no: u32,
3099 source: Source,
3100 start_resume: enum(u8) { start, @"resume", none },
3101) !void {
3102 try w.writeByte('#');
3103 if (pp.linemarkers == .line_directives) try w.writeAll("line");
3104 // line_no is 0 indexed
3105 try w.print(" {d} \"", .{line_no + 1});
3106 for (source.path) |byte| switch (byte) {
3107 '\n' => try w.writeAll("\\n"),
3108 '\r' => try w.writeAll("\\r"),
3109 '\t' => try w.writeAll("\\t"),
3110 '\\' => try w.writeAll("\\\\"),
3111 '"' => try w.writeAll("\\\""),
3112 ' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte),
3113 // Use hex escapes for any non-ASCII/unprintable characters.
3114 // This ensures that the parsed version of this string will end up
3115 // containing the same bytes as the input regardless of encoding.
3116 else => {
3117 try w.writeAll("\\x");
3118 try std.fmt.formatInt(byte, 16, .lower, .{ .width = 2, .fill = '0' }, w);
3119 },
3120 };
3121 try w.writeByte('"');
3122 if (pp.linemarkers == .numeric_directives) {
3123 switch (start_resume) {
3124 .none => {},
3125 .start => try w.writeAll(" 1"),
3126 .@"resume" => try w.writeAll(" 2"),
3127 }
3128 switch (source.kind) {
3129 .user => {},
3130 .system => try w.writeAll(" 3"),
3131 .extern_c_system => try w.writeAll(" 3 4"),
3132 }
3133 }
3134 try w.writeByte('\n');
3135}
3136
3137// After how many empty lines are needed to replace them with linemarkers.
3138const collapse_newlines = 8;
3139
3140/// Pretty print tokens and try to preserve whitespace.
3141pub fn prettyPrintTokens(pp: *Preprocessor, w: anytype) !void {
3142 const tok_ids = pp.tokens.items(.id);
3143
3144 var i: u32 = 0;
3145 var last_nl = true;
3146 outer: while (true) : (i += 1) {
3147 var cur: Token = pp.tokens.get(i);
3148 switch (cur.id) {
3149 .eof => {
3150 if (!last_nl) try w.writeByte('\n');
3151 return;
3152 },
3153 .nl => {
3154 var newlines: u32 = 0;
3155 for (tok_ids[i..], i..) |id, j| {
3156 if (id == .nl) {
3157 newlines += 1;
3158 } else if (id == .eof) {
3159 if (!last_nl) try w.writeByte('\n');
3160 return;
3161 } else if (id != .whitespace) {
3162 if (pp.linemarkers == .none) {
3163 if (newlines < 2) break;
3164 } else if (newlines < collapse_newlines) {
3165 break;
3166 }
3167
3168 i = @intCast((j - 1) - @intFromBool(tok_ids[j - 1] == .whitespace));
3169 if (!last_nl) try w.writeAll("\n");
3170 if (pp.linemarkers != .none) {
3171 const next = pp.tokens.get(i);
3172 const source = pp.comp.getSource(next.loc.id);
3173 const line_col = source.lineCol(next.loc);
3174 try pp.printLinemarker(w, line_col.line_no, source, .none);
3175 last_nl = true;
3176 }
3177 continue :outer;
3178 }
3179 }
3180 last_nl = true;
3181 try w.writeAll("\n");
3182 },
3183 .keyword_pragma => {
3184 const pragma_name = pp.expandedSlice(pp.tokens.get(i + 1));
3185 const end_idx = mem.indexOfScalarPos(Token.Id, tok_ids, i, .nl) orelse i + 1;
3186 const pragma_len = @as(u32, @intCast(end_idx)) - i;
3187
3188 if (pp.comp.getPragma(pragma_name)) |prag| {
3189 if (!prag.shouldPreserveTokens(pp, i + 1)) {
3190 try w.writeByte('\n');
3191 i += pragma_len;
3192 cur = pp.tokens.get(i);
3193 continue;
3194 }
3195 }
3196 try w.writeAll("#pragma");
3197 i += 1;
3198 while (true) : (i += 1) {
3199 cur = pp.tokens.get(i);
3200 if (cur.id == .nl) {
3201 try w.writeByte('\n');
3202 last_nl = true;
3203 break;
3204 }
3205 try w.writeByte(' ');
3206 const slice = pp.expandedSlice(cur);
3207 try w.writeAll(slice);
3208 }
3209 },
3210 .whitespace => {
3211 var slice = pp.expandedSlice(cur);
3212 while (mem.indexOfScalar(u8, slice, '\n')) |some| {
3213 if (pp.linemarkers != .none) try w.writeByte('\n');
3214 slice = slice[some + 1 ..];
3215 }
3216 for (slice) |_| try w.writeByte(' ');
3217 last_nl = false;
3218 },
3219 .include_start => {
3220 const source = pp.comp.getSource(cur.loc.id);
3221
3222 try pp.printLinemarker(w, 0, source, .start);
3223 last_nl = true;
3224 },
3225 .include_resume => {
3226 const source = pp.comp.getSource(cur.loc.id);
3227 const line_col = source.lineCol(cur.loc);
3228 if (!last_nl) try w.writeAll("\n");
3229
3230 try pp.printLinemarker(w, line_col.line_no, source, .@"resume");
3231 last_nl = true;
3232 },
3233 else => {
3234 const slice = pp.expandedSlice(cur);
3235 try w.writeAll(slice);
3236 last_nl = false;
3237 },
3238 }
3239 }
3240}
3241
3242test "Preserve pragma tokens sometimes" {
3243 const allocator = std.testing.allocator;
3244 const Test = struct {
3245 fn runPreprocessor(source_text: []const u8) ![]const u8 {
3246 var buf = std.ArrayList(u8).init(allocator);
3247 defer buf.deinit();
3248
3249 var comp = Compilation.init(allocator);
3250 defer comp.deinit();
3251
3252 try comp.addDefaultPragmaHandlers();
3253
3254 var pp = Preprocessor.init(&comp);
3255 defer pp.deinit();
3256
3257 pp.preserve_whitespace = true;
3258 assert(pp.linemarkers == .none);
3259
3260 const test_runner_macros = try comp.addSourceFromBuffer("<test_runner>", source_text);
3261 const eof = try pp.preprocess(test_runner_macros);
3262 try pp.tokens.append(pp.gpa, eof);
3263 try pp.prettyPrintTokens(buf.writer());
3264 return allocator.dupe(u8, buf.items);
3265 }
3266
3267 fn check(source_text: []const u8, expected: []const u8) !void {
3268 const output = try runPreprocessor(source_text);
3269 defer allocator.free(output);
3270
3271 try std.testing.expectEqualStrings(expected, output);
3272 }
3273 };
3274 const preserve_gcc_diagnostic =
3275 \\#pragma GCC diagnostic error "-Wnewline-eof"
3276 \\#pragma GCC warning error "-Wnewline-eof"
3277 \\int x;
3278 \\#pragma GCC ignored error "-Wnewline-eof"
3279 \\
3280 ;
3281 try Test.check(preserve_gcc_diagnostic, preserve_gcc_diagnostic);
3282
3283 const omit_once =
3284 \\#pragma once
3285 \\int x;
3286 \\#pragma once
3287 \\
3288 ;
3289 // TODO should only be one newline afterwards when emulating clang
3290 try Test.check(omit_once, "\nint x;\n\n");
3291
3292 const omit_poison =
3293 \\#pragma GCC poison foobar
3294 \\
3295 ;
3296 try Test.check(omit_poison, "\n");
3297}
3298
3299test "destringify" {
3300 const allocator = std.testing.allocator;
3301 const Test = struct {
3302 fn testDestringify(pp: *Preprocessor, stringified: []const u8, destringified: []const u8) !void {
3303 pp.char_buf.clearRetainingCapacity();
3304 try pp.char_buf.ensureUnusedCapacity(stringified.len);
3305 pp.destringify(stringified);
3306 try std.testing.expectEqualStrings(destringified, pp.char_buf.items);
3307 }
3308 };
3309 var comp = Compilation.init(allocator);
3310 defer comp.deinit();
3311 var pp = Preprocessor.init(&comp);
3312 defer pp.deinit();
3313
3314 try Test.testDestringify(&pp, "hello\tworld\n", "hello\tworld\n");
3315 try Test.testDestringify(&pp,
3316 \\ \"FOO BAR BAZ\"
3317 ,
3318 \\ "FOO BAR BAZ"
3319 );
3320 try Test.testDestringify(&pp,
3321 \\ \\t\\n
3322 \\
3323 ,
3324 \\ \t\n
3325 \\
3326 );
3327}
3328
3329test "Include guards" {
3330 const Test = struct {
3331 /// This is here so that when #elifdef / #elifndef are added we don't forget
3332 /// to test that they don't accidentally break include guard detection
3333 fn pairsWithIfndef(tok_id: RawToken.Id) bool {
3334 return switch (tok_id) {
3335 .keyword_elif,
3336 .keyword_elifdef,
3337 .keyword_elifndef,
3338 .keyword_else,
3339 => true,
3340
3341 .keyword_include,
3342 .keyword_include_next,
3343 .keyword_embed,
3344 .keyword_define,
3345 .keyword_defined,
3346 .keyword_undef,
3347 .keyword_ifdef,
3348 .keyword_ifndef,
3349 .keyword_error,
3350 .keyword_warning,
3351 .keyword_pragma,
3352 .keyword_line,
3353 .keyword_endif,
3354 => false,
3355 else => unreachable,
3356 };
3357 }
3358
3359 fn skippable(tok_id: RawToken.Id) bool {
3360 return switch (tok_id) {
3361 .keyword_defined, .keyword_va_args, .keyword_va_opt, .keyword_endif => true,
3362 else => false,
3363 };
3364 }
3365
3366 fn testIncludeGuard(allocator: std.mem.Allocator, comptime template: []const u8, tok_id: RawToken.Id, expected_guards: u32) !void {
3367 var comp = Compilation.init(allocator);
3368 defer comp.deinit();
3369 var pp = Preprocessor.init(&comp);
3370 defer pp.deinit();
3371
3372 const path = try std.fs.path.join(allocator, &.{ ".", "bar.h" });
3373 defer allocator.free(path);
3374
3375 _ = try comp.addSourceFromBuffer(path, "int bar = 5;\n");
3376
3377 var buf = std.ArrayList(u8).init(allocator);
3378 defer buf.deinit();
3379
3380 var writer = buf.writer();
3381 switch (tok_id) {
3382 .keyword_include, .keyword_include_next => try writer.print(template, .{ tok_id.lexeme().?, " \"bar.h\"" }),
3383 .keyword_define, .keyword_undef => try writer.print(template, .{ tok_id.lexeme().?, " BAR" }),
3384 .keyword_ifndef,
3385 .keyword_ifdef,
3386 .keyword_elifdef,
3387 .keyword_elifndef,
3388 => try writer.print(template, .{ tok_id.lexeme().?, " BAR\n#endif" }),
3389 else => try writer.print(template, .{ tok_id.lexeme().?, "" }),
3390 }
3391 const source = try comp.addSourceFromBuffer("test.h", buf.items);
3392 _ = try pp.preprocess(source);
3393
3394 try std.testing.expectEqual(expected_guards, pp.include_guards.count());
3395 }
3396 };
3397 const tags = std.meta.tags(RawToken.Id);
3398 for (tags) |tag| {
3399 if (Test.skippable(tag)) continue;
3400 var copy = tag;
3401 copy.simplifyMacroKeyword();
3402 if (copy != tag or tag == .keyword_else) {
3403 const inside_ifndef_template =
3404 \\//Leading comment (should be ignored)
3405 \\
3406 \\#ifndef FOO
3407 \\#{s}{s}
3408 \\#endif
3409 ;
3410 const expected_guards: u32 = if (Test.pairsWithIfndef(tag)) 0 else 1;
3411 try Test.testIncludeGuard(std.testing.allocator, inside_ifndef_template, tag, expected_guards);
3412
3413 const outside_ifndef_template =
3414 \\#ifndef FOO
3415 \\#endif
3416 \\#{s}{s}
3417 ;
3418 try Test.testIncludeGuard(std.testing.allocator, outside_ifndef_template, tag, 0);
3419 }
3420 }
3421}
deps/aro/aro/Source.zig deleted-127
......@@ -1,127 +0,0 @@
1const std = @import("std");
2
3pub const Id = enum(u32) {
4 unused = 0,
5 generated = 1,
6 _,
7};
8
9/// Classifies the file for line marker output in -E mode
10pub const Kind = enum {
11 /// regular file
12 user,
13 /// Included from a system include directory
14 system,
15 /// Included from an "implicit extern C" directory
16 extern_c_system,
17};
18
19pub const Location = struct {
20 id: Id = .unused,
21 byte_offset: u32 = 0,
22 line: u32 = 0,
23
24 pub fn eql(a: Location, b: Location) bool {
25 return a.id == b.id and a.byte_offset == b.byte_offset and a.line == b.line;
26 }
27};
28
29const Source = @This();
30
31path: []const u8,
32buf: []const u8,
33id: Id,
34/// each entry represents a byte position within `buf` where a backslash+newline was deleted
35/// from the original raw buffer. The same position can appear multiple times if multiple
36/// consecutive splices happened. Guaranteed to be non-decreasing
37splice_locs: []const u32,
38kind: Kind,
39
40/// Todo: binary search instead of scanning entire `splice_locs`.
41pub fn numSplicesBefore(source: Source, byte_offset: u32) u32 {
42 for (source.splice_locs, 0..) |splice_offset, i| {
43 if (splice_offset > byte_offset) return @intCast(i);
44 }
45 return @intCast(source.splice_locs.len);
46}
47
48/// Returns the actual line number (before newline splicing) of a Location
49/// This corresponds to what the user would actually see in their text editor
50pub fn physicalLine(source: Source, loc: Location) u32 {
51 return loc.line + source.numSplicesBefore(loc.byte_offset);
52}
53
54const LineCol = struct { line: []const u8, line_no: u32, col: u32, width: u32, end_with_splice: bool };
55
56pub fn lineCol(source: Source, loc: Location) LineCol {
57 var start: usize = 0;
58 // find the start of the line which is either a newline or a splice
59 if (std.mem.lastIndexOfScalar(u8, source.buf[0..loc.byte_offset], '\n')) |some| start = some + 1;
60 const splice_index: u32 = for (source.splice_locs, 0..) |splice_offset, i| {
61 if (splice_offset > start) {
62 if (splice_offset < loc.byte_offset) {
63 start = splice_offset;
64 break @as(u32, @intCast(i)) + 1;
65 }
66 break @intCast(i);
67 }
68 } else @intCast(source.splice_locs.len);
69 var i: usize = start;
70 var col: u32 = 1;
71 var width: u32 = 0;
72
73 while (i < loc.byte_offset) : (col += 1) { // TODO this is still incorrect, but better
74 const len = std.unicode.utf8ByteSequenceLength(source.buf[i]) catch {
75 i += 1;
76 continue;
77 };
78 const cp = std.unicode.utf8Decode(source.buf[i..][0..len]) catch {
79 i += 1;
80 continue;
81 };
82 width += codepointWidth(cp);
83 i += len;
84 }
85
86 // find the end of the line which is either a newline, EOF or a splice
87 var nl = source.buf.len;
88 var end_with_splice = false;
89 if (std.mem.indexOfScalar(u8, source.buf[start..], '\n')) |some| nl = some + start;
90 if (source.splice_locs.len > splice_index and nl > source.splice_locs[splice_index] and source.splice_locs[splice_index] > start) {
91 end_with_splice = true;
92 nl = source.splice_locs[splice_index];
93 }
94 return .{
95 .line = source.buf[start..nl],
96 .line_no = loc.line + splice_index,
97 .col = col,
98 .width = width,
99 .end_with_splice = end_with_splice,
100 };
101}
102
103fn codepointWidth(cp: u32) u32 {
104 return switch (cp) {
105 0x1100...0x115F,
106 0x2329,
107 0x232A,
108 0x2E80...0x303F,
109 0x3040...0x3247,
110 0x3250...0x4DBF,
111 0x4E00...0xA4C6,
112 0xA960...0xA97C,
113 0xAC00...0xD7A3,
114 0xF900...0xFAFF,
115 0xFE10...0xFE19,
116 0xFE30...0xFE6B,
117 0xFF01...0xFF60,
118 0xFFE0...0xFFE6,
119 0x1B000...0x1B001,
120 0x1F200...0x1F251,
121 0x20000...0x3FFFD,
122 0x1F300...0x1F5FF,
123 0x1F900...0x1F9FF,
124 => 2,
125 else => 1,
126 };
127}
deps/aro/aro/StringInterner.zig deleted-83
......@@ -1,83 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("Compilation.zig");
4
5const StringToIdMap = std.StringHashMapUnmanaged(StringId);
6
7pub const StringId = enum(u32) {
8 empty,
9 _,
10};
11
12pub const TypeMapper = struct {
13 const LookupSpeed = enum {
14 fast,
15 slow,
16 };
17
18 data: union(LookupSpeed) {
19 fast: []const []const u8,
20 slow: *const StringToIdMap,
21 },
22
23 pub fn lookup(self: TypeMapper, string_id: StringInterner.StringId) []const u8 {
24 if (string_id == .empty) return "";
25 switch (self.data) {
26 .fast => |arr| return arr[@intFromEnum(string_id)],
27 .slow => |map| {
28 var it = map.iterator();
29 while (it.next()) |entry| {
30 if (entry.value_ptr.* == string_id) return entry.key_ptr.*;
31 }
32 unreachable;
33 },
34 }
35 }
36
37 pub fn deinit(self: TypeMapper, allocator: mem.Allocator) void {
38 switch (self.data) {
39 .slow => {},
40 .fast => |arr| allocator.free(arr),
41 }
42 }
43};
44
45const StringInterner = @This();
46
47string_table: StringToIdMap = .{},
48next_id: StringId = @enumFromInt(@intFromEnum(StringId.empty) + 1),
49
50pub fn deinit(self: *StringInterner, allocator: mem.Allocator) void {
51 self.string_table.deinit(allocator);
52}
53
54pub fn intern(comp: *Compilation, str: []const u8) !StringId {
55 return comp.string_interner.internExtra(comp.gpa, str);
56}
57
58pub fn internExtra(self: *StringInterner, allocator: mem.Allocator, str: []const u8) !StringId {
59 if (str.len == 0) return .empty;
60
61 const gop = try self.string_table.getOrPut(allocator, str);
62 if (gop.found_existing) return gop.value_ptr.*;
63
64 defer self.next_id = @enumFromInt(@intFromEnum(self.next_id) + 1);
65 gop.value_ptr.* = self.next_id;
66 return self.next_id;
67}
68
69/// deinit for the returned TypeMapper is a no-op and does not need to be called
70pub fn getSlowTypeMapper(self: *const StringInterner) TypeMapper {
71 return TypeMapper{ .data = .{ .slow = &self.string_table } };
72}
73
74/// Caller must call `deinit` on the returned TypeMapper
75pub fn getFastTypeMapper(self: *const StringInterner, allocator: mem.Allocator) !TypeMapper {
76 var strings = try allocator.alloc([]const u8, @intFromEnum(self.next_id));
77 var it = self.string_table.iterator();
78 strings[0] = "";
79 while (it.next()) |entry| {
80 strings[@intFromEnum(entry.value_ptr.*)] = entry.key_ptr.*;
81 }
82 return TypeMapper{ .data = .{ .fast = strings } };
83}
deps/aro/aro/SymbolStack.zig deleted-392
......@@ -1,392 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const assert = std.debug.assert;
5const Tree = @import("Tree.zig");
6const Token = Tree.Token;
7const TokenIndex = Tree.TokenIndex;
8const NodeIndex = Tree.NodeIndex;
9const Type = @import("Type.zig");
10const Parser = @import("Parser.zig");
11const Value = @import("Value.zig");
12const StringId = @import("StringInterner.zig").StringId;
13
14const SymbolStack = @This();
15
16pub const Symbol = struct {
17 name: StringId,
18 ty: Type,
19 tok: TokenIndex,
20 node: NodeIndex = .none,
21 kind: Kind,
22 val: Value,
23};
24
25pub const Kind = enum {
26 typedef,
27 @"struct",
28 @"union",
29 @"enum",
30 decl,
31 def,
32 enumeration,
33 constexpr,
34};
35
36scopes: std.ArrayListUnmanaged(Scope) = .{},
37/// allocations from nested scopes are retained after popping; `active_len` is the number
38/// of currently-active items in `scopes`.
39active_len: usize = 0,
40
41const Scope = struct {
42 vars: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
43 tags: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
44
45 fn deinit(self: *Scope, allocator: Allocator) void {
46 self.vars.deinit(allocator);
47 self.tags.deinit(allocator);
48 }
49
50 fn clearRetainingCapacity(self: *Scope) void {
51 self.vars.clearRetainingCapacity();
52 self.tags.clearRetainingCapacity();
53 }
54};
55
56pub fn deinit(s: *SymbolStack, gpa: Allocator) void {
57 std.debug.assert(s.active_len == 0); // all scopes should have been popped
58 for (s.scopes.items) |*scope| {
59 scope.deinit(gpa);
60 }
61 s.scopes.deinit(gpa);
62 s.* = undefined;
63}
64
65pub fn pushScope(s: *SymbolStack, p: *Parser) !void {
66 if (s.active_len + 1 > s.scopes.items.len) {
67 try s.scopes.append(p.gpa, .{});
68 s.active_len = s.scopes.items.len;
69 } else {
70 s.scopes.items[s.active_len].clearRetainingCapacity();
71 s.active_len += 1;
72 }
73}
74
75pub fn popScope(s: *SymbolStack) void {
76 s.active_len -= 1;
77}
78
79pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol {
80 const prev = s.lookup(name, .vars) orelse s.lookup(name, .tags) orelse return null;
81 switch (prev.kind) {
82 .typedef => return prev,
83 .@"struct" => {
84 if (no_type_yet) return null;
85 try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));
86 return prev;
87 },
88 .@"union" => {
89 if (no_type_yet) return null;
90 try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));
91 return prev;
92 },
93 .@"enum" => {
94 if (no_type_yet) return null;
95 try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok));
96 return prev;
97 },
98 else => return null,
99 }
100}
101
102pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol {
103 return s.lookup(name, .vars);
104}
105
106pub fn findTag(
107 s: *SymbolStack,
108 p: *Parser,
109 name: StringId,
110 kind: Token.Id,
111 name_tok: TokenIndex,
112 next_tok_id: Token.Id,
113) !?Symbol {
114 // `tag Name;` should always result in a new type if in a new scope.
115 const prev = (if (next_tok_id == .semicolon) s.get(name, .tags) else s.lookup(name, .tags)) orelse return null;
116 switch (prev.kind) {
117 .@"enum" => if (kind == .keyword_enum) return prev,
118 .@"struct" => if (kind == .keyword_struct) return prev,
119 .@"union" => if (kind == .keyword_union) return prev,
120 else => unreachable,
121 }
122 if (s.get(name, .tags) == null) return null;
123 try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok));
124 try p.errTok(.previous_definition, prev.tok);
125 return null;
126}
127
128const ScopeKind = enum {
129 /// structs, enums, unions
130 tags,
131 /// everything else
132 vars,
133};
134
135/// Return the Symbol for `name` (or null if not found) in the innermost scope
136pub fn get(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol {
137 return switch (kind) {
138 .vars => s.scopes.items[s.active_len - 1].vars.get(name),
139 .tags => s.scopes.items[s.active_len - 1].tags.get(name),
140 };
141}
142
143/// Return the Symbol for `name` (or null if not found) in the nearest active scope,
144/// starting at the innermost.
145fn lookup(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol {
146 var i = s.active_len;
147 while (i > 0) {
148 i -= 1;
149 switch (kind) {
150 .vars => if (s.scopes.items[i].vars.get(name)) |sym| return sym,
151 .tags => if (s.scopes.items[i].tags.get(name)) |sym| return sym,
152 }
153 }
154 return null;
155}
156
157/// Define a symbol in the innermost scope. Does not issue diagnostics or check correctness
158/// with regard to the C standard.
159pub fn define(s: *SymbolStack, allocator: Allocator, symbol: Symbol) !void {
160 switch (symbol.kind) {
161 .constexpr, .def, .decl, .enumeration, .typedef => {
162 try s.scopes.items[s.active_len - 1].vars.put(allocator, symbol.name, symbol);
163 },
164 .@"struct", .@"union", .@"enum" => {
165 try s.scopes.items[s.active_len - 1].tags.put(allocator, symbol.name, symbol);
166 },
167 }
168}
169
170pub fn defineTypedef(
171 s: *SymbolStack,
172 p: *Parser,
173 name: StringId,
174 ty: Type,
175 tok: TokenIndex,
176 node: NodeIndex,
177) !void {
178 if (s.get(name, .vars)) |prev| {
179 switch (prev.kind) {
180 .typedef => {
181 if (!ty.eql(prev.ty, p.comp, true)) {
182 try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev.ty));
183 if (prev.tok != 0) try p.errTok(.previous_definition, prev.tok);
184 }
185 },
186 .enumeration, .decl, .def, .constexpr => {
187 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
188 try p.errTok(.previous_definition, prev.tok);
189 },
190 else => unreachable,
191 }
192 }
193 try s.define(p.gpa, .{
194 .kind = .typedef,
195 .name = name,
196 .tok = tok,
197 .ty = ty,
198 .node = node,
199 .val = .{},
200 });
201}
202
203pub fn defineSymbol(
204 s: *SymbolStack,
205 p: *Parser,
206 name: StringId,
207 ty: Type,
208 tok: TokenIndex,
209 node: NodeIndex,
210 val: Value,
211 constexpr: bool,
212) !void {
213 if (s.get(name, .vars)) |prev| {
214 switch (prev.kind) {
215 .enumeration => {
216 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
217 try p.errTok(.previous_definition, prev.tok);
218 },
219 .decl => {
220 if (!ty.eql(prev.ty, p.comp, true)) {
221 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
222 try p.errTok(.previous_definition, prev.tok);
223 }
224 },
225 .def, .constexpr => {
226 try p.errStr(.redefinition, tok, p.tokSlice(tok));
227 try p.errTok(.previous_definition, prev.tok);
228 },
229 .typedef => {
230 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
231 try p.errTok(.previous_definition, prev.tok);
232 },
233 else => unreachable,
234 }
235 }
236
237 try s.define(p.gpa, .{
238 .kind = if (constexpr) .constexpr else .def,
239 .name = name,
240 .tok = tok,
241 .ty = ty,
242 .node = node,
243 .val = val,
244 });
245}
246
247/// Get a pointer to the named symbol in the innermost scope.
248/// Asserts that a symbol with the name exists.
249pub fn getPtr(s: *SymbolStack, name: StringId, kind: ScopeKind) *Symbol {
250 return switch (kind) {
251 .tags => s.scopes.items[s.active_len - 1].tags.getPtr(name).?,
252 .vars => s.scopes.items[s.active_len - 1].vars.getPtr(name).?,
253 };
254}
255
256pub fn declareSymbol(
257 s: *SymbolStack,
258 p: *Parser,
259 name: StringId,
260 ty: Type,
261 tok: TokenIndex,
262 node: NodeIndex,
263) !void {
264 if (s.get(name, .vars)) |prev| {
265 switch (prev.kind) {
266 .enumeration => {
267 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
268 try p.errTok(.previous_definition, prev.tok);
269 },
270 .decl => {
271 if (!ty.eql(prev.ty, p.comp, true)) {
272 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
273 try p.errTok(.previous_definition, prev.tok);
274 }
275 },
276 .def, .constexpr => {
277 if (!ty.eql(prev.ty, p.comp, true)) {
278 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
279 try p.errTok(.previous_definition, prev.tok);
280 } else {
281 return;
282 }
283 },
284 .typedef => {
285 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
286 try p.errTok(.previous_definition, prev.tok);
287 },
288 else => unreachable,
289 }
290 }
291 try s.define(p.gpa, .{
292 .kind = .decl,
293 .name = name,
294 .tok = tok,
295 .ty = ty,
296 .node = node,
297 .val = .{},
298 });
299}
300
301pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void {
302 if (s.get(name, .vars)) |prev| {
303 switch (prev.kind) {
304 .enumeration, .decl, .def, .constexpr => {
305 try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok));
306 try p.errTok(.previous_definition, prev.tok);
307 },
308 .typedef => {
309 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
310 try p.errTok(.previous_definition, prev.tok);
311 },
312 else => unreachable,
313 }
314 }
315 if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
316 try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters");
317 }
318 try s.define(p.gpa, .{
319 .kind = .def,
320 .name = name,
321 .tok = tok,
322 .ty = ty,
323 .val = .{},
324 });
325}
326
327pub fn defineTag(
328 s: *SymbolStack,
329 p: *Parser,
330 name: StringId,
331 kind: Token.Id,
332 tok: TokenIndex,
333) !?Symbol {
334 const prev = s.get(name, .tags) orelse return null;
335 switch (prev.kind) {
336 .@"enum" => {
337 if (kind == .keyword_enum) return prev;
338 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
339 try p.errTok(.previous_definition, prev.tok);
340 return null;
341 },
342 .@"struct" => {
343 if (kind == .keyword_struct) return prev;
344 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
345 try p.errTok(.previous_definition, prev.tok);
346 return null;
347 },
348 .@"union" => {
349 if (kind == .keyword_union) return prev;
350 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
351 try p.errTok(.previous_definition, prev.tok);
352 return null;
353 },
354 else => unreachable,
355 }
356}
357
358pub fn defineEnumeration(
359 s: *SymbolStack,
360 p: *Parser,
361 name: StringId,
362 ty: Type,
363 tok: TokenIndex,
364 val: Value,
365) !void {
366 if (s.get(name, .vars)) |prev| {
367 switch (prev.kind) {
368 .enumeration => {
369 try p.errStr(.redefinition, tok, p.tokSlice(tok));
370 try p.errTok(.previous_definition, prev.tok);
371 return;
372 },
373 .decl, .def, .constexpr => {
374 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
375 try p.errTok(.previous_definition, prev.tok);
376 return;
377 },
378 .typedef => {
379 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
380 try p.errTok(.previous_definition, prev.tok);
381 },
382 else => unreachable,
383 }
384 }
385 try s.define(p.gpa, .{
386 .kind = .enumeration,
387 .name = name,
388 .tok = tok,
389 .ty = ty,
390 .val = val,
391 });
392}
deps/aro/aro/Tokenizer.zig deleted-2174
......@@ -1,2174 +0,0 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const Compilation = @import("Compilation.zig");
4const Source = @import("Source.zig");
5const LangOpts = @import("LangOpts.zig");
6
7pub const Token = struct {
8 id: Id,
9 source: Source.Id,
10 start: u32 = 0,
11 end: u32 = 0,
12 line: u32 = 0,
13
14 pub const Id = enum(u8) {
15 invalid,
16 nl,
17 whitespace,
18 eof,
19 /// identifier containing solely basic character set characters
20 identifier,
21 /// identifier with at least one extended character
22 extended_identifier,
23
24 // string literals with prefixes
25 string_literal,
26 string_literal_utf_16,
27 string_literal_utf_8,
28 string_literal_utf_32,
29 string_literal_wide,
30
31 /// Any string literal with an embedded newline or EOF
32 /// Always a parser error; by default just a warning from preprocessor
33 unterminated_string_literal,
34
35 // <foobar> only generated by preprocessor
36 macro_string,
37
38 // char literals with prefixes
39 char_literal,
40 char_literal_utf_8,
41 char_literal_utf_16,
42 char_literal_utf_32,
43 char_literal_wide,
44
45 /// Any character literal with nothing inside the quotes
46 /// Always a parser error; by default just a warning from preprocessor
47 empty_char_literal,
48
49 /// Any character literal with an embedded newline or EOF
50 /// Always a parser error; by default just a warning from preprocessor
51 unterminated_char_literal,
52
53 /// `/* */` style comment without a closing `*/` before EOF
54 unterminated_comment,
55
56 /// Integer literal tokens generated by preprocessor.
57 one,
58 zero,
59
60 bang,
61 bang_equal,
62 pipe,
63 pipe_pipe,
64 pipe_equal,
65 equal,
66 equal_equal,
67 l_paren,
68 r_paren,
69 l_brace,
70 r_brace,
71 l_bracket,
72 r_bracket,
73 period,
74 ellipsis,
75 caret,
76 caret_equal,
77 plus,
78 plus_plus,
79 plus_equal,
80 minus,
81 minus_minus,
82 minus_equal,
83 asterisk,
84 asterisk_equal,
85 percent,
86 percent_equal,
87 arrow,
88 colon,
89 colon_colon,
90 semicolon,
91 slash,
92 slash_equal,
93 comma,
94 ampersand,
95 ampersand_ampersand,
96 ampersand_equal,
97 question_mark,
98 angle_bracket_left,
99 angle_bracket_left_equal,
100 angle_bracket_angle_bracket_left,
101 angle_bracket_angle_bracket_left_equal,
102 angle_bracket_right,
103 angle_bracket_right_equal,
104 angle_bracket_angle_bracket_right,
105 angle_bracket_angle_bracket_right_equal,
106 tilde,
107 hash,
108 hash_hash,
109
110 /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
111 macro_param,
112 /// Special token to signal that the argument must be replaced without expansion (e.g. in concatenation)
113 macro_param_no_expand,
114 /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
115 stringify_param,
116 /// Same as stringify_param, but for var args
117 stringify_va_args,
118 /// Special macro whitespace, always equal to a single space
119 macro_ws,
120 /// Special token for implementing __has_attribute
121 macro_param_has_attribute,
122 /// Special token for implementing __has_c_attribute
123 macro_param_has_c_attribute,
124 /// Special token for implementing __has_declspec_attribute
125 macro_param_has_declspec_attribute,
126 /// Special token for implementing __has_warning
127 macro_param_has_warning,
128 /// Special token for implementing __has_feature
129 macro_param_has_feature,
130 /// Special token for implementing __has_extension
131 macro_param_has_extension,
132 /// Special token for implementing __has_builtin
133 macro_param_has_builtin,
134 /// Special token for implementing __has_include
135 macro_param_has_include,
136 /// Special token for implementing __has_include_next
137 macro_param_has_include_next,
138 /// Special token for implementing __has_embed
139 macro_param_has_embed,
140 /// Special token for implementing __is_identifier
141 macro_param_is_identifier,
142 /// Special token for implementing __FILE__
143 macro_file,
144 /// Special token for implementing __LINE__
145 macro_line,
146 /// Special token for implementing __COUNTER__
147 macro_counter,
148 /// Special token for implementing _Pragma
149 macro_param_pragma_operator,
150
151 /// Special identifier for implementing __func__
152 macro_func,
153 /// Special identifier for implementing __FUNCTION__
154 macro_function,
155 /// Special identifier for implementing __PRETTY_FUNCTION__
156 macro_pretty_func,
157
158 keyword_auto,
159 keyword_auto_type,
160 keyword_break,
161 keyword_case,
162 keyword_char,
163 keyword_const,
164 keyword_continue,
165 keyword_default,
166 keyword_do,
167 keyword_double,
168 keyword_else,
169 keyword_enum,
170 keyword_extern,
171 keyword_float,
172 keyword_for,
173 keyword_goto,
174 keyword_if,
175 keyword_int,
176 keyword_long,
177 keyword_register,
178 keyword_return,
179 keyword_short,
180 keyword_signed,
181 keyword_sizeof,
182 keyword_static,
183 keyword_struct,
184 keyword_switch,
185 keyword_typedef,
186 keyword_typeof1,
187 keyword_typeof2,
188 keyword_union,
189 keyword_unsigned,
190 keyword_void,
191 keyword_volatile,
192 keyword_while,
193
194 // ISO C99
195 keyword_bool,
196 keyword_complex,
197 keyword_imaginary,
198 keyword_inline,
199 keyword_restrict,
200
201 // ISO C11
202 keyword_alignas,
203 keyword_alignof,
204 keyword_atomic,
205 keyword_generic,
206 keyword_noreturn,
207 keyword_static_assert,
208 keyword_thread_local,
209
210 // ISO C23
211 keyword_bit_int,
212 keyword_c23_alignas,
213 keyword_c23_alignof,
214 keyword_c23_bool,
215 keyword_c23_static_assert,
216 keyword_c23_thread_local,
217 keyword_constexpr,
218 keyword_true,
219 keyword_false,
220 keyword_nullptr,
221 keyword_typeof_unqual,
222
223 // Preprocessor directives
224 keyword_include,
225 keyword_include_next,
226 keyword_embed,
227 keyword_define,
228 keyword_defined,
229 keyword_undef,
230 keyword_ifdef,
231 keyword_ifndef,
232 keyword_elif,
233 keyword_elifdef,
234 keyword_elifndef,
235 keyword_endif,
236 keyword_error,
237 keyword_warning,
238 keyword_pragma,
239 keyword_line,
240 keyword_va_args,
241 keyword_va_opt,
242
243 // gcc keywords
244 keyword_const1,
245 keyword_const2,
246 keyword_inline1,
247 keyword_inline2,
248 keyword_volatile1,
249 keyword_volatile2,
250 keyword_restrict1,
251 keyword_restrict2,
252 keyword_alignof1,
253 keyword_alignof2,
254 keyword_typeof,
255 keyword_attribute1,
256 keyword_attribute2,
257 keyword_extension,
258 keyword_asm,
259 keyword_asm1,
260 keyword_asm2,
261 keyword_float80,
262 /// _Float128
263 keyword_float128_1,
264 /// __float128
265 keyword_float128_2,
266 keyword_int128,
267 keyword_imag1,
268 keyword_imag2,
269 keyword_real1,
270 keyword_real2,
271 keyword_float16,
272
273 // clang keywords
274 keyword_fp16,
275
276 // ms keywords
277 keyword_declspec,
278 keyword_int64,
279 keyword_int64_2,
280 keyword_int32,
281 keyword_int32_2,
282 keyword_int16,
283 keyword_int16_2,
284 keyword_int8,
285 keyword_int8_2,
286 keyword_stdcall,
287 keyword_stdcall2,
288 keyword_thiscall,
289 keyword_thiscall2,
290 keyword_vectorcall,
291 keyword_vectorcall2,
292
293 // builtins that require special parsing
294 builtin_choose_expr,
295 builtin_va_arg,
296 builtin_offsetof,
297 builtin_bitoffsetof,
298 builtin_types_compatible_p,
299
300 /// Generated by #embed directive
301 /// Decimal value with no prefix or suffix
302 embed_byte,
303
304 /// preprocessor number
305 /// An optional period, followed by a digit 0-9, followed by any number of letters
306 /// digits, underscores, periods, and exponents (e+, e-, E+, E-, p+, p-, P+, P-)
307 pp_num,
308
309 /// preprocessor placemarker token
310 /// generated if `##` is used with a zero-token argument
311 /// removed after substitution, so the parser should never see this
312 /// See C99 6.10.3.3.2
313 placemarker,
314
315 /// Virtual linemarker token output from preprocessor to indicate start of a new include
316 include_start,
317
318 /// Virtual linemarker token output from preprocessor to indicate resuming a file after
319 /// completion of the preceding #include
320 include_resume,
321
322 /// A comment token if asked to preserve comments.
323 comment,
324
325 /// Return true if token is identifier or keyword.
326 pub fn isMacroIdentifier(id: Id) bool {
327 switch (id) {
328 .keyword_include,
329 .keyword_include_next,
330 .keyword_embed,
331 .keyword_define,
332 .keyword_defined,
333 .keyword_undef,
334 .keyword_ifdef,
335 .keyword_ifndef,
336 .keyword_elif,
337 .keyword_elifdef,
338 .keyword_elifndef,
339 .keyword_endif,
340 .keyword_error,
341 .keyword_warning,
342 .keyword_pragma,
343 .keyword_line,
344 .keyword_va_args,
345 .keyword_va_opt,
346 .macro_func,
347 .macro_function,
348 .macro_pretty_func,
349 .keyword_auto,
350 .keyword_auto_type,
351 .keyword_break,
352 .keyword_case,
353 .keyword_char,
354 .keyword_const,
355 .keyword_continue,
356 .keyword_default,
357 .keyword_do,
358 .keyword_double,
359 .keyword_else,
360 .keyword_enum,
361 .keyword_extern,
362 .keyword_float,
363 .keyword_for,
364 .keyword_goto,
365 .keyword_if,
366 .keyword_int,
367 .keyword_long,
368 .keyword_register,
369 .keyword_return,
370 .keyword_short,
371 .keyword_signed,
372 .keyword_sizeof,
373 .keyword_static,
374 .keyword_struct,
375 .keyword_switch,
376 .keyword_typedef,
377 .keyword_union,
378 .keyword_unsigned,
379 .keyword_void,
380 .keyword_volatile,
381 .keyword_while,
382 .keyword_bool,
383 .keyword_complex,
384 .keyword_imaginary,
385 .keyword_inline,
386 .keyword_restrict,
387 .keyword_alignas,
388 .keyword_alignof,
389 .keyword_atomic,
390 .keyword_generic,
391 .keyword_noreturn,
392 .keyword_static_assert,
393 .keyword_thread_local,
394 .identifier,
395 .extended_identifier,
396 .keyword_typeof,
397 .keyword_typeof1,
398 .keyword_typeof2,
399 .keyword_const1,
400 .keyword_const2,
401 .keyword_inline1,
402 .keyword_inline2,
403 .keyword_volatile1,
404 .keyword_volatile2,
405 .keyword_restrict1,
406 .keyword_restrict2,
407 .keyword_alignof1,
408 .keyword_alignof2,
409 .builtin_choose_expr,
410 .builtin_va_arg,
411 .builtin_offsetof,
412 .builtin_bitoffsetof,
413 .builtin_types_compatible_p,
414 .keyword_attribute1,
415 .keyword_attribute2,
416 .keyword_extension,
417 .keyword_asm,
418 .keyword_asm1,
419 .keyword_asm2,
420 .keyword_float80,
421 .keyword_float128_1,
422 .keyword_float128_2,
423 .keyword_int128,
424 .keyword_imag1,
425 .keyword_imag2,
426 .keyword_real1,
427 .keyword_real2,
428 .keyword_float16,
429 .keyword_fp16,
430 .keyword_declspec,
431 .keyword_int64,
432 .keyword_int64_2,
433 .keyword_int32,
434 .keyword_int32_2,
435 .keyword_int16,
436 .keyword_int16_2,
437 .keyword_int8,
438 .keyword_int8_2,
439 .keyword_stdcall,
440 .keyword_stdcall2,
441 .keyword_thiscall,
442 .keyword_thiscall2,
443 .keyword_vectorcall,
444 .keyword_vectorcall2,
445 .keyword_bit_int,
446 .keyword_c23_alignas,
447 .keyword_c23_alignof,
448 .keyword_c23_bool,
449 .keyword_c23_static_assert,
450 .keyword_c23_thread_local,
451 .keyword_constexpr,
452 .keyword_true,
453 .keyword_false,
454 .keyword_nullptr,
455 .keyword_typeof_unqual,
456 => return true,
457 else => return false,
458 }
459 }
460
461 /// Turn macro keywords into identifiers.
462 /// `keyword_defined` is special since it should only turn into an identifier if
463 /// we are *not* in an #if or #elif expression
464 pub fn simplifyMacroKeywordExtra(id: *Id, defined_to_identifier: bool) void {
465 switch (id.*) {
466 .keyword_include,
467 .keyword_include_next,
468 .keyword_embed,
469 .keyword_define,
470 .keyword_undef,
471 .keyword_ifdef,
472 .keyword_ifndef,
473 .keyword_elif,
474 .keyword_elifdef,
475 .keyword_elifndef,
476 .keyword_endif,
477 .keyword_error,
478 .keyword_warning,
479 .keyword_pragma,
480 .keyword_line,
481 .keyword_va_args,
482 .keyword_va_opt,
483 => id.* = .identifier,
484 .keyword_defined => if (defined_to_identifier) {
485 id.* = .identifier;
486 },
487 else => {},
488 }
489 }
490
491 pub fn simplifyMacroKeyword(id: *Id) void {
492 simplifyMacroKeywordExtra(id, false);
493 }
494
495 pub fn lexeme(id: Id) ?[]const u8 {
496 return switch (id) {
497 .include_start,
498 .include_resume,
499 => unreachable,
500
501 .unterminated_comment,
502 .invalid,
503 .identifier,
504 .extended_identifier,
505 .string_literal,
506 .string_literal_utf_16,
507 .string_literal_utf_8,
508 .string_literal_utf_32,
509 .string_literal_wide,
510 .unterminated_string_literal,
511 .unterminated_char_literal,
512 .empty_char_literal,
513 .char_literal,
514 .char_literal_utf_8,
515 .char_literal_utf_16,
516 .char_literal_utf_32,
517 .char_literal_wide,
518 .macro_string,
519 .whitespace,
520 .pp_num,
521 .embed_byte,
522 .comment,
523 => null,
524
525 .zero => "0",
526 .one => "1",
527
528 .nl,
529 .eof,
530 .macro_param,
531 .macro_param_no_expand,
532 .stringify_param,
533 .stringify_va_args,
534 .macro_param_has_attribute,
535 .macro_param_has_c_attribute,
536 .macro_param_has_declspec_attribute,
537 .macro_param_has_warning,
538 .macro_param_has_feature,
539 .macro_param_has_extension,
540 .macro_param_has_builtin,
541 .macro_param_has_include,
542 .macro_param_has_include_next,
543 .macro_param_has_embed,
544 .macro_param_is_identifier,
545 .macro_file,
546 .macro_line,
547 .macro_counter,
548 .macro_param_pragma_operator,
549 .placemarker,
550 => "",
551 .macro_ws => " ",
552
553 .macro_func => "__func__",
554 .macro_function => "__FUNCTION__",
555 .macro_pretty_func => "__PRETTY_FUNCTION__",
556
557 .bang => "!",
558 .bang_equal => "!=",
559 .pipe => "|",
560 .pipe_pipe => "||",
561 .pipe_equal => "|=",
562 .equal => "=",
563 .equal_equal => "==",
564 .l_paren => "(",
565 .r_paren => ")",
566 .l_brace => "{",
567 .r_brace => "}",
568 .l_bracket => "[",
569 .r_bracket => "]",
570 .period => ".",
571 .ellipsis => "...",
572 .caret => "^",
573 .caret_equal => "^=",
574 .plus => "+",
575 .plus_plus => "++",
576 .plus_equal => "+=",
577 .minus => "-",
578 .minus_minus => "--",
579 .minus_equal => "-=",
580 .asterisk => "*",
581 .asterisk_equal => "*=",
582 .percent => "%",
583 .percent_equal => "%=",
584 .arrow => "->",
585 .colon => ":",
586 .colon_colon => "::",
587 .semicolon => ";",
588 .slash => "/",
589 .slash_equal => "/=",
590 .comma => ",",
591 .ampersand => "&",
592 .ampersand_ampersand => "&&",
593 .ampersand_equal => "&=",
594 .question_mark => "?",
595 .angle_bracket_left => "<",
596 .angle_bracket_left_equal => "<=",
597 .angle_bracket_angle_bracket_left => "<<",
598 .angle_bracket_angle_bracket_left_equal => "<<=",
599 .angle_bracket_right => ">",
600 .angle_bracket_right_equal => ">=",
601 .angle_bracket_angle_bracket_right => ">>",
602 .angle_bracket_angle_bracket_right_equal => ">>=",
603 .tilde => "~",
604 .hash => "#",
605 .hash_hash => "##",
606
607 .keyword_auto => "auto",
608 .keyword_auto_type => "__auto_type",
609 .keyword_break => "break",
610 .keyword_case => "case",
611 .keyword_char => "char",
612 .keyword_const => "const",
613 .keyword_continue => "continue",
614 .keyword_default => "default",
615 .keyword_do => "do",
616 .keyword_double => "double",
617 .keyword_else => "else",
618 .keyword_enum => "enum",
619 .keyword_extern => "extern",
620 .keyword_float => "float",
621 .keyword_for => "for",
622 .keyword_goto => "goto",
623 .keyword_if => "if",
624 .keyword_int => "int",
625 .keyword_long => "long",
626 .keyword_register => "register",
627 .keyword_return => "return",
628 .keyword_short => "short",
629 .keyword_signed => "signed",
630 .keyword_sizeof => "sizeof",
631 .keyword_static => "static",
632 .keyword_struct => "struct",
633 .keyword_switch => "switch",
634 .keyword_typedef => "typedef",
635 .keyword_typeof => "typeof",
636 .keyword_union => "union",
637 .keyword_unsigned => "unsigned",
638 .keyword_void => "void",
639 .keyword_volatile => "volatile",
640 .keyword_while => "while",
641 .keyword_bool => "_Bool",
642 .keyword_complex => "_Complex",
643 .keyword_imaginary => "_Imaginary",
644 .keyword_inline => "inline",
645 .keyword_restrict => "restrict",
646 .keyword_alignas => "_Alignas",
647 .keyword_alignof => "_Alignof",
648 .keyword_atomic => "_Atomic",
649 .keyword_generic => "_Generic",
650 .keyword_noreturn => "_Noreturn",
651 .keyword_static_assert => "_Static_assert",
652 .keyword_thread_local => "_Thread_local",
653 .keyword_bit_int => "_BitInt",
654 .keyword_c23_alignas => "alignas",
655 .keyword_c23_alignof => "alignof",
656 .keyword_c23_bool => "bool",
657 .keyword_c23_static_assert => "static_assert",
658 .keyword_c23_thread_local => "thread_local",
659 .keyword_constexpr => "constexpr",
660 .keyword_true => "true",
661 .keyword_false => "false",
662 .keyword_nullptr => "nullptr",
663 .keyword_typeof_unqual => "typeof_unqual",
664 .keyword_include => "include",
665 .keyword_include_next => "include_next",
666 .keyword_embed => "embed",
667 .keyword_define => "define",
668 .keyword_defined => "defined",
669 .keyword_undef => "undef",
670 .keyword_ifdef => "ifdef",
671 .keyword_ifndef => "ifndef",
672 .keyword_elif => "elif",
673 .keyword_elifdef => "elifdef",
674 .keyword_elifndef => "elifndef",
675 .keyword_endif => "endif",
676 .keyword_error => "error",
677 .keyword_warning => "warning",
678 .keyword_pragma => "pragma",
679 .keyword_line => "line",
680 .keyword_va_args => "__VA_ARGS__",
681 .keyword_va_opt => "__VA_OPT__",
682 .keyword_const1 => "__const",
683 .keyword_const2 => "__const__",
684 .keyword_inline1 => "__inline",
685 .keyword_inline2 => "__inline__",
686 .keyword_volatile1 => "__volatile",
687 .keyword_volatile2 => "__volatile__",
688 .keyword_restrict1 => "__restrict",
689 .keyword_restrict2 => "__restrict__",
690 .keyword_alignof1 => "__alignof",
691 .keyword_alignof2 => "__alignof__",
692 .keyword_typeof1 => "__typeof",
693 .keyword_typeof2 => "__typeof__",
694 .builtin_choose_expr => "__builtin_choose_expr",
695 .builtin_va_arg => "__builtin_va_arg",
696 .builtin_offsetof => "__builtin_offsetof",
697 .builtin_bitoffsetof => "__builtin_bitoffsetof",
698 .builtin_types_compatible_p => "__builtin_types_compatible_p",
699 .keyword_attribute1 => "__attribute",
700 .keyword_attribute2 => "__attribute__",
701 .keyword_extension => "__extension__",
702 .keyword_asm => "asm",
703 .keyword_asm1 => "__asm",
704 .keyword_asm2 => "__asm__",
705 .keyword_float80 => "__float80",
706 .keyword_float128_1 => "_Float128",
707 .keyword_float128_2 => "__float128",
708 .keyword_int128 => "__int128",
709 .keyword_imag1 => "__imag",
710 .keyword_imag2 => "__imag__",
711 .keyword_real1 => "__real",
712 .keyword_real2 => "__real__",
713 .keyword_float16 => "_Float16",
714 .keyword_fp16 => "__fp16",
715 .keyword_declspec => "__declspec",
716 .keyword_int64 => "__int64",
717 .keyword_int64_2 => "_int64",
718 .keyword_int32 => "__int32",
719 .keyword_int32_2 => "_int32",
720 .keyword_int16 => "__int16",
721 .keyword_int16_2 => "_int16",
722 .keyword_int8 => "__int8",
723 .keyword_int8_2 => "_int8",
724 .keyword_stdcall => "__stdcall",
725 .keyword_stdcall2 => "_stdcall",
726 .keyword_thiscall => "__thiscall",
727 .keyword_thiscall2 => "_thiscall",
728 .keyword_vectorcall => "__vectorcall",
729 .keyword_vectorcall2 => "_vectorcall",
730 };
731 }
732
733 pub fn symbol(id: Id) []const u8 {
734 return switch (id) {
735 .macro_string, .invalid => unreachable,
736 .identifier,
737 .extended_identifier,
738 .macro_func,
739 .macro_function,
740 .macro_pretty_func,
741 .builtin_choose_expr,
742 .builtin_va_arg,
743 .builtin_offsetof,
744 .builtin_bitoffsetof,
745 .builtin_types_compatible_p,
746 => "an identifier",
747 .string_literal,
748 .string_literal_utf_16,
749 .string_literal_utf_8,
750 .string_literal_utf_32,
751 .string_literal_wide,
752 .unterminated_string_literal,
753 => "a string literal",
754 .char_literal,
755 .char_literal_utf_8,
756 .char_literal_utf_16,
757 .char_literal_utf_32,
758 .char_literal_wide,
759 .unterminated_char_literal,
760 .empty_char_literal,
761 => "a character literal",
762 .pp_num, .embed_byte => "A number",
763 else => id.lexeme().?,
764 };
765 }
766
767 /// tokens that can start an expression parsed by Preprocessor.expr
768 /// Note that eof, r_paren, and string literals cannot actually start a
769 /// preprocessor expression, but we include them here so that a nicer
770 /// error message can be generated by the parser.
771 pub fn validPreprocessorExprStart(id: Id) bool {
772 return switch (id) {
773 .eof,
774 .r_paren,
775 .string_literal,
776 .string_literal_utf_16,
777 .string_literal_utf_8,
778 .string_literal_utf_32,
779 .string_literal_wide,
780
781 .char_literal,
782 .char_literal_utf_8,
783 .char_literal_utf_16,
784 .char_literal_utf_32,
785 .char_literal_wide,
786 .l_paren,
787 .plus,
788 .minus,
789 .tilde,
790 .bang,
791 .identifier,
792 .extended_identifier,
793 .keyword_defined,
794 .one,
795 .zero,
796 .pp_num,
797 .keyword_true,
798 .keyword_false,
799 => true,
800 else => false,
801 };
802 }
803
804 pub fn allowsDigraphs(id: Id, langopts: LangOpts) bool {
805 return switch (id) {
806 .l_bracket,
807 .r_bracket,
808 .l_brace,
809 .r_brace,
810 .hash,
811 .hash_hash,
812 => langopts.hasDigraphs(),
813 else => false,
814 };
815 }
816
817 pub fn canOpenGCCAsmStmt(id: Id) bool {
818 return switch (id) {
819 .keyword_volatile, .keyword_volatile1, .keyword_volatile2, .keyword_inline, .keyword_inline1, .keyword_inline2, .keyword_goto, .l_paren => true,
820 else => false,
821 };
822 }
823
824 pub fn isStringLiteral(id: Id) bool {
825 return switch (id) {
826 .string_literal, .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32, .string_literal_wide => true,
827 else => false,
828 };
829 }
830 };
831
832 /// double underscore and underscore + capital letter identifiers
833 /// belong to the implementation namespace, so we always convert them
834 /// to keywords.
835 pub fn getTokenId(langopts: LangOpts, str: []const u8) Token.Id {
836 const kw = all_kws.get(str) orelse return .identifier;
837 const standard = langopts.standard;
838 return switch (kw) {
839 .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier,
840 .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier,
841 .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c23)) kw else .identifier,
842 .keyword_asm => if (standard.isGNU()) kw else .identifier,
843 .keyword_declspec => if (langopts.declspec_attrs) kw else .identifier,
844
845 .keyword_c23_alignas,
846 .keyword_c23_alignof,
847 .keyword_c23_bool,
848 .keyword_c23_static_assert,
849 .keyword_c23_thread_local,
850 .keyword_constexpr,
851 .keyword_true,
852 .keyword_false,
853 .keyword_nullptr,
854 .keyword_typeof_unqual,
855 .keyword_elifdef,
856 .keyword_elifndef,
857 => if (standard.atLeast(.c23)) kw else .identifier,
858
859 .keyword_int64,
860 .keyword_int64_2,
861 .keyword_int32,
862 .keyword_int32_2,
863 .keyword_int16,
864 .keyword_int16_2,
865 .keyword_int8,
866 .keyword_int8_2,
867 .keyword_stdcall2,
868 .keyword_thiscall2,
869 .keyword_vectorcall2,
870 => if (langopts.ms_extensions) kw else .identifier,
871 else => kw,
872 };
873 }
874
875 const all_kws = std.ComptimeStringMap(Id, .{
876 .{ "auto", auto: {
877 @setEvalBranchQuota(3000);
878 break :auto .keyword_auto;
879 } },
880 .{ "break", .keyword_break },
881 .{ "case", .keyword_case },
882 .{ "char", .keyword_char },
883 .{ "const", .keyword_const },
884 .{ "continue", .keyword_continue },
885 .{ "default", .keyword_default },
886 .{ "do", .keyword_do },
887 .{ "double", .keyword_double },
888 .{ "else", .keyword_else },
889 .{ "enum", .keyword_enum },
890 .{ "extern", .keyword_extern },
891 .{ "float", .keyword_float },
892 .{ "for", .keyword_for },
893 .{ "goto", .keyword_goto },
894 .{ "if", .keyword_if },
895 .{ "int", .keyword_int },
896 .{ "long", .keyword_long },
897 .{ "register", .keyword_register },
898 .{ "return", .keyword_return },
899 .{ "short", .keyword_short },
900 .{ "signed", .keyword_signed },
901 .{ "sizeof", .keyword_sizeof },
902 .{ "static", .keyword_static },
903 .{ "struct", .keyword_struct },
904 .{ "switch", .keyword_switch },
905 .{ "typedef", .keyword_typedef },
906 .{ "union", .keyword_union },
907 .{ "unsigned", .keyword_unsigned },
908 .{ "void", .keyword_void },
909 .{ "volatile", .keyword_volatile },
910 .{ "while", .keyword_while },
911 .{ "__typeof__", .keyword_typeof2 },
912 .{ "__typeof", .keyword_typeof1 },
913
914 // ISO C99
915 .{ "_Bool", .keyword_bool },
916 .{ "_Complex", .keyword_complex },
917 .{ "_Imaginary", .keyword_imaginary },
918 .{ "inline", .keyword_inline },
919 .{ "restrict", .keyword_restrict },
920
921 // ISO C11
922 .{ "_Alignas", .keyword_alignas },
923 .{ "_Alignof", .keyword_alignof },
924 .{ "_Atomic", .keyword_atomic },
925 .{ "_Generic", .keyword_generic },
926 .{ "_Noreturn", .keyword_noreturn },
927 .{ "_Static_assert", .keyword_static_assert },
928 .{ "_Thread_local", .keyword_thread_local },
929
930 // ISO C23
931 .{ "_BitInt", .keyword_bit_int },
932 .{ "alignas", .keyword_c23_alignas },
933 .{ "alignof", .keyword_c23_alignof },
934 .{ "bool", .keyword_c23_bool },
935 .{ "static_assert", .keyword_c23_static_assert },
936 .{ "thread_local", .keyword_c23_thread_local },
937 .{ "constexpr", .keyword_constexpr },
938 .{ "true", .keyword_true },
939 .{ "false", .keyword_false },
940 .{ "nullptr", .keyword_nullptr },
941 .{ "typeof_unqual", .keyword_typeof_unqual },
942
943 // Preprocessor directives
944 .{ "include", .keyword_include },
945 .{ "include_next", .keyword_include_next },
946 .{ "embed", .keyword_embed },
947 .{ "define", .keyword_define },
948 .{ "defined", .keyword_defined },
949 .{ "undef", .keyword_undef },
950 .{ "ifdef", .keyword_ifdef },
951 .{ "ifndef", .keyword_ifndef },
952 .{ "elif", .keyword_elif },
953 .{ "elifdef", .keyword_elifdef },
954 .{ "elifndef", .keyword_elifndef },
955 .{ "endif", .keyword_endif },
956 .{ "error", .keyword_error },
957 .{ "warning", .keyword_warning },
958 .{ "pragma", .keyword_pragma },
959 .{ "line", .keyword_line },
960 .{ "__VA_ARGS__", .keyword_va_args },
961 .{ "__VA_OPT__", .keyword_va_opt },
962 .{ "__func__", .macro_func },
963 .{ "__FUNCTION__", .macro_function },
964 .{ "__PRETTY_FUNCTION__", .macro_pretty_func },
965
966 // gcc keywords
967 .{ "__auto_type", .keyword_auto_type },
968 .{ "__const", .keyword_const1 },
969 .{ "__const__", .keyword_const2 },
970 .{ "__inline", .keyword_inline1 },
971 .{ "__inline__", .keyword_inline2 },
972 .{ "__volatile", .keyword_volatile1 },
973 .{ "__volatile__", .keyword_volatile2 },
974 .{ "__restrict", .keyword_restrict1 },
975 .{ "__restrict__", .keyword_restrict2 },
976 .{ "__alignof", .keyword_alignof1 },
977 .{ "__alignof__", .keyword_alignof2 },
978 .{ "typeof", .keyword_typeof },
979 .{ "__attribute", .keyword_attribute1 },
980 .{ "__attribute__", .keyword_attribute2 },
981 .{ "__extension__", .keyword_extension },
982 .{ "asm", .keyword_asm },
983 .{ "__asm", .keyword_asm1 },
984 .{ "__asm__", .keyword_asm2 },
985 .{ "__float80", .keyword_float80 },
986 .{ "_Float128", .keyword_float128_1 },
987 .{ "__float128", .keyword_float128_2 },
988 .{ "__int128", .keyword_int128 },
989 .{ "__imag", .keyword_imag1 },
990 .{ "__imag__", .keyword_imag2 },
991 .{ "__real", .keyword_real1 },
992 .{ "__real__", .keyword_real2 },
993 .{ "_Float16", .keyword_float16 },
994
995 // clang keywords
996 .{ "__fp16", .keyword_fp16 },
997
998 // ms keywords
999 .{ "__declspec", .keyword_declspec },
1000 .{ "__int64", .keyword_int64 },
1001 .{ "_int64", .keyword_int64_2 },
1002 .{ "__int32", .keyword_int32 },
1003 .{ "_int32", .keyword_int32_2 },
1004 .{ "__int16", .keyword_int16 },
1005 .{ "_int16", .keyword_int16_2 },
1006 .{ "__int8", .keyword_int8 },
1007 .{ "_int8", .keyword_int8_2 },
1008 .{ "__stdcall", .keyword_stdcall },
1009 .{ "_stdcall", .keyword_stdcall2 },
1010 .{ "__thiscall", .keyword_thiscall },
1011 .{ "_thiscall", .keyword_thiscall2 },
1012 .{ "__vectorcall", .keyword_vectorcall },
1013 .{ "_vectorcall", .keyword_vectorcall2 },
1014
1015 // builtins that require special parsing
1016 .{ "__builtin_choose_expr", .builtin_choose_expr },
1017 .{ "__builtin_va_arg", .builtin_va_arg },
1018 .{ "__builtin_offsetof", .builtin_offsetof },
1019 .{ "__builtin_bitoffsetof", .builtin_bitoffsetof },
1020 .{ "__builtin_types_compatible_p", .builtin_types_compatible_p },
1021 });
1022};
1023
1024const Tokenizer = @This();
1025
1026buf: []const u8,
1027index: u32 = 0,
1028source: Source.Id,
1029langopts: LangOpts,
1030line: u32 = 1,
1031
1032pub fn next(self: *Tokenizer) Token {
1033 var state: enum {
1034 start,
1035 whitespace,
1036 u,
1037 u8,
1038 U,
1039 L,
1040 string_literal,
1041 char_literal_start,
1042 char_literal,
1043 char_escape_sequence,
1044 string_escape_sequence,
1045 identifier,
1046 extended_identifier,
1047 equal,
1048 bang,
1049 pipe,
1050 colon,
1051 percent,
1052 asterisk,
1053 plus,
1054 angle_bracket_left,
1055 angle_bracket_angle_bracket_left,
1056 angle_bracket_right,
1057 angle_bracket_angle_bracket_right,
1058 caret,
1059 period,
1060 period2,
1061 minus,
1062 slash,
1063 ampersand,
1064 hash,
1065 hash_digraph,
1066 hash_hash_digraph_partial,
1067 line_comment,
1068 multi_line_comment,
1069 multi_line_comment_asterisk,
1070 multi_line_comment_done,
1071 pp_num,
1072 pp_num_exponent,
1073 pp_num_digit_separator,
1074 } = .start;
1075
1076 var start = self.index;
1077 var id: Token.Id = .eof;
1078
1079 while (self.index < self.buf.len) : (self.index += 1) {
1080 const c = self.buf[self.index];
1081 switch (state) {
1082 .start => switch (c) {
1083 '\n' => {
1084 id = .nl;
1085 self.index += 1;
1086 self.line += 1;
1087 break;
1088 },
1089 '"' => {
1090 id = .string_literal;
1091 state = .string_literal;
1092 },
1093 '\'' => {
1094 id = .char_literal;
1095 state = .char_literal_start;
1096 },
1097 'u' => state = .u,
1098 'U' => state = .U,
1099 'L' => state = .L,
1100 'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_' => state = .identifier,
1101 '=' => state = .equal,
1102 '!' => state = .bang,
1103 '|' => state = .pipe,
1104 '(' => {
1105 id = .l_paren;
1106 self.index += 1;
1107 break;
1108 },
1109 ')' => {
1110 id = .r_paren;
1111 self.index += 1;
1112 break;
1113 },
1114 '[' => {
1115 id = .l_bracket;
1116 self.index += 1;
1117 break;
1118 },
1119 ']' => {
1120 id = .r_bracket;
1121 self.index += 1;
1122 break;
1123 },
1124 ';' => {
1125 id = .semicolon;
1126 self.index += 1;
1127 break;
1128 },
1129 ',' => {
1130 id = .comma;
1131 self.index += 1;
1132 break;
1133 },
1134 '?' => {
1135 id = .question_mark;
1136 self.index += 1;
1137 break;
1138 },
1139 ':' => state = .colon,
1140 '%' => state = .percent,
1141 '*' => state = .asterisk,
1142 '+' => state = .plus,
1143 '<' => state = .angle_bracket_left,
1144 '>' => state = .angle_bracket_right,
1145 '^' => state = .caret,
1146 '{' => {
1147 id = .l_brace;
1148 self.index += 1;
1149 break;
1150 },
1151 '}' => {
1152 id = .r_brace;
1153 self.index += 1;
1154 break;
1155 },
1156 '~' => {
1157 id = .tilde;
1158 self.index += 1;
1159 break;
1160 },
1161 '.' => state = .period,
1162 '-' => state = .minus,
1163 '/' => state = .slash,
1164 '&' => state = .ampersand,
1165 '#' => state = .hash,
1166 '0'...'9' => state = .pp_num,
1167 '\t', '\x0B', '\x0C', ' ' => state = .whitespace,
1168 '$' => if (self.langopts.dollars_in_identifiers) {
1169 state = .extended_identifier;
1170 } else {
1171 id = .invalid;
1172 self.index += 1;
1173 break;
1174 },
1175 0x1A => if (self.langopts.ms_extensions) {
1176 id = .eof;
1177 break;
1178 } else {
1179 id = .invalid;
1180 self.index += 1;
1181 break;
1182 },
1183 0x80...0xFF => state = .extended_identifier,
1184 else => {
1185 id = .invalid;
1186 self.index += 1;
1187 break;
1188 },
1189 },
1190 .whitespace => switch (c) {
1191 '\t', '\x0B', '\x0C', ' ' => {},
1192 else => {
1193 id = .whitespace;
1194 break;
1195 },
1196 },
1197 .u => switch (c) {
1198 '8' => {
1199 state = .u8;
1200 },
1201 '\'' => {
1202 id = .char_literal_utf_16;
1203 state = .char_literal_start;
1204 },
1205 '\"' => {
1206 id = .string_literal_utf_16;
1207 state = .string_literal;
1208 },
1209 else => {
1210 self.index -= 1;
1211 state = .identifier;
1212 },
1213 },
1214 .u8 => switch (c) {
1215 '\"' => {
1216 id = .string_literal_utf_8;
1217 state = .string_literal;
1218 },
1219 '\'' => {
1220 id = .char_literal_utf_8;
1221 state = .char_literal_start;
1222 },
1223 else => {
1224 self.index -= 1;
1225 state = .identifier;
1226 },
1227 },
1228 .U => switch (c) {
1229 '\'' => {
1230 id = .char_literal_utf_32;
1231 state = .char_literal_start;
1232 },
1233 '\"' => {
1234 id = .string_literal_utf_32;
1235 state = .string_literal;
1236 },
1237 else => {
1238 self.index -= 1;
1239 state = .identifier;
1240 },
1241 },
1242 .L => switch (c) {
1243 '\'' => {
1244 id = .char_literal_wide;
1245 state = .char_literal_start;
1246 },
1247 '\"' => {
1248 id = .string_literal_wide;
1249 state = .string_literal;
1250 },
1251 else => {
1252 self.index -= 1;
1253 state = .identifier;
1254 },
1255 },
1256 .string_literal => switch (c) {
1257 '\\' => {
1258 state = .string_escape_sequence;
1259 },
1260 '"' => {
1261 self.index += 1;
1262 break;
1263 },
1264 '\n' => {
1265 id = .unterminated_string_literal;
1266 break;
1267 },
1268 '\r' => unreachable,
1269 else => {},
1270 },
1271 .char_literal_start => switch (c) {
1272 '\\' => {
1273 state = .char_escape_sequence;
1274 },
1275 '\'' => {
1276 id = .empty_char_literal;
1277 self.index += 1;
1278 break;
1279 },
1280 '\n' => {
1281 id = .unterminated_char_literal;
1282 break;
1283 },
1284 else => {
1285 state = .char_literal;
1286 },
1287 },
1288 .char_literal => switch (c) {
1289 '\\' => {
1290 state = .char_escape_sequence;
1291 },
1292 '\'' => {
1293 self.index += 1;
1294 break;
1295 },
1296 '\n' => {
1297 id = .unterminated_char_literal;
1298 break;
1299 },
1300 else => {},
1301 },
1302 .char_escape_sequence => switch (c) {
1303 '\r', '\n' => unreachable, // removed by line splicing
1304 else => state = .char_literal,
1305 },
1306 .string_escape_sequence => switch (c) {
1307 '\r', '\n' => unreachable, // removed by line splicing
1308 else => state = .string_literal,
1309 },
1310 .identifier, .extended_identifier => switch (c) {
1311 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
1312 '$' => if (self.langopts.dollars_in_identifiers) {
1313 state = .extended_identifier;
1314 } else {
1315 id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier;
1316 break;
1317 },
1318 0x80...0xFF => state = .extended_identifier,
1319 else => {
1320 id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier;
1321 break;
1322 },
1323 },
1324 .equal => switch (c) {
1325 '=' => {
1326 id = .equal_equal;
1327 self.index += 1;
1328 break;
1329 },
1330 else => {
1331 id = .equal;
1332 break;
1333 },
1334 },
1335 .bang => switch (c) {
1336 '=' => {
1337 id = .bang_equal;
1338 self.index += 1;
1339 break;
1340 },
1341 else => {
1342 id = .bang;
1343 break;
1344 },
1345 },
1346 .pipe => switch (c) {
1347 '=' => {
1348 id = .pipe_equal;
1349 self.index += 1;
1350 break;
1351 },
1352 '|' => {
1353 id = .pipe_pipe;
1354 self.index += 1;
1355 break;
1356 },
1357 else => {
1358 id = .pipe;
1359 break;
1360 },
1361 },
1362 .colon => switch (c) {
1363 '>' => {
1364 if (self.langopts.hasDigraphs()) {
1365 id = .r_bracket;
1366 self.index += 1;
1367 } else {
1368 id = .colon;
1369 }
1370 break;
1371 },
1372 ':' => {
1373 if (self.langopts.standard.atLeast(.c23)) {
1374 id = .colon_colon;
1375 self.index += 1;
1376 break;
1377 } else {
1378 id = .colon;
1379 break;
1380 }
1381 },
1382 else => {
1383 id = .colon;
1384 break;
1385 },
1386 },
1387 .percent => switch (c) {
1388 '=' => {
1389 id = .percent_equal;
1390 self.index += 1;
1391 break;
1392 },
1393 '>' => {
1394 if (self.langopts.hasDigraphs()) {
1395 id = .r_brace;
1396 self.index += 1;
1397 } else {
1398 id = .percent;
1399 }
1400 break;
1401 },
1402 ':' => {
1403 if (self.langopts.hasDigraphs()) {
1404 state = .hash_digraph;
1405 } else {
1406 id = .percent;
1407 break;
1408 }
1409 },
1410 else => {
1411 id = .percent;
1412 break;
1413 },
1414 },
1415 .asterisk => switch (c) {
1416 '=' => {
1417 id = .asterisk_equal;
1418 self.index += 1;
1419 break;
1420 },
1421 else => {
1422 id = .asterisk;
1423 break;
1424 },
1425 },
1426 .plus => switch (c) {
1427 '=' => {
1428 id = .plus_equal;
1429 self.index += 1;
1430 break;
1431 },
1432 '+' => {
1433 id = .plus_plus;
1434 self.index += 1;
1435 break;
1436 },
1437 else => {
1438 id = .plus;
1439 break;
1440 },
1441 },
1442 .angle_bracket_left => switch (c) {
1443 '<' => state = .angle_bracket_angle_bracket_left,
1444 '=' => {
1445 id = .angle_bracket_left_equal;
1446 self.index += 1;
1447 break;
1448 },
1449 ':' => {
1450 if (self.langopts.hasDigraphs()) {
1451 id = .l_bracket;
1452 self.index += 1;
1453 } else {
1454 id = .angle_bracket_left;
1455 }
1456 break;
1457 },
1458 '%' => {
1459 if (self.langopts.hasDigraphs()) {
1460 id = .l_brace;
1461 self.index += 1;
1462 } else {
1463 id = .angle_bracket_left;
1464 }
1465 break;
1466 },
1467 else => {
1468 id = .angle_bracket_left;
1469 break;
1470 },
1471 },
1472 .angle_bracket_angle_bracket_left => switch (c) {
1473 '=' => {
1474 id = .angle_bracket_angle_bracket_left_equal;
1475 self.index += 1;
1476 break;
1477 },
1478 else => {
1479 id = .angle_bracket_angle_bracket_left;
1480 break;
1481 },
1482 },
1483 .angle_bracket_right => switch (c) {
1484 '>' => state = .angle_bracket_angle_bracket_right,
1485 '=' => {
1486 id = .angle_bracket_right_equal;
1487 self.index += 1;
1488 break;
1489 },
1490 else => {
1491 id = .angle_bracket_right;
1492 break;
1493 },
1494 },
1495 .angle_bracket_angle_bracket_right => switch (c) {
1496 '=' => {
1497 id = .angle_bracket_angle_bracket_right_equal;
1498 self.index += 1;
1499 break;
1500 },
1501 else => {
1502 id = .angle_bracket_angle_bracket_right;
1503 break;
1504 },
1505 },
1506 .caret => switch (c) {
1507 '=' => {
1508 id = .caret_equal;
1509 self.index += 1;
1510 break;
1511 },
1512 else => {
1513 id = .caret;
1514 break;
1515 },
1516 },
1517 .period => switch (c) {
1518 '.' => state = .period2,
1519 '0'...'9' => state = .pp_num,
1520 else => {
1521 id = .period;
1522 break;
1523 },
1524 },
1525 .period2 => switch (c) {
1526 '.' => {
1527 id = .ellipsis;
1528 self.index += 1;
1529 break;
1530 },
1531 else => {
1532 id = .period;
1533 self.index -= 1;
1534 break;
1535 },
1536 },
1537 .minus => switch (c) {
1538 '>' => {
1539 id = .arrow;
1540 self.index += 1;
1541 break;
1542 },
1543 '=' => {
1544 id = .minus_equal;
1545 self.index += 1;
1546 break;
1547 },
1548 '-' => {
1549 id = .minus_minus;
1550 self.index += 1;
1551 break;
1552 },
1553 else => {
1554 id = .minus;
1555 break;
1556 },
1557 },
1558 .ampersand => switch (c) {
1559 '&' => {
1560 id = .ampersand_ampersand;
1561 self.index += 1;
1562 break;
1563 },
1564 '=' => {
1565 id = .ampersand_equal;
1566 self.index += 1;
1567 break;
1568 },
1569 else => {
1570 id = .ampersand;
1571 break;
1572 },
1573 },
1574 .hash => switch (c) {
1575 '#' => {
1576 id = .hash_hash;
1577 self.index += 1;
1578 break;
1579 },
1580 else => {
1581 id = .hash;
1582 break;
1583 },
1584 },
1585 .hash_digraph => switch (c) {
1586 '%' => state = .hash_hash_digraph_partial,
1587 else => {
1588 id = .hash;
1589 break;
1590 },
1591 },
1592 .hash_hash_digraph_partial => switch (c) {
1593 ':' => {
1594 id = .hash_hash;
1595 self.index += 1;
1596 break;
1597 },
1598 else => {
1599 id = .hash;
1600 self.index -= 1; // re-tokenize the percent
1601 break;
1602 },
1603 },
1604 .slash => switch (c) {
1605 '/' => state = .line_comment,
1606 '*' => state = .multi_line_comment,
1607 '=' => {
1608 id = .slash_equal;
1609 self.index += 1;
1610 break;
1611 },
1612 else => {
1613 id = .slash;
1614 break;
1615 },
1616 },
1617 .line_comment => switch (c) {
1618 '\n' => {
1619 if (self.langopts.preserve_comments) {
1620 id = .comment;
1621 break;
1622 }
1623 self.index -= 1;
1624 state = .start;
1625 },
1626 else => {},
1627 },
1628 .multi_line_comment => switch (c) {
1629 '*' => state = .multi_line_comment_asterisk,
1630 '\n' => self.line += 1,
1631 else => {},
1632 },
1633 .multi_line_comment_asterisk => switch (c) {
1634 '/' => {
1635 if (self.langopts.preserve_comments) {
1636 self.index += 1;
1637 id = .comment;
1638 break;
1639 }
1640 state = .multi_line_comment_done;
1641 },
1642 '\n' => {
1643 self.line += 1;
1644 state = .multi_line_comment;
1645 },
1646 '*' => {},
1647 else => state = .multi_line_comment,
1648 },
1649 .multi_line_comment_done => switch (c) {
1650 '\n' => {
1651 start = self.index;
1652 id = .nl;
1653 self.index += 1;
1654 self.line += 1;
1655 break;
1656 },
1657 '\r' => unreachable,
1658 '\t', '\x0B', '\x0C', ' ' => {
1659 start = self.index;
1660 state = .whitespace;
1661 },
1662 else => {
1663 id = .whitespace;
1664 break;
1665 },
1666 },
1667 .pp_num => switch (c) {
1668 'a'...'d',
1669 'A'...'D',
1670 'f'...'o',
1671 'F'...'O',
1672 'q'...'z',
1673 'Q'...'Z',
1674 '0'...'9',
1675 '_',
1676 '.',
1677 => {},
1678 'e', 'E', 'p', 'P' => state = .pp_num_exponent,
1679 '\'' => if (self.langopts.standard.atLeast(.c23)) {
1680 state = .pp_num_digit_separator;
1681 } else {
1682 id = .pp_num;
1683 break;
1684 },
1685 else => {
1686 id = .pp_num;
1687 break;
1688 },
1689 },
1690 .pp_num_digit_separator => switch (c) {
1691 'a'...'d',
1692 'A'...'D',
1693 'f'...'o',
1694 'F'...'O',
1695 'q'...'z',
1696 'Q'...'Z',
1697 '0'...'9',
1698 '_',
1699 => state = .pp_num,
1700 else => {
1701 self.index -= 1;
1702 id = .pp_num;
1703 break;
1704 },
1705 },
1706 .pp_num_exponent => switch (c) {
1707 'a'...'o',
1708 'q'...'z',
1709 'A'...'O',
1710 'Q'...'Z',
1711 '0'...'9',
1712 '_',
1713 '.',
1714 '+',
1715 '-',
1716 => state = .pp_num,
1717 'p', 'P' => {},
1718 else => {
1719 id = .pp_num;
1720 break;
1721 },
1722 },
1723 }
1724 } else if (self.index == self.buf.len) {
1725 switch (state) {
1726 .start, .line_comment => {},
1727 .u, .u8, .U, .L, .identifier => id = Token.getTokenId(self.langopts, self.buf[start..self.index]),
1728 .extended_identifier => id = .extended_identifier,
1729
1730 .period2 => {
1731 self.index -= 1;
1732 id = .period;
1733 },
1734
1735 .multi_line_comment,
1736 .multi_line_comment_asterisk,
1737 => id = .unterminated_comment,
1738
1739 .char_escape_sequence, .char_literal, .char_literal_start => id = .unterminated_char_literal,
1740 .string_escape_sequence, .string_literal => id = .unterminated_string_literal,
1741
1742 .whitespace => id = .whitespace,
1743 .multi_line_comment_done => id = .whitespace,
1744
1745 .equal => id = .equal,
1746 .bang => id = .bang,
1747 .minus => id = .minus,
1748 .slash => id = .slash,
1749 .ampersand => id = .ampersand,
1750 .hash => id = .hash,
1751 .period => id = .period,
1752 .pipe => id = .pipe,
1753 .angle_bracket_angle_bracket_right => id = .angle_bracket_angle_bracket_right,
1754 .angle_bracket_right => id = .angle_bracket_right,
1755 .angle_bracket_angle_bracket_left => id = .angle_bracket_angle_bracket_left,
1756 .angle_bracket_left => id = .angle_bracket_left,
1757 .plus => id = .plus,
1758 .colon => id = .colon,
1759 .percent => id = .percent,
1760 .caret => id = .caret,
1761 .asterisk => id = .asterisk,
1762 .hash_digraph => id = .hash,
1763 .hash_hash_digraph_partial => {
1764 id = .hash;
1765 self.index -= 1; // re-tokenize the percent
1766 },
1767 .pp_num, .pp_num_exponent, .pp_num_digit_separator => id = .pp_num,
1768 }
1769 }
1770
1771 return .{
1772 .id = id,
1773 .start = start,
1774 .end = self.index,
1775 .line = self.line,
1776 .source = self.source,
1777 };
1778}
1779
1780pub fn nextNoWS(self: *Tokenizer) Token {
1781 var tok = self.next();
1782 while (tok.id == .whitespace or tok.id == .comment) tok = self.next();
1783 return tok;
1784}
1785
1786pub fn nextNoWSComments(self: *Tokenizer) Token {
1787 var tok = self.next();
1788 while (tok.id == .whitespace) tok = self.next();
1789 return tok;
1790}
1791
1792/// Try to tokenize a '::' even if not supported by the current language standard.
1793pub fn colonColon(self: *Tokenizer) Token {
1794 var tok = self.nextNoWS();
1795 if (tok.id == .colon and self.buf[self.index] == ':') {
1796 self.index += 1;
1797 tok.id = .colon_colon;
1798 }
1799 return tok;
1800}
1801
1802test "operators" {
1803 try expectTokens(
1804 \\ ! != | || |= = ==
1805 \\ ( ) { } [ ] . .. ...
1806 \\ ^ ^= + ++ += - -- -=
1807 \\ * *= % %= -> : ; / /=
1808 \\ , & && &= ? < <= <<
1809 \\ <<= > >= >> >>= ~ # ##
1810 \\
1811 , &.{
1812 .bang,
1813 .bang_equal,
1814 .pipe,
1815 .pipe_pipe,
1816 .pipe_equal,
1817 .equal,
1818 .equal_equal,
1819 .nl,
1820 .l_paren,
1821 .r_paren,
1822 .l_brace,
1823 .r_brace,
1824 .l_bracket,
1825 .r_bracket,
1826 .period,
1827 .period,
1828 .period,
1829 .ellipsis,
1830 .nl,
1831 .caret,
1832 .caret_equal,
1833 .plus,
1834 .plus_plus,
1835 .plus_equal,
1836 .minus,
1837 .minus_minus,
1838 .minus_equal,
1839 .nl,
1840 .asterisk,
1841 .asterisk_equal,
1842 .percent,
1843 .percent_equal,
1844 .arrow,
1845 .colon,
1846 .semicolon,
1847 .slash,
1848 .slash_equal,
1849 .nl,
1850 .comma,
1851 .ampersand,
1852 .ampersand_ampersand,
1853 .ampersand_equal,
1854 .question_mark,
1855 .angle_bracket_left,
1856 .angle_bracket_left_equal,
1857 .angle_bracket_angle_bracket_left,
1858 .nl,
1859 .angle_bracket_angle_bracket_left_equal,
1860 .angle_bracket_right,
1861 .angle_bracket_right_equal,
1862 .angle_bracket_angle_bracket_right,
1863 .angle_bracket_angle_bracket_right_equal,
1864 .tilde,
1865 .hash,
1866 .hash_hash,
1867 .nl,
1868 });
1869}
1870
1871test "keywords" {
1872 try expectTokens(
1873 \\auto __auto_type break case char const continue default do
1874 \\double else enum extern float for goto if int
1875 \\long register return short signed sizeof static
1876 \\struct switch typedef union unsigned void volatile
1877 \\while _Bool _Complex _Imaginary inline restrict _Alignas
1878 \\_Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local
1879 \\__attribute __attribute__
1880 \\
1881 , &.{
1882 .keyword_auto,
1883 .keyword_auto_type,
1884 .keyword_break,
1885 .keyword_case,
1886 .keyword_char,
1887 .keyword_const,
1888 .keyword_continue,
1889 .keyword_default,
1890 .keyword_do,
1891 .nl,
1892 .keyword_double,
1893 .keyword_else,
1894 .keyword_enum,
1895 .keyword_extern,
1896 .keyword_float,
1897 .keyword_for,
1898 .keyword_goto,
1899 .keyword_if,
1900 .keyword_int,
1901 .nl,
1902 .keyword_long,
1903 .keyword_register,
1904 .keyword_return,
1905 .keyword_short,
1906 .keyword_signed,
1907 .keyword_sizeof,
1908 .keyword_static,
1909 .nl,
1910 .keyword_struct,
1911 .keyword_switch,
1912 .keyword_typedef,
1913 .keyword_union,
1914 .keyword_unsigned,
1915 .keyword_void,
1916 .keyword_volatile,
1917 .nl,
1918 .keyword_while,
1919 .keyword_bool,
1920 .keyword_complex,
1921 .keyword_imaginary,
1922 .keyword_inline,
1923 .keyword_restrict,
1924 .keyword_alignas,
1925 .nl,
1926 .keyword_alignof,
1927 .keyword_atomic,
1928 .keyword_generic,
1929 .keyword_noreturn,
1930 .keyword_static_assert,
1931 .keyword_thread_local,
1932 .nl,
1933 .keyword_attribute1,
1934 .keyword_attribute2,
1935 .nl,
1936 });
1937}
1938
1939test "preprocessor keywords" {
1940 try expectTokens(
1941 \\#include
1942 \\#include_next
1943 \\#embed
1944 \\#define
1945 \\#ifdef
1946 \\#ifndef
1947 \\#error
1948 \\#pragma
1949 \\
1950 , &.{
1951 .hash,
1952 .keyword_include,
1953 .nl,
1954 .hash,
1955 .keyword_include_next,
1956 .nl,
1957 .hash,
1958 .keyword_embed,
1959 .nl,
1960 .hash,
1961 .keyword_define,
1962 .nl,
1963 .hash,
1964 .keyword_ifdef,
1965 .nl,
1966 .hash,
1967 .keyword_ifndef,
1968 .nl,
1969 .hash,
1970 .keyword_error,
1971 .nl,
1972 .hash,
1973 .keyword_pragma,
1974 .nl,
1975 });
1976}
1977
1978test "line continuation" {
1979 try expectTokens(
1980 \\#define foo \
1981 \\ bar
1982 \\"foo\
1983 \\ bar"
1984 \\#define "foo"
1985 \\ "bar"
1986 \\#define "foo" \
1987 \\ "bar"
1988 , &.{
1989 .hash,
1990 .keyword_define,
1991 .identifier,
1992 .identifier,
1993 .nl,
1994 .string_literal,
1995 .nl,
1996 .hash,
1997 .keyword_define,
1998 .string_literal,
1999 .nl,
2000 .string_literal,
2001 .nl,
2002 .hash,
2003 .keyword_define,
2004 .string_literal,
2005 .string_literal,
2006 });
2007}
2008
2009test "string prefix" {
2010 try expectTokens(
2011 \\"foo"
2012 \\u"foo"
2013 \\u8"foo"
2014 \\U"foo"
2015 \\L"foo"
2016 \\'foo'
2017 \\u8'A'
2018 \\u'foo'
2019 \\U'foo'
2020 \\L'foo'
2021 \\
2022 , &.{
2023 .string_literal,
2024 .nl,
2025 .string_literal_utf_16,
2026 .nl,
2027 .string_literal_utf_8,
2028 .nl,
2029 .string_literal_utf_32,
2030 .nl,
2031 .string_literal_wide,
2032 .nl,
2033 .char_literal,
2034 .nl,
2035 .char_literal_utf_8,
2036 .nl,
2037 .char_literal_utf_16,
2038 .nl,
2039 .char_literal_utf_32,
2040 .nl,
2041 .char_literal_wide,
2042 .nl,
2043 });
2044}
2045
2046test "num suffixes" {
2047 try expectTokens(
2048 \\ 1.0f 1.0L 1.0 .0 1. 0x1p0f 0X1p0
2049 \\ 0l 0lu 0ll 0llu 0
2050 \\ 1u 1ul 1ull 1
2051 \\ 1.0i 1.0I
2052 \\ 1.0if 1.0If 1.0fi 1.0fI
2053 \\ 1.0il 1.0Il 1.0li 1.0lI
2054 \\
2055 , &.{
2056 .pp_num,
2057 .pp_num,
2058 .pp_num,
2059 .pp_num,
2060 .pp_num,
2061 .pp_num,
2062 .pp_num,
2063 .nl,
2064 .pp_num,
2065 .pp_num,
2066 .pp_num,
2067 .pp_num,
2068 .pp_num,
2069 .nl,
2070 .pp_num,
2071 .pp_num,
2072 .pp_num,
2073 .pp_num,
2074 .nl,
2075 .pp_num,
2076 .pp_num,
2077 .nl,
2078 .pp_num,
2079 .pp_num,
2080 .pp_num,
2081 .pp_num,
2082 .nl,
2083 .pp_num,
2084 .pp_num,
2085 .pp_num,
2086 .pp_num,
2087 .nl,
2088 });
2089}
2090
2091test "comments" {
2092 try expectTokens(
2093 \\//foo
2094 \\#foo
2095 , &.{
2096 .nl,
2097 .hash,
2098 .identifier,
2099 });
2100}
2101
2102test "extended identifiers" {
2103 try expectTokens("𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2104 try expectTokens("u𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2105 try expectTokens("u8𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2106 try expectTokens("U𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2107 try expectTokens("L𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2108 try expectTokens("1™", &.{ .pp_num, .extended_identifier });
2109 try expectTokens("1.™", &.{ .pp_num, .extended_identifier });
2110 try expectTokens("..™", &.{ .period, .period, .extended_identifier });
2111 try expectTokens("0™", &.{ .pp_num, .extended_identifier });
2112 try expectTokens("0b\u{E0000}", &.{ .pp_num, .extended_identifier });
2113 try expectTokens("0b0\u{E0000}", &.{ .pp_num, .extended_identifier });
2114 try expectTokens("01\u{E0000}", &.{ .pp_num, .extended_identifier });
2115 try expectTokens("010\u{E0000}", &.{ .pp_num, .extended_identifier });
2116 try expectTokens("0x\u{E0000}", &.{ .pp_num, .extended_identifier });
2117 try expectTokens("0x0\u{E0000}", &.{ .pp_num, .extended_identifier });
2118 try expectTokens("\"\\0\u{E0000}\"", &.{.string_literal});
2119 try expectTokens("\"\\x\u{E0000}\"", &.{.string_literal});
2120 try expectTokens("\"\\u\u{E0000}\"", &.{.string_literal});
2121 try expectTokens("1e\u{E0000}", &.{ .pp_num, .extended_identifier });
2122 try expectTokens("1e1\u{E0000}", &.{ .pp_num, .extended_identifier });
2123}
2124
2125test "digraphs" {
2126 try expectTokens("%:<::><%%>%:%:", &.{ .hash, .l_bracket, .r_bracket, .l_brace, .r_brace, .hash_hash });
2127 try expectTokens("\"%:<::><%%>%:%:\"", &.{.string_literal});
2128 try expectTokens("%:%42 %:%", &.{ .hash, .percent, .pp_num, .hash, .percent });
2129}
2130
2131test "C23 keywords" {
2132 try expectTokensExtra("true false alignas alignof bool static_assert thread_local nullptr typeof_unqual", &.{
2133 .keyword_true,
2134 .keyword_false,
2135 .keyword_c23_alignas,
2136 .keyword_c23_alignof,
2137 .keyword_c23_bool,
2138 .keyword_c23_static_assert,
2139 .keyword_c23_thread_local,
2140 .keyword_nullptr,
2141 .keyword_typeof_unqual,
2142 }, .c23);
2143}
2144
2145fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, standard: ?LangOpts.Standard) !void {
2146 var comp = Compilation.init(std.testing.allocator);
2147 defer comp.deinit();
2148 if (standard) |provided| {
2149 comp.langopts.standard = provided;
2150 }
2151 const source = try comp.addSourceFromBuffer("path", contents);
2152 var tokenizer = Tokenizer{
2153 .buf = source.buf,
2154 .source = source.id,
2155 .langopts = comp.langopts,
2156 };
2157 var i: usize = 0;
2158 while (i < expected_tokens.len) {
2159 const token = tokenizer.next();
2160 if (token.id == .whitespace) continue;
2161 const expected_token_id = expected_tokens[i];
2162 i += 1;
2163 if (!std.meta.eql(token.id, expected_token_id)) {
2164 std.debug.print("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
2165 return error.TokensDoNotEqual;
2166 }
2167 }
2168 const last_token = tokenizer.next();
2169 try std.testing.expect(last_token.id == .eof);
2170}
2171
2172fn expectTokens(contents: []const u8, expected_tokens: []const Token.Id) !void {
2173 return expectTokensExtra(contents, expected_tokens, null);
2174}
deps/aro/aro/Toolchain.zig deleted-489
......@@ -1,489 +0,0 @@
1const std = @import("std");
2const Driver = @import("Driver.zig");
3const Compilation = @import("Compilation.zig");
4const mem = std.mem;
5const system_defaults = @import("system_defaults");
6const target_util = @import("target.zig");
7const Linux = @import("toolchains/Linux.zig");
8const Multilib = @import("Driver/Multilib.zig");
9const Filesystem = @import("Driver/Filesystem.zig").Filesystem;
10
11pub const PathList = std.ArrayListUnmanaged([]const u8);
12
13pub const RuntimeLibKind = enum {
14 compiler_rt,
15 libgcc,
16};
17
18pub const FileKind = enum {
19 object,
20 static,
21 shared,
22};
23
24pub const LibGCCKind = enum {
25 unspecified,
26 static,
27 shared,
28};
29
30pub const UnwindLibKind = enum {
31 none,
32 compiler_rt,
33 libgcc,
34};
35
36const Inner = union(enum) {
37 uninitialized,
38 linux: Linux,
39 unknown: void,
40
41 fn deinit(self: *Inner, allocator: mem.Allocator) void {
42 switch (self.*) {
43 .linux => |*linux| linux.deinit(allocator),
44 .uninitialized, .unknown => {},
45 }
46 }
47};
48
49const Toolchain = @This();
50
51filesystem: Filesystem = .{ .real = {} },
52driver: *Driver,
53arena: mem.Allocator,
54
55/// The list of toolchain specific path prefixes to search for libraries.
56library_paths: PathList = .{},
57
58/// The list of toolchain specific path prefixes to search for files.
59file_paths: PathList = .{},
60
61/// The list of toolchain specific path prefixes to search for programs.
62program_paths: PathList = .{},
63
64selected_multilib: Multilib = .{},
65
66inner: Inner = .{ .uninitialized = {} },
67
68pub fn getTarget(tc: *const Toolchain) std.Target {
69 return tc.driver.comp.target;
70}
71
72fn getDefaultLinker(tc: *const Toolchain) []const u8 {
73 return switch (tc.inner) {
74 .uninitialized => unreachable,
75 .linux => |linux| linux.getDefaultLinker(tc.getTarget()),
76 .unknown => "ld",
77 };
78}
79
80/// Call this after driver has finished parsing command line arguments to find the toolchain
81pub fn discover(tc: *Toolchain) !void {
82 if (tc.inner != .uninitialized) return;
83
84 const target = tc.getTarget();
85 tc.inner = switch (target.os.tag) {
86 .elfiamcu,
87 .linux,
88 => if (target.cpu.arch == .hexagon)
89 .{ .unknown = {} } // TODO
90 else if (target.cpu.arch.isMIPS())
91 .{ .unknown = {} } // TODO
92 else if (target.cpu.arch.isPPC())
93 .{ .unknown = {} } // TODO
94 else if (target.cpu.arch == .ve)
95 .{ .unknown = {} } // TODO
96 else
97 .{ .linux = .{} },
98 else => .{ .unknown = {} }, // TODO
99 };
100 return switch (tc.inner) {
101 .uninitialized => unreachable,
102 .linux => |*linux| linux.discover(tc),
103 .unknown => {},
104 };
105}
106
107pub fn deinit(tc: *Toolchain) void {
108 const gpa = tc.driver.comp.gpa;
109 tc.inner.deinit(gpa);
110
111 tc.library_paths.deinit(gpa);
112 tc.file_paths.deinit(gpa);
113 tc.program_paths.deinit(gpa);
114}
115
116/// Write linker path to `buf` and return a slice of it
117pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
118 // --ld-path= takes precedence over -fuse-ld= and specifies the executable
119 // name. -B, COMPILER_PATH and PATH are consulted if the value does not
120 // contain a path component separator.
121 // -fuse-ld=lld can be used with --ld-path= to indicate that the binary
122 // that --ld-path= points to is lld.
123 const use_linker = tc.driver.use_linker orelse system_defaults.linker;
124
125 if (tc.driver.linker_path) |ld_path| {
126 var path = ld_path;
127 if (path.len > 0) {
128 if (std.fs.path.dirname(path) == null) {
129 path = tc.getProgramPath(path, buf);
130 }
131 if (tc.filesystem.canExecute(path)) {
132 return path;
133 }
134 }
135 return tc.driver.fatal(
136 "invalid linker name in argument '--ld-path={s}'",
137 .{path},
138 );
139 }
140
141 // If we're passed -fuse-ld= with no argument, or with the argument ld,
142 // then use whatever the default system linker is.
143 if (use_linker.len == 0 or mem.eql(u8, use_linker, "ld")) {
144 const default = tc.getDefaultLinker();
145 if (std.fs.path.isAbsolute(default)) return default;
146 return tc.getProgramPath(default, buf);
147 }
148
149 // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
150 // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
151 // to a relative path is surprising. This is more complex due to priorities
152 // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
153 if (mem.indexOfScalar(u8, use_linker, '/') != null) {
154 try tc.driver.comp.addDiagnostic(.{ .tag = .fuse_ld_path }, &.{});
155 }
156
157 if (std.fs.path.isAbsolute(use_linker)) {
158 if (tc.filesystem.canExecute(use_linker)) {
159 return use_linker;
160 }
161 } else {
162 var linker_name = try std.ArrayList(u8).initCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker
163 defer linker_name.deinit();
164 if (tc.getTarget().isDarwin()) {
165 linker_name.appendSliceAssumeCapacity("ld64.");
166 } else {
167 linker_name.appendSliceAssumeCapacity("ld.");
168 }
169 linker_name.appendSliceAssumeCapacity(use_linker);
170 const linker_path = tc.getProgramPath(linker_name.items, buf);
171 if (tc.filesystem.canExecute(linker_path)) {
172 return linker_path;
173 }
174 }
175
176 if (tc.driver.use_linker) |linker| {
177 return tc.driver.fatal(
178 "invalid linker name in argument '-fuse-ld={s}'",
179 .{linker},
180 );
181 }
182 const default_linker = tc.getDefaultLinker();
183 return tc.getProgramPath(default_linker, buf);
184}
185
186/// If an explicit target is provided, also check the prefixed tool-specific name
187/// TODO: this isn't exactly right since our target names don't necessarily match up
188/// with GCC's.
189/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools
190fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, buf: *[64]u8) std.BoundedArray([]const u8, 2) {
191 var possible_names: std.BoundedArray([]const u8, 2) = .{};
192 if (raw_triple) |triple| {
193 if (std.fmt.bufPrint(buf, "{s}-{s}", .{ triple, name })) |res| {
194 possible_names.appendAssumeCapacity(res);
195 } else |_| {}
196 }
197 possible_names.appendAssumeCapacity(name);
198
199 return possible_names;
200}
201
202/// Add toolchain `file_paths` to argv as `-L` arguments
203pub fn addFilePathLibArgs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
204 try argv.ensureUnusedCapacity(tc.file_paths.items.len);
205
206 var bytes_needed: usize = 0;
207 for (tc.file_paths.items) |path| {
208 bytes_needed += path.len + 2; // +2 for `-L`
209 }
210 var bytes = try tc.arena.alloc(u8, bytes_needed);
211 var index: usize = 0;
212 for (tc.file_paths.items) |path| {
213 @memcpy(bytes[index..][0..2], "-L");
214 @memcpy(bytes[index + 2 ..][0..path.len], path);
215 argv.appendAssumeCapacity(bytes[index..][0 .. path.len + 2]);
216 index += path.len + 2;
217 }
218}
219
220/// Search for an executable called `name` or `{triple}-{name} in program_paths and the $PATH environment variable
221/// If not found there, just use `name`
222/// Writes the result to `buf` and returns a slice of it
223fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8 {
224 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
225 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
226
227 var tool_specific_buf: [64]u8 = undefined;
228 const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf);
229
230 for (possible_names.constSlice()) |tool_name| {
231 for (tc.program_paths.items) |program_path| {
232 defer fib.reset();
233
234 const candidate = std.fs.path.join(fib.allocator(), &.{ program_path, tool_name }) catch continue;
235
236 if (tc.filesystem.canExecute(candidate) and candidate.len <= buf.len) {
237 @memcpy(buf[0..candidate.len], candidate);
238 return buf[0..candidate.len];
239 }
240 }
241 return tc.filesystem.findProgramByName(tc.driver.comp.gpa, name, tc.driver.comp.environment.path, buf) orelse continue;
242 }
243 @memcpy(buf[0..name.len], name);
244 return buf[0..name.len];
245}
246
247pub fn getSysroot(tc: *const Toolchain) []const u8 {
248 return tc.driver.sysroot orelse system_defaults.sysroot;
249}
250
251/// Search for `name` in a variety of places
252/// TODO: cache results based on `name` so we're not repeatedly allocating the same strings?
253pub fn getFilePath(tc: *const Toolchain, name: []const u8) ![]const u8 {
254 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
255 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
256 const allocator = fib.allocator();
257
258 const sysroot = tc.getSysroot();
259
260 // todo check resource dir
261 // todo check compiler RT path
262 const aro_dir = std.fs.path.dirname(tc.driver.aro_name) orelse "";
263 const candidate = try std.fs.path.join(allocator, &.{ aro_dir, "..", name });
264 if (tc.filesystem.exists(candidate)) {
265 return tc.arena.dupe(u8, candidate);
266 }
267
268 if (tc.searchPaths(&fib, sysroot, tc.library_paths.items, name)) |path| {
269 return tc.arena.dupe(u8, path);
270 }
271
272 if (tc.searchPaths(&fib, sysroot, tc.file_paths.items, name)) |path| {
273 return try tc.arena.dupe(u8, path);
274 }
275
276 return name;
277}
278
279/// Search a list of `path_prefixes` for the existence `name`
280/// Assumes that `fba` is a fixed-buffer allocator, so does not free joined path candidates
281fn searchPaths(tc: *const Toolchain, fib: *std.heap.FixedBufferAllocator, sysroot: []const u8, path_prefixes: []const []const u8, name: []const u8) ?[]const u8 {
282 for (path_prefixes) |path| {
283 fib.reset();
284 if (path.len == 0) continue;
285
286 const candidate = if (path[0] == '=')
287 std.fs.path.join(fib.allocator(), &.{ sysroot, path[1..], name }) catch continue
288 else
289 std.fs.path.join(fib.allocator(), &.{ path, name }) catch continue;
290
291 if (tc.filesystem.exists(candidate)) {
292 return candidate;
293 }
294 }
295 return null;
296}
297
298const PathKind = enum {
299 library,
300 file,
301 program,
302};
303
304/// Join `components` into a path. If the path exists, dupe it into the toolchain arena and
305/// add it to the specified path list.
306pub fn addPathIfExists(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
307 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
308 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
309
310 const candidate = try std.fs.path.join(fib.allocator(), components);
311
312 if (tc.filesystem.exists(candidate)) {
313 const duped = try tc.arena.dupe(u8, candidate);
314 const dest = switch (dest_kind) {
315 .library => &tc.library_paths,
316 .file => &tc.file_paths,
317 .program => &tc.program_paths,
318 };
319 try dest.append(tc.driver.comp.gpa, duped);
320 }
321}
322
323/// Join `components` using the toolchain arena and add the resulting path to `dest_kind`. Does not check
324/// whether the path actually exists
325pub fn addPathFromComponents(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
326 const full_path = try std.fs.path.join(tc.arena, components);
327 const dest = switch (dest_kind) {
328 .library => &tc.library_paths,
329 .file => &tc.file_paths,
330 .program => &tc.program_paths,
331 };
332 try dest.append(tc.driver.comp.gpa, full_path);
333}
334
335/// Add linker args to `argv`. Does not add path to linker executable as first item; that must be handled separately
336/// Items added to `argv` will be string literals or owned by `tc.arena` so they must not be individually freed
337pub fn buildLinkerArgs(tc: *Toolchain, argv: *std.ArrayList([]const u8)) !void {
338 return switch (tc.inner) {
339 .uninitialized => unreachable,
340 .linux => |*linux| linux.buildLinkerArgs(tc, argv),
341 .unknown => @panic("This toolchain does not support linking yet"),
342 };
343}
344
345fn getDefaultRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
346 if (tc.getTarget().isAndroid()) {
347 return .compiler_rt;
348 }
349 return .libgcc;
350}
351
352pub fn getRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
353 const libname = tc.driver.rtlib orelse system_defaults.rtlib;
354 if (mem.eql(u8, libname, "compiler-rt"))
355 return .compiler_rt
356 else if (mem.eql(u8, libname, "libgcc"))
357 return .libgcc
358 else
359 return tc.getDefaultRuntimeLibKind();
360}
361
362/// TODO
363pub fn getCompilerRt(tc: *const Toolchain, component: []const u8, file_kind: FileKind) ![]const u8 {
364 _ = file_kind;
365 _ = component;
366 _ = tc;
367 return "";
368}
369
370fn getLibGCCKind(tc: *const Toolchain) LibGCCKind {
371 const target = tc.getTarget();
372 if (tc.driver.static_libgcc or tc.driver.static or tc.driver.static_pie or target.isAndroid()) {
373 return .static;
374 }
375 if (tc.driver.shared_libgcc) {
376 return .shared;
377 }
378 return .unspecified;
379}
380
381fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
382 const libname = tc.driver.unwindlib orelse system_defaults.unwindlib;
383 if (libname.len == 0 or mem.eql(u8, libname, "platform")) {
384 switch (tc.getRuntimeLibKind()) {
385 .compiler_rt => {
386 const target = tc.getTarget();
387 if (target.isAndroid() or target.os.tag == .aix) {
388 return .compiler_rt;
389 } else {
390 return .none;
391 }
392 },
393 .libgcc => return .libgcc,
394 }
395 } else if (mem.eql(u8, libname, "none")) {
396 return .none;
397 } else if (mem.eql(u8, libname, "libgcc")) {
398 return .libgcc;
399 } else if (mem.eql(u8, libname, "libunwind")) {
400 if (tc.getRuntimeLibKind() == .libgcc) {
401 try tc.driver.comp.addDiagnostic(.{ .tag = .incompatible_unwindlib }, &.{});
402 }
403 return .compiler_rt;
404 } else {
405 unreachable;
406 }
407}
408
409fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 {
410 if (is_solaris) {
411 return if (needed) "-zignore" else "-zrecord";
412 } else {
413 return if (needed) "--as-needed" else "--no-as-needed";
414 }
415}
416
417fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
418 const unw = try tc.getUnwindLibKind();
419 const target = tc.getTarget();
420 if ((target.isAndroid() and unw == .libgcc) or
421 target.os.tag == .elfiamcu or
422 target.ofmt == .wasm or
423 target_util.isWindowsMSVCEnvironment(target) or
424 unw == .none) return;
425
426 const lgk = tc.getLibGCCKind();
427 const as_needed = lgk == .unspecified and !target.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
428 if (as_needed) {
429 try argv.append(getAsNeededOption(target.os.tag == .solaris, true));
430 }
431 switch (unw) {
432 .none => return,
433 .libgcc => if (lgk == .static) try argv.append("-lgcc_eh") else try argv.append("-lgcc_s"),
434 .compiler_rt => if (target.os.tag == .aix) {
435 if (lgk != .static) {
436 try argv.append("-lunwind");
437 }
438 } else if (lgk == .static) {
439 try argv.append("-l:libunwind.a");
440 } else if (lgk == .shared) {
441 if (target_util.isCygwinMinGW(target)) {
442 try argv.append("-l:libunwind.dll.a");
443 } else {
444 try argv.append("-l:libunwind.so");
445 }
446 } else {
447 try argv.append("-lunwind");
448 },
449 }
450
451 if (as_needed) {
452 try argv.append(getAsNeededOption(target.os.tag == .solaris, false));
453 }
454}
455
456fn addLibGCC(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
457 const libgcc_kind = tc.getLibGCCKind();
458 if (libgcc_kind == .static or libgcc_kind == .unspecified) {
459 try argv.append("-lgcc");
460 }
461 try tc.addUnwindLibrary(argv);
462 if (libgcc_kind == .shared) {
463 try argv.append("-lgcc");
464 }
465}
466
467pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
468 const target = tc.getTarget();
469 const rlt = tc.getRuntimeLibKind();
470 switch (rlt) {
471 .compiler_rt => {
472 // TODO
473 },
474 .libgcc => {
475 if (target_util.isKnownWindowsMSVCEnvironment(target)) {
476 const rtlib_str = tc.driver.rtlib orelse system_defaults.rtlib;
477 if (!mem.eql(u8, rtlib_str, "platform")) {
478 try tc.driver.comp.addDiagnostic(.{ .tag = .unsupported_rtlib_gcc, .extra = .{ .str = "MSVC" } }, &.{});
479 }
480 } else {
481 try tc.addLibGCC(argv);
482 }
483 },
484 }
485
486 if (target.isAndroid() and !tc.driver.static and !tc.driver.static_pie) {
487 try argv.append("-ldl");
488 }
489}
deps/aro/aro/Tree.zig deleted-1334
......@@ -1,1334 +0,0 @@
1const std = @import("std");
2const Interner = @import("backend").Interner;
3const Attribute = @import("Attribute.zig");
4const CodeGen = @import("CodeGen.zig");
5const Compilation = @import("Compilation.zig");
6const number_affixes = @import("Tree/number_affixes.zig");
7const Source = @import("Source.zig");
8const Tokenizer = @import("Tokenizer.zig");
9const Type = @import("Type.zig");
10const Value = @import("Value.zig");
11const StringInterner = @import("StringInterner.zig");
12
13pub const Token = struct {
14 id: Id,
15 flags: packed struct {
16 expansion_disabled: bool = false,
17 is_macro_arg: bool = false,
18 } = .{},
19 /// This location contains the actual token slice which might be generated.
20 /// If it is generated then there is guaranteed to be at least one
21 /// expansion location.
22 loc: Source.Location,
23 expansion_locs: ?[*]Source.Location = null,
24
25 pub fn expansionSlice(tok: Token) []const Source.Location {
26 const locs = tok.expansion_locs orelse return &[0]Source.Location{};
27 var i: usize = 0;
28 while (locs[i].id != .unused) : (i += 1) {}
29 return locs[0..i];
30 }
31
32 pub fn addExpansionLocation(tok: *Token, gpa: std.mem.Allocator, new: []const Source.Location) !void {
33 if (new.len == 0 or tok.id == .whitespace) return;
34 var list = std.ArrayList(Source.Location).init(gpa);
35 defer {
36 @memset(list.items.ptr[list.items.len..list.capacity], .{});
37 // Add a sentinel to indicate the end of the list since
38 // the ArrayList's capacity isn't guaranteed to be exactly
39 // what we ask for.
40 if (list.capacity > 0) {
41 list.items.ptr[list.capacity - 1].byte_offset = 1;
42 }
43 tok.expansion_locs = list.items.ptr;
44 }
45
46 if (tok.expansion_locs) |locs| {
47 var i: usize = 0;
48 while (locs[i].id != .unused) : (i += 1) {}
49 list.items = locs[0..i];
50 while (locs[i].byte_offset != 1) : (i += 1) {}
51 list.capacity = i + 1;
52 }
53
54 const min_len = @max(list.items.len + new.len + 1, 4);
55 const wanted_len = std.math.ceilPowerOfTwo(usize, min_len) catch
56 return error.OutOfMemory;
57 try list.ensureTotalCapacity(wanted_len);
58
59 for (new) |new_loc| {
60 if (new_loc.id == .generated) continue;
61 list.appendAssumeCapacity(new_loc);
62 }
63 }
64
65 pub fn free(expansion_locs: ?[*]Source.Location, gpa: std.mem.Allocator) void {
66 const locs = expansion_locs orelse return;
67 var i: usize = 0;
68 while (locs[i].id != .unused) : (i += 1) {}
69 while (locs[i].byte_offset != 1) : (i += 1) {}
70 gpa.free(locs[0 .. i + 1]);
71 }
72
73 pub fn dupe(tok: Token, gpa: std.mem.Allocator) !Token {
74 var copy = tok;
75 copy.expansion_locs = null;
76 try copy.addExpansionLocation(gpa, tok.expansionSlice());
77 return copy;
78 }
79
80 pub fn checkMsEof(tok: Token, source: Source, comp: *Compilation) !void {
81 std.debug.assert(tok.id == .eof);
82 if (source.buf.len > tok.loc.byte_offset and source.buf[tok.loc.byte_offset] == 0x1A) {
83 try comp.addDiagnostic(.{
84 .tag = .ctrl_z_eof,
85 .loc = .{
86 .id = source.id,
87 .byte_offset = tok.loc.byte_offset,
88 .line = tok.loc.line,
89 },
90 }, &.{});
91 }
92 }
93
94 pub const List = std.MultiArrayList(Token);
95 pub const Id = Tokenizer.Token.Id;
96 pub const NumberPrefix = number_affixes.Prefix;
97 pub const NumberSuffix = number_affixes.Suffix;
98};
99
100pub const TokenIndex = u32;
101pub const NodeIndex = enum(u32) { none, _ };
102pub const ValueMap = std.AutoHashMap(NodeIndex, Value);
103
104const Tree = @This();
105
106comp: *Compilation,
107arena: std.heap.ArenaAllocator,
108generated: []const u8,
109tokens: Token.List.Slice,
110nodes: Node.List.Slice,
111data: []const NodeIndex,
112root_decls: []const NodeIndex,
113value_map: ValueMap,
114
115pub const genIr = CodeGen.genIr;
116
117pub fn deinit(tree: *Tree) void {
118 tree.comp.gpa.free(tree.root_decls);
119 tree.comp.gpa.free(tree.data);
120 tree.nodes.deinit(tree.comp.gpa);
121 tree.arena.deinit();
122 tree.value_map.deinit();
123}
124
125pub const GNUAssemblyQualifiers = struct {
126 @"volatile": bool = false,
127 @"inline": bool = false,
128 goto: bool = false,
129};
130
131pub const Node = struct {
132 tag: Tag,
133 ty: Type = .{ .specifier = .void },
134 data: Data,
135
136 pub const Range = struct { start: u32, end: u32 };
137
138 pub const Data = union {
139 decl: struct {
140 name: TokenIndex,
141 node: NodeIndex = .none,
142 },
143 decl_ref: TokenIndex,
144 range: Range,
145 if3: struct {
146 cond: NodeIndex,
147 body: u32,
148 },
149 un: NodeIndex,
150 bin: struct {
151 lhs: NodeIndex,
152 rhs: NodeIndex,
153 },
154 member: struct {
155 lhs: NodeIndex,
156 index: u32,
157 },
158 union_init: struct {
159 field_index: u32,
160 node: NodeIndex,
161 },
162 cast: struct {
163 operand: NodeIndex,
164 kind: CastKind,
165 },
166 int: u64,
167 return_zero: bool,
168
169 pub fn forDecl(data: Data, tree: *const Tree) struct {
170 decls: []const NodeIndex,
171 cond: NodeIndex,
172 incr: NodeIndex,
173 body: NodeIndex,
174 } {
175 const items = tree.data[data.range.start..data.range.end];
176 const decls = items[0 .. items.len - 3];
177
178 return .{
179 .decls = decls,
180 .cond = items[items.len - 3],
181 .incr = items[items.len - 2],
182 .body = items[items.len - 1],
183 };
184 }
185
186 pub fn forStmt(data: Data, tree: *const Tree) struct {
187 init: NodeIndex,
188 cond: NodeIndex,
189 incr: NodeIndex,
190 body: NodeIndex,
191 } {
192 const items = tree.data[data.if3.body..];
193
194 return .{
195 .init = items[0],
196 .cond = items[1],
197 .incr = items[2],
198 .body = data.if3.cond,
199 };
200 }
201 };
202
203 pub const List = std.MultiArrayList(Node);
204};
205
206pub const CastKind = enum(u8) {
207 /// Does nothing except possibly add qualifiers
208 no_op,
209 /// Interpret one bit pattern as another. Used for operands which have the same
210 /// size and unrelated types, e.g. casting one pointer type to another
211 bitcast,
212 /// Convert T[] to T *
213 array_to_pointer,
214 /// Converts an lvalue to an rvalue
215 lval_to_rval,
216 /// Convert a function type to a pointer to a function
217 function_to_pointer,
218 /// Convert a pointer type to a _Bool
219 pointer_to_bool,
220 /// Convert a pointer type to an integer type
221 pointer_to_int,
222 /// Convert _Bool to an integer type
223 bool_to_int,
224 /// Convert _Bool to a floating type
225 bool_to_float,
226 /// Convert a _Bool to a pointer; will cause a warning
227 bool_to_pointer,
228 /// Convert an integer type to _Bool
229 int_to_bool,
230 /// Convert an integer to a floating type
231 int_to_float,
232 /// Convert a complex integer to a complex floating type
233 complex_int_to_complex_float,
234 /// Convert an integer type to a pointer type
235 int_to_pointer,
236 /// Convert a floating type to a _Bool
237 float_to_bool,
238 /// Convert a floating type to an integer
239 float_to_int,
240 /// Convert a complex floating type to a complex integer
241 complex_float_to_complex_int,
242 /// Convert one integer type to another
243 int_cast,
244 /// Convert one complex integer type to another
245 complex_int_cast,
246 /// Convert real part of complex integer to a integer
247 complex_int_to_real,
248 /// Create a complex integer type using operand as the real part
249 real_to_complex_int,
250 /// Convert one floating type to another
251 float_cast,
252 /// Convert one complex floating type to another
253 complex_float_cast,
254 /// Convert real part of complex float to a float
255 complex_float_to_real,
256 /// Create a complex floating type using operand as the real part
257 real_to_complex_float,
258 /// Convert type to void
259 to_void,
260 /// Convert a literal 0 to a null pointer
261 null_to_pointer,
262 /// GNU cast-to-union extension
263 union_cast,
264 /// Create vector where each value is same as the input scalar.
265 vector_splat,
266};
267
268pub const Tag = enum(u8) {
269 /// Must appear at index 0. Also used as the tag for __builtin_types_compatible_p arguments, since the arguments are types
270 /// Reaching it is always the result of a bug.
271 invalid,
272
273 // ====== Decl ======
274
275 // _Static_assert
276 static_assert,
277
278 // function prototype
279 fn_proto,
280 static_fn_proto,
281 inline_fn_proto,
282 inline_static_fn_proto,
283
284 // function definition
285 fn_def,
286 static_fn_def,
287 inline_fn_def,
288 inline_static_fn_def,
289
290 // variable declaration
291 @"var",
292 extern_var,
293 static_var,
294 // same as static_var, used for __func__, __FUNCTION__ and __PRETTY_FUNCTION__
295 implicit_static_var,
296 threadlocal_var,
297 threadlocal_extern_var,
298 threadlocal_static_var,
299
300 /// __asm__("...") at file scope
301 file_scope_asm,
302
303 // typedef declaration
304 typedef,
305
306 // container declarations
307 /// { lhs; rhs; }
308 struct_decl_two,
309 /// { lhs; rhs; }
310 union_decl_two,
311 /// { lhs, rhs, }
312 enum_decl_two,
313 /// { range }
314 struct_decl,
315 /// { range }
316 union_decl,
317 /// { range }
318 enum_decl,
319 /// struct decl_ref;
320 struct_forward_decl,
321 /// union decl_ref;
322 union_forward_decl,
323 /// enum decl_ref;
324 enum_forward_decl,
325
326 /// name = node
327 enum_field_decl,
328 /// ty name : node
329 /// name == 0 means unnamed
330 record_field_decl,
331 /// Used when a record has an unnamed record as a field
332 indirect_record_field_decl,
333
334 // ====== Stmt ======
335
336 labeled_stmt,
337 /// { first; second; } first and second may be null
338 compound_stmt_two,
339 /// { data }
340 compound_stmt,
341 /// if (first) data[second] else data[second+1];
342 if_then_else_stmt,
343 /// if (first) second; second may be null
344 if_then_stmt,
345 /// switch (first) second
346 switch_stmt,
347 /// case first: second
348 case_stmt,
349 /// case data[body]...data[body+1]: cond
350 case_range_stmt,
351 /// default: first
352 default_stmt,
353 /// while (first) second
354 while_stmt,
355 /// do second while(first);
356 do_while_stmt,
357 /// for (data[..]; data[len-3]; data[len-2]) data[len-1]
358 for_decl_stmt,
359 /// for (;;;) first
360 forever_stmt,
361 /// for (data[first]; data[first+1]; data[first+2]) second
362 for_stmt,
363 /// goto first;
364 goto_stmt,
365 /// goto *un;
366 computed_goto_stmt,
367 // continue; first and second unused
368 continue_stmt,
369 // break; first and second unused
370 break_stmt,
371 // null statement (just a semicolon); first and second unused
372 null_stmt,
373 /// return first; first may be null
374 return_stmt,
375 /// Assembly statement of the form __asm__("string literal")
376 gnu_asm_simple,
377
378 // ====== Expr ======
379
380 /// lhs , rhs
381 comma_expr,
382 /// lhs ? data[0] : data[1]
383 binary_cond_expr,
384 /// Used as the base for casts of the lhs in `binary_cond_expr`.
385 cond_dummy_expr,
386 /// lhs ? data[0] : data[1]
387 cond_expr,
388 /// lhs = rhs
389 assign_expr,
390 /// lhs *= rhs
391 mul_assign_expr,
392 /// lhs /= rhs
393 div_assign_expr,
394 /// lhs %= rhs
395 mod_assign_expr,
396 /// lhs += rhs
397 add_assign_expr,
398 /// lhs -= rhs
399 sub_assign_expr,
400 /// lhs <<= rhs
401 shl_assign_expr,
402 /// lhs >>= rhs
403 shr_assign_expr,
404 /// lhs &= rhs
405 bit_and_assign_expr,
406 /// lhs ^= rhs
407 bit_xor_assign_expr,
408 /// lhs |= rhs
409 bit_or_assign_expr,
410 /// lhs || rhs
411 bool_or_expr,
412 /// lhs && rhs
413 bool_and_expr,
414 /// lhs | rhs
415 bit_or_expr,
416 /// lhs ^ rhs
417 bit_xor_expr,
418 /// lhs & rhs
419 bit_and_expr,
420 /// lhs == rhs
421 equal_expr,
422 /// lhs != rhs
423 not_equal_expr,
424 /// lhs < rhs
425 less_than_expr,
426 /// lhs <= rhs
427 less_than_equal_expr,
428 /// lhs > rhs
429 greater_than_expr,
430 /// lhs >= rhs
431 greater_than_equal_expr,
432 /// lhs << rhs
433 shl_expr,
434 /// lhs >> rhs
435 shr_expr,
436 /// lhs + rhs
437 add_expr,
438 /// lhs - rhs
439 sub_expr,
440 /// lhs * rhs
441 mul_expr,
442 /// lhs / rhs
443 div_expr,
444 /// lhs % rhs
445 mod_expr,
446 /// Explicit: (type) cast
447 explicit_cast,
448 /// Implicit: cast
449 implicit_cast,
450 /// &un
451 addr_of_expr,
452 /// &&decl_ref
453 addr_of_label,
454 /// *un
455 deref_expr,
456 /// +un
457 plus_expr,
458 /// -un
459 negate_expr,
460 /// ~un
461 bit_not_expr,
462 /// !un
463 bool_not_expr,
464 /// ++un
465 pre_inc_expr,
466 /// --un
467 pre_dec_expr,
468 /// __imag un
469 imag_expr,
470 /// __real un
471 real_expr,
472 /// lhs[rhs] lhs is pointer/array type, rhs is integer type
473 array_access_expr,
474 /// first(second) second may be 0
475 call_expr_one,
476 /// data[0](data[1..])
477 call_expr,
478 /// decl
479 builtin_call_expr_one,
480 builtin_call_expr,
481 /// lhs.member
482 member_access_expr,
483 /// lhs->member
484 member_access_ptr_expr,
485 /// un++
486 post_inc_expr,
487 /// un--
488 post_dec_expr,
489 /// (un)
490 paren_expr,
491 /// decl_ref
492 decl_ref_expr,
493 /// decl_ref
494 enumeration_ref,
495 /// C23 bool literal `true` / `false`
496 bool_literal,
497 /// C23 nullptr literal
498 nullptr_literal,
499 /// integer literal, always unsigned
500 int_literal,
501 /// Same as int_literal, but originates from a char literal
502 char_literal,
503 /// a floating point literal
504 float_literal,
505 /// wraps a float or double literal: un
506 imaginary_literal,
507 /// tree.str[index..][0..len]
508 string_literal_expr,
509 /// sizeof(un?)
510 sizeof_expr,
511 /// _Alignof(un?)
512 alignof_expr,
513 /// _Generic(controlling lhs, chosen rhs)
514 generic_expr_one,
515 /// _Generic(controlling range[0], chosen range[1], rest range[2..])
516 generic_expr,
517 /// ty: un
518 generic_association_expr,
519 // default: un
520 generic_default_expr,
521 /// __builtin_choose_expr(lhs, data[0], data[1])
522 builtin_choose_expr,
523 /// __builtin_types_compatible_p(lhs, rhs)
524 builtin_types_compatible_p,
525 /// decl - special builtins require custom parsing
526 special_builtin_call_one,
527 /// ({ un })
528 stmt_expr,
529
530 // ====== Initializer expressions ======
531
532 /// { lhs, rhs }
533 array_init_expr_two,
534 /// { range }
535 array_init_expr,
536 /// { lhs, rhs }
537 struct_init_expr_two,
538 /// { range }
539 struct_init_expr,
540 /// { union_init }
541 union_init_expr,
542 /// (ty){ un }
543 compound_literal_expr,
544 /// (static ty){ un }
545 static_compound_literal_expr,
546 /// (thread_local ty){ un }
547 thread_local_compound_literal_expr,
548 /// (static thread_local ty){ un }
549 static_thread_local_compound_literal_expr,
550
551 /// Inserted at the end of a function body if no return stmt is found.
552 /// ty is the functions return type
553 /// data is return_zero which is true if the function is called "main" and ty is compatible with int
554 implicit_return,
555
556 /// Inserted in array_init_expr to represent unspecified elements.
557 /// data.int contains the amount of elements.
558 array_filler_expr,
559 /// Inserted in record and scalar initializers for unspecified elements.
560 default_init_expr,
561
562 pub fn isImplicit(tag: Tag) bool {
563 return switch (tag) {
564 .implicit_cast,
565 .implicit_return,
566 .array_filler_expr,
567 .default_init_expr,
568 .implicit_static_var,
569 .cond_dummy_expr,
570 => true,
571 else => false,
572 };
573 }
574};
575
576pub fn isBitfield(tree: *const Tree, node: NodeIndex) bool {
577 return tree.bitfieldWidth(node, false) != null;
578}
579
580/// Returns null if node is not a bitfield. If inspect_lval is true, this function will
581/// recurse into implicit lval_to_rval casts (useful for arithmetic conversions)
582pub fn bitfieldWidth(tree: *const Tree, node: NodeIndex, inspect_lval: bool) ?u32 {
583 if (node == .none) return null;
584 switch (tree.nodes.items(.tag)[@intFromEnum(node)]) {
585 .member_access_expr, .member_access_ptr_expr => {
586 const member = tree.nodes.items(.data)[@intFromEnum(node)].member;
587 var ty = tree.nodes.items(.ty)[@intFromEnum(member.lhs)];
588 if (ty.isPtr()) ty = ty.elemType();
589 const record_ty = ty.get(.@"struct") orelse ty.get(.@"union") orelse return null;
590 const field = record_ty.data.record.fields[member.index];
591 return field.bit_width;
592 },
593 .implicit_cast => {
594 if (!inspect_lval) return null;
595
596 const data = tree.nodes.items(.data)[@intFromEnum(node)];
597 return switch (data.cast.kind) {
598 .lval_to_rval => tree.bitfieldWidth(data.cast.operand, false),
599 else => null,
600 };
601 },
602 else => return null,
603 }
604}
605
606pub fn isLval(tree: *const Tree, node: NodeIndex) bool {
607 var is_const: bool = undefined;
608 return tree.isLvalExtra(node, &is_const);
609}
610
611pub fn isLvalExtra(tree: *const Tree, node: NodeIndex, is_const: *bool) bool {
612 is_const.* = false;
613 switch (tree.nodes.items(.tag)[@intFromEnum(node)]) {
614 .compound_literal_expr,
615 .static_compound_literal_expr,
616 .thread_local_compound_literal_expr,
617 .static_thread_local_compound_literal_expr,
618 => {
619 is_const.* = tree.nodes.items(.ty)[@intFromEnum(node)].isConst();
620 return true;
621 },
622 .string_literal_expr => return true,
623 .member_access_ptr_expr => {
624 const lhs_expr = tree.nodes.items(.data)[@intFromEnum(node)].member.lhs;
625 const ptr_ty = tree.nodes.items(.ty)[@intFromEnum(lhs_expr)];
626 if (ptr_ty.isPtr()) is_const.* = ptr_ty.elemType().isConst();
627 return true;
628 },
629 .array_access_expr => {
630 const lhs_expr = tree.nodes.items(.data)[@intFromEnum(node)].bin.lhs;
631 if (lhs_expr != .none) {
632 const array_ty = tree.nodes.items(.ty)[@intFromEnum(lhs_expr)];
633 if (array_ty.isPtr() or array_ty.isArray()) is_const.* = array_ty.elemType().isConst();
634 }
635 return true;
636 },
637 .decl_ref_expr => {
638 const decl_ty = tree.nodes.items(.ty)[@intFromEnum(node)];
639 is_const.* = decl_ty.isConst();
640 return true;
641 },
642 .deref_expr => {
643 const data = tree.nodes.items(.data)[@intFromEnum(node)];
644 const operand_ty = tree.nodes.items(.ty)[@intFromEnum(data.un)];
645 if (operand_ty.isFunc()) return false;
646 if (operand_ty.isPtr() or operand_ty.isArray()) is_const.* = operand_ty.elemType().isConst();
647 return true;
648 },
649 .member_access_expr => {
650 const data = tree.nodes.items(.data)[@intFromEnum(node)];
651 return tree.isLvalExtra(data.member.lhs, is_const);
652 },
653 .paren_expr => {
654 const data = tree.nodes.items(.data)[@intFromEnum(node)];
655 return tree.isLvalExtra(data.un, is_const);
656 },
657 .builtin_choose_expr => {
658 const data = tree.nodes.items(.data)[@intFromEnum(node)];
659
660 if (tree.value_map.get(data.if3.cond)) |val| {
661 const offset = @intFromBool(val.isZero(tree.comp));
662 return tree.isLvalExtra(tree.data[data.if3.body + offset], is_const);
663 }
664 return false;
665 },
666 else => return false,
667 }
668}
669
670pub fn tokSlice(tree: *const Tree, tok_i: TokenIndex) []const u8 {
671 if (tree.tokens.items(.id)[tok_i].lexeme()) |some| return some;
672 const loc = tree.tokens.items(.loc)[tok_i];
673 var tmp_tokenizer = Tokenizer{
674 .buf = tree.comp.getSource(loc.id).buf,
675 .langopts = tree.comp.langopts,
676 .index = loc.byte_offset,
677 .source = .generated,
678 };
679 const tok = tmp_tokenizer.next();
680 return tmp_tokenizer.buf[tok.start..tok.end];
681}
682
683pub fn dump(tree: *const Tree, config: std.io.tty.Config, writer: anytype) !void {
684 const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper();
685 defer mapper.deinit(tree.comp.gpa);
686
687 for (tree.root_decls) |i| {
688 try tree.dumpNode(i, 0, mapper, config, writer);
689 try writer.writeByte('\n');
690 }
691}
692
693fn dumpFieldAttributes(tree: *const Tree, attributes: []const Attribute, level: u32, writer: anytype) !void {
694 for (attributes) |attr| {
695 try writer.writeByteNTimes(' ', level);
696 try writer.print("field attr: {s}", .{@tagName(attr.tag)});
697 try tree.dumpAttribute(attr, writer);
698 }
699}
700
701fn dumpAttribute(tree: *const Tree, attr: Attribute, writer: anytype) !void {
702 switch (attr.tag) {
703 inline else => |tag| {
704 const args = @field(attr.args, @tagName(tag));
705 const fields = @typeInfo(@TypeOf(args)).Struct.fields;
706 if (fields.len == 0) {
707 try writer.writeByte('\n');
708 return;
709 }
710 try writer.writeByte(' ');
711 inline for (fields, 0..) |f, i| {
712 if (comptime std.mem.eql(u8, f.name, "__name_tok")) continue;
713 if (i != 0) {
714 try writer.writeAll(", ");
715 }
716 try writer.writeAll(f.name);
717 try writer.writeAll(": ");
718 switch (f.type) {
719 Interner.Ref => try writer.print("\"{s}\"", .{tree.interner.get(@field(args, f.name)).bytes}),
720 ?Interner.Ref => try writer.print("\"{?s}\"", .{if (@field(args, f.name)) |str| tree.interner.get(str).bytes else null}),
721 else => switch (@typeInfo(f.type)) {
722 .Enum => try writer.writeAll(@tagName(@field(args, f.name))),
723 else => try writer.print("{any}", .{@field(args, f.name)}),
724 },
725 }
726 }
727 try writer.writeByte('\n');
728 return;
729 },
730 }
731}
732
733fn dumpNode(
734 tree: *const Tree,
735 node: NodeIndex,
736 level: u32,
737 mapper: StringInterner.TypeMapper,
738 config: std.io.tty.Config,
739 w: anytype,
740) !void {
741 const delta = 2;
742 const half = delta / 2;
743 const TYPE = std.io.tty.Color.bright_magenta;
744 const TAG = std.io.tty.Color.bright_cyan;
745 const IMPLICIT = std.io.tty.Color.bright_blue;
746 const NAME = std.io.tty.Color.bright_red;
747 const LITERAL = std.io.tty.Color.bright_green;
748 const ATTRIBUTE = std.io.tty.Color.bright_yellow;
749 std.debug.assert(node != .none);
750
751 const tag = tree.nodes.items(.tag)[@intFromEnum(node)];
752 const data = tree.nodes.items(.data)[@intFromEnum(node)];
753 const ty = tree.nodes.items(.ty)[@intFromEnum(node)];
754 try w.writeByteNTimes(' ', level);
755
756 try config.setColor(w, if (tag.isImplicit()) IMPLICIT else TAG);
757 try w.print("{s}: ", .{@tagName(tag)});
758 if (tag == .implicit_cast or tag == .explicit_cast) {
759 try config.setColor(w, .white);
760 try w.print("({s}) ", .{@tagName(data.cast.kind)});
761 }
762 try config.setColor(w, TYPE);
763 try w.writeByte('\'');
764 try ty.dump(mapper, tree.comp.langopts, w);
765 try w.writeByte('\'');
766
767 if (tree.isLval(node)) {
768 try config.setColor(w, ATTRIBUTE);
769 try w.writeAll(" lvalue");
770 }
771 if (tree.isBitfield(node)) {
772 try config.setColor(w, ATTRIBUTE);
773 try w.writeAll(" bitfield");
774 }
775 if (tree.value_map.get(node)) |val| {
776 try config.setColor(w, LITERAL);
777 try w.writeAll(" (value: ");
778 try val.print(ty, tree.comp, w);
779 try w.writeByte(')');
780 }
781 if (tag == .implicit_return and data.return_zero) {
782 try config.setColor(w, IMPLICIT);
783 try w.writeAll(" (value: 0)");
784 try config.setColor(w, .reset);
785 }
786
787 try w.writeAll("\n");
788 try config.setColor(w, .reset);
789
790 if (ty.specifier == .attributed) {
791 try config.setColor(w, ATTRIBUTE);
792 for (ty.data.attributed.attributes) |attr| {
793 try w.writeByteNTimes(' ', level + half);
794 try w.print("attr: {s}", .{@tagName(attr.tag)});
795 try tree.dumpAttribute(attr, w);
796 }
797 try config.setColor(w, .reset);
798 }
799
800 switch (tag) {
801 .invalid => unreachable,
802 .file_scope_asm => {
803 try w.writeByteNTimes(' ', level + 1);
804 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
805 },
806 .gnu_asm_simple => {
807 try w.writeByteNTimes(' ', level);
808 try tree.dumpNode(data.un, level, mapper, config, w);
809 },
810 .static_assert => {
811 try w.writeByteNTimes(' ', level + 1);
812 try w.writeAll("condition:\n");
813 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
814 if (data.bin.rhs != .none) {
815 try w.writeByteNTimes(' ', level + 1);
816 try w.writeAll("diagnostic:\n");
817 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
818 }
819 },
820 .fn_proto,
821 .static_fn_proto,
822 .inline_fn_proto,
823 .inline_static_fn_proto,
824 => {
825 try w.writeByteNTimes(' ', level + half);
826 try w.writeAll("name: ");
827 try config.setColor(w, NAME);
828 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
829 try config.setColor(w, .reset);
830 },
831 .fn_def,
832 .static_fn_def,
833 .inline_fn_def,
834 .inline_static_fn_def,
835 => {
836 try w.writeByteNTimes(' ', level + half);
837 try w.writeAll("name: ");
838 try config.setColor(w, NAME);
839 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
840 try config.setColor(w, .reset);
841 try w.writeByteNTimes(' ', level + half);
842 try w.writeAll("body:\n");
843 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
844 },
845 .typedef,
846 .@"var",
847 .extern_var,
848 .static_var,
849 .implicit_static_var,
850 .threadlocal_var,
851 .threadlocal_extern_var,
852 .threadlocal_static_var,
853 => {
854 try w.writeByteNTimes(' ', level + half);
855 try w.writeAll("name: ");
856 try config.setColor(w, NAME);
857 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
858 try config.setColor(w, .reset);
859 if (data.decl.node != .none) {
860 try w.writeByteNTimes(' ', level + half);
861 try w.writeAll("init:\n");
862 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
863 }
864 },
865 .enum_field_decl => {
866 try w.writeByteNTimes(' ', level + half);
867 try w.writeAll("name: ");
868 try config.setColor(w, NAME);
869 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
870 try config.setColor(w, .reset);
871 if (data.decl.node != .none) {
872 try w.writeByteNTimes(' ', level + half);
873 try w.writeAll("value:\n");
874 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
875 }
876 },
877 .record_field_decl => {
878 if (data.decl.name != 0) {
879 try w.writeByteNTimes(' ', level + half);
880 try w.writeAll("name: ");
881 try config.setColor(w, NAME);
882 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
883 try config.setColor(w, .reset);
884 }
885 if (data.decl.node != .none) {
886 try w.writeByteNTimes(' ', level + half);
887 try w.writeAll("bits:\n");
888 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
889 }
890 },
891 .indirect_record_field_decl => {},
892 .compound_stmt,
893 .array_init_expr,
894 .struct_init_expr,
895 .enum_decl,
896 .struct_decl,
897 .union_decl,
898 => {
899 const maybe_field_attributes = if (ty.getRecord()) |record| record.field_attributes else null;
900 for (tree.data[data.range.start..data.range.end], 0..) |stmt, i| {
901 if (i != 0) try w.writeByte('\n');
902 try tree.dumpNode(stmt, level + delta, mapper, config, w);
903 if (maybe_field_attributes) |field_attributes| {
904 if (field_attributes[i].len == 0) continue;
905
906 try config.setColor(w, ATTRIBUTE);
907 try tree.dumpFieldAttributes(field_attributes[i], level + delta + half, w);
908 try config.setColor(w, .reset);
909 }
910 }
911 },
912 .compound_stmt_two,
913 .array_init_expr_two,
914 .struct_init_expr_two,
915 .enum_decl_two,
916 .struct_decl_two,
917 .union_decl_two,
918 => {
919 var attr_array = [2][]const Attribute{ &.{}, &.{} };
920 const empty: [][]const Attribute = &attr_array;
921 const field_attributes = if (ty.getRecord()) |record| (record.field_attributes orelse empty.ptr) else empty.ptr;
922 if (data.bin.lhs != .none) {
923 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
924 if (field_attributes[0].len > 0) {
925 try config.setColor(w, ATTRIBUTE);
926 try tree.dumpFieldAttributes(field_attributes[0], level + delta + half, w);
927 try config.setColor(w, .reset);
928 }
929 }
930 if (data.bin.rhs != .none) {
931 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
932 if (field_attributes[1].len > 0) {
933 try config.setColor(w, ATTRIBUTE);
934 try tree.dumpFieldAttributes(field_attributes[1], level + delta + half, w);
935 try config.setColor(w, .reset);
936 }
937 }
938 },
939 .union_init_expr => {
940 try w.writeByteNTimes(' ', level + half);
941 try w.writeAll("field index: ");
942 try config.setColor(w, LITERAL);
943 try w.print("{d}\n", .{data.union_init.field_index});
944 try config.setColor(w, .reset);
945 if (data.union_init.node != .none) {
946 try tree.dumpNode(data.union_init.node, level + delta, mapper, config, w);
947 }
948 },
949 .compound_literal_expr,
950 .static_compound_literal_expr,
951 .thread_local_compound_literal_expr,
952 .static_thread_local_compound_literal_expr,
953 => {
954 try tree.dumpNode(data.un, level + half, mapper, config, w);
955 },
956 .labeled_stmt => {
957 try w.writeByteNTimes(' ', level + half);
958 try w.writeAll("label: ");
959 try config.setColor(w, LITERAL);
960 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
961 try config.setColor(w, .reset);
962 if (data.decl.node != .none) {
963 try w.writeByteNTimes(' ', level + half);
964 try w.writeAll("stmt:\n");
965 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
966 }
967 },
968 .case_stmt => {
969 try w.writeByteNTimes(' ', level + half);
970 try w.writeAll("value:\n");
971 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
972 if (data.bin.rhs != .none) {
973 try w.writeByteNTimes(' ', level + half);
974 try w.writeAll("stmt:\n");
975 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
976 }
977 },
978 .case_range_stmt => {
979 try w.writeByteNTimes(' ', level + half);
980 try w.writeAll("range start:\n");
981 try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, config, w);
982
983 try w.writeByteNTimes(' ', level + half);
984 try w.writeAll("range end:\n");
985 try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, config, w);
986
987 if (data.if3.cond != .none) {
988 try w.writeByteNTimes(' ', level + half);
989 try w.writeAll("stmt:\n");
990 try tree.dumpNode(data.if3.cond, level + delta, mapper, config, w);
991 }
992 },
993 .default_stmt => {
994 if (data.un != .none) {
995 try w.writeByteNTimes(' ', level + half);
996 try w.writeAll("stmt:\n");
997 try tree.dumpNode(data.un, level + delta, mapper, config, w);
998 }
999 },
1000 .binary_cond_expr, .cond_expr, .if_then_else_stmt, .builtin_choose_expr => {
1001 try w.writeByteNTimes(' ', level + half);
1002 try w.writeAll("cond:\n");
1003 try tree.dumpNode(data.if3.cond, level + delta, mapper, config, w);
1004
1005 try w.writeByteNTimes(' ', level + half);
1006 try w.writeAll("then:\n");
1007 try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, config, w);
1008
1009 try w.writeByteNTimes(' ', level + half);
1010 try w.writeAll("else:\n");
1011 try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, config, w);
1012 },
1013 .builtin_types_compatible_p => {
1014 std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.lhs)] == .invalid);
1015 std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.rhs)] == .invalid);
1016
1017 try w.writeByteNTimes(' ', level + half);
1018 try w.writeAll("lhs: ");
1019
1020 const lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.lhs)];
1021 try config.setColor(w, TYPE);
1022 try lhs_ty.dump(mapper, tree.comp.langopts, w);
1023 try config.setColor(w, .reset);
1024 try w.writeByte('\n');
1025
1026 try w.writeByteNTimes(' ', level + half);
1027 try w.writeAll("rhs: ");
1028
1029 const rhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.rhs)];
1030 try config.setColor(w, TYPE);
1031 try rhs_ty.dump(mapper, tree.comp.langopts, w);
1032 try config.setColor(w, .reset);
1033 try w.writeByte('\n');
1034 },
1035 .if_then_stmt => {
1036 try w.writeByteNTimes(' ', level + half);
1037 try w.writeAll("cond:\n");
1038 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1039
1040 if (data.bin.rhs != .none) {
1041 try w.writeByteNTimes(' ', level + half);
1042 try w.writeAll("then:\n");
1043 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1044 }
1045 },
1046 .switch_stmt, .while_stmt, .do_while_stmt => {
1047 try w.writeByteNTimes(' ', level + half);
1048 try w.writeAll("cond:\n");
1049 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1050
1051 if (data.bin.rhs != .none) {
1052 try w.writeByteNTimes(' ', level + half);
1053 try w.writeAll("body:\n");
1054 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1055 }
1056 },
1057 .for_decl_stmt => {
1058 const for_decl = data.forDecl(tree);
1059
1060 try w.writeByteNTimes(' ', level + half);
1061 try w.writeAll("decl:\n");
1062 for (for_decl.decls) |decl| {
1063 try tree.dumpNode(decl, level + delta, mapper, config, w);
1064 try w.writeByte('\n');
1065 }
1066 if (for_decl.cond != .none) {
1067 try w.writeByteNTimes(' ', level + half);
1068 try w.writeAll("cond:\n");
1069 try tree.dumpNode(for_decl.cond, level + delta, mapper, config, w);
1070 }
1071 if (for_decl.incr != .none) {
1072 try w.writeByteNTimes(' ', level + half);
1073 try w.writeAll("incr:\n");
1074 try tree.dumpNode(for_decl.incr, level + delta, mapper, config, w);
1075 }
1076 if (for_decl.body != .none) {
1077 try w.writeByteNTimes(' ', level + half);
1078 try w.writeAll("body:\n");
1079 try tree.dumpNode(for_decl.body, level + delta, mapper, config, w);
1080 }
1081 },
1082 .forever_stmt => {
1083 if (data.un != .none) {
1084 try w.writeByteNTimes(' ', level + half);
1085 try w.writeAll("body:\n");
1086 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1087 }
1088 },
1089 .for_stmt => {
1090 const for_stmt = data.forStmt(tree);
1091
1092 if (for_stmt.init != .none) {
1093 try w.writeByteNTimes(' ', level + half);
1094 try w.writeAll("init:\n");
1095 try tree.dumpNode(for_stmt.init, level + delta, mapper, config, w);
1096 }
1097 if (for_stmt.cond != .none) {
1098 try w.writeByteNTimes(' ', level + half);
1099 try w.writeAll("cond:\n");
1100 try tree.dumpNode(for_stmt.cond, level + delta, mapper, config, w);
1101 }
1102 if (for_stmt.incr != .none) {
1103 try w.writeByteNTimes(' ', level + half);
1104 try w.writeAll("incr:\n");
1105 try tree.dumpNode(for_stmt.incr, level + delta, mapper, config, w);
1106 }
1107 if (for_stmt.body != .none) {
1108 try w.writeByteNTimes(' ', level + half);
1109 try w.writeAll("body:\n");
1110 try tree.dumpNode(for_stmt.body, level + delta, mapper, config, w);
1111 }
1112 },
1113 .goto_stmt, .addr_of_label => {
1114 try w.writeByteNTimes(' ', level + half);
1115 try w.writeAll("label: ");
1116 try config.setColor(w, LITERAL);
1117 try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
1118 try config.setColor(w, .reset);
1119 },
1120 .continue_stmt, .break_stmt, .implicit_return, .null_stmt => {},
1121 .return_stmt => {
1122 if (data.un != .none) {
1123 try w.writeByteNTimes(' ', level + half);
1124 try w.writeAll("expr:\n");
1125 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1126 }
1127 },
1128 .call_expr => {
1129 try w.writeByteNTimes(' ', level + half);
1130 try w.writeAll("lhs:\n");
1131 try tree.dumpNode(tree.data[data.range.start], level + delta, mapper, config, w);
1132
1133 try w.writeByteNTimes(' ', level + half);
1134 try w.writeAll("args:\n");
1135 for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, config, w);
1136 },
1137 .call_expr_one => {
1138 try w.writeByteNTimes(' ', level + half);
1139 try w.writeAll("lhs:\n");
1140 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1141 if (data.bin.rhs != .none) {
1142 try w.writeByteNTimes(' ', level + half);
1143 try w.writeAll("arg:\n");
1144 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1145 }
1146 },
1147 .builtin_call_expr => {
1148 try w.writeByteNTimes(' ', level + half);
1149 try w.writeAll("name: ");
1150 try config.setColor(w, NAME);
1151 try w.print("{s}\n", .{tree.tokSlice(@intFromEnum(tree.data[data.range.start]))});
1152 try config.setColor(w, .reset);
1153
1154 try w.writeByteNTimes(' ', level + half);
1155 try w.writeAll("args:\n");
1156 for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, config, w);
1157 },
1158 .builtin_call_expr_one => {
1159 try w.writeByteNTimes(' ', level + half);
1160 try w.writeAll("name: ");
1161 try config.setColor(w, NAME);
1162 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
1163 try config.setColor(w, .reset);
1164 if (data.decl.node != .none) {
1165 try w.writeByteNTimes(' ', level + half);
1166 try w.writeAll("arg:\n");
1167 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
1168 }
1169 },
1170 .special_builtin_call_one => {
1171 try w.writeByteNTimes(' ', level + half);
1172 try w.writeAll("name: ");
1173 try config.setColor(w, NAME);
1174 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
1175 try config.setColor(w, .reset);
1176 if (data.decl.node != .none) {
1177 try w.writeByteNTimes(' ', level + half);
1178 try w.writeAll("arg:\n");
1179 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
1180 }
1181 },
1182 .comma_expr,
1183 .assign_expr,
1184 .mul_assign_expr,
1185 .div_assign_expr,
1186 .mod_assign_expr,
1187 .add_assign_expr,
1188 .sub_assign_expr,
1189 .shl_assign_expr,
1190 .shr_assign_expr,
1191 .bit_and_assign_expr,
1192 .bit_xor_assign_expr,
1193 .bit_or_assign_expr,
1194 .bool_or_expr,
1195 .bool_and_expr,
1196 .bit_or_expr,
1197 .bit_xor_expr,
1198 .bit_and_expr,
1199 .equal_expr,
1200 .not_equal_expr,
1201 .less_than_expr,
1202 .less_than_equal_expr,
1203 .greater_than_expr,
1204 .greater_than_equal_expr,
1205 .shl_expr,
1206 .shr_expr,
1207 .add_expr,
1208 .sub_expr,
1209 .mul_expr,
1210 .div_expr,
1211 .mod_expr,
1212 => {
1213 try w.writeByteNTimes(' ', level + 1);
1214 try w.writeAll("lhs:\n");
1215 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1216 try w.writeByteNTimes(' ', level + 1);
1217 try w.writeAll("rhs:\n");
1218 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1219 },
1220 .explicit_cast, .implicit_cast => try tree.dumpNode(data.cast.operand, level + delta, mapper, config, w),
1221 .addr_of_expr,
1222 .computed_goto_stmt,
1223 .deref_expr,
1224 .plus_expr,
1225 .negate_expr,
1226 .bit_not_expr,
1227 .bool_not_expr,
1228 .pre_inc_expr,
1229 .pre_dec_expr,
1230 .imag_expr,
1231 .real_expr,
1232 .post_inc_expr,
1233 .post_dec_expr,
1234 .paren_expr,
1235 => {
1236 try w.writeByteNTimes(' ', level + 1);
1237 try w.writeAll("operand:\n");
1238 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1239 },
1240 .decl_ref_expr => {
1241 try w.writeByteNTimes(' ', level + 1);
1242 try w.writeAll("name: ");
1243 try config.setColor(w, NAME);
1244 try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
1245 try config.setColor(w, .reset);
1246 },
1247 .enumeration_ref => {
1248 try w.writeByteNTimes(' ', level + 1);
1249 try w.writeAll("name: ");
1250 try config.setColor(w, NAME);
1251 try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
1252 try config.setColor(w, .reset);
1253 },
1254 .bool_literal,
1255 .nullptr_literal,
1256 .int_literal,
1257 .char_literal,
1258 .float_literal,
1259 .string_literal_expr,
1260 => {},
1261 .member_access_expr, .member_access_ptr_expr => {
1262 try w.writeByteNTimes(' ', level + 1);
1263 try w.writeAll("lhs:\n");
1264 try tree.dumpNode(data.member.lhs, level + delta, mapper, config, w);
1265
1266 var lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
1267 if (lhs_ty.isPtr()) lhs_ty = lhs_ty.elemType();
1268 lhs_ty = lhs_ty.canonicalize(.standard);
1269
1270 try w.writeByteNTimes(' ', level + 1);
1271 try w.writeAll("name: ");
1272 try config.setColor(w, NAME);
1273 try w.print("{s}\n", .{mapper.lookup(lhs_ty.data.record.fields[data.member.index].name)});
1274 try config.setColor(w, .reset);
1275 },
1276 .array_access_expr => {
1277 if (data.bin.lhs != .none) {
1278 try w.writeByteNTimes(' ', level + 1);
1279 try w.writeAll("lhs:\n");
1280 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1281 }
1282 try w.writeByteNTimes(' ', level + 1);
1283 try w.writeAll("index:\n");
1284 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1285 },
1286 .sizeof_expr, .alignof_expr => {
1287 if (data.un != .none) {
1288 try w.writeByteNTimes(' ', level + 1);
1289 try w.writeAll("expr:\n");
1290 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1291 }
1292 },
1293 .generic_expr_one => {
1294 try w.writeByteNTimes(' ', level + 1);
1295 try w.writeAll("controlling:\n");
1296 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1297 try w.writeByteNTimes(' ', level + 1);
1298 if (data.bin.rhs != .none) {
1299 try w.writeAll("chosen:\n");
1300 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1301 }
1302 },
1303 .generic_expr => {
1304 const nodes = tree.data[data.range.start..data.range.end];
1305 try w.writeByteNTimes(' ', level + 1);
1306 try w.writeAll("controlling:\n");
1307 try tree.dumpNode(nodes[0], level + delta, mapper, config, w);
1308 try w.writeByteNTimes(' ', level + 1);
1309 try w.writeAll("chosen:\n");
1310 try tree.dumpNode(nodes[1], level + delta, mapper, config, w);
1311 try w.writeByteNTimes(' ', level + 1);
1312 try w.writeAll("rest:\n");
1313 for (nodes[2..]) |expr| {
1314 try tree.dumpNode(expr, level + delta, mapper, config, w);
1315 }
1316 },
1317 .generic_association_expr, .generic_default_expr, .stmt_expr, .imaginary_literal => {
1318 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1319 },
1320 .array_filler_expr => {
1321 try w.writeByteNTimes(' ', level + 1);
1322 try w.writeAll("count: ");
1323 try config.setColor(w, LITERAL);
1324 try w.print("{d}\n", .{data.int});
1325 try config.setColor(w, .reset);
1326 },
1327 .struct_forward_decl,
1328 .union_forward_decl,
1329 .enum_forward_decl,
1330 .default_init_expr,
1331 .cond_dummy_expr,
1332 => {},
1333 }
1334}
deps/aro/aro/Tree/number_affixes.zig deleted-187
......@@ -1,187 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3
4pub const Prefix = enum(u8) {
5 binary = 2,
6 octal = 8,
7 decimal = 10,
8 hex = 16,
9
10 pub fn digitAllowed(prefix: Prefix, c: u8) bool {
11 return switch (c) {
12 '0', '1' => true,
13 '2'...'7' => prefix != .binary,
14 '8'...'9' => prefix == .decimal or prefix == .hex,
15 'a'...'f', 'A'...'F' => prefix == .hex,
16 else => false,
17 };
18 }
19
20 pub fn fromString(buf: []const u8) Prefix {
21 if (buf.len == 1) return .decimal;
22 // tokenizer enforces that first byte is a decimal digit or period
23 switch (buf[0]) {
24 '.', '1'...'9' => return .decimal,
25 '0' => {},
26 else => unreachable,
27 }
28 switch (buf[1]) {
29 'x', 'X' => return if (buf.len == 2) .decimal else .hex,
30 'b', 'B' => return if (buf.len == 2) .decimal else .binary,
31 else => {
32 if (mem.indexOfAny(u8, buf, "eE.")) |_| {
33 // This is a decimal floating point number that happens to start with zero
34 return .decimal;
35 } else if (Suffix.fromString(buf[1..], .int)) |_| {
36 // This is `0` with a valid suffix
37 return .decimal;
38 } else {
39 return .octal;
40 }
41 },
42 }
43 }
44
45 /// Length of this prefix as a string
46 pub fn stringLen(prefix: Prefix) usize {
47 return switch (prefix) {
48 .binary => 2,
49 .octal => 1,
50 .decimal => 0,
51 .hex => 2,
52 };
53 }
54};
55
56pub const Suffix = enum {
57 // zig fmt: off
58
59 // int and imaginary int
60 None, I,
61
62 // unsigned real integers
63 U, UL, ULL,
64
65 // unsigned imaginary integers
66 IU, IUL, IULL,
67
68 // long or long double, real and imaginary
69 L, IL,
70
71 // long long and imaginary long long
72 LL, ILL,
73
74 // float and imaginary float
75 F, IF,
76
77 // _Float16
78 F16,
79
80 // __float80
81 W,
82
83 // Imaginary __float80
84 IW,
85
86 // _Float128
87 Q, F128,
88
89 // Imaginary _Float128
90 IQ, IF128,
91
92 // Imaginary _Bitint
93 IWB, IUWB,
94
95 // _Bitint
96 WB, UWB,
97
98 // zig fmt: on
99
100 const Tuple = struct { Suffix, []const []const u8 };
101
102 const IntSuffixes = &[_]Tuple{
103 .{ .U, &.{"U"} },
104 .{ .L, &.{"L"} },
105 .{ .WB, &.{"WB"} },
106 .{ .UL, &.{ "U", "L" } },
107 .{ .UWB, &.{ "U", "WB" } },
108 .{ .LL, &.{"LL"} },
109 .{ .ULL, &.{ "U", "LL" } },
110
111 .{ .I, &.{"I"} },
112
113 .{ .IWB, &.{ "I", "WB" } },
114 .{ .IU, &.{ "I", "U" } },
115 .{ .IL, &.{ "I", "L" } },
116 .{ .IUL, &.{ "I", "U", "L" } },
117 .{ .IUWB, &.{ "I", "U", "WB" } },
118 .{ .ILL, &.{ "I", "LL" } },
119 .{ .IULL, &.{ "I", "U", "LL" } },
120 };
121
122 const FloatSuffixes = &[_]Tuple{
123 .{ .F16, &.{"F16"} },
124 .{ .F, &.{"F"} },
125 .{ .L, &.{"L"} },
126 .{ .W, &.{"W"} },
127 .{ .F128, &.{"F128"} },
128 .{ .Q, &.{"Q"} },
129
130 .{ .I, &.{"I"} },
131 .{ .IL, &.{ "I", "L" } },
132 .{ .IF, &.{ "I", "F" } },
133 .{ .IW, &.{ "I", "W" } },
134 .{ .IF128, &.{ "I", "F128" } },
135 .{ .IQ, &.{ "I", "Q" } },
136 };
137
138 pub fn fromString(buf: []const u8, suffix_kind: enum { int, float }) ?Suffix {
139 if (buf.len == 0) return .None;
140
141 const suffixes = switch (suffix_kind) {
142 .float => FloatSuffixes,
143 .int => IntSuffixes,
144 };
145 var scratch: [4]u8 = undefined;
146 top: for (suffixes) |candidate| {
147 const tag = candidate[0];
148 const parts = candidate[1];
149 var len: usize = 0;
150 for (parts) |part| len += part.len;
151 if (len != buf.len) continue;
152
153 for (parts) |part| {
154 const lower = std.ascii.lowerString(&scratch, part);
155 if (mem.indexOf(u8, buf, part) == null and mem.indexOf(u8, buf, lower) == null) continue :top;
156 }
157 return tag;
158 }
159 return null;
160 }
161
162 pub fn isImaginary(suffix: Suffix) bool {
163 return switch (suffix) {
164 .I, .IL, .IF, .IU, .IUL, .ILL, .IULL, .IWB, .IUWB, .IF128, .IQ, .IW => true,
165 .None, .L, .F16, .F, .U, .UL, .LL, .ULL, .WB, .UWB, .F128, .Q, .W => false,
166 };
167 }
168
169 pub fn isSignedInteger(suffix: Suffix) bool {
170 return switch (suffix) {
171 .None, .L, .LL, .I, .IL, .ILL, .WB, .IWB => true,
172 .U, .UL, .ULL, .IU, .IUL, .IULL, .UWB, .IUWB => false,
173 .F, .IF, .F16, .F128, .IF128, .Q, .IQ, .W, .IW => unreachable,
174 };
175 }
176
177 pub fn signedness(suffix: Suffix) std.builtin.Signedness {
178 return if (suffix.isSignedInteger()) .signed else .unsigned;
179 }
180
181 pub fn isBitInt(suffix: Suffix) bool {
182 return switch (suffix) {
183 .WB, .UWB, .IWB, .IUWB => true,
184 else => false,
185 };
186 }
187};
deps/aro/aro/Type.zig deleted-2670
......@@ -1,2670 +0,0 @@
1const std = @import("std");
2const Tree = @import("Tree.zig");
3const TokenIndex = Tree.TokenIndex;
4const NodeIndex = Tree.NodeIndex;
5const Parser = @import("Parser.zig");
6const Compilation = @import("Compilation.zig");
7const Attribute = @import("Attribute.zig");
8const StringInterner = @import("StringInterner.zig");
9const StringId = StringInterner.StringId;
10const target_util = @import("target.zig");
11const LangOpts = @import("LangOpts.zig");
12
13pub const Qualifiers = packed struct {
14 @"const": bool = false,
15 atomic: bool = false,
16 @"volatile": bool = false,
17 restrict: bool = false,
18
19 // for function parameters only, stored here since it fits in the padding
20 register: bool = false,
21
22 pub fn any(quals: Qualifiers) bool {
23 return quals.@"const" or quals.restrict or quals.@"volatile" or quals.atomic;
24 }
25
26 pub fn dump(quals: Qualifiers, w: anytype) !void {
27 if (quals.@"const") try w.writeAll("const ");
28 if (quals.atomic) try w.writeAll("_Atomic ");
29 if (quals.@"volatile") try w.writeAll("volatile ");
30 if (quals.restrict) try w.writeAll("restrict ");
31 if (quals.register) try w.writeAll("register ");
32 }
33
34 /// Merge the const/volatile qualifiers, used by type resolution
35 /// of the conditional operator
36 pub fn mergeCV(a: Qualifiers, b: Qualifiers) Qualifiers {
37 return .{
38 .@"const" = a.@"const" or b.@"const",
39 .@"volatile" = a.@"volatile" or b.@"volatile",
40 };
41 }
42
43 /// Merge all qualifiers, used by typeof()
44 fn mergeAll(a: Qualifiers, b: Qualifiers) Qualifiers {
45 return .{
46 .@"const" = a.@"const" or b.@"const",
47 .atomic = a.atomic or b.atomic,
48 .@"volatile" = a.@"volatile" or b.@"volatile",
49 .restrict = a.restrict or b.restrict,
50 .register = a.register or b.register,
51 };
52 }
53
54 /// Checks if a has all the qualifiers of b
55 pub fn hasQuals(a: Qualifiers, b: Qualifiers) bool {
56 if (b.@"const" and !a.@"const") return false;
57 if (b.@"volatile" and !a.@"volatile") return false;
58 if (b.atomic and !a.atomic) return false;
59 return true;
60 }
61
62 /// register is a storage class and not actually a qualifier
63 /// so it is not preserved by typeof()
64 pub fn inheritFromTypeof(quals: Qualifiers) Qualifiers {
65 var res = quals;
66 res.register = false;
67 return res;
68 }
69
70 pub const Builder = struct {
71 @"const": ?TokenIndex = null,
72 atomic: ?TokenIndex = null,
73 @"volatile": ?TokenIndex = null,
74 restrict: ?TokenIndex = null,
75
76 pub fn finish(b: Qualifiers.Builder, p: *Parser, ty: *Type) !void {
77 if (ty.specifier != .pointer and b.restrict != null) {
78 try p.errStr(.restrict_non_pointer, b.restrict.?, try p.typeStr(ty.*));
79 }
80 if (b.atomic) |some| {
81 if (ty.isArray()) try p.errStr(.atomic_array, some, try p.typeStr(ty.*));
82 if (ty.isFunc()) try p.errStr(.atomic_func, some, try p.typeStr(ty.*));
83 if (ty.hasIncompleteSize()) try p.errStr(.atomic_incomplete, some, try p.typeStr(ty.*));
84 }
85
86 if (b.@"const" != null) ty.qual.@"const" = true;
87 if (b.atomic != null) ty.qual.atomic = true;
88 if (b.@"volatile" != null) ty.qual.@"volatile" = true;
89 if (b.restrict != null) ty.qual.restrict = true;
90 }
91 };
92};
93
94// TODO improve memory usage
95pub const Func = struct {
96 return_type: Type,
97 params: []Param,
98
99 pub const Param = struct {
100 ty: Type,
101 name: StringId,
102 name_tok: TokenIndex,
103 };
104
105 fn eql(a: *const Func, b: *const Func, a_spec: Specifier, b_spec: Specifier, comp: *const Compilation) bool {
106 // return type cannot have qualifiers
107 if (!a.return_type.eql(b.return_type, comp, false)) return false;
108
109 if (a.params.len != b.params.len) {
110 if (a_spec == .old_style_func or b_spec == .old_style_func) {
111 const maybe_has_params = if (a_spec == .old_style_func) b else a;
112 for (maybe_has_params.params) |param| {
113 if (param.ty.undergoesDefaultArgPromotion(comp)) return false;
114 }
115 return true;
116 }
117 }
118 if ((a_spec == .func) != (b_spec == .func)) return false;
119 // TODO validate this
120 for (a.params, b.params) |param, b_qual| {
121 var a_unqual = param.ty;
122 a_unqual.qual.@"const" = false;
123 a_unqual.qual.@"volatile" = false;
124 var b_unqual = b_qual.ty;
125 b_unqual.qual.@"const" = false;
126 b_unqual.qual.@"volatile" = false;
127 if (!a_unqual.eql(b_unqual, comp, true)) return false;
128 }
129 return true;
130 }
131};
132
133pub const Array = struct {
134 len: u64,
135 elem: Type,
136};
137
138pub const Expr = struct {
139 node: NodeIndex,
140 ty: Type,
141};
142
143pub const Attributed = struct {
144 attributes: []Attribute,
145 base: Type,
146
147 pub fn create(allocator: std.mem.Allocator, base: Type, existing_attributes: []const Attribute, attributes: []const Attribute) !*Attributed {
148 const attributed_type = try allocator.create(Attributed);
149 errdefer allocator.destroy(attributed_type);
150
151 const all_attrs = try allocator.alloc(Attribute, existing_attributes.len + attributes.len);
152 @memcpy(all_attrs[0..existing_attributes.len], existing_attributes);
153 @memcpy(all_attrs[existing_attributes.len..], attributes);
154
155 attributed_type.* = .{
156 .attributes = all_attrs,
157 .base = base,
158 };
159 return attributed_type;
160 }
161};
162
163// TODO improve memory usage
164pub const Enum = struct {
165 fields: []Field,
166 tag_ty: Type,
167 name: StringId,
168 fixed: bool,
169
170 pub const Field = struct {
171 ty: Type,
172 name: StringId,
173 name_tok: TokenIndex,
174 node: NodeIndex,
175 };
176
177 pub fn isIncomplete(e: Enum) bool {
178 return e.fields.len == std.math.maxInt(usize);
179 }
180
181 pub fn create(allocator: std.mem.Allocator, name: StringId, fixed_ty: ?Type) !*Enum {
182 var e = try allocator.create(Enum);
183 e.name = name;
184 e.fields.len = std.math.maxInt(usize);
185 if (fixed_ty) |some| e.tag_ty = some;
186 e.fixed = fixed_ty != null;
187 return e;
188 }
189};
190
191// might not need all 4 of these when finished,
192// but currently it helps having all 4 when diff-ing
193// the rust code.
194pub const TypeLayout = struct {
195 /// The size of the type in bits.
196 ///
197 /// This is the value returned by `sizeof` and C and `std::mem::size_of` in Rust
198 /// (but in bits instead of bytes). This is a multiple of `pointer_alignment_bits`.
199 size_bits: u64,
200 /// The alignment of the type, in bits, when used as a field in a record.
201 ///
202 /// This is usually the value returned by `_Alignof` in C, but there are some edge
203 /// cases in GCC where `_Alignof` returns a smaller value.
204 field_alignment_bits: u32,
205 /// The alignment, in bits, of valid pointers to this type.
206 ///
207 /// This is the value returned by `std::mem::align_of` in Rust
208 /// (but in bits instead of bytes). `size_bits` is a multiple of this value.
209 pointer_alignment_bits: u32,
210 /// The required alignment of the type in bits.
211 ///
212 /// This value is only used by MSVC targets. It is 8 on all other
213 /// targets. On MSVC targets, this value restricts the effects of `#pragma pack` except
214 /// in some cases involving bit-fields.
215 required_alignment_bits: u32,
216};
217
218pub const FieldLayout = struct {
219 /// `offset_bits` and `size_bits` should both be INVALID if and only if the field
220 /// is an unnamed bitfield. There is no way to reference an unnamed bitfield in C, so
221 /// there should be no way to observe these values. If it is used, this value will
222 /// maximize the chance that a safety-checked overflow will occur.
223 const INVALID = std.math.maxInt(u64);
224
225 /// The offset of the field, in bits, from the start of the struct.
226 offset_bits: u64 = INVALID,
227 /// The size, in bits, of the field.
228 ///
229 /// For bit-fields, this is the width of the field.
230 size_bits: u64 = INVALID,
231
232 pub fn isUnnamed(self: FieldLayout) bool {
233 return self.offset_bits == INVALID and self.size_bits == INVALID;
234 }
235};
236
237// TODO improve memory usage
238pub const Record = struct {
239 fields: []Field,
240 type_layout: TypeLayout,
241 /// If this is null, none of the fields have attributes
242 /// Otherwise, it's a pointer to N items (where N == number of fields)
243 /// and the item at index i is the attributes for the field at index i
244 field_attributes: ?[*][]const Attribute,
245 name: StringId,
246
247 pub const Field = struct {
248 ty: Type,
249 name: StringId,
250 /// zero for anonymous fields
251 name_tok: TokenIndex = 0,
252 bit_width: ?u32 = null,
253 layout: FieldLayout = .{
254 .offset_bits = 0,
255 .size_bits = 0,
256 },
257
258 pub fn isNamed(f: *const Field) bool {
259 return f.name_tok != 0;
260 }
261
262 pub fn isAnonymousRecord(f: Field) bool {
263 return !f.isNamed() and f.ty.isRecord();
264 }
265
266 /// false for bitfields
267 pub fn isRegularField(f: *const Field) bool {
268 return f.bit_width == null;
269 }
270
271 /// bit width as specified in the C source. Asserts that `f` is a bitfield.
272 pub fn specifiedBitWidth(f: *const Field) u32 {
273 return f.bit_width.?;
274 }
275 };
276
277 pub fn isIncomplete(r: Record) bool {
278 return r.fields.len == std.math.maxInt(usize);
279 }
280
281 pub fn create(allocator: std.mem.Allocator, name: StringId) !*Record {
282 var r = try allocator.create(Record);
283 r.name = name;
284 r.fields.len = std.math.maxInt(usize);
285 r.field_attributes = null;
286 r.type_layout = .{
287 .size_bits = 8,
288 .field_alignment_bits = 8,
289 .pointer_alignment_bits = 8,
290 .required_alignment_bits = 8,
291 };
292 return r;
293 }
294
295 pub fn hasFieldOfType(self: *const Record, ty: Type, comp: *const Compilation) bool {
296 if (self.isIncomplete()) return false;
297 for (self.fields) |f| {
298 if (ty.eql(f.ty, comp, false)) return true;
299 }
300 return false;
301 }
302};
303
304pub const Specifier = enum {
305 /// A NaN-like poison value
306 invalid,
307
308 /// GNU auto type
309 /// This is a placeholder specifier - it must be replaced by the actual type specifier (determined by the initializer)
310 auto_type,
311 /// C23 auto, behaves like auto_type
312 c23_auto,
313
314 void,
315 bool,
316
317 // integers
318 char,
319 schar,
320 uchar,
321 short,
322 ushort,
323 int,
324 uint,
325 long,
326 ulong,
327 long_long,
328 ulong_long,
329 int128,
330 uint128,
331 complex_char,
332 complex_schar,
333 complex_uchar,
334 complex_short,
335 complex_ushort,
336 complex_int,
337 complex_uint,
338 complex_long,
339 complex_ulong,
340 complex_long_long,
341 complex_ulong_long,
342 complex_int128,
343 complex_uint128,
344
345 // data.int
346 bit_int,
347 complex_bit_int,
348
349 // floating point numbers
350 fp16,
351 float16,
352 float,
353 double,
354 long_double,
355 float80,
356 float128,
357 complex_float,
358 complex_double,
359 complex_long_double,
360 complex_float80,
361 complex_float128,
362
363 // data.sub_type
364 pointer,
365 unspecified_variable_len_array,
366 // data.func
367 /// int foo(int bar, char baz) and int (void)
368 func,
369 /// int foo(int bar, char baz, ...)
370 var_args_func,
371 /// int foo(bar, baz) and int foo()
372 /// is also var args, but we can give warnings about incorrect amounts of parameters
373 old_style_func,
374
375 // data.array
376 array,
377 static_array,
378 incomplete_array,
379 vector,
380 // data.expr
381 variable_len_array,
382
383 // data.record
384 @"struct",
385 @"union",
386
387 // data.enum
388 @"enum",
389
390 /// typeof(type-name)
391 typeof_type,
392
393 /// typeof(expression)
394 typeof_expr,
395
396 /// data.attributed
397 attributed,
398
399 /// C23 nullptr_t
400 nullptr_t,
401};
402
403const Type = @This();
404
405/// All fields of Type except data may be mutated
406data: union {
407 sub_type: *Type,
408 func: *Func,
409 array: *Array,
410 expr: *Expr,
411 @"enum": *Enum,
412 record: *Record,
413 attributed: *Attributed,
414 none: void,
415 int: struct {
416 bits: u16,
417 signedness: std.builtin.Signedness,
418 },
419} = .{ .none = {} },
420specifier: Specifier,
421qual: Qualifiers = .{},
422decayed: bool = false,
423
424pub const int = Type{ .specifier = .int };
425pub const invalid = Type{ .specifier = .invalid };
426
427/// Determine if type matches the given specifier, recursing into typeof
428/// types if necessary.
429pub fn is(ty: Type, specifier: Specifier) bool {
430 std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
431 return ty.get(specifier) != null;
432}
433
434pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type {
435 if (attributes.len == 0) return self;
436 const attributed_type = try Type.Attributed.create(allocator, self, self.getAttributes(), attributes);
437 return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type }, .decayed = self.decayed };
438}
439
440pub fn isCallable(ty: Type) ?Type {
441 return switch (ty.specifier) {
442 .func, .var_args_func, .old_style_func => ty,
443 .pointer => if (ty.data.sub_type.isFunc()) ty.data.sub_type.* else null,
444 .typeof_type => ty.data.sub_type.isCallable(),
445 .typeof_expr => ty.data.expr.ty.isCallable(),
446 .attributed => ty.data.attributed.base.isCallable(),
447 else => null,
448 };
449}
450
451pub fn isFunc(ty: Type) bool {
452 return switch (ty.specifier) {
453 .func, .var_args_func, .old_style_func => true,
454 .typeof_type => ty.data.sub_type.isFunc(),
455 .typeof_expr => ty.data.expr.ty.isFunc(),
456 .attributed => ty.data.attributed.base.isFunc(),
457 else => false,
458 };
459}
460
461pub fn isArray(ty: Type) bool {
462 return switch (ty.specifier) {
463 .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => !ty.isDecayed(),
464 .typeof_type => !ty.isDecayed() and ty.data.sub_type.isArray(),
465 .typeof_expr => !ty.isDecayed() and ty.data.expr.ty.isArray(),
466 .attributed => !ty.isDecayed() and ty.data.attributed.base.isArray(),
467 else => false,
468 };
469}
470
471/// Whether the type is promoted if used as a variadic argument or as an argument to a function with no prototype
472fn undergoesDefaultArgPromotion(ty: Type, comp: *const Compilation) bool {
473 return switch (ty.specifier) {
474 .bool => true,
475 .char, .uchar, .schar => true,
476 .short, .ushort => true,
477 .@"enum" => if (comp.langopts.emulate == .clang) ty.data.@"enum".isIncomplete() else false,
478 .float => true,
479
480 .typeof_type => ty.data.sub_type.undergoesDefaultArgPromotion(comp),
481 .typeof_expr => ty.data.expr.ty.undergoesDefaultArgPromotion(comp),
482 .attributed => ty.data.attributed.base.undergoesDefaultArgPromotion(comp),
483 else => false,
484 };
485}
486
487pub fn isScalar(ty: Type) bool {
488 return ty.isInt() or ty.isScalarNonInt();
489}
490
491/// To avoid calling isInt() twice for allowable loop/if controlling expressions
492pub fn isScalarNonInt(ty: Type) bool {
493 return ty.isFloat() or ty.isPtr() or ty.is(.nullptr_t);
494}
495
496pub fn isDecayed(ty: Type) bool {
497 return ty.decayed;
498}
499
500pub fn isPtr(ty: Type) bool {
501 return switch (ty.specifier) {
502 .pointer => true,
503
504 .array,
505 .static_array,
506 .incomplete_array,
507 .variable_len_array,
508 .unspecified_variable_len_array,
509 => ty.isDecayed(),
510 .typeof_type => ty.isDecayed() or ty.data.sub_type.isPtr(),
511 .typeof_expr => ty.isDecayed() or ty.data.expr.ty.isPtr(),
512 .attributed => ty.isDecayed() or ty.data.attributed.base.isPtr(),
513 else => false,
514 };
515}
516
517pub fn isInt(ty: Type) bool {
518 return switch (ty.specifier) {
519 // zig fmt: off
520 .@"enum", .bool, .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong,
521 .long_long, .ulong_long, .int128, .uint128, .complex_char, .complex_schar, .complex_uchar,
522 .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
523 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
524 .bit_int, .complex_bit_int => true,
525 // zig fmt: on
526 .typeof_type => ty.data.sub_type.isInt(),
527 .typeof_expr => ty.data.expr.ty.isInt(),
528 .attributed => ty.data.attributed.base.isInt(),
529 else => false,
530 };
531}
532
533pub fn isFloat(ty: Type) bool {
534 return switch (ty.specifier) {
535 // zig fmt: off
536 .float, .double, .long_double, .complex_float, .complex_double, .complex_long_double,
537 .fp16, .float16, .float80, .float128, .complex_float80, .complex_float128 => true,
538 // zig fmt: on
539 .typeof_type => ty.data.sub_type.isFloat(),
540 .typeof_expr => ty.data.expr.ty.isFloat(),
541 .attributed => ty.data.attributed.base.isFloat(),
542 else => false,
543 };
544}
545
546pub fn isReal(ty: Type) bool {
547 return switch (ty.specifier) {
548 // zig fmt: off
549 .complex_float, .complex_double, .complex_long_double, .complex_float80,
550 .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
551 .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
552 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
553 .complex_bit_int => false,
554 // zig fmt: on
555 .typeof_type => ty.data.sub_type.isReal(),
556 .typeof_expr => ty.data.expr.ty.isReal(),
557 .attributed => ty.data.attributed.base.isReal(),
558 else => true,
559 };
560}
561
562pub fn isComplex(ty: Type) bool {
563 return switch (ty.specifier) {
564 // zig fmt: off
565 .complex_float, .complex_double, .complex_long_double, .complex_float80,
566 .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
567 .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
568 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
569 .complex_bit_int => true,
570 // zig fmt: on
571 .typeof_type => ty.data.sub_type.isComplex(),
572 .typeof_expr => ty.data.expr.ty.isComplex(),
573 .attributed => ty.data.attributed.base.isComplex(),
574 else => false,
575 };
576}
577
578pub fn isVoidStar(ty: Type) bool {
579 return switch (ty.specifier) {
580 .pointer => ty.data.sub_type.specifier == .void,
581 .typeof_type => ty.data.sub_type.isVoidStar(),
582 .typeof_expr => ty.data.expr.ty.isVoidStar(),
583 .attributed => ty.data.attributed.base.isVoidStar(),
584 else => false,
585 };
586}
587
588pub fn isTypeof(ty: Type) bool {
589 return switch (ty.specifier) {
590 .typeof_type, .typeof_expr => true,
591 else => false,
592 };
593}
594
595pub fn isConst(ty: Type) bool {
596 return switch (ty.specifier) {
597 .typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(),
598 .typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(),
599 .attributed => ty.data.attributed.base.isConst(),
600 else => ty.qual.@"const",
601 };
602}
603
604pub fn isUnsignedInt(ty: Type, comp: *const Compilation) bool {
605 return ty.signedness(comp) == .unsigned;
606}
607
608pub fn signedness(ty: Type, comp: *const Compilation) std.builtin.Signedness {
609 return switch (ty.specifier) {
610 // zig fmt: off
611 .char, .complex_char => return comp.getCharSignedness(),
612 .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128, .bool, .complex_uchar, .complex_ushort,
613 .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => .unsigned,
614 // zig fmt: on
615 .bit_int, .complex_bit_int => ty.data.int.signedness,
616 .typeof_type => ty.data.sub_type.signedness(comp),
617 .typeof_expr => ty.data.expr.ty.signedness(comp),
618 .attributed => ty.data.attributed.base.signedness(comp),
619 else => .signed,
620 };
621}
622
623pub fn isEnumOrRecord(ty: Type) bool {
624 return switch (ty.specifier) {
625 .@"enum", .@"struct", .@"union" => true,
626 .typeof_type => ty.data.sub_type.isEnumOrRecord(),
627 .typeof_expr => ty.data.expr.ty.isEnumOrRecord(),
628 .attributed => ty.data.attributed.base.isEnumOrRecord(),
629 else => false,
630 };
631}
632
633pub fn isRecord(ty: Type) bool {
634 return switch (ty.specifier) {
635 .@"struct", .@"union" => true,
636 .typeof_type => ty.data.sub_type.isRecord(),
637 .typeof_expr => ty.data.expr.ty.isRecord(),
638 .attributed => ty.data.attributed.base.isRecord(),
639 else => false,
640 };
641}
642
643pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool {
644 return switch (ty.specifier) {
645 // anonymous records can be recognized by their names which are in
646 // the format "(anonymous TAG at path:line:col)".
647 .@"struct", .@"union" => {
648 const mapper = comp.string_interner.getSlowTypeMapper();
649 return mapper.lookup(ty.data.record.name)[0] == '(';
650 },
651 .typeof_type => ty.data.sub_type.isAnonymousRecord(comp),
652 .typeof_expr => ty.data.expr.ty.isAnonymousRecord(comp),
653 .attributed => ty.data.attributed.base.isAnonymousRecord(comp),
654 else => false,
655 };
656}
657
658pub fn elemType(ty: Type) Type {
659 return switch (ty.specifier) {
660 .pointer, .unspecified_variable_len_array => ty.data.sub_type.*,
661 .array, .static_array, .incomplete_array, .vector => ty.data.array.elem,
662 .variable_len_array => ty.data.expr.ty,
663 .typeof_type, .typeof_expr => {
664 const unwrapped = ty.canonicalize(.preserve_quals);
665 var elem = unwrapped.elemType();
666 elem.qual = elem.qual.mergeAll(unwrapped.qual);
667 return elem;
668 },
669 .attributed => ty.data.attributed.base.elemType(),
670 .invalid => Type.invalid,
671 // zig fmt: off
672 .complex_float, .complex_double, .complex_long_double, .complex_float80,
673 .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
674 .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
675 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
676 .complex_bit_int => ty.makeReal(),
677 // zig fmt: on
678 else => unreachable,
679 };
680}
681
682pub fn returnType(ty: Type) Type {
683 return switch (ty.specifier) {
684 .func, .var_args_func, .old_style_func => ty.data.func.return_type,
685 .typeof_type => ty.data.sub_type.returnType(),
686 .typeof_expr => ty.data.expr.ty.returnType(),
687 .attributed => ty.data.attributed.base.returnType(),
688 .invalid => Type.invalid,
689 else => unreachable,
690 };
691}
692
693pub fn params(ty: Type) []Func.Param {
694 return switch (ty.specifier) {
695 .func, .var_args_func, .old_style_func => ty.data.func.params,
696 .typeof_type => ty.data.sub_type.params(),
697 .typeof_expr => ty.data.expr.ty.params(),
698 .attributed => ty.data.attributed.base.params(),
699 .invalid => &.{},
700 else => unreachable,
701 };
702}
703
704pub fn arrayLen(ty: Type) ?u64 {
705 return switch (ty.specifier) {
706 .array, .static_array => ty.data.array.len,
707 .typeof_type => ty.data.sub_type.arrayLen(),
708 .typeof_expr => ty.data.expr.ty.arrayLen(),
709 .attributed => ty.data.attributed.base.arrayLen(),
710 else => null,
711 };
712}
713
714/// Complex numbers are scalars but they can be initialized with a 2-element initList
715pub fn expectedInitListSize(ty: Type) ?u64 {
716 return if (ty.isComplex()) 2 else ty.arrayLen();
717}
718
719pub fn anyQual(ty: Type) bool {
720 return switch (ty.specifier) {
721 .typeof_type => ty.qual.any() or ty.data.sub_type.anyQual(),
722 .typeof_expr => ty.qual.any() or ty.data.expr.ty.anyQual(),
723 else => ty.qual.any(),
724 };
725}
726
727pub fn getAttributes(ty: Type) []const Attribute {
728 return switch (ty.specifier) {
729 .attributed => ty.data.attributed.attributes,
730 .typeof_type => ty.data.sub_type.getAttributes(),
731 .typeof_expr => ty.data.expr.ty.getAttributes(),
732 else => &.{},
733 };
734}
735
736pub fn getRecord(ty: Type) ?*const Type.Record {
737 return switch (ty.specifier) {
738 .attributed => ty.data.attributed.base.getRecord(),
739 .typeof_type => ty.data.sub_type.getRecord(),
740 .typeof_expr => ty.data.expr.ty.getRecord(),
741 .@"struct", .@"union" => ty.data.record,
742 else => null,
743 };
744}
745
746pub fn compareIntegerRanks(a: Type, b: Type, comp: *const Compilation) std.math.Order {
747 std.debug.assert(a.isInt() and b.isInt());
748 if (a.eql(b, comp, false)) return .eq;
749
750 const a_unsigned = a.isUnsignedInt(comp);
751 const b_unsigned = b.isUnsignedInt(comp);
752
753 const a_rank = a.integerRank(comp);
754 const b_rank = b.integerRank(comp);
755 if (a_unsigned == b_unsigned) {
756 return std.math.order(a_rank, b_rank);
757 }
758 if (a_unsigned) {
759 if (a_rank >= b_rank) return .gt;
760 return .lt;
761 }
762 std.debug.assert(b_unsigned);
763 if (b_rank >= a_rank) return .lt;
764 return .gt;
765}
766
767fn realIntegerConversion(a: Type, b: Type, comp: *const Compilation) Type {
768 std.debug.assert(a.isReal() and b.isReal());
769 const type_order = a.compareIntegerRanks(b, comp);
770 const a_signed = !a.isUnsignedInt(comp);
771 const b_signed = !b.isUnsignedInt(comp);
772 if (a_signed == b_signed) {
773 // If both have the same sign, use higher-rank type.
774 return switch (type_order) {
775 .lt => b,
776 .eq, .gt => a,
777 };
778 } else if (type_order != if (a_signed) std.math.Order.gt else std.math.Order.lt) {
779 // Only one is signed; and the unsigned type has rank >= the signed type
780 // Use the unsigned type
781 return if (b_signed) a else b;
782 } else if (a.bitSizeof(comp).? != b.bitSizeof(comp).?) {
783 // Signed type is higher rank and sizes are not equal
784 // Use the signed type
785 return if (a_signed) a else b;
786 } else {
787 // Signed type is higher rank but same size as unsigned type
788 // e.g. `long` and `unsigned` on x86-linux-gnu
789 // Use unsigned version of the signed type
790 return if (a_signed) a.makeIntegerUnsigned() else b.makeIntegerUnsigned();
791 }
792}
793
794pub fn makeIntegerUnsigned(ty: Type) Type {
795 // TODO discards attributed/typeof
796 var base = ty.canonicalize(.standard);
797 switch (base.specifier) {
798 // zig fmt: off
799 .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128,
800 .complex_uchar, .complex_ushort, .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128,
801 => return ty,
802 // zig fmt: on
803
804 .char, .complex_char => {
805 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 2);
806 return base;
807 },
808
809 // zig fmt: off
810 .schar, .short, .int, .long, .long_long, .int128,
811 .complex_schar, .complex_short, .complex_int, .complex_long, .complex_long_long, .complex_int128 => {
812 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 1);
813 return base;
814 },
815 // zig fmt: on
816
817 .bit_int, .complex_bit_int => {
818 base.data.int.signedness = .unsigned;
819 return base;
820 },
821 else => unreachable,
822 }
823}
824
825/// Find the common type of a and b for binary operations
826pub fn integerConversion(a: Type, b: Type, comp: *const Compilation) Type {
827 const a_real = a.isReal();
828 const b_real = b.isReal();
829 const target_ty = a.makeReal().realIntegerConversion(b.makeReal(), comp);
830 return if (a_real and b_real) target_ty else target_ty.makeComplex();
831}
832
833pub fn integerPromotion(ty: Type, comp: *Compilation) Type {
834 var specifier = ty.specifier;
835 switch (specifier) {
836 .@"enum" => {
837 if (ty.hasIncompleteSize()) return .{ .specifier = .int };
838 specifier = ty.data.@"enum".tag_ty.specifier;
839 },
840 .bit_int, .complex_bit_int => return .{ .specifier = specifier, .data = ty.data },
841 else => {},
842 }
843 return switch (specifier) {
844 else => .{
845 .specifier = switch (specifier) {
846 // zig fmt: off
847 .bool, .char, .schar, .uchar, .short => .int,
848 .ushort => if (ty.sizeof(comp).? == sizeof(.{ .specifier = .int }, comp)) Specifier.uint else .int,
849 .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128, .complex_char,
850 .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
851 .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
852 .complex_int128, .complex_uint128 => specifier,
853 // zig fmt: on
854 .typeof_type => return ty.data.sub_type.integerPromotion(comp),
855 .typeof_expr => return ty.data.expr.ty.integerPromotion(comp),
856 .attributed => return ty.data.attributed.base.integerPromotion(comp),
857 .invalid => .invalid,
858 else => unreachable, // _BitInt, or not an integer type
859 },
860 },
861 };
862}
863
864/// Promote a bitfield. If `int` can hold all the values of the underlying field,
865/// promote to int. Otherwise, promote to unsigned int
866/// Returns null if no promotion is necessary
867pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type {
868 const type_size_bits = ty.bitSizeof(comp).?;
869
870 // Note: GCC and clang will promote `long: 3` to int even though the C standard does not allow this
871 if (width < type_size_bits) {
872 return int;
873 }
874
875 if (width == type_size_bits) {
876 return if (ty.isUnsignedInt(comp)) .{ .specifier = .uint } else int;
877 }
878
879 return null;
880}
881
882pub fn hasIncompleteSize(ty: Type) bool {
883 if (ty.isDecayed()) return false;
884 return switch (ty.specifier) {
885 .void, .incomplete_array => true,
886 .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed,
887 .@"struct", .@"union" => ty.data.record.isIncomplete(),
888 .array, .static_array => ty.data.array.elem.hasIncompleteSize(),
889 .typeof_type => ty.data.sub_type.hasIncompleteSize(),
890 .typeof_expr => ty.data.expr.ty.hasIncompleteSize(),
891 .attributed => ty.data.attributed.base.hasIncompleteSize(),
892 else => false,
893 };
894}
895
896pub fn hasUnboundVLA(ty: Type) bool {
897 var cur = ty;
898 while (true) {
899 switch (cur.specifier) {
900 .unspecified_variable_len_array => return true,
901 .array,
902 .static_array,
903 .incomplete_array,
904 .variable_len_array,
905 => cur = cur.elemType(),
906 .typeof_type => cur = cur.data.sub_type.*,
907 .typeof_expr => cur = cur.data.expr.ty,
908 .attributed => cur = cur.data.attributed.base,
909 else => return false,
910 }
911 }
912}
913
914pub fn hasField(ty: Type, name: StringId) bool {
915 switch (ty.specifier) {
916 .@"struct" => {
917 std.debug.assert(!ty.data.record.isIncomplete());
918 for (ty.data.record.fields) |f| {
919 if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
920 if (name == f.name) return true;
921 }
922 },
923 .@"union" => {
924 std.debug.assert(!ty.data.record.isIncomplete());
925 for (ty.data.record.fields) |f| {
926 if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
927 if (name == f.name) return true;
928 }
929 },
930 .typeof_type => return ty.data.sub_type.hasField(name),
931 .typeof_expr => return ty.data.expr.ty.hasField(name),
932 .attributed => return ty.data.attributed.base.hasField(name),
933 .invalid => return false,
934 else => unreachable,
935 }
936 return false;
937}
938
939// TODO handle bitints
940pub fn minInt(ty: Type, comp: *const Compilation) i64 {
941 std.debug.assert(ty.isInt());
942 if (ty.isUnsignedInt(comp)) return 0;
943 return switch (ty.sizeof(comp).?) {
944 1 => std.math.minInt(i8),
945 2 => std.math.minInt(i16),
946 4 => std.math.minInt(i32),
947 8 => std.math.minInt(i64),
948 else => unreachable,
949 };
950}
951
952// TODO handle bitints
953pub fn maxInt(ty: Type, comp: *const Compilation) u64 {
954 std.debug.assert(ty.isInt());
955 return switch (ty.sizeof(comp).?) {
956 1 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u8)) else std.math.maxInt(i8),
957 2 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u16)) else std.math.maxInt(i16),
958 4 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u32)) else std.math.maxInt(i32),
959 8 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u64)) else std.math.maxInt(i64),
960 else => unreachable,
961 };
962}
963
964const TypeSizeOrder = enum {
965 lt,
966 gt,
967 eq,
968 indeterminate,
969};
970
971pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder {
972 const a_size = a.sizeof(comp) orelse return .indeterminate;
973 const b_size = b.sizeof(comp) orelse return .indeterminate;
974 return switch (std.math.order(a_size, b_size)) {
975 .lt => .lt,
976 .gt => .gt,
977 .eq => .eq,
978 };
979}
980
981/// Size of type as reported by sizeof
982pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
983 if (ty.isPtr()) return comp.target.ptrBitWidth() / 8;
984
985 return switch (ty.specifier) {
986 .auto_type, .c23_auto => unreachable,
987 .variable_len_array, .unspecified_variable_len_array => null,
988 .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null,
989 .func, .var_args_func, .old_style_func, .void, .bool => 1,
990 .char, .schar, .uchar => 1,
991 .short => comp.target.c_type_byte_size(.short),
992 .ushort => comp.target.c_type_byte_size(.ushort),
993 .int => comp.target.c_type_byte_size(.int),
994 .uint => comp.target.c_type_byte_size(.uint),
995 .long => comp.target.c_type_byte_size(.long),
996 .ulong => comp.target.c_type_byte_size(.ulong),
997 .long_long => comp.target.c_type_byte_size(.longlong),
998 .ulong_long => comp.target.c_type_byte_size(.ulonglong),
999 .long_double => comp.target.c_type_byte_size(.longdouble),
1000 .int128, .uint128 => 16,
1001 .fp16, .float16 => 2,
1002 .float => comp.target.c_type_byte_size(.float),
1003 .double => comp.target.c_type_byte_size(.double),
1004 .float80 => 16,
1005 .float128 => 16,
1006 .bit_int => {
1007 return std.mem.alignForward(u64, (ty.data.int.bits + 7) / 8, ty.alignof(comp));
1008 },
1009 // zig fmt: off
1010 .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
1011 .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
1012 .complex_int128, .complex_uint128, .complex_float, .complex_double,
1013 .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
1014 => return 2 * ty.makeReal().sizeof(comp).?,
1015 // zig fmt: on
1016 .pointer => unreachable,
1017 .static_array,
1018 .nullptr_t,
1019 => comp.target.ptrBitWidth() / 8,
1020 .array, .vector => {
1021 const size = ty.data.array.elem.sizeof(comp) orelse return null;
1022 const arr_size = size * ty.data.array.len;
1023 if (comp.langopts.emulate == .msvc) {
1024 // msvc ignores array type alignment.
1025 // Since the size might not be a multiple of the field
1026 // alignment, the address of the second element might not be properly aligned
1027 // for the field alignment. A flexible array has size 0. See test case 0018.
1028 return arr_size;
1029 } else {
1030 return std.mem.alignForward(u64, arr_size, ty.alignof(comp));
1031 }
1032 },
1033 .@"struct", .@"union" => if (ty.data.record.isIncomplete()) null else @as(u64, ty.data.record.type_layout.size_bits / 8),
1034 .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) null else ty.data.@"enum".tag_ty.sizeof(comp),
1035 .typeof_type => ty.data.sub_type.sizeof(comp),
1036 .typeof_expr => ty.data.expr.ty.sizeof(comp),
1037 .attributed => ty.data.attributed.base.sizeof(comp),
1038 .invalid => return null,
1039 };
1040}
1041
1042pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {
1043 return switch (ty.specifier) {
1044 .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1,
1045 .typeof_type => ty.data.sub_type.bitSizeof(comp),
1046 .typeof_expr => ty.data.expr.ty.bitSizeof(comp),
1047 .attributed => ty.data.attributed.base.bitSizeof(comp),
1048 .bit_int => return ty.data.int.bits,
1049 .long_double => comp.target.c_type_bit_size(.longdouble),
1050 .float80 => return 80,
1051 else => 8 * (ty.sizeof(comp) orelse return null),
1052 };
1053}
1054
1055pub fn alignable(ty: Type) bool {
1056 return ty.isArray() or !ty.hasIncompleteSize() or ty.is(.void);
1057}
1058
1059/// Get the alignment of a type
1060pub fn alignof(ty: Type, comp: *const Compilation) u29 {
1061 // don't return the attribute for records
1062 // layout has already accounted for requested alignment
1063 if (ty.requestedAlignment(comp)) |requested| {
1064 // gcc does not respect alignment on enums
1065 if (ty.get(.@"enum")) |ty_enum| {
1066 if (comp.langopts.emulate == .gcc) {
1067 return ty_enum.alignof(comp);
1068 }
1069 } else if (ty.getRecord()) |rec| {
1070 if (ty.hasIncompleteSize()) return 0;
1071 const computed: u29 = @intCast(@divExact(rec.type_layout.field_alignment_bits, 8));
1072 return @max(requested, computed);
1073 } else if (comp.langopts.emulate == .msvc) {
1074 const type_align = ty.data.attributed.base.alignof(comp);
1075 return @max(requested, type_align);
1076 }
1077 return requested;
1078 }
1079
1080 return switch (ty.specifier) {
1081 .invalid => unreachable,
1082 .auto_type, .c23_auto => unreachable,
1083
1084 .variable_len_array,
1085 .incomplete_array,
1086 .unspecified_variable_len_array,
1087 .array,
1088 .vector,
1089 => if (ty.isPtr()) switch (comp.target.cpu.arch) {
1090 .avr => 1,
1091 else => comp.target.ptrBitWidth() / 8,
1092 } else ty.elemType().alignof(comp),
1093 .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target),
1094 .char, .schar, .uchar, .void, .bool => 1,
1095
1096 // zig fmt: off
1097 .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
1098 .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
1099 .complex_int128, .complex_uint128, .complex_float, .complex_double,
1100 .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
1101 => return ty.makeReal().alignof(comp),
1102 // zig fmt: on
1103
1104 .short => comp.target.c_type_alignment(.short),
1105 .ushort => comp.target.c_type_alignment(.ushort),
1106 .int => comp.target.c_type_alignment(.int),
1107 .uint => comp.target.c_type_alignment(.uint),
1108
1109 .long => comp.target.c_type_alignment(.long),
1110 .ulong => comp.target.c_type_alignment(.ulong),
1111 .long_long => comp.target.c_type_alignment(.longlong),
1112 .ulong_long => comp.target.c_type_alignment(.ulonglong),
1113
1114 .bit_int => @min(
1115 std.math.ceilPowerOfTwoPromote(u16, (ty.data.int.bits + 7) / 8),
1116 comp.target.maxIntAlignment(),
1117 ),
1118
1119 .float => comp.target.c_type_alignment(.float),
1120 .double => comp.target.c_type_alignment(.double),
1121 .long_double => comp.target.c_type_alignment(.longdouble),
1122
1123 .int128, .uint128 => if (comp.target.cpu.arch == .s390x and comp.target.os.tag == .linux and comp.target.isGnu()) 8 else 16,
1124 .fp16, .float16 => 2,
1125
1126 .float80, .float128 => 16,
1127 .pointer,
1128 .static_array,
1129 .nullptr_t,
1130 => switch (comp.target.cpu.arch) {
1131 .avr => 1,
1132 else => comp.target.ptrBitWidth() / 8,
1133 },
1134 .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8),
1135 .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp),
1136 .typeof_type => ty.data.sub_type.alignof(comp),
1137 .typeof_expr => ty.data.expr.ty.alignof(comp),
1138 .attributed => ty.data.attributed.base.alignof(comp),
1139 };
1140}
1141
1142/// Canonicalize a possibly-typeof() type. If the type is not a typeof() type, simply
1143/// return it. Otherwise, determine the actual qualified type.
1144/// The `qual_handling` parameter can be used to return the full set of qualifiers
1145/// added by typeof() operations, which is useful when determining the elemType of
1146/// arrays and pointers.
1147pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {
1148 var cur = ty;
1149 if (cur.specifier == .attributed) {
1150 cur = cur.data.attributed.base;
1151 cur.decayed = ty.decayed;
1152 }
1153 if (!cur.isTypeof()) return cur;
1154
1155 var qual = cur.qual;
1156 while (true) {
1157 switch (cur.specifier) {
1158 .typeof_type => cur = cur.data.sub_type.*,
1159 .typeof_expr => cur = cur.data.expr.ty,
1160 else => break,
1161 }
1162 qual = qual.mergeAll(cur.qual);
1163 }
1164 if ((cur.isArray() or cur.isPtr()) and qual_handling == .standard) {
1165 cur.qual = .{};
1166 } else {
1167 cur.qual = qual;
1168 }
1169 cur.decayed = ty.decayed;
1170 return cur;
1171}
1172
1173pub fn get(ty: *const Type, specifier: Specifier) ?*const Type {
1174 std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
1175 return switch (ty.specifier) {
1176 .typeof_type => ty.data.sub_type.get(specifier),
1177 .typeof_expr => ty.data.expr.ty.get(specifier),
1178 .attributed => ty.data.attributed.base.get(specifier),
1179 else => if (ty.specifier == specifier) ty else null,
1180 };
1181}
1182
1183pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 {
1184 return switch (ty.specifier) {
1185 .typeof_type => ty.data.sub_type.requestedAlignment(comp),
1186 .typeof_expr => ty.data.expr.ty.requestedAlignment(comp),
1187 .attributed => annotationAlignment(comp, ty.data.attributed.attributes),
1188 else => null,
1189 };
1190}
1191
1192pub fn enumIsPacked(ty: Type, comp: *const Compilation) bool {
1193 std.debug.assert(ty.is(.@"enum"));
1194 return comp.langopts.short_enums or target_util.packAllEnums(comp.target) or ty.hasAttribute(.@"packed");
1195}
1196
1197pub fn annotationAlignment(comp: *const Compilation, attrs: ?[]const Attribute) ?u29 {
1198 const a = attrs orelse return null;
1199
1200 var max_requested: ?u29 = null;
1201 for (a) |attribute| {
1202 if (attribute.tag != .aligned) continue;
1203 const requested = if (attribute.args.aligned.alignment) |alignment| alignment.requested else target_util.defaultAlignment(comp.target);
1204 if (max_requested == null or max_requested.? < requested) {
1205 max_requested = requested;
1206 }
1207 }
1208 return max_requested;
1209}
1210
1211pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifiers: bool) bool {
1212 const a = a_param.canonicalize(.standard);
1213 const b = b_param.canonicalize(.standard);
1214
1215 if (a.specifier == .invalid or b.specifier == .invalid) return false;
1216 if (a.alignof(comp) != b.alignof(comp)) return false;
1217 if (a.isPtr()) {
1218 if (!b.isPtr()) return false;
1219 } else if (a.isFunc()) {
1220 if (!b.isFunc()) return false;
1221 } else if (a.isArray()) {
1222 if (!b.isArray()) return false;
1223 } else if (a.specifier != b.specifier) return false;
1224
1225 if (a.qual.atomic != b.qual.atomic) return false;
1226 if (check_qualifiers) {
1227 if (a.qual.@"const" != b.qual.@"const") return false;
1228 if (a.qual.@"volatile" != b.qual.@"volatile") return false;
1229 }
1230
1231 if (a.isPtr()) {
1232 return a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers);
1233 }
1234 switch (a.specifier) {
1235 .pointer => unreachable,
1236
1237 .func,
1238 .var_args_func,
1239 .old_style_func,
1240 => if (!a.data.func.eql(b.data.func, a.specifier, b.specifier, comp)) return false,
1241
1242 .array,
1243 .static_array,
1244 .incomplete_array,
1245 .vector,
1246 => {
1247 const a_len = a.arrayLen();
1248 const b_len = b.arrayLen();
1249 if (a_len == null or b_len == null) {
1250 // At least one array is incomplete; only check child type for equality
1251 } else if (a_len.? != b_len.?) {
1252 return false;
1253 }
1254 if (!a.elemType().eql(b.elemType(), comp, false)) return false;
1255 },
1256 .variable_len_array => {
1257 if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false;
1258 },
1259 .@"struct", .@"union" => if (a.data.record != b.data.record) return false,
1260 .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false,
1261 .bit_int, .complex_bit_int => return a.data.int.bits == b.data.int.bits and a.data.int.signedness == b.data.int.signedness,
1262
1263 else => {},
1264 }
1265 return true;
1266}
1267
1268/// Decays an array to a pointer
1269pub fn decayArray(ty: *Type) void {
1270 std.debug.assert(ty.isArray());
1271 ty.decayed = true;
1272}
1273
1274pub fn originalTypeOfDecayedArray(ty: Type) Type {
1275 std.debug.assert(ty.isDecayed());
1276 var copy = ty;
1277 copy.decayed = false;
1278 return copy;
1279}
1280
1281/// Rank for floating point conversions, ignoring domain (complex vs real)
1282/// Asserts that ty is a floating point type
1283pub fn floatRank(ty: Type) usize {
1284 const real = ty.makeReal();
1285 return switch (real.specifier) {
1286 // TODO: bfloat16 => 0
1287 .float16 => 1,
1288 .fp16 => 2,
1289 .float => 3,
1290 .double => 4,
1291 .long_double => 5,
1292 .float128 => 6,
1293 // TODO: ibm128 => 7
1294 else => unreachable,
1295 };
1296}
1297
1298/// Rank for integer conversions, ignoring domain (complex vs real)
1299/// Asserts that ty is an integer type
1300pub fn integerRank(ty: Type, comp: *const Compilation) usize {
1301 const real = ty.makeReal();
1302 return @intCast(switch (real.specifier) {
1303 .bit_int => @as(u64, real.data.int.bits) << 3,
1304
1305 .bool => 1 + (ty.bitSizeof(comp).? << 3),
1306 .char, .schar, .uchar => 2 + (ty.bitSizeof(comp).? << 3),
1307 .short, .ushort => 3 + (ty.bitSizeof(comp).? << 3),
1308 .int, .uint => 4 + (ty.bitSizeof(comp).? << 3),
1309 .long, .ulong => 5 + (ty.bitSizeof(comp).? << 3),
1310 .long_long, .ulong_long => 6 + (ty.bitSizeof(comp).? << 3),
1311 .int128, .uint128 => 7 + (ty.bitSizeof(comp).? << 3),
1312
1313 else => unreachable,
1314 });
1315}
1316
1317/// Returns true if `a` and `b` are integer types that differ only in sign
1318pub fn sameRankDifferentSign(a: Type, b: Type, comp: *const Compilation) bool {
1319 if (!a.isInt() or !b.isInt()) return false;
1320 if (a.integerRank(comp) != b.integerRank(comp)) return false;
1321 return a.isUnsignedInt(comp) != b.isUnsignedInt(comp);
1322}
1323
1324pub fn makeReal(ty: Type) Type {
1325 // TODO discards attributed/typeof
1326 var base = ty.canonicalize(.standard);
1327 switch (base.specifier) {
1328 .complex_float, .complex_double, .complex_long_double, .complex_float80, .complex_float128 => {
1329 base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 5);
1330 return base;
1331 },
1332 .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128 => {
1333 base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 13);
1334 return base;
1335 },
1336 .complex_bit_int => {
1337 base.specifier = .bit_int;
1338 return base;
1339 },
1340 else => return ty,
1341 }
1342}
1343
1344pub fn makeComplex(ty: Type) Type {
1345 // TODO discards attributed/typeof
1346 var base = ty.canonicalize(.standard);
1347 switch (base.specifier) {
1348 .float, .double, .long_double, .float80, .float128 => {
1349 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 5);
1350 return base;
1351 },
1352 .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128 => {
1353 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 13);
1354 return base;
1355 },
1356 .bit_int => {
1357 base.specifier = .complex_bit_int;
1358 return base;
1359 },
1360 else => return ty,
1361 }
1362}
1363
1364/// Combines types recursively in the order they were parsed, uses `.void` specifier as a sentinel value.
1365pub fn combine(inner: *Type, outer: Type) Parser.Error!void {
1366 switch (inner.specifier) {
1367 .pointer => return inner.data.sub_type.combine(outer),
1368 .unspecified_variable_len_array => {
1369 std.debug.assert(!inner.isDecayed());
1370 try inner.data.sub_type.combine(outer);
1371 },
1372 .variable_len_array => {
1373 std.debug.assert(!inner.isDecayed());
1374 try inner.data.expr.ty.combine(outer);
1375 },
1376 .array, .static_array, .incomplete_array => {
1377 std.debug.assert(!inner.isDecayed());
1378 try inner.data.array.elem.combine(outer);
1379 },
1380 .func, .var_args_func, .old_style_func => {
1381 try inner.data.func.return_type.combine(outer);
1382 },
1383 .typeof_type,
1384 .typeof_expr,
1385 => std.debug.assert(!inner.isDecayed()),
1386 .void, .invalid => inner.* = outer,
1387 else => unreachable,
1388 }
1389}
1390
1391pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser.Error!void {
1392 switch (ty.specifier) {
1393 .pointer => return ty.data.sub_type.validateCombinedType(p, source_tok),
1394 .unspecified_variable_len_array,
1395 .variable_len_array,
1396 .array,
1397 .static_array,
1398 .incomplete_array,
1399 => {
1400 const elem_ty = ty.elemType();
1401 if (elem_ty.hasIncompleteSize()) {
1402 try p.errStr(.array_incomplete_elem, source_tok, try p.typeStr(elem_ty));
1403 return error.ParsingFailed;
1404 }
1405 if (elem_ty.isFunc()) {
1406 try p.errTok(.array_func_elem, source_tok);
1407 return error.ParsingFailed;
1408 }
1409 if (elem_ty.specifier == .static_array and elem_ty.isArray()) {
1410 try p.errTok(.static_non_outermost_array, source_tok);
1411 }
1412 if (elem_ty.anyQual() and elem_ty.isArray()) {
1413 try p.errTok(.qualifier_non_outermost_array, source_tok);
1414 }
1415 },
1416 .func, .var_args_func, .old_style_func => {
1417 const ret_ty = &ty.data.func.return_type;
1418 if (ret_ty.isArray()) try p.errTok(.func_cannot_return_array, source_tok);
1419 if (ret_ty.isFunc()) try p.errTok(.func_cannot_return_func, source_tok);
1420 if (ret_ty.qual.@"const") {
1421 try p.errStr(.qual_on_ret_type, source_tok, "const");
1422 ret_ty.qual.@"const" = false;
1423 }
1424 if (ret_ty.qual.@"volatile") {
1425 try p.errStr(.qual_on_ret_type, source_tok, "volatile");
1426 ret_ty.qual.@"volatile" = false;
1427 }
1428 if (ret_ty.qual.atomic) {
1429 try p.errStr(.qual_on_ret_type, source_tok, "atomic");
1430 ret_ty.qual.atomic = false;
1431 }
1432 if (ret_ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
1433 try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value");
1434 }
1435 },
1436 .typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok),
1437 .typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok),
1438 .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok),
1439 else => {},
1440 }
1441}
1442
1443/// An unfinished Type
1444pub const Builder = struct {
1445 complex_tok: ?TokenIndex = null,
1446 bit_int_tok: ?TokenIndex = null,
1447 auto_type_tok: ?TokenIndex = null,
1448 typedef: ?struct {
1449 tok: TokenIndex,
1450 ty: Type,
1451 } = null,
1452 specifier: Builder.Specifier = .none,
1453 qual: Qualifiers.Builder = .{},
1454 typeof: ?Type = null,
1455 /// When true an error is returned instead of adding a diagnostic message.
1456 /// Used for trying to combine typedef types.
1457 error_on_invalid: bool = false,
1458
1459 pub const Specifier = union(enum) {
1460 none,
1461 void,
1462 /// GNU __auto_type extension
1463 auto_type,
1464 /// C23 auto
1465 c23_auto,
1466 nullptr_t,
1467 bool,
1468 char,
1469 schar,
1470 uchar,
1471 complex_char,
1472 complex_schar,
1473 complex_uchar,
1474
1475 unsigned,
1476 signed,
1477 short,
1478 sshort,
1479 ushort,
1480 short_int,
1481 sshort_int,
1482 ushort_int,
1483 int,
1484 sint,
1485 uint,
1486 long,
1487 slong,
1488 ulong,
1489 long_int,
1490 slong_int,
1491 ulong_int,
1492 long_long,
1493 slong_long,
1494 ulong_long,
1495 long_long_int,
1496 slong_long_int,
1497 ulong_long_int,
1498 int128,
1499 sint128,
1500 uint128,
1501 complex_unsigned,
1502 complex_signed,
1503 complex_short,
1504 complex_sshort,
1505 complex_ushort,
1506 complex_short_int,
1507 complex_sshort_int,
1508 complex_ushort_int,
1509 complex_int,
1510 complex_sint,
1511 complex_uint,
1512 complex_long,
1513 complex_slong,
1514 complex_ulong,
1515 complex_long_int,
1516 complex_slong_int,
1517 complex_ulong_int,
1518 complex_long_long,
1519 complex_slong_long,
1520 complex_ulong_long,
1521 complex_long_long_int,
1522 complex_slong_long_int,
1523 complex_ulong_long_int,
1524 complex_int128,
1525 complex_sint128,
1526 complex_uint128,
1527 bit_int: u64,
1528 sbit_int: u64,
1529 ubit_int: u64,
1530 complex_bit_int: u64,
1531 complex_sbit_int: u64,
1532 complex_ubit_int: u64,
1533
1534 fp16,
1535 float16,
1536 float,
1537 double,
1538 long_double,
1539 float80,
1540 float128,
1541 complex,
1542 complex_float,
1543 complex_double,
1544 complex_long_double,
1545 complex_float80,
1546 complex_float128,
1547
1548 pointer: *Type,
1549 unspecified_variable_len_array: *Type,
1550 decayed_unspecified_variable_len_array: *Type,
1551 func: *Func,
1552 var_args_func: *Func,
1553 old_style_func: *Func,
1554 array: *Array,
1555 decayed_array: *Array,
1556 static_array: *Array,
1557 decayed_static_array: *Array,
1558 incomplete_array: *Array,
1559 decayed_incomplete_array: *Array,
1560 vector: *Array,
1561 variable_len_array: *Expr,
1562 decayed_variable_len_array: *Expr,
1563 @"struct": *Record,
1564 @"union": *Record,
1565 @"enum": *Enum,
1566 typeof_type: *Type,
1567 decayed_typeof_type: *Type,
1568 typeof_expr: *Expr,
1569 decayed_typeof_expr: *Expr,
1570
1571 attributed: *Attributed,
1572 decayed_attributed: *Attributed,
1573
1574 pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 {
1575 return switch (spec) {
1576 .none => unreachable,
1577 .void => "void",
1578 .auto_type => "__auto_type",
1579 .c23_auto => "auto",
1580 .nullptr_t => "nullptr_t",
1581 .bool => if (langopts.standard.atLeast(.c23)) "bool" else "_Bool",
1582 .char => "char",
1583 .schar => "signed char",
1584 .uchar => "unsigned char",
1585 .unsigned => "unsigned",
1586 .signed => "signed",
1587 .short => "short",
1588 .ushort => "unsigned short",
1589 .sshort => "signed short",
1590 .short_int => "short int",
1591 .sshort_int => "signed short int",
1592 .ushort_int => "unsigned short int",
1593 .int => "int",
1594 .sint => "signed int",
1595 .uint => "unsigned int",
1596 .long => "long",
1597 .slong => "signed long",
1598 .ulong => "unsigned long",
1599 .long_int => "long int",
1600 .slong_int => "signed long int",
1601 .ulong_int => "unsigned long int",
1602 .long_long => "long long",
1603 .slong_long => "signed long long",
1604 .ulong_long => "unsigned long long",
1605 .long_long_int => "long long int",
1606 .slong_long_int => "signed long long int",
1607 .ulong_long_int => "unsigned long long int",
1608 .int128 => "__int128",
1609 .sint128 => "signed __int128",
1610 .uint128 => "unsigned __int128",
1611 .bit_int => "_BitInt",
1612 .sbit_int => "signed _BitInt",
1613 .ubit_int => "unsigned _BitInt",
1614 .complex_char => "_Complex char",
1615 .complex_schar => "_Complex signed char",
1616 .complex_uchar => "_Complex unsigned char",
1617 .complex_unsigned => "_Complex unsigned",
1618 .complex_signed => "_Complex signed",
1619 .complex_short => "_Complex short",
1620 .complex_ushort => "_Complex unsigned short",
1621 .complex_sshort => "_Complex signed short",
1622 .complex_short_int => "_Complex short int",
1623 .complex_sshort_int => "_Complex signed short int",
1624 .complex_ushort_int => "_Complex unsigned short int",
1625 .complex_int => "_Complex int",
1626 .complex_sint => "_Complex signed int",
1627 .complex_uint => "_Complex unsigned int",
1628 .complex_long => "_Complex long",
1629 .complex_slong => "_Complex signed long",
1630 .complex_ulong => "_Complex unsigned long",
1631 .complex_long_int => "_Complex long int",
1632 .complex_slong_int => "_Complex signed long int",
1633 .complex_ulong_int => "_Complex unsigned long int",
1634 .complex_long_long => "_Complex long long",
1635 .complex_slong_long => "_Complex signed long long",
1636 .complex_ulong_long => "_Complex unsigned long long",
1637 .complex_long_long_int => "_Complex long long int",
1638 .complex_slong_long_int => "_Complex signed long long int",
1639 .complex_ulong_long_int => "_Complex unsigned long long int",
1640 .complex_int128 => "_Complex __int128",
1641 .complex_sint128 => "_Complex signed __int128",
1642 .complex_uint128 => "_Complex unsigned __int128",
1643 .complex_bit_int => "_Complex _BitInt",
1644 .complex_sbit_int => "_Complex signed _BitInt",
1645 .complex_ubit_int => "_Complex unsigned _BitInt",
1646
1647 .fp16 => "__fp16",
1648 .float16 => "_Float16",
1649 .float => "float",
1650 .double => "double",
1651 .long_double => "long double",
1652 .float80 => "__float80",
1653 .float128 => "__float128",
1654 .complex => "_Complex",
1655 .complex_float => "_Complex float",
1656 .complex_double => "_Complex double",
1657 .complex_long_double => "_Complex long double",
1658 .complex_float80 => "_Complex __float80",
1659 .complex_float128 => "_Complex __float128",
1660
1661 .attributed => |attributed| Builder.fromType(attributed.base).str(langopts),
1662
1663 else => null,
1664 };
1665 }
1666 };
1667
1668 pub fn finish(b: Builder, p: *Parser) Parser.Error!Type {
1669 var ty: Type = .{ .specifier = undefined };
1670 if (b.typedef) |typedef| {
1671 ty = typedef.ty;
1672 if (ty.isArray()) {
1673 var elem = ty.elemType();
1674 try b.qual.finish(p, &elem);
1675 // TODO this really should be easier
1676 switch (ty.specifier) {
1677 .array, .static_array, .incomplete_array => {
1678 const old = ty.data.array;
1679 ty.data.array = try p.arena.create(Array);
1680 ty.data.array.* = .{
1681 .len = old.len,
1682 .elem = elem,
1683 };
1684 },
1685 .variable_len_array, .unspecified_variable_len_array => {
1686 const old = ty.data.expr;
1687 ty.data.expr = try p.arena.create(Expr);
1688 ty.data.expr.* = .{
1689 .node = old.node,
1690 .ty = elem,
1691 };
1692 },
1693 .typeof_type => {}, // TODO handle
1694 .typeof_expr => {}, // TODO handle
1695 .attributed => {}, // TODO handle
1696 else => unreachable,
1697 }
1698
1699 return ty;
1700 }
1701 try b.qual.finish(p, &ty);
1702 return ty;
1703 }
1704 switch (b.specifier) {
1705 .none => {
1706 if (b.typeof) |typeof| {
1707 ty = typeof;
1708 } else {
1709 ty.specifier = .int;
1710 if (p.comp.langopts.standard.atLeast(.c23)) {
1711 try p.err(.missing_type_specifier_c23);
1712 } else {
1713 try p.err(.missing_type_specifier);
1714 }
1715 }
1716 },
1717 .void => ty.specifier = .void,
1718 .auto_type => ty.specifier = .auto_type,
1719 .c23_auto => ty.specifier = .c23_auto,
1720 .nullptr_t => unreachable, // nullptr_t can only be accessed via typeof(nullptr)
1721 .bool => ty.specifier = .bool,
1722 .char => ty.specifier = .char,
1723 .schar => ty.specifier = .schar,
1724 .uchar => ty.specifier = .uchar,
1725 .complex_char => ty.specifier = .complex_char,
1726 .complex_schar => ty.specifier = .complex_schar,
1727 .complex_uchar => ty.specifier = .complex_uchar,
1728
1729 .unsigned => ty.specifier = .uint,
1730 .signed => ty.specifier = .int,
1731 .short_int, .sshort_int, .short, .sshort => ty.specifier = .short,
1732 .ushort, .ushort_int => ty.specifier = .ushort,
1733 .int, .sint => ty.specifier = .int,
1734 .uint => ty.specifier = .uint,
1735 .long, .slong, .long_int, .slong_int => ty.specifier = .long,
1736 .ulong, .ulong_int => ty.specifier = .ulong,
1737 .long_long, .slong_long, .long_long_int, .slong_long_int => ty.specifier = .long_long,
1738 .ulong_long, .ulong_long_int => ty.specifier = .ulong_long,
1739 .int128, .sint128 => ty.specifier = .int128,
1740 .uint128 => ty.specifier = .uint128,
1741 .complex_unsigned => ty.specifier = .complex_uint,
1742 .complex_signed => ty.specifier = .complex_int,
1743 .complex_short_int, .complex_sshort_int, .complex_short, .complex_sshort => ty.specifier = .complex_short,
1744 .complex_ushort, .complex_ushort_int => ty.specifier = .complex_ushort,
1745 .complex_int, .complex_sint => ty.specifier = .complex_int,
1746 .complex_uint => ty.specifier = .complex_uint,
1747 .complex_long, .complex_slong, .complex_long_int, .complex_slong_int => ty.specifier = .complex_long,
1748 .complex_ulong, .complex_ulong_int => ty.specifier = .complex_ulong,
1749 .complex_long_long, .complex_slong_long, .complex_long_long_int, .complex_slong_long_int => ty.specifier = .complex_long_long,
1750 .complex_ulong_long, .complex_ulong_long_int => ty.specifier = .complex_ulong_long,
1751 .complex_int128, .complex_sint128 => ty.specifier = .complex_int128,
1752 .complex_uint128 => ty.specifier = .complex_uint128,
1753 .bit_int, .sbit_int, .ubit_int, .complex_bit_int, .complex_ubit_int, .complex_sbit_int => |bits| {
1754 const unsigned = b.specifier == .ubit_int or b.specifier == .complex_ubit_int;
1755 if (unsigned) {
1756 if (bits < 1) {
1757 try p.errStr(.unsigned_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
1758 return Type.invalid;
1759 }
1760 } else {
1761 if (bits < 2) {
1762 try p.errStr(.signed_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
1763 return Type.invalid;
1764 }
1765 }
1766 if (bits > Compilation.bit_int_max_bits) {
1767 try p.errStr(.bit_int_too_big, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
1768 return Type.invalid;
1769 }
1770 ty.specifier = if (b.complex_tok != null) .complex_bit_int else .bit_int;
1771 ty.data = .{ .int = .{
1772 .signedness = if (unsigned) .unsigned else .signed,
1773 .bits = @intCast(bits),
1774 } };
1775 },
1776
1777 .fp16 => ty.specifier = .fp16,
1778 .float16 => ty.specifier = .float16,
1779 .float => ty.specifier = .float,
1780 .double => ty.specifier = .double,
1781 .long_double => ty.specifier = .long_double,
1782 .float80 => ty.specifier = .float80,
1783 .float128 => ty.specifier = .float128,
1784 .complex_float => ty.specifier = .complex_float,
1785 .complex_double => ty.specifier = .complex_double,
1786 .complex_long_double => ty.specifier = .complex_long_double,
1787 .complex_float80 => ty.specifier = .complex_float80,
1788 .complex_float128 => ty.specifier = .complex_float128,
1789 .complex => {
1790 try p.errTok(.plain_complex, p.tok_i - 1);
1791 ty.specifier = .complex_double;
1792 },
1793
1794 .pointer => |data| {
1795 ty.specifier = .pointer;
1796 ty.data = .{ .sub_type = data };
1797 },
1798 .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => |data| {
1799 ty.specifier = .unspecified_variable_len_array;
1800 ty.data = .{ .sub_type = data };
1801 ty.decayed = b.specifier == .decayed_unspecified_variable_len_array;
1802 },
1803 .func => |data| {
1804 ty.specifier = .func;
1805 ty.data = .{ .func = data };
1806 },
1807 .var_args_func => |data| {
1808 ty.specifier = .var_args_func;
1809 ty.data = .{ .func = data };
1810 },
1811 .old_style_func => |data| {
1812 ty.specifier = .old_style_func;
1813 ty.data = .{ .func = data };
1814 },
1815 .array, .decayed_array => |data| {
1816 ty.specifier = .array;
1817 ty.data = .{ .array = data };
1818 ty.decayed = b.specifier == .decayed_array;
1819 },
1820 .static_array, .decayed_static_array => |data| {
1821 ty.specifier = .static_array;
1822 ty.data = .{ .array = data };
1823 ty.decayed = b.specifier == .decayed_static_array;
1824 },
1825 .incomplete_array, .decayed_incomplete_array => |data| {
1826 ty.specifier = .incomplete_array;
1827 ty.data = .{ .array = data };
1828 ty.decayed = b.specifier == .decayed_incomplete_array;
1829 },
1830 .vector => |data| {
1831 ty.specifier = .vector;
1832 ty.data = .{ .array = data };
1833 },
1834 .variable_len_array, .decayed_variable_len_array => |data| {
1835 ty.specifier = .variable_len_array;
1836 ty.data = .{ .expr = data };
1837 ty.decayed = b.specifier == .decayed_variable_len_array;
1838 },
1839 .@"struct" => |data| {
1840 ty.specifier = .@"struct";
1841 ty.data = .{ .record = data };
1842 },
1843 .@"union" => |data| {
1844 ty.specifier = .@"union";
1845 ty.data = .{ .record = data };
1846 },
1847 .@"enum" => |data| {
1848 ty.specifier = .@"enum";
1849 ty.data = .{ .@"enum" = data };
1850 },
1851 .typeof_type, .decayed_typeof_type => |data| {
1852 ty.specifier = .typeof_type;
1853 ty.data = .{ .sub_type = data };
1854 ty.decayed = b.specifier == .decayed_typeof_type;
1855 },
1856 .typeof_expr, .decayed_typeof_expr => |data| {
1857 ty.specifier = .typeof_expr;
1858 ty.data = .{ .expr = data };
1859 ty.decayed = b.specifier == .decayed_typeof_expr;
1860 },
1861 .attributed, .decayed_attributed => |data| {
1862 ty.specifier = .attributed;
1863 ty.data = .{ .attributed = data };
1864 ty.decayed = b.specifier == .decayed_attributed;
1865 },
1866 }
1867 if (!ty.isReal() and ty.isInt()) {
1868 if (b.complex_tok) |tok| try p.errTok(.complex_int, tok);
1869 }
1870 try b.qual.finish(p, &ty);
1871 return ty;
1872 }
1873
1874 fn cannotCombine(b: Builder, p: *Parser, source_tok: TokenIndex) !void {
1875 if (b.error_on_invalid) return error.CannotCombine;
1876 const ty_str = b.specifier.str(p.comp.langopts) orelse try p.typeStr(try b.finish(p));
1877 try p.errExtra(.cannot_combine_spec, source_tok, .{ .str = ty_str });
1878 if (b.typedef) |some| try p.errStr(.spec_from_typedef, some.tok, try p.typeStr(some.ty));
1879 }
1880
1881 fn duplicateSpec(b: *Builder, p: *Parser, source_tok: TokenIndex, spec: []const u8) !void {
1882 if (b.error_on_invalid) return error.CannotCombine;
1883 if (p.comp.langopts.emulate != .clang) return b.cannotCombine(p, source_tok);
1884 try p.errStr(.duplicate_decl_spec, p.tok_i, spec);
1885 }
1886
1887 pub fn combineFromTypeof(b: *Builder, p: *Parser, new: Type, source_tok: TokenIndex) Compilation.Error!void {
1888 if (b.typeof != null) return p.errStr(.cannot_combine_spec, source_tok, "typeof");
1889 if (b.specifier != .none) return p.errStr(.invalid_typeof, source_tok, @tagName(b.specifier));
1890 const inner = switch (new.specifier) {
1891 .typeof_type => new.data.sub_type.*,
1892 .typeof_expr => new.data.expr.ty,
1893 .nullptr_t => new, // typeof(nullptr) is special-cased to be an unwrapped typeof-expr
1894 else => unreachable,
1895 };
1896
1897 b.typeof = switch (inner.specifier) {
1898 .attributed => inner.data.attributed.base,
1899 else => new,
1900 };
1901 }
1902
1903 /// Try to combine type from typedef, returns true if successful.
1904 pub fn combineTypedef(b: *Builder, p: *Parser, typedef_ty: Type, name_tok: TokenIndex) bool {
1905 b.error_on_invalid = true;
1906 defer b.error_on_invalid = false;
1907
1908 const new_spec = fromType(typedef_ty);
1909 b.combineExtra(p, new_spec, 0) catch |err| switch (err) {
1910 error.FatalError => unreachable, // we do not add any diagnostics
1911 error.OutOfMemory => unreachable, // we do not add any diagnostics
1912 error.ParsingFailed => unreachable, // we do not add any diagnostics
1913 error.CannotCombine => return false,
1914 };
1915 b.typedef = .{ .tok = name_tok, .ty = typedef_ty };
1916 return true;
1917 }
1918
1919 pub fn combine(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
1920 b.combineExtra(p, new, source_tok) catch |err| switch (err) {
1921 error.CannotCombine => unreachable,
1922 else => |e| return e,
1923 };
1924 }
1925
1926 fn combineExtra(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
1927 if (b.typeof != null) {
1928 if (b.error_on_invalid) return error.CannotCombine;
1929 try p.errStr(.invalid_typeof, source_tok, @tagName(new));
1930 }
1931
1932 switch (new) {
1933 .complex => b.complex_tok = source_tok,
1934 .bit_int => b.bit_int_tok = source_tok,
1935 .auto_type => b.auto_type_tok = source_tok,
1936 else => {},
1937 }
1938
1939 if (new == .int128 and !target_util.hasInt128(p.comp.target)) {
1940 try p.errStr(.type_not_supported_on_target, source_tok, "__int128");
1941 }
1942
1943 switch (new) {
1944 else => switch (b.specifier) {
1945 .none => b.specifier = new,
1946 else => return b.cannotCombine(p, source_tok),
1947 },
1948 .signed => b.specifier = switch (b.specifier) {
1949 .none => .signed,
1950 .char => .schar,
1951 .short => .sshort,
1952 .short_int => .sshort_int,
1953 .int => .sint,
1954 .long => .slong,
1955 .long_int => .slong_int,
1956 .long_long => .slong_long,
1957 .long_long_int => .slong_long_int,
1958 .int128 => .sint128,
1959 .bit_int => |bits| .{ .sbit_int = bits },
1960 .complex => .complex_signed,
1961 .complex_char => .complex_schar,
1962 .complex_short => .complex_sshort,
1963 .complex_short_int => .complex_sshort_int,
1964 .complex_int => .complex_sint,
1965 .complex_long => .complex_slong,
1966 .complex_long_int => .complex_slong_int,
1967 .complex_long_long => .complex_slong_long,
1968 .complex_long_long_int => .complex_slong_long_int,
1969 .complex_int128 => .complex_sint128,
1970 .complex_bit_int => |bits| .{ .complex_sbit_int = bits },
1971 .signed,
1972 .sshort,
1973 .sshort_int,
1974 .sint,
1975 .slong,
1976 .slong_int,
1977 .slong_long,
1978 .slong_long_int,
1979 .sint128,
1980 .sbit_int,
1981 .complex_schar,
1982 .complex_signed,
1983 .complex_sshort,
1984 .complex_sshort_int,
1985 .complex_sint,
1986 .complex_slong,
1987 .complex_slong_int,
1988 .complex_slong_long,
1989 .complex_slong_long_int,
1990 .complex_sint128,
1991 .complex_sbit_int,
1992 => return b.duplicateSpec(p, source_tok, "signed"),
1993 else => return b.cannotCombine(p, source_tok),
1994 },
1995 .unsigned => b.specifier = switch (b.specifier) {
1996 .none => .unsigned,
1997 .char => .uchar,
1998 .short => .ushort,
1999 .short_int => .ushort_int,
2000 .int => .uint,
2001 .long => .ulong,
2002 .long_int => .ulong_int,
2003 .long_long => .ulong_long,
2004 .long_long_int => .ulong_long_int,
2005 .int128 => .uint128,
2006 .bit_int => |bits| .{ .ubit_int = bits },
2007 .complex => .complex_unsigned,
2008 .complex_char => .complex_uchar,
2009 .complex_short => .complex_ushort,
2010 .complex_short_int => .complex_ushort_int,
2011 .complex_int => .complex_uint,
2012 .complex_long => .complex_ulong,
2013 .complex_long_int => .complex_ulong_int,
2014 .complex_long_long => .complex_ulong_long,
2015 .complex_long_long_int => .complex_ulong_long_int,
2016 .complex_int128 => .complex_uint128,
2017 .complex_bit_int => |bits| .{ .complex_ubit_int = bits },
2018 .unsigned,
2019 .ushort,
2020 .ushort_int,
2021 .uint,
2022 .ulong,
2023 .ulong_int,
2024 .ulong_long,
2025 .ulong_long_int,
2026 .uint128,
2027 .ubit_int,
2028 .complex_uchar,
2029 .complex_unsigned,
2030 .complex_ushort,
2031 .complex_ushort_int,
2032 .complex_uint,
2033 .complex_ulong,
2034 .complex_ulong_int,
2035 .complex_ulong_long,
2036 .complex_ulong_long_int,
2037 .complex_uint128,
2038 .complex_ubit_int,
2039 => return b.duplicateSpec(p, source_tok, "unsigned"),
2040 else => return b.cannotCombine(p, source_tok),
2041 },
2042 .char => b.specifier = switch (b.specifier) {
2043 .none => .char,
2044 .unsigned => .uchar,
2045 .signed => .schar,
2046 .complex => .complex_char,
2047 .complex_signed => .complex_schar,
2048 .complex_unsigned => .complex_uchar,
2049 else => return b.cannotCombine(p, source_tok),
2050 },
2051 .short => b.specifier = switch (b.specifier) {
2052 .none => .short,
2053 .unsigned => .ushort,
2054 .signed => .sshort,
2055 .int => .short_int,
2056 .sint => .sshort_int,
2057 .uint => .ushort_int,
2058 .complex => .complex_short,
2059 .complex_signed => .complex_sshort,
2060 .complex_unsigned => .complex_ushort,
2061 else => return b.cannotCombine(p, source_tok),
2062 },
2063 .int => b.specifier = switch (b.specifier) {
2064 .none => .int,
2065 .signed => .sint,
2066 .unsigned => .uint,
2067 .short => .short_int,
2068 .sshort => .sshort_int,
2069 .ushort => .ushort_int,
2070 .long => .long_int,
2071 .slong => .slong_int,
2072 .ulong => .ulong_int,
2073 .long_long => .long_long_int,
2074 .slong_long => .slong_long_int,
2075 .ulong_long => .ulong_long_int,
2076 .complex => .complex_int,
2077 .complex_signed => .complex_sint,
2078 .complex_unsigned => .complex_uint,
2079 .complex_short => .complex_short_int,
2080 .complex_sshort => .complex_sshort_int,
2081 .complex_ushort => .complex_ushort_int,
2082 .complex_long => .complex_long_int,
2083 .complex_slong => .complex_slong_int,
2084 .complex_ulong => .complex_ulong_int,
2085 .complex_long_long => .complex_long_long_int,
2086 .complex_slong_long => .complex_slong_long_int,
2087 .complex_ulong_long => .complex_ulong_long_int,
2088 else => return b.cannotCombine(p, source_tok),
2089 },
2090 .long => b.specifier = switch (b.specifier) {
2091 .none => .long,
2092 .long => .long_long,
2093 .unsigned => .ulong,
2094 .signed => .long,
2095 .int => .long_int,
2096 .sint => .slong_int,
2097 .ulong => .ulong_long,
2098 .complex => .complex_long,
2099 .complex_signed => .complex_slong,
2100 .complex_unsigned => .complex_ulong,
2101 .complex_long => .complex_long_long,
2102 .complex_slong => .complex_slong_long,
2103 .complex_ulong => .complex_ulong_long,
2104 else => return b.cannotCombine(p, source_tok),
2105 },
2106 .int128 => b.specifier = switch (b.specifier) {
2107 .none => .int128,
2108 .unsigned => .uint128,
2109 .signed => .sint128,
2110 .complex => .complex_int128,
2111 .complex_signed => .complex_sint128,
2112 .complex_unsigned => .complex_uint128,
2113 else => return b.cannotCombine(p, source_tok),
2114 },
2115 .bit_int => b.specifier = switch (b.specifier) {
2116 .none => .{ .bit_int = new.bit_int },
2117 .unsigned => .{ .ubit_int = new.bit_int },
2118 .signed => .{ .sbit_int = new.bit_int },
2119 .complex => .{ .complex_bit_int = new.bit_int },
2120 .complex_signed => .{ .complex_sbit_int = new.bit_int },
2121 .complex_unsigned => .{ .complex_ubit_int = new.bit_int },
2122 else => return b.cannotCombine(p, source_tok),
2123 },
2124 .auto_type => b.specifier = switch (b.specifier) {
2125 .none => .auto_type,
2126 else => return b.cannotCombine(p, source_tok),
2127 },
2128 .c23_auto => b.specifier = switch (b.specifier) {
2129 .none => .c23_auto,
2130 else => return b.cannotCombine(p, source_tok),
2131 },
2132 .fp16 => b.specifier = switch (b.specifier) {
2133 .none => .fp16,
2134 else => return b.cannotCombine(p, source_tok),
2135 },
2136 .float16 => b.specifier = switch (b.specifier) {
2137 .none => .float16,
2138 else => return b.cannotCombine(p, source_tok),
2139 },
2140 .float => b.specifier = switch (b.specifier) {
2141 .none => .float,
2142 .complex => .complex_float,
2143 else => return b.cannotCombine(p, source_tok),
2144 },
2145 .double => b.specifier = switch (b.specifier) {
2146 .none => .double,
2147 .long => .long_double,
2148 .complex_long => .complex_long_double,
2149 .complex => .complex_double,
2150 else => return b.cannotCombine(p, source_tok),
2151 },
2152 .float80 => b.specifier = switch (b.specifier) {
2153 .none => .float80,
2154 .complex => .complex_float80,
2155 else => return b.cannotCombine(p, source_tok),
2156 },
2157 .float128 => b.specifier = switch (b.specifier) {
2158 .none => .float128,
2159 .complex => .complex_float128,
2160 else => return b.cannotCombine(p, source_tok),
2161 },
2162 .complex => b.specifier = switch (b.specifier) {
2163 .none => .complex,
2164 .float => .complex_float,
2165 .double => .complex_double,
2166 .long_double => .complex_long_double,
2167 .float80 => .complex_float80,
2168 .float128 => .complex_float128,
2169 .char => .complex_char,
2170 .schar => .complex_schar,
2171 .uchar => .complex_uchar,
2172 .unsigned => .complex_unsigned,
2173 .signed => .complex_signed,
2174 .short => .complex_short,
2175 .sshort => .complex_sshort,
2176 .ushort => .complex_ushort,
2177 .short_int => .complex_short_int,
2178 .sshort_int => .complex_sshort_int,
2179 .ushort_int => .complex_ushort_int,
2180 .int => .complex_int,
2181 .sint => .complex_sint,
2182 .uint => .complex_uint,
2183 .long => .complex_long,
2184 .slong => .complex_slong,
2185 .ulong => .complex_ulong,
2186 .long_int => .complex_long_int,
2187 .slong_int => .complex_slong_int,
2188 .ulong_int => .complex_ulong_int,
2189 .long_long => .complex_long_long,
2190 .slong_long => .complex_slong_long,
2191 .ulong_long => .complex_ulong_long,
2192 .long_long_int => .complex_long_long_int,
2193 .slong_long_int => .complex_slong_long_int,
2194 .ulong_long_int => .complex_ulong_long_int,
2195 .int128 => .complex_int128,
2196 .sint128 => .complex_sint128,
2197 .uint128 => .complex_uint128,
2198 .bit_int => |bits| .{ .complex_bit_int = bits },
2199 .sbit_int => |bits| .{ .complex_sbit_int = bits },
2200 .ubit_int => |bits| .{ .complex_ubit_int = bits },
2201 .complex,
2202 .complex_float,
2203 .complex_double,
2204 .complex_long_double,
2205 .complex_float80,
2206 .complex_float128,
2207 .complex_char,
2208 .complex_schar,
2209 .complex_uchar,
2210 .complex_unsigned,
2211 .complex_signed,
2212 .complex_short,
2213 .complex_sshort,
2214 .complex_ushort,
2215 .complex_short_int,
2216 .complex_sshort_int,
2217 .complex_ushort_int,
2218 .complex_int,
2219 .complex_sint,
2220 .complex_uint,
2221 .complex_long,
2222 .complex_slong,
2223 .complex_ulong,
2224 .complex_long_int,
2225 .complex_slong_int,
2226 .complex_ulong_int,
2227 .complex_long_long,
2228 .complex_slong_long,
2229 .complex_ulong_long,
2230 .complex_long_long_int,
2231 .complex_slong_long_int,
2232 .complex_ulong_long_int,
2233 .complex_int128,
2234 .complex_sint128,
2235 .complex_uint128,
2236 .complex_bit_int,
2237 .complex_sbit_int,
2238 .complex_ubit_int,
2239 => return b.duplicateSpec(p, source_tok, "_Complex"),
2240 else => return b.cannotCombine(p, source_tok),
2241 },
2242 }
2243 }
2244
2245 pub fn fromType(ty: Type) Builder.Specifier {
2246 return switch (ty.specifier) {
2247 .void => .void,
2248 .auto_type => .auto_type,
2249 .c23_auto => .c23_auto,
2250 .nullptr_t => .nullptr_t,
2251 .bool => .bool,
2252 .char => .char,
2253 .schar => .schar,
2254 .uchar => .uchar,
2255 .short => .short,
2256 .ushort => .ushort,
2257 .int => .int,
2258 .uint => .uint,
2259 .long => .long,
2260 .ulong => .ulong,
2261 .long_long => .long_long,
2262 .ulong_long => .ulong_long,
2263 .int128 => .int128,
2264 .uint128 => .uint128,
2265 .bit_int => if (ty.data.int.signedness == .unsigned) {
2266 return .{ .ubit_int = ty.data.int.bits };
2267 } else {
2268 return .{ .bit_int = ty.data.int.bits };
2269 },
2270 .complex_char => .complex_char,
2271 .complex_schar => .complex_schar,
2272 .complex_uchar => .complex_uchar,
2273 .complex_short => .complex_short,
2274 .complex_ushort => .complex_ushort,
2275 .complex_int => .complex_int,
2276 .complex_uint => .complex_uint,
2277 .complex_long => .complex_long,
2278 .complex_ulong => .complex_ulong,
2279 .complex_long_long => .complex_long_long,
2280 .complex_ulong_long => .complex_ulong_long,
2281 .complex_int128 => .complex_int128,
2282 .complex_uint128 => .complex_uint128,
2283 .complex_bit_int => if (ty.data.int.signedness == .unsigned) {
2284 return .{ .complex_ubit_int = ty.data.int.bits };
2285 } else {
2286 return .{ .complex_bit_int = ty.data.int.bits };
2287 },
2288 .fp16 => .fp16,
2289 .float16 => .float16,
2290 .float => .float,
2291 .double => .double,
2292 .float80 => .float80,
2293 .float128 => .float128,
2294 .long_double => .long_double,
2295 .complex_float => .complex_float,
2296 .complex_double => .complex_double,
2297 .complex_long_double => .complex_long_double,
2298 .complex_float80 => .complex_float80,
2299 .complex_float128 => .complex_float128,
2300
2301 .pointer => .{ .pointer = ty.data.sub_type },
2302 .unspecified_variable_len_array => if (ty.isDecayed())
2303 .{ .decayed_unspecified_variable_len_array = ty.data.sub_type }
2304 else
2305 .{ .unspecified_variable_len_array = ty.data.sub_type },
2306 .func => .{ .func = ty.data.func },
2307 .var_args_func => .{ .var_args_func = ty.data.func },
2308 .old_style_func => .{ .old_style_func = ty.data.func },
2309 .array => if (ty.isDecayed())
2310 .{ .decayed_array = ty.data.array }
2311 else
2312 .{ .array = ty.data.array },
2313 .static_array => if (ty.isDecayed())
2314 .{ .decayed_static_array = ty.data.array }
2315 else
2316 .{ .static_array = ty.data.array },
2317 .incomplete_array => if (ty.isDecayed())
2318 .{ .decayed_incomplete_array = ty.data.array }
2319 else
2320 .{ .incomplete_array = ty.data.array },
2321 .vector => .{ .vector = ty.data.array },
2322 .variable_len_array => if (ty.isDecayed())
2323 .{ .decayed_variable_len_array = ty.data.expr }
2324 else
2325 .{ .variable_len_array = ty.data.expr },
2326 .@"struct" => .{ .@"struct" = ty.data.record },
2327 .@"union" => .{ .@"union" = ty.data.record },
2328 .@"enum" => .{ .@"enum" = ty.data.@"enum" },
2329
2330 .typeof_type => if (ty.isDecayed())
2331 .{ .decayed_typeof_type = ty.data.sub_type }
2332 else
2333 .{ .typeof_type = ty.data.sub_type },
2334 .typeof_expr => if (ty.isDecayed())
2335 .{ .decayed_typeof_expr = ty.data.expr }
2336 else
2337 .{ .typeof_expr = ty.data.expr },
2338
2339 .attributed => if (ty.isDecayed())
2340 .{ .decayed_attributed = ty.data.attributed }
2341 else
2342 .{ .attributed = ty.data.attributed },
2343 else => unreachable,
2344 };
2345 }
2346};
2347
2348pub fn getAttribute(ty: Type, comptime tag: Attribute.Tag) ?Attribute.ArgumentsForTag(tag) {
2349 switch (ty.specifier) {
2350 .typeof_type => return ty.data.sub_type.getAttribute(tag),
2351 .typeof_expr => return ty.data.expr.ty.getAttribute(tag),
2352 .attributed => {
2353 for (ty.data.attributed.attributes) |attribute| {
2354 if (attribute.tag == tag) return @field(attribute.args, @tagName(tag));
2355 }
2356 return null;
2357 },
2358 else => return null,
2359 }
2360}
2361
2362pub fn hasAttribute(ty: Type, tag: Attribute.Tag) bool {
2363 for (ty.getAttributes()) |attr| {
2364 if (attr.tag == tag) return true;
2365 }
2366 return false;
2367}
2368
2369/// printf format modifier
2370pub fn formatModifier(ty: Type) []const u8 {
2371 return switch (ty.specifier) {
2372 .schar, .uchar => "hh",
2373 .short, .ushort => "h",
2374 .int, .uint => "",
2375 .long, .ulong => "l",
2376 .long_long, .ulong_long => "ll",
2377 else => unreachable,
2378 };
2379}
2380
2381/// Suffix for integer values of this type
2382pub fn intValueSuffix(ty: Type, comp: *const Compilation) []const u8 {
2383 return switch (ty.specifier) {
2384 .schar, .short, .int => "",
2385 .long => "L",
2386 .long_long => "LL",
2387 .uchar, .char => {
2388 if (ty.specifier == .char and comp.getCharSignedness() == .signed) return "";
2389 // Only 8-bit char supported currently;
2390 // TODO: handle platforms with 16-bit int + 16-bit char
2391 std.debug.assert(ty.sizeof(comp).? == 1);
2392 return "";
2393 },
2394 .ushort => {
2395 if (ty.sizeof(comp).? < int.sizeof(comp).?) {
2396 return "";
2397 }
2398 return "U";
2399 },
2400 .uint => "U",
2401 .ulong => "UL",
2402 .ulong_long => "ULL",
2403 else => unreachable, // not integer
2404 };
2405}
2406
2407/// Print type in C style
2408pub fn print(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2409 _ = try ty.printPrologue(mapper, langopts, w);
2410 try ty.printEpilogue(mapper, langopts, w);
2411}
2412
2413pub fn printNamed(ty: Type, name: []const u8, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2414 const simple = try ty.printPrologue(mapper, langopts, w);
2415 if (simple) try w.writeByte(' ');
2416 try w.writeAll(name);
2417 try ty.printEpilogue(mapper, langopts, w);
2418}
2419
2420const StringGetter = fn (TokenIndex) []const u8;
2421
2422/// return true if `ty` is simple
2423fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!bool {
2424 if (ty.qual.atomic) {
2425 var non_atomic_ty = ty;
2426 non_atomic_ty.qual.atomic = false;
2427 try w.writeAll("_Atomic(");
2428 try non_atomic_ty.print(mapper, langopts, w);
2429 try w.writeAll(")");
2430 return true;
2431 }
2432 if (ty.isPtr()) {
2433 const elem_ty = ty.elemType();
2434 const simple = try elem_ty.printPrologue(mapper, langopts, w);
2435 if (simple) try w.writeByte(' ');
2436 if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('(');
2437 try w.writeByte('*');
2438 try ty.qual.dump(w);
2439 return false;
2440 }
2441 switch (ty.specifier) {
2442 .pointer => unreachable,
2443 .func, .var_args_func, .old_style_func => {
2444 const ret_ty = ty.data.func.return_type;
2445 const simple = try ret_ty.printPrologue(mapper, langopts, w);
2446 if (simple) try w.writeByte(' ');
2447 return false;
2448 },
2449 .array, .static_array, .incomplete_array, .unspecified_variable_len_array, .variable_len_array => {
2450 const elem_ty = ty.elemType();
2451 const simple = try elem_ty.printPrologue(mapper, langopts, w);
2452 if (simple) try w.writeByte(' ');
2453 return false;
2454 },
2455 .typeof_type, .typeof_expr => {
2456 const actual = ty.canonicalize(.standard);
2457 return actual.printPrologue(mapper, langopts, w);
2458 },
2459 .attributed => {
2460 const actual = ty.canonicalize(.standard);
2461 return actual.printPrologue(mapper, langopts, w);
2462 },
2463 else => {},
2464 }
2465 try ty.qual.dump(w);
2466
2467 switch (ty.specifier) {
2468 .@"enum" => if (ty.data.@"enum".fixed) {
2469 try w.print("enum {s}: ", .{mapper.lookup(ty.data.@"enum".name)});
2470 try ty.data.@"enum".tag_ty.dump(mapper, langopts, w);
2471 } else {
2472 try w.print("enum {s}", .{mapper.lookup(ty.data.@"enum".name)});
2473 },
2474 .@"struct" => try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)}),
2475 .@"union" => try w.print("union {s}", .{mapper.lookup(ty.data.record.name)}),
2476 .vector => {
2477 const len = ty.data.array.len;
2478 const elem_ty = ty.data.array.elem;
2479 try w.print("__attribute__((__vector_size__({d} * sizeof(", .{len});
2480 _ = try elem_ty.printPrologue(mapper, langopts, w);
2481 try w.writeAll(")))) ");
2482 _ = try elem_ty.printPrologue(mapper, langopts, w);
2483 try w.print(" (vector of {d} '", .{len});
2484 _ = try elem_ty.printPrologue(mapper, langopts, w);
2485 try w.writeAll("' values)");
2486 },
2487 else => try w.writeAll(Builder.fromType(ty).str(langopts).?),
2488 }
2489 return true;
2490}
2491
2492fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2493 if (ty.qual.atomic) return;
2494 if (ty.isPtr()) {
2495 const elem_ty = ty.elemType();
2496 if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')');
2497 try elem_ty.printEpilogue(mapper, langopts, w);
2498 return;
2499 }
2500 switch (ty.specifier) {
2501 .pointer => unreachable, // handled above
2502 .func, .var_args_func, .old_style_func => {
2503 try w.writeByte('(');
2504 for (ty.data.func.params, 0..) |param, i| {
2505 if (i != 0) try w.writeAll(", ");
2506 _ = try param.ty.printPrologue(mapper, langopts, w);
2507 try param.ty.printEpilogue(mapper, langopts, w);
2508 }
2509 if (ty.specifier != .func) {
2510 if (ty.data.func.params.len != 0) try w.writeAll(", ");
2511 try w.writeAll("...");
2512 } else if (ty.data.func.params.len == 0) {
2513 try w.writeAll("void");
2514 }
2515 try w.writeByte(')');
2516 try ty.data.func.return_type.printEpilogue(mapper, langopts, w);
2517 },
2518 .array, .static_array => {
2519 try w.writeByte('[');
2520 if (ty.specifier == .static_array) try w.writeAll("static ");
2521 try ty.qual.dump(w);
2522 try w.print("{d}]", .{ty.data.array.len});
2523 try ty.data.array.elem.printEpilogue(mapper, langopts, w);
2524 },
2525 .incomplete_array => {
2526 try w.writeByte('[');
2527 try ty.qual.dump(w);
2528 try w.writeByte(']');
2529 try ty.data.array.elem.printEpilogue(mapper, langopts, w);
2530 },
2531 .unspecified_variable_len_array => {
2532 try w.writeByte('[');
2533 try ty.qual.dump(w);
2534 try w.writeAll("*]");
2535 try ty.data.sub_type.printEpilogue(mapper, langopts, w);
2536 },
2537 .variable_len_array => {
2538 try w.writeByte('[');
2539 try ty.qual.dump(w);
2540 try w.writeAll("<expr>]");
2541 try ty.data.expr.ty.printEpilogue(mapper, langopts, w);
2542 },
2543 .typeof_type, .typeof_expr => {
2544 const actual = ty.canonicalize(.standard);
2545 try actual.printEpilogue(mapper, langopts, w);
2546 },
2547 .attributed => {
2548 const actual = ty.canonicalize(.standard);
2549 try actual.printEpilogue(mapper, langopts, w);
2550 },
2551 else => {},
2552 }
2553}
2554
2555/// Useful for debugging, too noisy to be enabled by default.
2556const dump_detailed_containers = false;
2557
2558// Print as Zig types since those are actually readable
2559pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2560 try ty.qual.dump(w);
2561 switch (ty.specifier) {
2562 .invalid => try w.writeAll("invalid"),
2563 .pointer => {
2564 try w.writeAll("*");
2565 try ty.data.sub_type.dump(mapper, langopts, w);
2566 },
2567 .func, .var_args_func, .old_style_func => {
2568 if (ty.specifier == .old_style_func)
2569 try w.writeAll("kr (")
2570 else
2571 try w.writeAll("fn (");
2572 for (ty.data.func.params, 0..) |param, i| {
2573 if (i != 0) try w.writeAll(", ");
2574 if (param.name != .empty) try w.print("{s}: ", .{mapper.lookup(param.name)});
2575 try param.ty.dump(mapper, langopts, w);
2576 }
2577 if (ty.specifier != .func) {
2578 if (ty.data.func.params.len != 0) try w.writeAll(", ");
2579 try w.writeAll("...");
2580 }
2581 try w.writeAll(") ");
2582 try ty.data.func.return_type.dump(mapper, langopts, w);
2583 },
2584 .array, .static_array => {
2585 if (ty.isDecayed()) try w.writeAll("*d");
2586 try w.writeByte('[');
2587 if (ty.specifier == .static_array) try w.writeAll("static ");
2588 try w.print("{d}]", .{ty.data.array.len});
2589 try ty.data.array.elem.dump(mapper, langopts, w);
2590 },
2591 .vector => {
2592 try w.print("vector({d}, ", .{ty.data.array.len});
2593 try ty.data.array.elem.dump(mapper, langopts, w);
2594 try w.writeAll(")");
2595 },
2596 .incomplete_array => {
2597 if (ty.isDecayed()) try w.writeAll("*d");
2598 try w.writeAll("[]");
2599 try ty.data.array.elem.dump(mapper, langopts, w);
2600 },
2601 .@"enum" => {
2602 const enum_ty = ty.data.@"enum";
2603 if (enum_ty.isIncomplete() and !enum_ty.fixed) {
2604 try w.print("enum {s}", .{mapper.lookup(enum_ty.name)});
2605 } else {
2606 try w.print("enum {s}: ", .{mapper.lookup(enum_ty.name)});
2607 try enum_ty.tag_ty.dump(mapper, langopts, w);
2608 }
2609 if (dump_detailed_containers) try dumpEnum(enum_ty, mapper, w);
2610 },
2611 .@"struct" => {
2612 try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)});
2613 if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
2614 },
2615 .@"union" => {
2616 try w.print("union {s}", .{mapper.lookup(ty.data.record.name)});
2617 if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
2618 },
2619 .unspecified_variable_len_array => {
2620 if (ty.isDecayed()) try w.writeAll("*d");
2621 try w.writeAll("[*]");
2622 try ty.data.sub_type.dump(mapper, langopts, w);
2623 },
2624 .variable_len_array => {
2625 if (ty.isDecayed()) try w.writeAll("*d");
2626 try w.writeAll("[<expr>]");
2627 try ty.data.expr.ty.dump(mapper, langopts, w);
2628 },
2629 .typeof_type => {
2630 try w.writeAll("typeof(");
2631 try ty.data.sub_type.dump(mapper, langopts, w);
2632 try w.writeAll(")");
2633 },
2634 .typeof_expr => {
2635 try w.writeAll("typeof(<expr>: ");
2636 try ty.data.expr.ty.dump(mapper, langopts, w);
2637 try w.writeAll(")");
2638 },
2639 .attributed => {
2640 if (ty.isDecayed()) try w.writeAll("*d:");
2641 try w.writeAll("attributed(");
2642 try ty.data.attributed.base.dump(mapper, langopts, w);
2643 try w.writeAll(")");
2644 },
2645 else => {
2646 try w.writeAll(Builder.fromType(ty).str(langopts).?);
2647 if (ty.specifier == .bit_int or ty.specifier == .complex_bit_int) {
2648 try w.print("({d})", .{ty.data.int.bits});
2649 }
2650 },
2651 }
2652}
2653
2654fn dumpEnum(@"enum": *Enum, mapper: StringInterner.TypeMapper, w: anytype) @TypeOf(w).Error!void {
2655 try w.writeAll(" {");
2656 for (@"enum".fields) |field| {
2657 try w.print(" {s} = {d},", .{ mapper.lookup(field.name), field.value });
2658 }
2659 try w.writeAll(" }");
2660}
2661
2662fn dumpRecord(record: *Record, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2663 try w.writeAll(" {");
2664 for (record.fields) |field| {
2665 try w.writeByte(' ');
2666 try field.ty.dump(mapper, langopts, w);
2667 try w.print(" {s}: {d};", .{ mapper.lookup(field.name), field.bit_width });
2668 }
2669 try w.writeAll(" }");
2670}
deps/aro/aro/Value.zig deleted-726
......@@ -1,726 +0,0 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const BigIntConst = std.math.big.int.Const;
4const BigIntMutable = std.math.big.int.Mutable;
5const backend = @import("backend");
6const Interner = backend.Interner;
7const BigIntSpace = Interner.Tag.Int.BigIntSpace;
8const Compilation = @import("Compilation.zig");
9const Type = @import("Type.zig");
10const target_util = @import("target.zig");
11
12const Value = @This();
13
14opt_ref: Interner.OptRef = .none,
15
16pub const zero = Value{ .opt_ref = .zero };
17pub const one = Value{ .opt_ref = .one };
18pub const @"null" = Value{ .opt_ref = .null };
19
20pub fn intern(comp: *Compilation, k: Interner.Key) !Value {
21 const r = try comp.interner.put(comp.gpa, k);
22 return .{ .opt_ref = @enumFromInt(@intFromEnum(r)) };
23}
24
25pub fn int(i: anytype, comp: *Compilation) !Value {
26 const info = @typeInfo(@TypeOf(i));
27 if (info == .ComptimeInt or info.Int.signedness == .unsigned) {
28 return intern(comp, .{ .int = .{ .u64 = i } });
29 } else {
30 return intern(comp, .{ .int = .{ .i64 = i } });
31 }
32}
33
34pub fn ref(v: Value) Interner.Ref {
35 std.debug.assert(v.opt_ref != .none);
36 return @enumFromInt(@intFromEnum(v.opt_ref));
37}
38
39pub fn is(v: Value, tag: std.meta.Tag(Interner.Key), comp: *const Compilation) bool {
40 if (v.opt_ref == .none) return false;
41 return comp.interner.get(v.ref()) == tag;
42}
43
44/// Number of bits needed to hold `v`.
45/// Asserts that `v` is not negative
46pub fn minUnsignedBits(v: Value, comp: *const Compilation) usize {
47 var space: BigIntSpace = undefined;
48 const big = v.toBigInt(&space, comp);
49 assert(big.positive);
50 return big.bitCountAbs();
51}
52
53test "minUnsignedBits" {
54 const Test = struct {
55 fn checkIntBits(comp: *Compilation, v: u64, expected: usize) !void {
56 const val = try intern(comp, .{ .int = .{ .u64 = v } });
57 try std.testing.expectEqual(expected, val.minUnsignedBits(comp));
58 }
59 };
60
61 var comp = Compilation.init(std.testing.allocator);
62 defer comp.deinit();
63 comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
64
65 try Test.checkIntBits(&comp, 0, 0);
66 try Test.checkIntBits(&comp, 1, 1);
67 try Test.checkIntBits(&comp, 2, 2);
68 try Test.checkIntBits(&comp, std.math.maxInt(i8), 7);
69 try Test.checkIntBits(&comp, std.math.maxInt(u8), 8);
70 try Test.checkIntBits(&comp, std.math.maxInt(i16), 15);
71 try Test.checkIntBits(&comp, std.math.maxInt(u16), 16);
72 try Test.checkIntBits(&comp, std.math.maxInt(i32), 31);
73 try Test.checkIntBits(&comp, std.math.maxInt(u32), 32);
74 try Test.checkIntBits(&comp, std.math.maxInt(i64), 63);
75 try Test.checkIntBits(&comp, std.math.maxInt(u64), 64);
76}
77
78/// Minimum number of bits needed to represent `v` in 2's complement notation
79/// Asserts that `v` is negative.
80pub fn minSignedBits(v: Value, comp: *const Compilation) usize {
81 var space: BigIntSpace = undefined;
82 const big = v.toBigInt(&space, comp);
83 assert(!big.positive);
84 return big.bitCountTwosComp();
85}
86
87test "minSignedBits" {
88 const Test = struct {
89 fn checkIntBits(comp: *Compilation, v: i64, expected: usize) !void {
90 const val = try intern(comp, .{ .int = .{ .i64 = v } });
91 try std.testing.expectEqual(expected, val.minSignedBits(comp));
92 }
93 };
94
95 var comp = Compilation.init(std.testing.allocator);
96 defer comp.deinit();
97 comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
98
99 try Test.checkIntBits(&comp, -1, 1);
100 try Test.checkIntBits(&comp, -2, 2);
101 try Test.checkIntBits(&comp, -10, 5);
102 try Test.checkIntBits(&comp, -101, 8);
103 try Test.checkIntBits(&comp, std.math.minInt(i8), 8);
104 try Test.checkIntBits(&comp, std.math.minInt(i16), 16);
105 try Test.checkIntBits(&comp, std.math.minInt(i32), 32);
106 try Test.checkIntBits(&comp, std.math.minInt(i64), 64);
107}
108
109pub const FloatToIntChangeKind = enum {
110 /// value did not change
111 none,
112 /// floating point number too small or large for destination integer type
113 out_of_range,
114 /// tried to convert a NaN or Infinity
115 overflow,
116 /// fractional value was converted to zero
117 nonzero_to_zero,
118 /// fractional part truncated
119 value_changed,
120};
121
122/// Converts the stored value from a float to an integer.
123/// `.none` value remains unchanged.
124pub fn floatToInt(v: *Value, dest_ty: Type, comp: *Compilation) !FloatToIntChangeKind {
125 if (v.opt_ref == .none) return .none;
126
127 const float_val = v.toFloat(f128, comp);
128 const was_zero = float_val == 0;
129
130 if (dest_ty.is(.bool)) {
131 const was_one = float_val == 1.0;
132 v.* = fromBool(!was_zero);
133 if (was_zero or was_one) return .none;
134 return .value_changed;
135 } else if (dest_ty.isUnsignedInt(comp) and v.compare(.lt, zero, comp)) {
136 v.* = zero;
137 return .out_of_range;
138 }
139
140 const had_fraction = @rem(float_val, 1) != 0;
141 const is_negative = std.math.signbit(float_val);
142 const floored = @floor(@abs(float_val));
143
144 var rational = try std.math.big.Rational.init(comp.gpa);
145 defer rational.deinit();
146 rational.setFloat(f128, floored) catch |err| switch (err) {
147 error.NonFiniteFloat => {
148 v.* = .{};
149 return .overflow;
150 },
151 error.OutOfMemory => return error.OutOfMemory,
152 };
153
154 // The float is reduced in rational.setFloat, so we assert that denominator is equal to one
155 const big_one = std.math.big.int.Const{ .limbs = &.{1}, .positive = true };
156 assert(rational.q.toConst().eqlAbs(big_one));
157
158 if (is_negative) {
159 rational.negate();
160 }
161
162 const signedness = dest_ty.signedness(comp);
163 const bits: usize = @intCast(dest_ty.bitSizeof(comp).?);
164
165 // rational.p.truncate(rational.p.toConst(), signedness: Signedness, bit_count: usize)
166 const fits = rational.p.fitsInTwosComp(signedness, bits);
167 v.* = try intern(comp, .{ .int = .{ .big_int = rational.p.toConst() } });
168 try rational.p.truncate(&rational.p, signedness, bits);
169
170 if (!was_zero and v.isZero(comp)) return .nonzero_to_zero;
171 if (!fits) return .out_of_range;
172 if (had_fraction) return .value_changed;
173 return .none;
174}
175
176/// Converts the stored value from an integer to a float.
177/// `.none` value remains unchanged.
178pub fn intToFloat(v: *Value, dest_ty: Type, comp: *Compilation) !void {
179 if (v.opt_ref == .none) return;
180 const bits = dest_ty.bitSizeof(comp).?;
181 return switch (comp.interner.get(v.ref()).int) {
182 inline .u64, .i64 => |data| {
183 const f: Interner.Key.Float = switch (bits) {
184 16 => .{ .f16 = @floatFromInt(data) },
185 32 => .{ .f32 = @floatFromInt(data) },
186 64 => .{ .f64 = @floatFromInt(data) },
187 80 => .{ .f80 = @floatFromInt(data) },
188 128 => .{ .f128 = @floatFromInt(data) },
189 else => unreachable,
190 };
191 v.* = try intern(comp, .{ .float = f });
192 },
193 .big_int => |data| {
194 const big_f = bigIntToFloat(data.limbs, data.positive);
195 const f: Interner.Key.Float = switch (bits) {
196 16 => .{ .f16 = @floatCast(big_f) },
197 32 => .{ .f32 = @floatCast(big_f) },
198 64 => .{ .f64 = @floatCast(big_f) },
199 80 => .{ .f80 = @floatCast(big_f) },
200 128 => .{ .f128 = @floatCast(big_f) },
201 else => unreachable,
202 };
203 v.* = try intern(comp, .{ .float = f });
204 },
205 };
206}
207
208/// Truncates or extends bits based on type.
209/// `.none` value remains unchanged.
210pub fn intCast(v: *Value, dest_ty: Type, comp: *Compilation) !void {
211 if (v.opt_ref == .none) return;
212 const bits: usize = @intCast(dest_ty.bitSizeof(comp).?);
213 var space: BigIntSpace = undefined;
214 const big = v.toBigInt(&space, comp);
215
216 const limbs = try comp.gpa.alloc(
217 std.math.big.Limb,
218 std.math.big.int.calcTwosCompLimbCount(@max(big.bitCountTwosComp(), bits)),
219 );
220 defer comp.gpa.free(limbs);
221 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
222 result_bigint.truncate(big, dest_ty.signedness(comp), bits);
223
224 v.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
225}
226
227/// Converts the stored value from an integer to a float.
228/// `.none` value remains unchanged.
229pub fn floatCast(v: *Value, dest_ty: Type, comp: *Compilation) !void {
230 if (v.opt_ref == .none) return;
231 // TODO complex values
232 const bits = dest_ty.makeReal().bitSizeof(comp).?;
233 const f: Interner.Key.Float = switch (bits) {
234 16 => .{ .f16 = v.toFloat(f16, comp) },
235 32 => .{ .f32 = v.toFloat(f32, comp) },
236 64 => .{ .f64 = v.toFloat(f64, comp) },
237 80 => .{ .f80 = v.toFloat(f80, comp) },
238 128 => .{ .f128 = v.toFloat(f128, comp) },
239 else => unreachable,
240 };
241 v.* = try intern(comp, .{ .float = f });
242}
243
244pub fn toFloat(v: Value, comptime T: type, comp: *const Compilation) T {
245 return switch (comp.interner.get(v.ref())) {
246 .int => |repr| switch (repr) {
247 inline .u64, .i64 => |data| @floatFromInt(data),
248 .big_int => |data| @floatCast(bigIntToFloat(data.limbs, data.positive)),
249 },
250 .float => |repr| switch (repr) {
251 inline else => |data| @floatCast(data),
252 },
253 else => unreachable,
254 };
255}
256
257fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 {
258 if (limbs.len == 0) return 0;
259
260 const base = std.math.maxInt(std.math.big.Limb) + 1;
261 var result: f128 = 0;
262 var i: usize = limbs.len;
263 while (i != 0) {
264 i -= 1;
265 const limb: f128 = @as(f128, @floatFromInt(limbs[i]));
266 result = @mulAdd(f128, base, result, limb);
267 }
268 if (positive) {
269 return result;
270 } else {
271 return -result;
272 }
273}
274
275pub fn toBigInt(val: Value, space: *BigIntSpace, comp: *const Compilation) BigIntConst {
276 return switch (comp.interner.get(val.ref()).int) {
277 inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(),
278 .big_int => |b| b,
279 };
280}
281
282pub fn isZero(v: Value, comp: *const Compilation) bool {
283 if (v.opt_ref == .none) return false;
284 switch (v.ref()) {
285 .zero => return true,
286 .one => return false,
287 .null => return target_util.nullRepr(comp.target) == 0,
288 else => {},
289 }
290 const key = comp.interner.get(v.ref());
291 switch (key) {
292 .float => |repr| switch (repr) {
293 inline else => |data| return data == 0,
294 },
295 .int => |repr| switch (repr) {
296 inline .i64, .u64 => |data| return data == 0,
297 .big_int => |data| return data.eqlZero(),
298 },
299 .bytes => return false,
300 else => unreachable,
301 }
302}
303
304/// Converts value to zero or one;
305/// `.none` value remains unchanged.
306pub fn boolCast(v: *Value, comp: *const Compilation) void {
307 if (v.opt_ref == .none) return;
308 v.* = fromBool(v.toBool(comp));
309}
310
311pub fn fromBool(b: bool) Value {
312 return if (b) one else zero;
313}
314
315pub fn toBool(v: Value, comp: *const Compilation) bool {
316 return !v.isZero(comp);
317}
318
319pub fn toInt(v: Value, comptime T: type, comp: *const Compilation) ?T {
320 if (v.opt_ref == .none) return null;
321 if (comp.interner.get(v.ref()) != .int) return null;
322 var space: BigIntSpace = undefined;
323 const big_int = v.toBigInt(&space, comp);
324 return big_int.to(T) catch null;
325}
326
327pub fn add(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
328 const bits: usize = @intCast(ty.bitSizeof(comp).?);
329 if (ty.isFloat()) {
330 const f: Interner.Key.Float = switch (bits) {
331 16 => .{ .f16 = lhs.toFloat(f16, comp) + rhs.toFloat(f16, comp) },
332 32 => .{ .f32 = lhs.toFloat(f32, comp) + rhs.toFloat(f32, comp) },
333 64 => .{ .f64 = lhs.toFloat(f64, comp) + rhs.toFloat(f64, comp) },
334 80 => .{ .f80 = lhs.toFloat(f80, comp) + rhs.toFloat(f80, comp) },
335 128 => .{ .f128 = lhs.toFloat(f128, comp) + rhs.toFloat(f128, comp) },
336 else => unreachable,
337 };
338 res.* = try intern(comp, .{ .float = f });
339 return false;
340 } else {
341 var lhs_space: BigIntSpace = undefined;
342 var rhs_space: BigIntSpace = undefined;
343 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
344 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
345
346 const limbs = try comp.gpa.alloc(
347 std.math.big.Limb,
348 std.math.big.int.calcTwosCompLimbCount(bits),
349 );
350 defer comp.gpa.free(limbs);
351 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
352
353 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, ty.signedness(comp), bits);
354 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
355 return overflowed;
356 }
357}
358
359pub fn sub(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
360 const bits: usize = @intCast(ty.bitSizeof(comp).?);
361 if (ty.isFloat()) {
362 const f: Interner.Key.Float = switch (bits) {
363 16 => .{ .f16 = lhs.toFloat(f16, comp) - rhs.toFloat(f16, comp) },
364 32 => .{ .f32 = lhs.toFloat(f32, comp) - rhs.toFloat(f32, comp) },
365 64 => .{ .f64 = lhs.toFloat(f64, comp) - rhs.toFloat(f64, comp) },
366 80 => .{ .f80 = lhs.toFloat(f80, comp) - rhs.toFloat(f80, comp) },
367 128 => .{ .f128 = lhs.toFloat(f128, comp) - rhs.toFloat(f128, comp) },
368 else => unreachable,
369 };
370 res.* = try intern(comp, .{ .float = f });
371 return false;
372 } else {
373 var lhs_space: BigIntSpace = undefined;
374 var rhs_space: BigIntSpace = undefined;
375 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
376 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
377
378 const limbs = try comp.gpa.alloc(
379 std.math.big.Limb,
380 std.math.big.int.calcTwosCompLimbCount(bits),
381 );
382 defer comp.gpa.free(limbs);
383 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
384
385 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, ty.signedness(comp), bits);
386 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
387 return overflowed;
388 }
389}
390
391pub fn mul(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
392 const bits: usize = @intCast(ty.bitSizeof(comp).?);
393 if (ty.isFloat()) {
394 const f: Interner.Key.Float = switch (bits) {
395 16 => .{ .f16 = lhs.toFloat(f16, comp) * rhs.toFloat(f16, comp) },
396 32 => .{ .f32 = lhs.toFloat(f32, comp) * rhs.toFloat(f32, comp) },
397 64 => .{ .f64 = lhs.toFloat(f64, comp) * rhs.toFloat(f64, comp) },
398 80 => .{ .f80 = lhs.toFloat(f80, comp) * rhs.toFloat(f80, comp) },
399 128 => .{ .f128 = lhs.toFloat(f128, comp) * rhs.toFloat(f128, comp) },
400 else => unreachable,
401 };
402 res.* = try intern(comp, .{ .float = f });
403 return false;
404 } else {
405 var lhs_space: BigIntSpace = undefined;
406 var rhs_space: BigIntSpace = undefined;
407 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
408 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
409
410 const limbs = try comp.gpa.alloc(
411 std.math.big.Limb,
412 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
413 );
414 defer comp.gpa.free(limbs);
415 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
416
417 const limbs_buffer = try comp.gpa.alloc(
418 std.math.big.Limb,
419 std.math.big.int.calcMulLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len, 1),
420 );
421 defer comp.gpa.free(limbs_buffer);
422
423 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, comp.gpa);
424
425 const signedness = ty.signedness(comp);
426 const overflowed = !result_bigint.toConst().fitsInTwosComp(signedness, bits);
427 if (overflowed) {
428 result_bigint.truncate(result_bigint.toConst(), signedness, bits);
429 }
430 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
431 return overflowed;
432 }
433}
434
435/// caller guarantees rhs != 0
436pub fn div(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
437 const bits: usize = @intCast(ty.bitSizeof(comp).?);
438 if (ty.isFloat()) {
439 const f: Interner.Key.Float = switch (bits) {
440 16 => .{ .f16 = lhs.toFloat(f16, comp) / rhs.toFloat(f16, comp) },
441 32 => .{ .f32 = lhs.toFloat(f32, comp) / rhs.toFloat(f32, comp) },
442 64 => .{ .f64 = lhs.toFloat(f64, comp) / rhs.toFloat(f64, comp) },
443 80 => .{ .f80 = lhs.toFloat(f80, comp) / rhs.toFloat(f80, comp) },
444 128 => .{ .f128 = lhs.toFloat(f128, comp) / rhs.toFloat(f128, comp) },
445 else => unreachable,
446 };
447 res.* = try intern(comp, .{ .float = f });
448 return false;
449 } else {
450 var lhs_space: BigIntSpace = undefined;
451 var rhs_space: BigIntSpace = undefined;
452 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
453 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
454
455 const limbs_q = try comp.gpa.alloc(
456 std.math.big.Limb,
457 lhs_bigint.limbs.len,
458 );
459 defer comp.gpa.free(limbs_q);
460 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
461
462 const limbs_r = try comp.gpa.alloc(
463 std.math.big.Limb,
464 rhs_bigint.limbs.len,
465 );
466 defer comp.gpa.free(limbs_r);
467 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
468
469 const limbs_buffer = try comp.gpa.alloc(
470 std.math.big.Limb,
471 std.math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
472 );
473 defer comp.gpa.free(limbs_buffer);
474
475 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
476
477 res.* = try intern(comp, .{ .int = .{ .big_int = result_q.toConst() } });
478 return !result_q.toConst().fitsInTwosComp(ty.signedness(comp), bits);
479 }
480}
481
482/// caller guarantees rhs != 0
483/// caller guarantees lhs != std.math.minInt(T) OR rhs != -1
484pub fn rem(lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !Value {
485 var lhs_space: BigIntSpace = undefined;
486 var rhs_space: BigIntSpace = undefined;
487 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
488 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
489
490 const signedness = ty.signedness(comp);
491 if (signedness == .signed) {
492 var spaces: [3]BigIntSpace = undefined;
493 const min_val = BigIntMutable.init(&spaces[0].limbs, ty.minInt(comp)).toConst();
494 const negative = BigIntMutable.init(&spaces[1].limbs, -1).toConst();
495 const big_one = BigIntMutable.init(&spaces[2].limbs, 1).toConst();
496 if (lhs_bigint.eql(min_val) and rhs_bigint.eql(negative)) {
497 return .{};
498 } else if (rhs_bigint.order(big_one).compare(.lt)) {
499 // lhs - @divTrunc(lhs, rhs) * rhs
500 var tmp: Value = undefined;
501 _ = try tmp.div(lhs, rhs, ty, comp);
502 _ = try tmp.mul(tmp, rhs, ty, comp);
503 _ = try tmp.sub(lhs, tmp, ty, comp);
504 return tmp;
505 }
506 }
507
508 const limbs_q = try comp.gpa.alloc(
509 std.math.big.Limb,
510 lhs_bigint.limbs.len,
511 );
512 defer comp.gpa.free(limbs_q);
513 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
514
515 const limbs_r = try comp.gpa.alloc(
516 std.math.big.Limb,
517 rhs_bigint.limbs.len,
518 );
519 defer comp.gpa.free(limbs_r);
520 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
521
522 const limbs_buffer = try comp.gpa.alloc(
523 std.math.big.Limb,
524 std.math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
525 );
526 defer comp.gpa.free(limbs_buffer);
527
528 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
529 return intern(comp, .{ .int = .{ .big_int = result_r.toConst() } });
530}
531
532pub fn bitOr(lhs: Value, rhs: Value, comp: *Compilation) !Value {
533 var lhs_space: BigIntSpace = undefined;
534 var rhs_space: BigIntSpace = undefined;
535 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
536 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
537
538 const limbs = try comp.gpa.alloc(
539 std.math.big.Limb,
540 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
541 );
542 defer comp.gpa.free(limbs);
543 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
544
545 result_bigint.bitOr(lhs_bigint, rhs_bigint);
546 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
547}
548
549pub fn bitXor(lhs: Value, rhs: Value, comp: *Compilation) !Value {
550 var lhs_space: BigIntSpace = undefined;
551 var rhs_space: BigIntSpace = undefined;
552 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
553 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
554
555 const limbs = try comp.gpa.alloc(
556 std.math.big.Limb,
557 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
558 );
559 defer comp.gpa.free(limbs);
560 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
561
562 result_bigint.bitXor(lhs_bigint, rhs_bigint);
563 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
564}
565
566pub fn bitAnd(lhs: Value, rhs: Value, comp: *Compilation) !Value {
567 var lhs_space: BigIntSpace = undefined;
568 var rhs_space: BigIntSpace = undefined;
569 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
570 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
571
572 const limbs = try comp.gpa.alloc(
573 std.math.big.Limb,
574 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
575 );
576 defer comp.gpa.free(limbs);
577 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
578
579 result_bigint.bitAnd(lhs_bigint, rhs_bigint);
580 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
581}
582
583pub fn bitNot(val: Value, ty: Type, comp: *Compilation) !Value {
584 const bits: usize = @intCast(ty.bitSizeof(comp).?);
585 var val_space: Value.BigIntSpace = undefined;
586 const val_bigint = val.toBigInt(&val_space, comp);
587
588 const limbs = try comp.gpa.alloc(
589 std.math.big.Limb,
590 std.math.big.int.calcTwosCompLimbCount(bits),
591 );
592 defer comp.gpa.free(limbs);
593 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
594
595 result_bigint.bitNotWrap(val_bigint, ty.signedness(comp), bits);
596 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
597}
598
599pub fn shl(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
600 var lhs_space: Value.BigIntSpace = undefined;
601 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
602 const shift = rhs.toInt(usize, comp) orelse std.math.maxInt(usize);
603
604 const bits: usize = @intCast(ty.bitSizeof(comp).?);
605 if (shift > bits) {
606 if (lhs_bigint.positive) {
607 res.* = try intern(comp, .{ .int = .{ .u64 = ty.maxInt(comp) } });
608 } else {
609 res.* = try intern(comp, .{ .int = .{ .i64 = ty.minInt(comp) } });
610 }
611 return true;
612 }
613
614 const limbs = try comp.gpa.alloc(
615 std.math.big.Limb,
616 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
617 );
618 defer comp.gpa.free(limbs);
619 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
620
621 result_bigint.shiftLeft(lhs_bigint, shift);
622 const signedness = ty.signedness(comp);
623 const overflowed = !result_bigint.toConst().fitsInTwosComp(signedness, bits);
624 if (overflowed) {
625 result_bigint.truncate(result_bigint.toConst(), signedness, bits);
626 }
627 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
628 return overflowed;
629}
630
631pub fn shr(lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !Value {
632 var lhs_space: Value.BigIntSpace = undefined;
633 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
634 const shift = rhs.toInt(usize, comp) orelse return zero;
635
636 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
637 if (result_limbs == 0) {
638 // The shift is enough to remove all the bits from the number, which means the
639 // result is 0 or -1 depending on the sign.
640 if (lhs_bigint.positive) {
641 return zero;
642 } else {
643 return intern(comp, .{ .int = .{ .i64 = -1 } });
644 }
645 }
646
647 const bits: usize = @intCast(ty.bitSizeof(comp).?);
648 const limbs = try comp.gpa.alloc(
649 std.math.big.Limb,
650 std.math.big.int.calcTwosCompLimbCount(bits),
651 );
652 defer comp.gpa.free(limbs);
653 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
654
655 result_bigint.shiftRight(lhs_bigint, shift);
656 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
657}
658
659pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, comp: *const Compilation) bool {
660 if (op == .eq) {
661 return lhs.opt_ref == rhs.opt_ref;
662 } else if (lhs.opt_ref == rhs.opt_ref) {
663 return std.math.Order.eq.compare(op);
664 }
665
666 const lhs_key = comp.interner.get(lhs.ref());
667 const rhs_key = comp.interner.get(rhs.ref());
668 if (lhs_key == .float or rhs_key == .float) {
669 const lhs_f128 = lhs.toFloat(f128, comp);
670 const rhs_f128 = rhs.toFloat(f128, comp);
671 return std.math.compare(lhs_f128, op, rhs_f128);
672 }
673
674 var lhs_bigint_space: BigIntSpace = undefined;
675 var rhs_bigint_space: BigIntSpace = undefined;
676 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space, comp);
677 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, comp);
678 return lhs_bigint.order(rhs_bigint).compare(op);
679}
680
681pub fn print(v: Value, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w).Error!void {
682 if (ty.is(.bool)) {
683 return w.writeAll(if (v.isZero(comp)) "false" else "true");
684 }
685 const key = comp.interner.get(v.ref());
686 switch (key) {
687 .null => return w.writeAll("nullptr_t"),
688 .int => |repr| switch (repr) {
689 inline else => |x| return w.print("{d}", .{x}),
690 },
691 .float => |repr| switch (repr) {
692 .f16 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000) / 1000}),
693 .f32 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000000) / 1000000}),
694 inline else => |x| return w.print("{d}", .{@as(f64, @floatCast(x))}),
695 },
696 .bytes => |b| return printString(b, ty, comp, w),
697 else => unreachable, // not a value
698 }
699}
700
701pub fn printString(bytes: []const u8, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w).Error!void {
702 const size: Compilation.CharUnitSize = @enumFromInt(ty.elemType().sizeof(comp).?);
703 const without_null = bytes[0 .. bytes.len - @intFromEnum(size)];
704 switch (size) {
705 inline .@"1", .@"2" => |sz| {
706 const data_slice: []const sz.Type() = @alignCast(std.mem.bytesAsSlice(sz.Type(), without_null));
707 const formatter = if (sz == .@"1") std.zig.fmtEscapes(data_slice) else std.unicode.fmtUtf16le(data_slice);
708 try w.print("\"{}\"", .{formatter});
709 },
710 .@"4" => {
711 try w.writeByte('"');
712 const data_slice = std.mem.bytesAsSlice(u32, without_null);
713 var buf: [4]u8 = undefined;
714 for (data_slice) |item| {
715 if (item <= std.math.maxInt(u21) and std.unicode.utf8ValidCodepoint(@intCast(item))) {
716 const codepoint: u21 = @intCast(item);
717 const written = std.unicode.utf8Encode(codepoint, &buf) catch unreachable;
718 try w.print("{s}", .{buf[0..written]});
719 } else {
720 try w.print("\\x{x}", .{item});
721 }
722 }
723 try w.writeByte('"');
724 },
725 }
726}
deps/aro/aro/char_info.zig deleted-1111
......@@ -1,1111 +0,0 @@
1//! This module provides functions for classifying characters according to
2//! various C standards. All classification routines *do not* consider
3//! characters from the basic character set; it is assumed those will be
4//! checked separately
5//! isXidStart and isXidContinue are adapted from https://github.com/dtolnay/unicode-ident
6
7const assert = @import("std").debug.assert;
8const tables = @import("char_info/identifier_tables.zig");
9
10/// C11 Standard Annex D
11pub fn isC11IdChar(codepoint: u21) bool {
12 assert(codepoint > 0x7F);
13 return switch (codepoint) {
14 // 1
15 0x00A8,
16 0x00AA,
17 0x00AD,
18 0x00AF,
19 0x00B2...0x00B5,
20 0x00B7...0x00BA,
21 0x00BC...0x00BE,
22 0x00C0...0x00D6,
23 0x00D8...0x00F6,
24 0x00F8...0x00FF,
25
26 // 2
27 0x0100...0x167F,
28 0x1681...0x180D,
29 0x180F...0x1FFF,
30
31 // 3
32 0x200B...0x200D,
33 0x202A...0x202E,
34 0x203F...0x2040,
35 0x2054,
36 0x2060...0x206F,
37
38 // 4
39 0x2070...0x218F,
40 0x2460...0x24FF,
41 0x2776...0x2793,
42 0x2C00...0x2DFF,
43 0x2E80...0x2FFF,
44
45 // 5
46 0x3004...0x3007,
47 0x3021...0x302F,
48 0x3031...0x303F,
49
50 // 6
51 0x3040...0xD7FF,
52
53 // 7
54 0xF900...0xFD3D,
55 0xFD40...0xFDCF,
56 0xFDF0...0xFE44,
57 0xFE47...0xFFFD,
58
59 // 8
60 0x10000...0x1FFFD,
61 0x20000...0x2FFFD,
62 0x30000...0x3FFFD,
63 0x40000...0x4FFFD,
64 0x50000...0x5FFFD,
65 0x60000...0x6FFFD,
66 0x70000...0x7FFFD,
67 0x80000...0x8FFFD,
68 0x90000...0x9FFFD,
69 0xA0000...0xAFFFD,
70 0xB0000...0xBFFFD,
71 0xC0000...0xCFFFD,
72 0xD0000...0xDFFFD,
73 0xE0000...0xEFFFD,
74 => true,
75 else => false,
76 };
77}
78
79/// C99 Standard Annex D
80pub fn isC99IdChar(codepoint: u21) bool {
81 assert(codepoint > 0x7F);
82 return switch (codepoint) {
83 // Latin
84 0x00AA,
85 0x00BA,
86 0x00C0...0x00D6,
87 0x00D8...0x00F6,
88 0x00F8...0x01F5,
89 0x01FA...0x0217,
90 0x0250...0x02A8,
91 0x1E00...0x1E9B,
92 0x1EA0...0x1EF9,
93 0x207F,
94
95 // Greek
96 0x0386,
97 0x0388...0x038A,
98 0x038C,
99 0x038E...0x03A1,
100 0x03A3...0x03CE,
101 0x03D0...0x03D6,
102 0x03DA,
103 0x03DC,
104 0x03DE,
105 0x03E0,
106 0x03E2...0x03F3,
107 0x1F00...0x1F15,
108 0x1F18...0x1F1D,
109 0x1F20...0x1F45,
110 0x1F48...0x1F4D,
111 0x1F50...0x1F57,
112 0x1F59,
113 0x1F5B,
114 0x1F5D,
115 0x1F5F...0x1F7D,
116 0x1F80...0x1FB4,
117 0x1FB6...0x1FBC,
118 0x1FC2...0x1FC4,
119 0x1FC6...0x1FCC,
120 0x1FD0...0x1FD3,
121 0x1FD6...0x1FDB,
122 0x1FE0...0x1FEC,
123 0x1FF2...0x1FF4,
124 0x1FF6...0x1FFC,
125
126 // Cyrillic
127 0x0401...0x040C,
128 0x040E...0x044F,
129 0x0451...0x045C,
130 0x045E...0x0481,
131 0x0490...0x04C4,
132 0x04C7...0x04C8,
133 0x04CB...0x04CC,
134 0x04D0...0x04EB,
135 0x04EE...0x04F5,
136 0x04F8...0x04F9,
137
138 // Armenian
139 0x0531...0x0556,
140 0x0561...0x0587,
141
142 // Hebrew
143 0x05B0...0x05B9,
144 0x05BB...0x05BD,
145 0x05BF,
146 0x05C1...0x05C2,
147 0x05D0...0x05EA,
148 0x05F0...0x05F2,
149
150 // Arabic
151 0x0621...0x063A,
152 0x0640...0x0652,
153 0x0670...0x06B7,
154 0x06BA...0x06BE,
155 0x06C0...0x06CE,
156 0x06D0...0x06DC,
157 0x06E5...0x06E8,
158 0x06EA...0x06ED,
159
160 // Devanagari
161 0x0901...0x0903,
162 0x0905...0x0939,
163 0x093E...0x094D,
164 0x0950...0x0952,
165 0x0958...0x0963,
166
167 // Bengali
168 0x0981...0x0983,
169 0x0985...0x098C,
170 0x098F...0x0990,
171 0x0993...0x09A8,
172 0x09AA...0x09B0,
173 0x09B2,
174 0x09B6...0x09B9,
175 0x09BE...0x09C4,
176 0x09C7...0x09C8,
177 0x09CB...0x09CD,
178 0x09DC...0x09DD,
179 0x09DF...0x09E3,
180 0x09F0...0x09F1,
181
182 // Gurmukhi
183 0x0A02,
184 0x0A05...0x0A0A,
185 0x0A0F...0x0A10,
186 0x0A13...0x0A28,
187 0x0A2A...0x0A30,
188 0x0A32...0x0A33,
189 0x0A35...0x0A36,
190 0x0A38...0x0A39,
191 0x0A3E...0x0A42,
192 0x0A47...0x0A48,
193 0x0A4B...0x0A4D,
194 0x0A59...0x0A5C,
195 0x0A5E,
196 0x0A74,
197
198 // Gujarati
199 0x0A81...0x0A83,
200 0x0A85...0x0A8B,
201 0x0A8D,
202 0x0A8F...0x0A91,
203 0x0A93...0x0AA8,
204 0x0AAA...0x0AB0,
205 0x0AB2...0x0AB3,
206 0x0AB5...0x0AB9,
207 0x0ABD...0x0AC5,
208 0x0AC7...0x0AC9,
209 0x0ACB...0x0ACD,
210 0x0AD0,
211 0x0AE0,
212
213 // Oriya
214 0x0B01...0x0B03,
215 0x0B05...0x0B0C,
216 0x0B0F...0x0B10,
217 0x0B13...0x0B28,
218 0x0B2A...0x0B30,
219 0x0B32...0x0B33,
220 0x0B36...0x0B39,
221 0x0B3E...0x0B43,
222 0x0B47...0x0B48,
223 0x0B4B...0x0B4D,
224 0x0B5C...0x0B5D,
225 0x0B5F...0x0B61,
226
227 // Tamil
228 0x0B82...0x0B83,
229 0x0B85...0x0B8A,
230 0x0B8E...0x0B90,
231 0x0B92...0x0B95,
232 0x0B99...0x0B9A,
233 0x0B9C,
234 0x0B9E...0x0B9F,
235 0x0BA3...0x0BA4,
236 0x0BA8...0x0BAA,
237 0x0BAE...0x0BB5,
238 0x0BB7...0x0BB9,
239 0x0BBE...0x0BC2,
240 0x0BC6...0x0BC8,
241 0x0BCA...0x0BCD,
242
243 // Telugu
244 0x0C01...0x0C03,
245 0x0C05...0x0C0C,
246 0x0C0E...0x0C10,
247 0x0C12...0x0C28,
248 0x0C2A...0x0C33,
249 0x0C35...0x0C39,
250 0x0C3E...0x0C44,
251 0x0C46...0x0C48,
252 0x0C4A...0x0C4D,
253 0x0C60...0x0C61,
254
255 // Kannada
256 0x0C82...0x0C83,
257 0x0C85...0x0C8C,
258 0x0C8E...0x0C90,
259 0x0C92...0x0CA8,
260 0x0CAA...0x0CB3,
261 0x0CB5...0x0CB9,
262 0x0CBE...0x0CC4,
263 0x0CC6...0x0CC8,
264 0x0CCA...0x0CCD,
265 0x0CDE,
266 0x0CE0...0x0CE1,
267
268 // Malayalam
269 0x0D02...0x0D03,
270 0x0D05...0x0D0C,
271 0x0D0E...0x0D10,
272 0x0D12...0x0D28,
273 0x0D2A...0x0D39,
274 0x0D3E...0x0D43,
275 0x0D46...0x0D48,
276 0x0D4A...0x0D4D,
277 0x0D60...0x0D61,
278
279 // Thai (excluding digits 0x0E50...0x0E59; originally 0x0E01...0x0E3A and 0x0E40...0x0E5B
280 0x0E01...0x0E3A,
281 0x0E40...0x0E4F,
282 0x0E5A...0x0E5B,
283
284 // Lao
285 0x0E81...0x0E82,
286 0x0E84,
287 0x0E87...0x0E88,
288 0x0E8A,
289 0x0E8D,
290 0x0E94...0x0E97,
291 0x0E99...0x0E9F,
292 0x0EA1...0x0EA3,
293 0x0EA5,
294 0x0EA7,
295 0x0EAA...0x0EAB,
296 0x0EAD...0x0EAE,
297 0x0EB0...0x0EB9,
298 0x0EBB...0x0EBD,
299 0x0EC0...0x0EC4,
300 0x0EC6,
301 0x0EC8...0x0ECD,
302 0x0EDC...0x0EDD,
303
304 // Tibetan
305 0x0F00,
306 0x0F18...0x0F19,
307 0x0F35,
308 0x0F37,
309 0x0F39,
310 0x0F3E...0x0F47,
311 0x0F49...0x0F69,
312 0x0F71...0x0F84,
313 0x0F86...0x0F8B,
314 0x0F90...0x0F95,
315 0x0F97,
316 0x0F99...0x0FAD,
317 0x0FB1...0x0FB7,
318 0x0FB9,
319
320 // Georgian
321 0x10A0...0x10C5,
322 0x10D0...0x10F6,
323
324 // Hiragana
325 0x3041...0x3093,
326 0x309B...0x309C,
327
328 // Katakana
329 0x30A1...0x30F6,
330 0x30FB...0x30FC,
331
332 // Bopomofo
333 0x3105...0x312C,
334
335 // CJK Unified Ideographs
336 0x4E00...0x9FA5,
337
338 // Hangul
339 0xAC00...0xD7A3,
340
341 // Digits
342 0x0660...0x0669,
343 0x06F0...0x06F9,
344 0x0966...0x096F,
345 0x09E6...0x09EF,
346 0x0A66...0x0A6F,
347 0x0AE6...0x0AEF,
348 0x0B66...0x0B6F,
349 0x0BE7...0x0BEF,
350 0x0C66...0x0C6F,
351 0x0CE6...0x0CEF,
352 0x0D66...0x0D6F,
353 0x0E50...0x0E59,
354 0x0ED0...0x0ED9,
355 0x0F20...0x0F33,
356
357 // Special characters
358 0x00B5,
359 0x00B7,
360 0x02B0...0x02B8,
361 0x02BB,
362 0x02BD...0x02C1,
363 0x02D0...0x02D1,
364 0x02E0...0x02E4,
365 0x037A,
366 0x0559,
367 0x093D,
368 0x0B3D,
369 0x1FBE,
370 0x203F...0x2040,
371 0x2102,
372 0x2107,
373 0x210A...0x2113,
374 0x2115,
375 0x2118...0x211D,
376 0x2124,
377 0x2126,
378 0x2128,
379 0x212A...0x2131,
380 0x2133...0x2138,
381 0x2160...0x2182,
382 0x3005...0x3007,
383 0x3021...0x3029,
384 => true,
385 else => false,
386 };
387}
388
389/// C11 standard Annex D
390pub fn isC11DisallowedInitialIdChar(codepoint: u21) bool {
391 assert(codepoint > 0x7F);
392 return switch (codepoint) {
393 0x0300...0x036F,
394 0x1DC0...0x1DFF,
395 0x20D0...0x20FF,
396 0xFE20...0xFE2F,
397 => true,
398 else => false,
399 };
400}
401
402/// These are "digit" characters; C99 disallows them as the first
403/// character of an identifier
404pub fn isC99DisallowedInitialIDChar(codepoint: u21) bool {
405 assert(codepoint > 0x7F);
406 return switch (codepoint) {
407 0x0660...0x0669,
408 0x06F0...0x06F9,
409 0x0966...0x096F,
410 0x09E6...0x09EF,
411 0x0A66...0x0A6F,
412 0x0AE6...0x0AEF,
413 0x0B66...0x0B6F,
414 0x0BE7...0x0BEF,
415 0x0C66...0x0C6F,
416 0x0CE6...0x0CEF,
417 0x0D66...0x0D6F,
418 0x0E50...0x0E59,
419 0x0ED0...0x0ED9,
420 0x0F20...0x0F33,
421 => true,
422 else => false,
423 };
424}
425
426pub fn isInvisible(codepoint: u21) bool {
427 assert(codepoint > 0x7F);
428 return switch (codepoint) {
429 0x00ad, // SOFT HYPHEN
430 0x200b, // ZERO WIDTH SPACE
431 0x200c, // ZERO WIDTH NON-JOINER
432 0x200d, // ZERO WIDTH JOINER
433 0x2060, // WORD JOINER
434 0x2061, // FUNCTION APPLICATION
435 0x2062, // INVISIBLE TIMES
436 0x2063, // INVISIBLE SEPARATOR
437 0x2064, // INVISIBLE PLUS
438 0xfeff, // ZERO WIDTH NO-BREAK SPACE
439 => true,
440 else => false,
441 };
442}
443
444/// Checks for identifier characters which resemble non-identifier characters
445pub fn homoglyph(codepoint: u21) ?u21 {
446 assert(codepoint > 0x7F);
447 return switch (codepoint) {
448 0x01c3 => '!', // LATIN LETTER RETROFLEX CLICK
449 0x037e => ';', // GREEK QUESTION MARK
450 0x2212 => '-', // MINUS SIGN
451 0x2215 => '/', // DIVISION SLASH
452 0x2216 => '\\', // SET MINUS
453 0x2217 => '*', // ASTERISK OPERATOR
454 0x2223 => '|', // DIVIDES
455 0x2227 => '^', // LOGICAL AND
456 0x2236 => ':', // RATIO
457 0x223c => '~', // TILDE OPERATOR
458 0xa789 => ':', // MODIFIER LETTER COLON
459 0xff01 => '!', // FULLWIDTH EXCLAMATION MARK
460 0xff03 => '#', // FULLWIDTH NUMBER SIGN
461 0xff04 => '$', // FULLWIDTH DOLLAR SIGN
462 0xff05 => '%', // FULLWIDTH PERCENT SIGN
463 0xff06 => '&', // FULLWIDTH AMPERSAND
464 0xff08 => '(', // FULLWIDTH LEFT PARENTHESIS
465 0xff09 => ')', // FULLWIDTH RIGHT PARENTHESIS
466 0xff0a => '*', // FULLWIDTH ASTERISK
467 0xff0b => '+', // FULLWIDTH ASTERISK
468 0xff0c => ',', // FULLWIDTH COMMA
469 0xff0d => '-', // FULLWIDTH HYPHEN-MINUS
470 0xff0e => '.', // FULLWIDTH FULL STOP
471 0xff0f => '/', // FULLWIDTH SOLIDUS
472 0xff1a => ':', // FULLWIDTH COLON
473 0xff1b => ';', // FULLWIDTH SEMICOLON
474 0xff1c => '<', // FULLWIDTH LESS-THAN SIGN
475 0xff1d => '=', // FULLWIDTH EQUALS SIGN
476 0xff1e => '>', // FULLWIDTH GREATER-THAN SIGN
477 0xff1f => '?', // FULLWIDTH QUESTION MARK
478 0xff20 => '@', // FULLWIDTH COMMERCIAL AT
479 0xff3b => '[', // FULLWIDTH LEFT SQUARE BRACKET
480 0xff3c => '\\', // FULLWIDTH REVERSE SOLIDUS
481 0xff3d => ']', // FULLWIDTH RIGHT SQUARE BRACKET
482 0xff3e => '^', // FULLWIDTH CIRCUMFLEX ACCENT
483 0xff5b => '{', // FULLWIDTH LEFT CURLY BRACKET
484 0xff5c => '|', // FULLWIDTH VERTICAL LINE
485 0xff5d => '}', // FULLWIDTH RIGHT CURLY BRACKET
486 0xff5e => '~', // FULLWIDTH TILDE
487 else => null,
488 };
489}
490
491pub fn isXidStart(c: u21) bool {
492 assert(c > 0x7F);
493 const idx = c / 8 / tables.chunk;
494 const chunk: usize = if (idx < tables.trie_start.len) tables.trie_start[idx] else 0;
495 const offset = chunk * tables.chunk / 2 + c / 8 % tables.chunk;
496 return (tables.leaf[offset] >> (@as(u3, @intCast(c % 8)))) & 1 != 0;
497}
498
499pub fn isXidContinue(c: u21) bool {
500 assert(c > 0x7F);
501 const idx = c / 8 / tables.chunk;
502 const chunk: usize = if (idx < tables.trie_continue.len) tables.trie_continue[idx] else 0;
503 const offset = chunk * tables.chunk / 2 + c / 8 % tables.chunk;
504 return (tables.leaf[offset] >> (@as(u3, @intCast(c % 8)))) & 1 != 0;
505}
506
507test "isXidStart / isXidContinue panic check" {
508 const std = @import("std");
509 for (0x80..0x110000) |i| {
510 const c: u21 = @intCast(i);
511 if (std.unicode.utf8ValidCodepoint(c)) {
512 _ = isXidStart(c);
513 _ = isXidContinue(c);
514 }
515 }
516}
517
518test isXidStart {
519 const std = @import("std");
520 try std.testing.expect(!isXidStart('᠑'));
521 try std.testing.expect(!isXidStart('™'));
522 try std.testing.expect(!isXidStart('£'));
523 try std.testing.expect(!isXidStart('\u{1f914}')); // 🤔
524}
525
526test isXidContinue {
527 const std = @import("std");
528 try std.testing.expect(isXidContinue('᠑'));
529 try std.testing.expect(!isXidContinue('™'));
530 try std.testing.expect(!isXidContinue('£'));
531 try std.testing.expect(!isXidContinue('\u{1f914}')); // 🤔
532}
533
534pub const NfcQuickCheck = enum { no, maybe, yes };
535
536pub fn isNormalized(codepoint: u21) NfcQuickCheck {
537 return switch (codepoint) {
538 0x0340...0x0341,
539 0x0343...0x0344,
540 0x0374,
541 0x037E,
542 0x0387,
543 0x0958...0x095F,
544 0x09DC...0x09DD,
545 0x09DF,
546 0x0A33,
547 0x0A36,
548 0x0A59...0x0A5B,
549 0x0A5E,
550 0x0B5C...0x0B5D,
551 0x0F43,
552 0x0F4D,
553 0x0F52,
554 0x0F57,
555 0x0F5C,
556 0x0F69,
557 0x0F73,
558 0x0F75...0x0F76,
559 0x0F78,
560 0x0F81,
561 0x0F93,
562 0x0F9D,
563 0x0FA2,
564 0x0FA7,
565 0x0FAC,
566 0x0FB9,
567 0x1F71,
568 0x1F73,
569 0x1F75,
570 0x1F77,
571 0x1F79,
572 0x1F7B,
573 0x1F7D,
574 0x1FBB,
575 0x1FBE,
576 0x1FC9,
577 0x1FCB,
578 0x1FD3,
579 0x1FDB,
580 0x1FE3,
581 0x1FEB,
582 0x1FEE...0x1FEF,
583 0x1FF9,
584 0x1FFB,
585 0x1FFD,
586 0x2000...0x2001,
587 0x2126,
588 0x212A...0x212B,
589 0x2329,
590 0x232A,
591 0x2ADC,
592 0xF900...0xFA0D,
593 0xFA10,
594 0xFA12,
595 0xFA15...0xFA1E,
596 0xFA20,
597 0xFA22,
598 0xFA25...0xFA26,
599 0xFA2A...0xFA6D,
600 0xFA70...0xFAD9,
601 0xFB1D,
602 0xFB1F,
603 0xFB2A...0xFB36,
604 0xFB38...0xFB3C,
605 0xFB3E,
606 0xFB40...0xFB41,
607 0xFB43...0xFB44,
608 0xFB46...0xFB4E,
609 0x1D15E...0x1D164,
610 0x1D1BB...0x1D1C0,
611 0x2F800...0x2FA1D,
612 => .no,
613 0x0300...0x0304,
614 0x0306...0x030C,
615 0x030F,
616 0x0311,
617 0x0313...0x0314,
618 0x031B,
619 0x0323...0x0328,
620 0x032D...0x032E,
621 0x0330...0x0331,
622 0x0338,
623 0x0342,
624 0x0345,
625 0x0653...0x0655,
626 0x093C,
627 0x09BE,
628 0x09D7,
629 0x0B3E,
630 0x0B56,
631 0x0B57,
632 0x0BBE,
633 0x0BD7,
634 0x0C56,
635 0x0CC2,
636 0x0CD5...0x0CD6,
637 0x0D3E,
638 0x0D57,
639 0x0DCA,
640 0x0DCF,
641 0x0DDF,
642 0x102E,
643 0x1161...0x1175,
644 0x11A8...0x11C2,
645 0x1B35,
646 0x3099...0x309A,
647 0x110BA,
648 0x11127,
649 0x1133E,
650 0x11357,
651 0x114B0,
652 0x114BA,
653 0x114BD,
654 0x115AF,
655 => .maybe,
656 else => .yes,
657 };
658}
659
660pub const CanonicalCombiningClass = enum(u8) {
661 not_reordered = 0,
662 overlay = 1,
663 han_reading = 6,
664 nukta = 7,
665 kana_voicing = 8,
666 virama = 9,
667 ccc10 = 10,
668 ccc11 = 11,
669 ccc12 = 12,
670 ccc13 = 13,
671 ccc14 = 14,
672 ccc15 = 15,
673 ccc16 = 16,
674 ccc17 = 17,
675 ccc18 = 18,
676 ccc19 = 19,
677 ccc20 = 20,
678 ccc21 = 21,
679 ccc22 = 22,
680 ccc23 = 23,
681 ccc24 = 24,
682 ccc25 = 25,
683 ccc26 = 26,
684 ccc27 = 27,
685 ccc28 = 28,
686 ccc29 = 29,
687 ccc30 = 30,
688 ccc31 = 31,
689 ccc32 = 32,
690 ccc33 = 33,
691 ccc34 = 34,
692 ccc35 = 35,
693 ccc36 = 36,
694 ccc84 = 84,
695 ccc91 = 91,
696 ccc103 = 103,
697 ccc107 = 107,
698 ccc118 = 118,
699 ccc122 = 122,
700 ccc129 = 129,
701 ccc130 = 130,
702 ccc132 = 132,
703 attached_below = 202,
704 attached_above = 214,
705 attached_above_right = 216,
706 below_left = 218,
707 below = 220,
708 below_right = 222,
709 left = 224,
710 right = 226,
711 above_left = 228,
712 above = 230,
713 above_right = 232,
714 double_below = 233,
715 double_above = 234,
716 iota_subscript = 240,
717};
718
719pub fn getCanonicalClass(codepoint: u21) CanonicalCombiningClass {
720 return switch (codepoint) {
721 0x300...0x314 => .above,
722 0x315...0x315 => .above_right,
723 0x316...0x319 => .below,
724 0x31A...0x31A => .above_right,
725 0x31B...0x31B => .attached_above_right,
726 0x31C...0x320 => .below,
727 0x321...0x322 => .attached_below,
728 0x323...0x326 => .below,
729 0x327...0x328 => .attached_below,
730 0x329...0x333 => .below,
731 0x334...0x338 => .overlay,
732 0x339...0x33C => .below,
733 0x33D...0x344 => .above,
734 0x345...0x345 => .iota_subscript,
735 0x346...0x346 => .above,
736 0x347...0x349 => .below,
737 0x34A...0x34C => .above,
738 0x34D...0x34E => .below,
739 0x350...0x352 => .above,
740 0x353...0x356 => .below,
741 0x357...0x357 => .above,
742 0x358...0x358 => .above_right,
743 0x359...0x35A => .below,
744 0x35B...0x35B => .above,
745 0x35C...0x35C => .double_below,
746 0x35D...0x35E => .double_above,
747 0x35F...0x35F => .double_below,
748 0x360...0x361 => .double_above,
749 0x362...0x362 => .double_below,
750 0x363...0x36F => .above,
751 0x483...0x487 => .above,
752 0x591...0x591 => .below,
753 0x592...0x595 => .above,
754 0x596...0x596 => .below,
755 0x597...0x599 => .above,
756 0x59A...0x59A => .below_right,
757 0x59B...0x59B => .below,
758 0x59C...0x5A1 => .above,
759 0x5A2...0x5A7 => .below,
760 0x5A8...0x5A9 => .above,
761 0x5AA...0x5AA => .below,
762 0x5AB...0x5AC => .above,
763 0x5AD...0x5AD => .below_right,
764 0x5AE...0x5AE => .above_left,
765 0x5AF...0x5AF => .above,
766 0x5B0...0x5B0 => .ccc10,
767 0x5B1...0x5B1 => .ccc11,
768 0x5B2...0x5B2 => .ccc12,
769 0x5B3...0x5B3 => .ccc13,
770 0x5B4...0x5B4 => .ccc14,
771 0x5B5...0x5B5 => .ccc15,
772 0x5B6...0x5B6 => .ccc16,
773 0x5B7...0x5B7 => .ccc17,
774 0x5B8...0x5B8 => .ccc18,
775 0x5B9...0x5BA => .ccc19,
776 0x5BB...0x5BB => .ccc20,
777 0x5BC...0x5BC => .ccc21,
778 0x5BD...0x5BD => .ccc22,
779 0x5BF...0x5BF => .ccc23,
780 0x5C1...0x5C1 => .ccc24,
781 0x5C2...0x5C2 => .ccc25,
782 0x5C4...0x5C4 => .above,
783 0x5C5...0x5C5 => .below,
784 0x5C7...0x5C7 => .ccc18,
785 0x610...0x617 => .above,
786 0x618...0x618 => .ccc30,
787 0x619...0x619 => .ccc31,
788 0x61A...0x61A => .ccc32,
789 0x64B...0x64B => .ccc27,
790 0x64C...0x64C => .ccc28,
791 0x64D...0x64D => .ccc29,
792 0x64E...0x64E => .ccc30,
793 0x64F...0x64F => .ccc31,
794 0x650...0x650 => .ccc32,
795 0x651...0x651 => .ccc33,
796 0x652...0x652 => .ccc34,
797 0x653...0x654 => .above,
798 0x655...0x656 => .below,
799 0x657...0x65B => .above,
800 0x65C...0x65C => .below,
801 0x65D...0x65E => .above,
802 0x65F...0x65F => .below,
803 0x670...0x670 => .ccc35,
804 0x6D6...0x6DC => .above,
805 0x6DF...0x6E2 => .above,
806 0x6E3...0x6E3 => .below,
807 0x6E4...0x6E4 => .above,
808 0x6E7...0x6E8 => .above,
809 0x6EA...0x6EA => .below,
810 0x6EB...0x6EC => .above,
811 0x6ED...0x6ED => .below,
812 0x711...0x711 => .ccc36,
813 0x730...0x730 => .above,
814 0x731...0x731 => .below,
815 0x732...0x733 => .above,
816 0x734...0x734 => .below,
817 0x735...0x736 => .above,
818 0x737...0x739 => .below,
819 0x73A...0x73A => .above,
820 0x73B...0x73C => .below,
821 0x73D...0x73D => .above,
822 0x73E...0x73E => .below,
823 0x73F...0x741 => .above,
824 0x742...0x742 => .below,
825 0x743...0x743 => .above,
826 0x744...0x744 => .below,
827 0x745...0x745 => .above,
828 0x746...0x746 => .below,
829 0x747...0x747 => .above,
830 0x748...0x748 => .below,
831 0x749...0x74A => .above,
832 0x7EB...0x7F1 => .above,
833 0x7F2...0x7F2 => .below,
834 0x7F3...0x7F3 => .above,
835 0x7FD...0x7FD => .below,
836 0x816...0x819 => .above,
837 0x81B...0x823 => .above,
838 0x825...0x827 => .above,
839 0x829...0x82D => .above,
840 0x859...0x85B => .below,
841 0x898...0x898 => .above,
842 0x899...0x89B => .below,
843 0x89C...0x89F => .above,
844 0x8CA...0x8CE => .above,
845 0x8CF...0x8D3 => .below,
846 0x8D4...0x8E1 => .above,
847 0x8E3...0x8E3 => .below,
848 0x8E4...0x8E5 => .above,
849 0x8E6...0x8E6 => .below,
850 0x8E7...0x8E8 => .above,
851 0x8E9...0x8E9 => .below,
852 0x8EA...0x8EC => .above,
853 0x8ED...0x8EF => .below,
854 0x8F0...0x8F0 => .ccc27,
855 0x8F1...0x8F1 => .ccc28,
856 0x8F2...0x8F2 => .ccc29,
857 0x8F3...0x8F5 => .above,
858 0x8F6...0x8F6 => .below,
859 0x8F7...0x8F8 => .above,
860 0x8F9...0x8FA => .below,
861 0x8FB...0x8FF => .above,
862 0x93C...0x93C => .nukta,
863 0x94D...0x94D => .virama,
864 0x951...0x951 => .above,
865 0x952...0x952 => .below,
866 0x953...0x954 => .above,
867 0x9BC...0x9BC => .nukta,
868 0x9CD...0x9CD => .virama,
869 0x9FE...0x9FE => .above,
870 0xA3C...0xA3C => .nukta,
871 0xA4D...0xA4D => .virama,
872 0xABC...0xABC => .nukta,
873 0xACD...0xACD => .virama,
874 0xB3C...0xB3C => .nukta,
875 0xB4D...0xB4D => .virama,
876 0xBCD...0xBCD => .virama,
877 0xC3C...0xC3C => .nukta,
878 0xC4D...0xC4D => .virama,
879 0xC55...0xC55 => .ccc84,
880 0xC56...0xC56 => .ccc91,
881 0xCBC...0xCBC => .nukta,
882 0xCCD...0xCCD => .virama,
883 0xD3B...0xD3C => .virama,
884 0xD4D...0xD4D => .virama,
885 0xDCA...0xDCA => .virama,
886 0xE38...0xE39 => .ccc103,
887 0xE3A...0xE3A => .virama,
888 0xE48...0xE4B => .ccc107,
889 0xEB8...0xEB9 => .ccc118,
890 0xEBA...0xEBA => .virama,
891 0xEC8...0xECB => .ccc122,
892 0xF18...0xF19 => .below,
893 0xF35...0xF35 => .below,
894 0xF37...0xF37 => .below,
895 0xF39...0xF39 => .attached_above_right,
896 0xF71...0xF71 => .ccc129,
897 0xF72...0xF72 => .ccc130,
898 0xF74...0xF74 => .ccc132,
899 0xF7A...0xF7D => .ccc130,
900 0xF80...0xF80 => .ccc130,
901 0xF82...0xF83 => .above,
902 0xF84...0xF84 => .virama,
903 0xF86...0xF87 => .above,
904 0xFC6...0xFC6 => .below,
905 0x1037...0x1037 => .nukta,
906 0x1039...0x103A => .virama,
907 0x108D...0x108D => .below,
908 0x135D...0x135F => .above,
909 0x1714...0x1715 => .virama,
910 0x1734...0x1734 => .virama,
911 0x17D2...0x17D2 => .virama,
912 0x17DD...0x17DD => .above,
913 0x18A9...0x18A9 => .above_left,
914 0x1939...0x1939 => .below_right,
915 0x193A...0x193A => .above,
916 0x193B...0x193B => .below,
917 0x1A17...0x1A17 => .above,
918 0x1A18...0x1A18 => .below,
919 0x1A60...0x1A60 => .virama,
920 0x1A75...0x1A7C => .above,
921 0x1A7F...0x1A7F => .below,
922 0x1AB0...0x1AB4 => .above,
923 0x1AB5...0x1ABA => .below,
924 0x1ABB...0x1ABC => .above,
925 0x1ABD...0x1ABD => .below,
926 0x1ABF...0x1AC0 => .below,
927 0x1AC1...0x1AC2 => .above,
928 0x1AC3...0x1AC4 => .below,
929 0x1AC5...0x1AC9 => .above,
930 0x1ACA...0x1ACA => .below,
931 0x1ACB...0x1ACE => .above,
932 0x1B34...0x1B34 => .nukta,
933 0x1B44...0x1B44 => .virama,
934 0x1B6B...0x1B6B => .above,
935 0x1B6C...0x1B6C => .below,
936 0x1B6D...0x1B73 => .above,
937 0x1BAA...0x1BAB => .virama,
938 0x1BE6...0x1BE6 => .nukta,
939 0x1BF2...0x1BF3 => .virama,
940 0x1C37...0x1C37 => .nukta,
941 0x1CD0...0x1CD2 => .above,
942 0x1CD4...0x1CD4 => .overlay,
943 0x1CD5...0x1CD9 => .below,
944 0x1CDA...0x1CDB => .above,
945 0x1CDC...0x1CDF => .below,
946 0x1CE0...0x1CE0 => .above,
947 0x1CE2...0x1CE8 => .overlay,
948 0x1CED...0x1CED => .below,
949 0x1CF4...0x1CF4 => .above,
950 0x1CF8...0x1CF9 => .above,
951 0x1DC0...0x1DC1 => .above,
952 0x1DC2...0x1DC2 => .below,
953 0x1DC3...0x1DC9 => .above,
954 0x1DCA...0x1DCA => .below,
955 0x1DCB...0x1DCC => .above,
956 0x1DCD...0x1DCD => .double_above,
957 0x1DCE...0x1DCE => .attached_above,
958 0x1DCF...0x1DCF => .below,
959 0x1DD0...0x1DD0 => .attached_below,
960 0x1DD1...0x1DF5 => .above,
961 0x1DF6...0x1DF6 => .above_right,
962 0x1DF7...0x1DF8 => .above_left,
963 0x1DF9...0x1DF9 => .below,
964 0x1DFA...0x1DFA => .below_left,
965 0x1DFB...0x1DFB => .above,
966 0x1DFC...0x1DFC => .double_below,
967 0x1DFD...0x1DFD => .below,
968 0x1DFE...0x1DFE => .above,
969 0x1DFF...0x1DFF => .below,
970 0x20D0...0x20D1 => .above,
971 0x20D2...0x20D3 => .overlay,
972 0x20D4...0x20D7 => .above,
973 0x20D8...0x20DA => .overlay,
974 0x20DB...0x20DC => .above,
975 0x20E1...0x20E1 => .above,
976 0x20E5...0x20E6 => .overlay,
977 0x20E7...0x20E7 => .above,
978 0x20E8...0x20E8 => .below,
979 0x20E9...0x20E9 => .above,
980 0x20EA...0x20EB => .overlay,
981 0x20EC...0x20EF => .below,
982 0x20F0...0x20F0 => .above,
983 0x2CEF...0x2CF1 => .above,
984 0x2D7F...0x2D7F => .virama,
985 0x2DE0...0x2DFF => .above,
986 0x302A...0x302A => .below_left,
987 0x302B...0x302B => .above_left,
988 0x302C...0x302C => .above_right,
989 0x302D...0x302D => .below_right,
990 0x302E...0x302F => .left,
991 0x3099...0x309A => .kana_voicing,
992 0xA66F...0xA66F => .above,
993 0xA674...0xA67D => .above,
994 0xA69E...0xA69F => .above,
995 0xA6F0...0xA6F1 => .above,
996 0xA806...0xA806 => .virama,
997 0xA82C...0xA82C => .virama,
998 0xA8C4...0xA8C4 => .virama,
999 0xA8E0...0xA8F1 => .above,
1000 0xA92B...0xA92D => .below,
1001 0xA953...0xA953 => .virama,
1002 0xA9B3...0xA9B3 => .nukta,
1003 0xA9C0...0xA9C0 => .virama,
1004 0xAAB0...0xAAB0 => .above,
1005 0xAAB2...0xAAB3 => .above,
1006 0xAAB4...0xAAB4 => .below,
1007 0xAAB7...0xAAB8 => .above,
1008 0xAABE...0xAABF => .above,
1009 0xAAC1...0xAAC1 => .above,
1010 0xAAF6...0xAAF6 => .virama,
1011 0xABED...0xABED => .virama,
1012 0xFB1E...0xFB1E => .ccc26,
1013 0xFE20...0xFE26 => .above,
1014 0xFE27...0xFE2D => .below,
1015 0xFE2E...0xFE2F => .above,
1016 0x101FD...0x101FD => .below,
1017 0x102E0...0x102E0 => .below,
1018 0x10376...0x1037A => .above,
1019 0x10A0D...0x10A0D => .below,
1020 0x10A0F...0x10A0F => .above,
1021 0x10A38...0x10A38 => .above,
1022 0x10A39...0x10A39 => .overlay,
1023 0x10A3A...0x10A3A => .below,
1024 0x10A3F...0x10A3F => .virama,
1025 0x10AE5...0x10AE5 => .above,
1026 0x10AE6...0x10AE6 => .below,
1027 0x10D24...0x10D27 => .above,
1028 0x10EAB...0x10EAC => .above,
1029 0x10EFD...0x10EFF => .below,
1030 0x10F46...0x10F47 => .below,
1031 0x10F48...0x10F4A => .above,
1032 0x10F4B...0x10F4B => .below,
1033 0x10F4C...0x10F4C => .above,
1034 0x10F4D...0x10F50 => .below,
1035 0x10F82...0x10F82 => .above,
1036 0x10F83...0x10F83 => .below,
1037 0x10F84...0x10F84 => .above,
1038 0x10F85...0x10F85 => .below,
1039 0x11046...0x11046 => .virama,
1040 0x11070...0x11070 => .virama,
1041 0x1107F...0x1107F => .virama,
1042 0x110B9...0x110B9 => .virama,
1043 0x110BA...0x110BA => .nukta,
1044 0x11100...0x11102 => .above,
1045 0x11133...0x11134 => .virama,
1046 0x11173...0x11173 => .nukta,
1047 0x111C0...0x111C0 => .virama,
1048 0x111CA...0x111CA => .nukta,
1049 0x11235...0x11235 => .virama,
1050 0x11236...0x11236 => .nukta,
1051 0x112E9...0x112E9 => .nukta,
1052 0x112EA...0x112EA => .virama,
1053 0x1133B...0x1133C => .nukta,
1054 0x1134D...0x1134D => .virama,
1055 0x11366...0x1136C => .above,
1056 0x11370...0x11374 => .above,
1057 0x11442...0x11442 => .virama,
1058 0x11446...0x11446 => .nukta,
1059 0x1145E...0x1145E => .above,
1060 0x114C2...0x114C2 => .virama,
1061 0x114C3...0x114C3 => .nukta,
1062 0x115BF...0x115BF => .virama,
1063 0x115C0...0x115C0 => .nukta,
1064 0x1163F...0x1163F => .virama,
1065 0x116B6...0x116B6 => .virama,
1066 0x116B7...0x116B7 => .nukta,
1067 0x1172B...0x1172B => .virama,
1068 0x11839...0x11839 => .virama,
1069 0x1183A...0x1183A => .nukta,
1070 0x1193D...0x1193E => .virama,
1071 0x11943...0x11943 => .nukta,
1072 0x119E0...0x119E0 => .virama,
1073 0x11A34...0x11A34 => .virama,
1074 0x11A47...0x11A47 => .virama,
1075 0x11A99...0x11A99 => .virama,
1076 0x11C3F...0x11C3F => .virama,
1077 0x11D42...0x11D42 => .nukta,
1078 0x11D44...0x11D45 => .virama,
1079 0x11D97...0x11D97 => .virama,
1080 0x11F41...0x11F42 => .virama,
1081 0x16AF0...0x16AF4 => .overlay,
1082 0x16B30...0x16B36 => .above,
1083 0x16FF0...0x16FF1 => .han_reading,
1084 0x1BC9E...0x1BC9E => .overlay,
1085 0x1D165...0x1D166 => .attached_above_right,
1086 0x1D167...0x1D169 => .overlay,
1087 0x1D16D...0x1D16D => .right,
1088 0x1D16E...0x1D172 => .attached_above_right,
1089 0x1D17B...0x1D182 => .below,
1090 0x1D185...0x1D189 => .above,
1091 0x1D18A...0x1D18B => .below,
1092 0x1D1AA...0x1D1AD => .above,
1093 0x1D242...0x1D244 => .above,
1094 0x1E000...0x1E006 => .above,
1095 0x1E008...0x1E018 => .above,
1096 0x1E01B...0x1E021 => .above,
1097 0x1E023...0x1E024 => .above,
1098 0x1E026...0x1E02A => .above,
1099 0x1E08F...0x1E08F => .above,
1100 0x1E130...0x1E136 => .above,
1101 0x1E2AE...0x1E2AE => .above,
1102 0x1E2EC...0x1E2EF => .above,
1103 0x1E4EC...0x1E4ED => .above_right,
1104 0x1E4EE...0x1E4EE => .below,
1105 0x1E4EF...0x1E4EF => .above,
1106 0x1E8D0...0x1E8D6 => .below,
1107 0x1E944...0x1E949 => .above,
1108 0x1E94A...0x1E94A => .nukta,
1109 else => .not_reordered,
1110 };
1111}
deps/aro/aro/char_info/identifier_tables.zig deleted-627
......@@ -1,627 +0,0 @@
1//! Adapted from the `unicode-ident` crate: https://github.com/dtolnay/unicode-ident
2//! and Unicode Standard Annex #31 https://www.unicode.org/reports/tr31/
3//! Licensed under the MIT License and the Unicode license
4
5pub const chunk = 64;
6
7pub const trie_start: [402]u8 align(8) = .{
8 0x04, 0x0B, 0x0F, 0x13, 0x17, 0x1B, 0x1F, 0x23, 0x27, 0x2D, 0x31, 0x34, 0x38, 0x3C, 0x40, 0x02,
9 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
10 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
11 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
12 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
13 0x05, 0x05, 0x51, 0x54, 0x58, 0x5C, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
14 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00,
15 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60, 0x64, 0x66,
16 0x6A, 0x6E, 0x72, 0x28, 0x76, 0x78, 0x7C, 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9E, 0xA2,
17 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00,
18 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
19 0x00, 0x00, 0x00, 0x00, 0x05, 0xB1, 0x00, 0xB5, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
20 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC8, 0x00, 0x00, 0x00, 0xAF,
23 0xCE, 0xD2, 0xD6, 0xBC, 0xDA, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
25 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
26 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
27 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
28 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
29 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05,
30 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
31 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00,
32 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
33 0x05, 0xE7,
34};
35
36pub const trie_continue: [1793]u8 align(8) = .{
37 0x08, 0x0D, 0x11, 0x15, 0x19, 0x1D, 0x21, 0x25, 0x2A, 0x2F, 0x31, 0x36, 0x3A, 0x3E, 0x42, 0x02,
38 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x4F, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
39 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
40 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
41 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
42 0x05, 0x05, 0x51, 0x56, 0x5A, 0x5E, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
43 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x64, 0x68,
45 0x6C, 0x70, 0x74, 0x28, 0x76, 0x7A, 0x7E, 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9B, 0xA0, 0xA4,
46 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x05, 0xB3, 0x00, 0xB7, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
49 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC, 0xC4, 0xC6, 0xCA, 0x00, 0xCC, 0x00, 0xAF,
52 0xD0, 0xD4, 0xD8, 0xBC, 0xDC, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00,
53 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
54 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
55 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
56 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
57 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
58 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05,
59 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
60 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00,
61 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
62 0x05, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0xC2,
150};
151
152pub const leaf: [7584]u8 align(64) = .{
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xAA, 0xFF, 0xFF, 0xFF, 0x3F,
160 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x5F, 0xDC, 0x1F, 0xCF, 0x0F, 0xFF, 0x1F, 0xDC, 0x1F,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
163 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
164 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
165 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
166 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xA0, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
171 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
172 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
173 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
174 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
175 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
176 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xB8,
178 0x40, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
179 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
180 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00,
181 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xB8,
182 0xC0, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
185 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
186 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00,
187 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
188 0xFB, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
190 0xFF, 0x01, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xB6, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF,
192 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x60, 0xC0, 0x00, 0x9C,
193 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
194 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x02, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x07, 0x30, 0x04,
195 0x00, 0x00, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF,
196 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x9F, 0xFF, 0xFD, 0xFF, 0x9F,
197 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
198 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x24,
199 0xFF, 0xFF, 0x3F, 0x04, 0x10, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0xFF,
200 0xFF, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0x01, 0xFF, 0x03, 0x00, 0xFE, 0xFF,
202 0xE1, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0x23, 0x00, 0x40, 0x00, 0xB0, 0x03, 0x00, 0x03, 0x10,
203 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x07, 0xFF, 0xFF,
204 0xFF, 0x7E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF,
205 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0xFF,
206 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0xF3, 0x9F, 0x79, 0x80, 0xB0, 0xCF, 0xFF, 0x03, 0x50,
207 0xE0, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0x03, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x1C, 0x00,
208 0xE0, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02,
209 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x00, 0xB0, 0x03, 0x00, 0x02, 0x00,
210 0xE8, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0xEE, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0xD3, 0x87, 0x39, 0x02, 0x5E, 0xC0, 0xFF, 0x3F, 0x00,
212 0xEE, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0xBF, 0x3B, 0x01, 0x00, 0xCF, 0xFF, 0x00, 0xFE,
213 0xEE, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0x9F, 0x39, 0xE0, 0xB0, 0xCF, 0xFF, 0x02, 0x00,
214 0xEC, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0xC3, 0xC7, 0x3D, 0x81, 0x00, 0xC0, 0xFF, 0x00, 0x00,
215 0xE0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0x23, 0x00, 0x00, 0x00, 0x27, 0x03, 0x00, 0x00, 0x00,
216 0xE1, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0x23, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x06, 0x00,
217 0xF0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00, 0x40, 0x70, 0x80, 0x03, 0x00, 0x00, 0xFC,
218 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xF3, 0xDF, 0x3D, 0x60, 0x27, 0xCF, 0xFF, 0x00, 0x00,
220 0xEF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0xF3, 0xDF, 0x3D, 0x60, 0x60, 0xCF, 0xFF, 0x0E, 0x00,
221 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7D, 0xF0, 0x80, 0xCF, 0xFF, 0x00, 0xFC,
222 0xEE, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x84, 0x5F, 0xFF, 0xC0, 0xFF, 0x0C, 0x00,
223 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0x05, 0x20, 0x5F, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00,
225 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00,
226 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x7F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
228 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0x3F, 0x5F, 0x7F, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00,
229 0x01, 0x00, 0x00, 0x03, 0xFF, 0x03, 0xA0, 0xC2, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0xFE, 0xFF,
230 0xDF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x80, 0x00, 0x00, 0x3F, 0x3C, 0x62, 0xC0, 0xE1, 0xFF,
232 0x03, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
233 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
234 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
235 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00,
236 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
238 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
239 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
240 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
241 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
242 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF,
244 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
245 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
246 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F,
247 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF,
248 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
249 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0xFE, 0x03, 0x00,
250 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F,
251 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
252 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
253 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
254 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
255 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
256 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
257 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
258 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01,
259 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xDF, 0x01, 0x00,
260 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00,
261 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
262 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01,
263 0xFF, 0xFF, 0x3F, 0x80, 0xFF, 0xFF, 0x1F, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xDF, 0x0D, 0x00,
264 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x30, 0xFF, 0x03, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
266 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
267 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
268 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0xB8, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
270 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
271 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x0F, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
272 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
273 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0xF8, 0xFF, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00,
277 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x9F,
278 0xFF, 0x03, 0xFF, 0x03, 0x80, 0x00, 0xFF, 0xBF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x03, 0x00, 0xF8, 0x0F, 0x00,
280 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
281 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F,
282 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x6F, 0x04,
283 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
284 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
286 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
287 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
288 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
289 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0xF0, 0x00, 0xFF, 0xFF,
290 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
292 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
294 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x80,
296 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x1F, 0xE2, 0xFF, 0x01, 0x00,
297 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
298 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
300 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x78, 0x0C, 0x00,
301 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
302 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00,
303 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
304 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0x0F, 0x00,
305 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x80,
306 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
307 0xE0, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
308 0xFF, 0xFF, 0x7F, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
309 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
310 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
311 0xE0, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
312 0xFF, 0xFF, 0x7F, 0xE6, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
313 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
314 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
315 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
316 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
317 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
318 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
319 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
320 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
321 0xFF, 0x1F, 0xFF, 0xFF, 0x00, 0x0C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x80,
322 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
323 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
324 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF,
325 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xBF,
326 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
327 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
328 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF,
329 0xBB, 0xF7, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
330 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x68,
331 0x00, 0xFC, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
332 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0xDF, 0xFF, 0x00, 0x7C,
333 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
334 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xE8,
335 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
336 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x7F,
337 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF7, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0xC4,
338 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x3E, 0x05, 0x00, 0x00, 0x38, 0xFF, 0x07, 0x1C, 0x00,
339 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF,
340 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00,
341 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0x7F, 0xFC,
342 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x38, 0xFF, 0xFF, 0x7C, 0x00,
343 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF,
344 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x37, 0xFF, 0x03,
345 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
346 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
347 0x7F, 0x00, 0xF8, 0xA0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
348 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
349 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
350 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
351 0x7F, 0x00, 0xF8, 0xE0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
352 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
353 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF,
354 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
355 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
356 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA,
358 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
359 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF,
360 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00,
361 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA,
362 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
363 0x00, 0x00, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF,
364 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00,
365 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
366 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
370 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
376 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
379 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
380 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
382 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
383 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7,
384 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
386 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
387 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7,
388 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x3F, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x91, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
390 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x37, 0x00,
391 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x01, 0x00, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
394 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00,
395 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00,
396 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x6F, 0xF0, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x87, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
398 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00,
399 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00,
400 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
403 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
407 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
412 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
415 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF,
416 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
417 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00,
418 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00,
419 0xF8, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x90, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0x00,
420 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
421 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x80,
422 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03,
423 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x00,
424 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xDE, 0xFF, 0x17, 0x00, 0x00, 0x00, 0x00,
425 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x0F, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
427 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0xE0, 0x03, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x03,
431 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xFB, 0x9F, 0x39, 0x81, 0xE0, 0xCF, 0x1F, 0x1F, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
434 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
437 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xC3, 0x03, 0x00, 0x00, 0x00,
438 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00,
441 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x11, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
446 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0x0F, 0xFF, 0x03, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80,
451 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00,
453 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x80,
455 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0xBF, 0xF9, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1B, 0x00, 0x00, 0x00,
457 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0x00, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
458 0xFF, 0x03, 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00,
463 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
464 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x6F,
469 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
470 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xBF, 0xFD, 0xFF, 0xFF,
472 0xFF, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x01, 0x00, 0xFF, 0x03, 0x00, 0x00, 0xFC, 0xFF,
474 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xB4, 0xFF, 0x00, 0xFF, 0x03, 0xBF, 0xFD, 0xFF, 0xFF,
476 0xFF, 0x7F, 0xFB, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x00,
479 0xF4, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
483 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x07, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00,
486 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
487 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE3, 0x07, 0xF8,
500 0xE7, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF,
508 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
509 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xE0,
510 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF,
512 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
513 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x0F, 0x00, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xE0,
514 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
522 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00,
523 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
524 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
528 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x6F, 0xFF, 0x7F,
533 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F,
534 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
539 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F,
540 0xFF, 0x01, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
544 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
550 0xFF, 0xFF, 0xFF, 0xDF, 0x64, 0xDE, 0xFF, 0xEB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
551 0xBF, 0xE7, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0x7B, 0x5F, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
552 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
553 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
554 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7,
555 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
556 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
558 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7,
559 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
560 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
561 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x00,
562 0x10, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x3F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x7F, 0xFF, 0xFF, 0xF9, 0xDB, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
570 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
590 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
594 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0xEF, 0xFF, 0xFF, 0xFF, 0x96, 0xFE, 0xF7, 0x0A, 0x84, 0xEA, 0x96, 0xAA, 0x96, 0xF7, 0xF7, 0x5E,
598 0xFF, 0xFB, 0xFF, 0x0F, 0xEE, 0xFB, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
602 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
603 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
604 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
605 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
606 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0xFF, 0xFF,
607 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
608 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
609 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
610 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
611 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
612 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
613 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
614 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
615 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
616 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
617 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
618 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627};
deps/aro/aro/features.zig deleted-76
......@@ -1,76 +0,0 @@
1const std = @import("std");
2const Compilation = @import("Compilation.zig");
3const target_util = @import("target.zig");
4
5/// Used to implement the __has_feature macro.
6pub fn hasFeature(comp: *Compilation, ext: []const u8) bool {
7 const list = .{
8 .assume_nonnull = true,
9 .attribute_analyzer_noreturn = true,
10 .attribute_availability = true,
11 .attribute_availability_with_message = true,
12 .attribute_availability_app_extension = true,
13 .attribute_availability_with_version_underscores = true,
14 .attribute_availability_tvos = true,
15 .attribute_availability_watchos = true,
16 .attribute_availability_with_strict = true,
17 .attribute_availability_with_replacement = true,
18 .attribute_availability_in_templates = true,
19 .attribute_availability_swift = true,
20 .attribute_cf_returns_not_retained = true,
21 .attribute_cf_returns_retained = true,
22 .attribute_cf_returns_on_parameters = true,
23 .attribute_deprecated_with_message = true,
24 .attribute_deprecated_with_replacement = true,
25 .attribute_ext_vector_type = true,
26 .attribute_ns_returns_not_retained = true,
27 .attribute_ns_returns_retained = true,
28 .attribute_ns_consumes_self = true,
29 .attribute_ns_consumed = true,
30 .attribute_cf_consumed = true,
31 .attribute_overloadable = true,
32 .attribute_unavailable_with_message = true,
33 .attribute_unused_on_fields = true,
34 .attribute_diagnose_if_objc = true,
35 .blocks = false, // TODO
36 .c_thread_safety_attributes = true,
37 .enumerator_attributes = true,
38 .nullability = true,
39 .nullability_on_arrays = true,
40 .nullability_nullable_result = true,
41 .c_alignas = comp.langopts.standard.atLeast(.c11),
42 .c_alignof = comp.langopts.standard.atLeast(.c11),
43 .c_atomic = comp.langopts.standard.atLeast(.c11),
44 .c_generic_selections = comp.langopts.standard.atLeast(.c11),
45 .c_static_assert = comp.langopts.standard.atLeast(.c11),
46 .c_thread_local = comp.langopts.standard.atLeast(.c11) and target_util.isTlsSupported(comp.target),
47 };
48 inline for (std.meta.fields(@TypeOf(list))) |f| {
49 if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
50 }
51 return false;
52}
53
54/// Used to implement the __has_extension macro.
55pub fn hasExtension(comp: *Compilation, ext: []const u8) bool {
56 const list = .{
57 // C11 features
58 .c_alignas = true,
59 .c_alignof = true,
60 .c_atomic = false, // TODO
61 .c_generic_selections = true,
62 .c_static_assert = true,
63 .c_thread_local = target_util.isTlsSupported(comp.target),
64 // misc
65 .overloadable_unmarked = false, // TODO
66 .statement_attributes_with_gnu_syntax = false, // TODO
67 .gnu_asm = true,
68 .gnu_asm_goto_with_outputs = true,
69 .matrix_types = false, // TODO
70 .matrix_types_scalar_division = false, // TODO
71 };
72 inline for (std.meta.fields(@TypeOf(list))) |f| {
73 if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
74 }
75 return false;
76}
deps/aro/aro/pragmas/gcc.zig deleted-199
......@@ -1,199 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const TokenIndex = @import("../Tree.zig").TokenIndex;
9
10const GCC = @This();
11
12pragma: Pragma = .{
13 .beforeParse = beforeParse,
14 .beforePreprocess = beforePreprocess,
15 .afterParse = afterParse,
16 .deinit = deinit,
17 .preprocessorHandler = preprocessorHandler,
18 .parserHandler = parserHandler,
19 .preserveTokens = preserveTokens,
20},
21original_options: Diagnostics.Options = .{},
22options_stack: std.ArrayListUnmanaged(Diagnostics.Options) = .{},
23
24const Directive = enum {
25 warning,
26 @"error",
27 diagnostic,
28 poison,
29 const Diagnostics = enum {
30 ignored,
31 warning,
32 @"error",
33 fatal,
34 push,
35 pop,
36 };
37};
38
39fn beforePreprocess(pragma: *Pragma, comp: *Compilation) void {
40 var self = @fieldParentPtr(GCC, "pragma", pragma);
41 self.original_options = comp.diagnostics.options;
42}
43
44fn beforeParse(pragma: *Pragma, comp: *Compilation) void {
45 var self = @fieldParentPtr(GCC, "pragma", pragma);
46 comp.diagnostics.options = self.original_options;
47 self.options_stack.items.len = 0;
48}
49
50fn afterParse(pragma: *Pragma, comp: *Compilation) void {
51 var self = @fieldParentPtr(GCC, "pragma", pragma);
52 comp.diagnostics.options = self.original_options;
53 self.options_stack.items.len = 0;
54}
55
56pub fn init(allocator: mem.Allocator) !*Pragma {
57 var gcc = try allocator.create(GCC);
58 gcc.* = .{};
59 return &gcc.pragma;
60}
61
62fn deinit(pragma: *Pragma, comp: *Compilation) void {
63 var self = @fieldParentPtr(GCC, "pragma", pragma);
64 self.options_stack.deinit(comp.gpa);
65 comp.gpa.destroy(self);
66}
67
68fn diagnosticHandler(self: *GCC, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
69 const diagnostic_tok = pp.tokens.get(start_idx);
70 if (diagnostic_tok.id == .nl) return;
71
72 const diagnostic = std.meta.stringToEnum(Directive.Diagnostics, pp.expandedSlice(diagnostic_tok)) orelse
73 return error.UnknownPragma;
74
75 switch (diagnostic) {
76 .ignored, .warning, .@"error", .fatal => {
77 const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
78 error.ExpectedStringLiteral => {
79 return pp.comp.addDiagnostic(.{
80 .tag = .pragma_requires_string_literal,
81 .loc = diagnostic_tok.loc,
82 .extra = .{ .str = "GCC diagnostic" },
83 }, diagnostic_tok.expansionSlice());
84 },
85 else => |e| return e,
86 };
87 if (!mem.startsWith(u8, str, "-W")) {
88 const next = pp.tokens.get(start_idx + 1);
89 return pp.comp.addDiagnostic(.{
90 .tag = .malformed_warning_check,
91 .loc = next.loc,
92 .extra = .{ .str = "GCC diagnostic" },
93 }, next.expansionSlice());
94 }
95 const new_kind: Diagnostics.Kind = switch (diagnostic) {
96 .ignored => .off,
97 .warning => .warning,
98 .@"error" => .@"error",
99 .fatal => .@"fatal error",
100 else => unreachable,
101 };
102
103 try pp.comp.diagnostics.set(str[2..], new_kind);
104 },
105 .push => try self.options_stack.append(pp.comp.gpa, pp.comp.diagnostics.options),
106 .pop => pp.comp.diagnostics.options = self.options_stack.popOrNull() orelse self.original_options,
107 }
108}
109
110fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
111 var self = @fieldParentPtr(GCC, "pragma", pragma);
112 const directive_tok = pp.tokens.get(start_idx + 1);
113 if (directive_tok.id == .nl) return;
114
115 const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse
116 return pp.comp.addDiagnostic(.{
117 .tag = .unknown_gcc_pragma,
118 .loc = directive_tok.loc,
119 }, directive_tok.expansionSlice());
120
121 switch (gcc_pragma) {
122 .warning, .@"error" => {
123 const text = Pragma.pasteTokens(pp, start_idx + 2) catch |err| switch (err) {
124 error.ExpectedStringLiteral => {
125 return pp.comp.addDiagnostic(.{
126 .tag = .pragma_requires_string_literal,
127 .loc = directive_tok.loc,
128 .extra = .{ .str = @tagName(gcc_pragma) },
129 }, directive_tok.expansionSlice());
130 },
131 else => |e| return e,
132 };
133 const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diagnostics.arena.allocator().dupe(u8, text) };
134 const diagnostic_tag: Diagnostics.Tag = if (gcc_pragma == .warning) .pragma_warning_message else .pragma_error_message;
135 return pp.comp.addDiagnostic(
136 .{ .tag = diagnostic_tag, .loc = directive_tok.loc, .extra = extra },
137 directive_tok.expansionSlice(),
138 );
139 },
140 .diagnostic => return self.diagnosticHandler(pp, start_idx + 2) catch |err| switch (err) {
141 error.UnknownPragma => {
142 const tok = pp.tokens.get(start_idx + 2);
143 return pp.comp.addDiagnostic(.{
144 .tag = .unknown_gcc_pragma_directive,
145 .loc = tok.loc,
146 }, tok.expansionSlice());
147 },
148 else => |e| return e,
149 },
150 .poison => {
151 var i: usize = 2;
152 while (true) : (i += 1) {
153 const tok = pp.tokens.get(start_idx + i);
154 if (tok.id == .nl) break;
155
156 if (!tok.id.isMacroIdentifier()) {
157 return pp.comp.addDiagnostic(.{
158 .tag = .pragma_poison_identifier,
159 .loc = tok.loc,
160 }, tok.expansionSlice());
161 }
162 const str = pp.expandedSlice(tok);
163 if (pp.defines.get(str) != null) {
164 try pp.comp.addDiagnostic(.{
165 .tag = .pragma_poison_macro,
166 .loc = tok.loc,
167 }, tok.expansionSlice());
168 }
169 try pp.poisoned_identifiers.put(str, {});
170 }
171 return;
172 },
173 }
174}
175
176fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
177 var self = @fieldParentPtr(GCC, "pragma", pragma);
178 const directive_tok = p.pp.tokens.get(start_idx + 1);
179 if (directive_tok.id == .nl) return;
180 const name = p.pp.expandedSlice(directive_tok);
181 if (mem.eql(u8, name, "diagnostic")) {
182 return self.diagnosticHandler(p.pp, start_idx + 2) catch |err| switch (err) {
183 error.UnknownPragma => {}, // handled during preprocessing
184 error.StopPreprocessing => unreachable, // Only used by #pragma once
185 else => |e| return e,
186 };
187 }
188}
189
190fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
191 const next = pp.tokens.get(start_idx + 1);
192 if (next.id != .nl) {
193 const name = pp.expandedSlice(next);
194 if (mem.eql(u8, name, "poison")) {
195 return false;
196 }
197 }
198 return true;
199}
deps/aro/aro/pragmas/message.zig deleted-50
......@@ -1,50 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const TokenIndex = @import("../Tree.zig").TokenIndex;
9const Source = @import("../Source.zig");
10
11const Message = @This();
12
13pragma: Pragma = .{
14 .deinit = deinit,
15 .preprocessorHandler = preprocessorHandler,
16},
17
18pub fn init(allocator: mem.Allocator) !*Pragma {
19 var once = try allocator.create(Message);
20 once.* = .{};
21 return &once.pragma;
22}
23
24fn deinit(pragma: *Pragma, comp: *Compilation) void {
25 const self = @fieldParentPtr(Message, "pragma", pragma);
26 comp.gpa.destroy(self);
27}
28
29fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
30 const message_tok = pp.tokens.get(start_idx);
31 const message_expansion_locs = message_tok.expansionSlice();
32
33 const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
34 error.ExpectedStringLiteral => {
35 return pp.comp.addDiagnostic(.{
36 .tag = .pragma_requires_string_literal,
37 .loc = message_tok.loc,
38 .extra = .{ .str = "message" },
39 }, message_expansion_locs);
40 },
41 else => |e| return e,
42 };
43
44 const loc = if (message_expansion_locs.len != 0)
45 message_expansion_locs[message_expansion_locs.len - 1]
46 else
47 message_tok.loc;
48 const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diagnostics.arena.allocator().dupe(u8, str) };
49 return pp.comp.addDiagnostic(.{ .tag = .pragma_message, .loc = loc, .extra = extra }, &.{});
50}
deps/aro/aro/pragmas/once.zig deleted-56
......@@ -1,56 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const TokenIndex = @import("../Tree.zig").TokenIndex;
9const Source = @import("../Source.zig");
10
11const Once = @This();
12
13pragma: Pragma = .{
14 .afterParse = afterParse,
15 .deinit = deinit,
16 .preprocessorHandler = preprocessorHandler,
17},
18pragma_once: std.AutoHashMap(Source.Id, void),
19preprocess_count: u32 = 0,
20
21pub fn init(allocator: mem.Allocator) !*Pragma {
22 var once = try allocator.create(Once);
23 once.* = .{
24 .pragma_once = std.AutoHashMap(Source.Id, void).init(allocator),
25 };
26 return &once.pragma;
27}
28
29fn afterParse(pragma: *Pragma, _: *Compilation) void {
30 var self = @fieldParentPtr(Once, "pragma", pragma);
31 self.pragma_once.clearRetainingCapacity();
32}
33
34fn deinit(pragma: *Pragma, comp: *Compilation) void {
35 var self = @fieldParentPtr(Once, "pragma", pragma);
36 self.pragma_once.deinit();
37 comp.gpa.destroy(self);
38}
39
40fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
41 var self = @fieldParentPtr(Once, "pragma", pragma);
42 const name_tok = pp.tokens.get(start_idx);
43 const next = pp.tokens.get(start_idx + 1);
44 if (next.id != .nl) {
45 try pp.comp.addDiagnostic(.{
46 .tag = .extra_tokens_directive_end,
47 .loc = name_tok.loc,
48 }, next.expansionSlice());
49 }
50 const seen = self.preprocess_count == pp.preprocess_count;
51 const prev = try self.pragma_once.fetchPut(name_tok.loc.id, {});
52 if (prev != null and !seen) {
53 return error.StopPreprocessing;
54 }
55 self.preprocess_count = pp.preprocess_count;
56}
deps/aro/aro/pragmas/pack.zig deleted-164
......@@ -1,164 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const Tree = @import("../Tree.zig");
9const TokenIndex = Tree.TokenIndex;
10
11const Pack = @This();
12
13pragma: Pragma = .{
14 .deinit = deinit,
15 .parserHandler = parserHandler,
16 .preserveTokens = preserveTokens,
17},
18stack: std.ArrayListUnmanaged(struct { label: []const u8, val: u8 }) = .{},
19
20pub fn init(allocator: mem.Allocator) !*Pragma {
21 var pack = try allocator.create(Pack);
22 pack.* = .{};
23 return &pack.pragma;
24}
25
26fn deinit(pragma: *Pragma, comp: *Compilation) void {
27 var self = @fieldParentPtr(Pack, "pragma", pragma);
28 self.stack.deinit(comp.gpa);
29 comp.gpa.destroy(self);
30}
31
32fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
33 var pack = @fieldParentPtr(Pack, "pragma", pragma);
34 var idx = start_idx + 1;
35 const l_paren = p.pp.tokens.get(idx);
36 if (l_paren.id != .l_paren) {
37 return p.comp.addDiagnostic(.{
38 .tag = .pragma_pack_lparen,
39 .loc = l_paren.loc,
40 }, l_paren.expansionSlice());
41 }
42 idx += 1;
43
44 // TODO -fapple-pragma-pack -fxl-pragma-pack
45 const apple_or_xl = false;
46 const tok_ids = p.pp.tokens.items(.id);
47 const arg = idx;
48 switch (tok_ids[arg]) {
49 .identifier => {
50 idx += 1;
51 const Action = enum {
52 show,
53 push,
54 pop,
55 };
56 const action = std.meta.stringToEnum(Action, p.tokSlice(arg)) orelse {
57 return p.errTok(.pragma_pack_unknown_action, arg);
58 };
59 switch (action) {
60 .show => {
61 try p.errExtra(.pragma_pack_show, arg, .{ .unsigned = p.pragma_pack orelse 8 });
62 },
63 .push, .pop => {
64 var new_val: ?u8 = null;
65 var label: ?[]const u8 = null;
66 if (tok_ids[idx] == .comma) {
67 idx += 1;
68 const next = idx;
69 idx += 1;
70 switch (tok_ids[next]) {
71 .pp_num => new_val = (try packInt(p, next)) orelse return,
72 .identifier => {
73 label = p.tokSlice(next);
74 if (tok_ids[idx] == .comma) {
75 idx += 1;
76 const int = idx;
77 idx += 1;
78 if (tok_ids[int] != .pp_num) return p.errTok(.pragma_pack_int_ident, int);
79 new_val = (try packInt(p, int)) orelse return;
80 }
81 },
82 else => return p.errTok(.pragma_pack_int_ident, next),
83 }
84 }
85 if (action == .push) {
86 try pack.stack.append(p.gpa, .{ .label = label orelse "", .val = p.pragma_pack orelse 8 });
87 } else {
88 pack.pop(p, label);
89 if (new_val != null) {
90 try p.errTok(.pragma_pack_undefined_pop, arg);
91 } else if (pack.stack.items.len == 0) {
92 try p.errTok(.pragma_pack_empty_stack, arg);
93 }
94 }
95 if (new_val) |some| {
96 p.pragma_pack = some;
97 }
98 },
99 }
100 },
101 .r_paren => if (apple_or_xl) {
102 pack.pop(p, null);
103 } else {
104 p.pragma_pack = null;
105 },
106 .pp_num => {
107 const new_val = (try packInt(p, arg)) orelse return;
108 idx += 1;
109 if (apple_or_xl) {
110 try pack.stack.append(p.gpa, .{ .label = "", .val = p.pragma_pack });
111 }
112 p.pragma_pack = new_val;
113 },
114 else => {},
115 }
116
117 if (tok_ids[idx] != .r_paren) {
118 return p.errTok(.pragma_pack_rparen, idx);
119 }
120}
121
122fn packInt(p: *Parser, tok_i: TokenIndex) Compilation.Error!?u8 {
123 const res = p.parseNumberToken(tok_i) catch |err| switch (err) {
124 error.ParsingFailed => {
125 try p.errTok(.pragma_pack_int, tok_i);
126 return null;
127 },
128 else => |e| return e,
129 };
130 const int = res.val.toInt(u64, p.comp) orelse 99;
131 switch (int) {
132 1, 2, 4, 8, 16 => return @intCast(int),
133 else => {
134 try p.errTok(.pragma_pack_int, tok_i);
135 return null;
136 },
137 }
138}
139
140fn pop(pack: *Pack, p: *Parser, maybe_label: ?[]const u8) void {
141 if (maybe_label) |label| {
142 var i = pack.stack.items.len;
143 while (i > 0) {
144 i -= 1;
145 if (std.mem.eql(u8, pack.stack.items[i].label, label)) {
146 const prev = pack.stack.orderedRemove(i);
147 p.pragma_pack = prev.val;
148 return;
149 }
150 }
151 } else {
152 const prev = pack.stack.popOrNull() orelse {
153 p.pragma_pack = 2;
154 return;
155 };
156 p.pragma_pack = prev.val;
157 }
158}
159
160fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
161 _ = pp;
162 _ = start_idx;
163 return true;
164}
deps/aro/aro/record_layout.zig deleted-671
......@@ -1,671 +0,0 @@
1//! Record layout code adapted from https://github.com/mahkoh/repr-c
2//! Licensed under MIT license: https://github.com/mahkoh/repr-c/tree/master/repc/facade
3
4const std = @import("std");
5const Type = @import("Type.zig");
6const Attribute = @import("Attribute.zig");
7const Compilation = @import("Compilation.zig");
8const Parser = @import("Parser.zig");
9const Record = Type.Record;
10const Field = Record.Field;
11const TypeLayout = Type.TypeLayout;
12const FieldLayout = Type.FieldLayout;
13const target_util = @import("target.zig");
14
15const BITS_PER_BYTE = 8;
16
17const OngoingBitfield = struct {
18 size_bits: u64,
19 unused_size_bits: u64,
20};
21
22const SysVContext = struct {
23 /// Does the record have an __attribute__((packed)) annotation.
24 attr_packed: bool,
25 /// The value of #pragma pack(N) at the type level if any.
26 max_field_align_bits: ?u64,
27 /// The alignment of this record.
28 aligned_bits: u32,
29 is_union: bool,
30 /// The size of the record. This might not be a multiple of 8 if the record contains bit-fields.
31 /// For structs, this is also the offset of the first bit after the last field.
32 size_bits: u64,
33 /// non-null if the previous field was a non-zero-sized bit-field. Only used by MinGW.
34 ongoing_bitfield: ?OngoingBitfield,
35
36 comp: *const Compilation,
37
38 fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) SysVContext {
39 var pack_value: ?u64 = null;
40 if (pragma_pack) |pak| {
41 pack_value = pak * BITS_PER_BYTE;
42 }
43 var req_align: u29 = BITS_PER_BYTE;
44 if (ty.requestedAlignment(comp)) |aln| {
45 req_align = aln * BITS_PER_BYTE;
46 }
47 return SysVContext{
48 .attr_packed = ty.hasAttribute(.@"packed"),
49 .max_field_align_bits = pack_value,
50 .aligned_bits = req_align,
51 .is_union = ty.is(.@"union"),
52 .size_bits = 0,
53 .comp = comp,
54 .ongoing_bitfield = null,
55 };
56 }
57
58 fn layoutFields(self: *SysVContext, rec: *const Record) void {
59 for (rec.fields, 0..) |*fld, fld_indx| {
60 if (fld.ty.specifier == .invalid) continue;
61 const type_layout = computeLayout(fld.ty, self.comp);
62
63 var field_attrs: ?[]const Attribute = null;
64 if (rec.field_attributes) |attrs| {
65 field_attrs = attrs[fld_indx];
66 }
67 if (self.comp.target.isMinGW()) {
68 fld.layout = self.layoutMinGWField(fld, field_attrs, type_layout);
69 } else {
70 if (fld.isRegularField()) {
71 fld.layout = self.layoutRegularField(field_attrs, type_layout);
72 } else {
73 fld.layout = self.layoutBitField(field_attrs, type_layout, fld.isNamed(), fld.specifiedBitWidth());
74 }
75 }
76 }
77 }
78
79 /// On MinGW the alignment of the field is calculated in the usual way except that the alignment of
80 /// the underlying type is ignored in three cases
81 /// - the field is packed
82 /// - the field is a bit-field and the previous field was a non-zero-sized bit-field with the same type size
83 /// - the field is a zero-sized bit-field and the previous field was not a non-zero-sized bit-field
84 /// See test case 0068.
85 fn ignoreTypeAlignment(is_attr_packed: bool, bit_width: ?u32, ongoing_bitfield: ?OngoingBitfield, fld_layout: TypeLayout) bool {
86 if (is_attr_packed) return true;
87 if (bit_width) |width| {
88 if (ongoing_bitfield) |ongoing| {
89 if (ongoing.size_bits == fld_layout.size_bits) return true;
90 } else {
91 if (width == 0) return true;
92 }
93 }
94 return false;
95 }
96
97 fn layoutMinGWField(
98 self: *SysVContext,
99 field: *const Field,
100 field_attrs: ?[]const Attribute,
101 field_layout: TypeLayout,
102 ) FieldLayout {
103 const annotation_alignment_bits = BITS_PER_BYTE * (Type.annotationAlignment(self.comp, field_attrs) orelse 1);
104 const is_attr_packed = self.attr_packed or isPacked(field_attrs);
105 const ignore_type_alignment = ignoreTypeAlignment(is_attr_packed, field.bit_width, self.ongoing_bitfield, field_layout);
106
107 var field_alignment_bits: u64 = field_layout.field_alignment_bits;
108 if (ignore_type_alignment) {
109 field_alignment_bits = BITS_PER_BYTE;
110 }
111 field_alignment_bits = @max(field_alignment_bits, annotation_alignment_bits);
112 if (self.max_field_align_bits) |bits| {
113 field_alignment_bits = @min(field_alignment_bits, bits);
114 }
115
116 // The field affects the record alignment in one of three cases
117 // - the field is a regular field
118 // - the field is a zero-width bit-field following a non-zero-width bit-field
119 // - the field is a non-zero-width bit-field and not packed.
120 // See test case 0069.
121 const update_record_alignment =
122 field.isRegularField() or
123 (field.specifiedBitWidth() == 0 and self.ongoing_bitfield != null) or
124 (field.specifiedBitWidth() != 0 and !is_attr_packed);
125
126 // If a field affects the alignment of a record, the alignment is calculated in the
127 // usual way except that __attribute__((packed)) is ignored on a zero-width bit-field.
128 // See test case 0068.
129 if (update_record_alignment) {
130 var ty_alignment_bits = field_layout.field_alignment_bits;
131 if (is_attr_packed and (field.isRegularField() or field.specifiedBitWidth() != 0)) {
132 ty_alignment_bits = BITS_PER_BYTE;
133 }
134 ty_alignment_bits = @max(ty_alignment_bits, annotation_alignment_bits);
135 if (self.max_field_align_bits) |bits| {
136 ty_alignment_bits = @intCast(@min(ty_alignment_bits, bits));
137 }
138 self.aligned_bits = @max(self.aligned_bits, ty_alignment_bits);
139 }
140
141 // NOTE: ty_alignment_bits and field_alignment_bits are different in the following case:
142 // Y = { size: 64, alignment: 64 }struct {
143 // { offset: 0, size: 1 }c { size: 8, alignment: 8 }char:1,
144 // @attr_packed _ { size: 64, alignment: 64 }long long:0,
145 // { offset: 8, size: 8 }d { size: 8, alignment: 8 }char,
146 // }
147 if (field.isRegularField()) {
148 return self.layoutRegularFieldMinGW(field_layout.size_bits, field_alignment_bits);
149 } else {
150 return self.layoutBitFieldMinGW(field_layout.size_bits, field_alignment_bits, field.isNamed(), field.specifiedBitWidth());
151 }
152 }
153
154 fn layoutBitFieldMinGW(
155 self: *SysVContext,
156 ty_size_bits: u64,
157 field_alignment_bits: u64,
158 is_named: bool,
159 width: u64,
160 ) FieldLayout {
161 std.debug.assert(width <= ty_size_bits); // validated in parser
162
163 // In a union, the size of the underlying type does not affect the size of the union.
164 // See test case 0070.
165 if (self.is_union) {
166 self.size_bits = @max(self.size_bits, width);
167 if (!is_named) return .{};
168 return .{
169 .offset_bits = 0,
170 .size_bits = width,
171 };
172 }
173 if (width == 0) {
174 self.ongoing_bitfield = null;
175 } else {
176 // If there is an ongoing bit-field in a struct whose underlying type has the same size and
177 // if there is enough space left to place this bit-field, then this bit-field is placed in
178 // the ongoing bit-field and the size of the struct is not affected by this
179 // bit-field. See test case 0037.
180 if (self.ongoing_bitfield) |*ongoing| {
181 if (ongoing.size_bits == ty_size_bits and ongoing.unused_size_bits >= width) {
182 const offset_bits = self.size_bits - ongoing.unused_size_bits;
183 ongoing.unused_size_bits -= width;
184 if (!is_named) return .{};
185 return .{
186 .offset_bits = offset_bits,
187 .size_bits = width,
188 };
189 }
190 }
191 // Otherwise this field is part of a new ongoing bit-field.
192 self.ongoing_bitfield = .{
193 .size_bits = ty_size_bits,
194 .unused_size_bits = ty_size_bits - width,
195 };
196 }
197 const offset_bits = std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
198 self.size_bits = if (width == 0) offset_bits else offset_bits + ty_size_bits;
199 if (!is_named) return .{};
200 return .{
201 .offset_bits = offset_bits,
202 .size_bits = width,
203 };
204 }
205
206 fn layoutRegularFieldMinGW(
207 self: *SysVContext,
208 ty_size_bits: u64,
209 field_alignment_bits: u64,
210 ) FieldLayout {
211 self.ongoing_bitfield = null;
212 // A struct field starts at the next offset in the struct that is properly
213 // aligned with respect to the start of the struct. See test case 0033.
214 // A union field always starts at offset 0.
215 const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
216
217 // Set the size of the record to the maximum of the current size and the end of
218 // the field. See test case 0034.
219 self.size_bits = @max(self.size_bits, offset_bits + ty_size_bits);
220
221 return .{
222 .offset_bits = offset_bits,
223 .size_bits = ty_size_bits,
224 };
225 }
226
227 fn layoutRegularField(
228 self: *SysVContext,
229 fld_attrs: ?[]const Attribute,
230 fld_layout: TypeLayout,
231 ) FieldLayout {
232 var fld_align_bits = fld_layout.field_alignment_bits;
233
234 // If the struct or the field is packed, then the alignment of the underlying type is
235 // ignored. See test case 0084.
236 if (self.attr_packed or isPacked(fld_attrs)) {
237 fld_align_bits = BITS_PER_BYTE;
238 }
239
240 // The field alignment can be increased by __attribute__((aligned)) annotations on the
241 // field. See test case 0085.
242 if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
243 fld_align_bits = @max(fld_align_bits, anno * BITS_PER_BYTE);
244 }
245
246 // #pragma pack takes precedence over all other attributes. See test cases 0084 and
247 // 0085.
248 if (self.max_field_align_bits) |req_bits| {
249 fld_align_bits = @intCast(@min(fld_align_bits, req_bits));
250 }
251
252 // A struct field starts at the next offset in the struct that is properly
253 // aligned with respect to the start of the struct.
254 const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, fld_align_bits);
255 const size_bits = fld_layout.size_bits;
256
257 // The alignment of a record is the maximum of its field alignments. See test cases
258 // 0084, 0085, 0086.
259 self.size_bits = @max(self.size_bits, offset_bits + size_bits);
260 self.aligned_bits = @max(self.aligned_bits, fld_align_bits);
261
262 return .{
263 .offset_bits = offset_bits,
264 .size_bits = size_bits,
265 };
266 }
267
268 fn layoutBitField(
269 self: *SysVContext,
270 fld_attrs: ?[]const Attribute,
271 fld_layout: TypeLayout,
272 is_named: bool,
273 bit_width: u64,
274 ) FieldLayout {
275 const ty_size_bits = fld_layout.size_bits;
276 var ty_fld_algn_bits: u32 = fld_layout.field_alignment_bits;
277
278 if (bit_width > 0) {
279 std.debug.assert(bit_width <= ty_size_bits); // Checked in parser
280 // Some targets ignore the alignment of the underlying type when laying out
281 // non-zero-sized bit-fields. See test case 0072. On such targets, bit-fields never
282 // cross a storage boundary. See test case 0081.
283 if (target_util.ignoreNonZeroSizedBitfieldTypeAlignment(self.comp.target)) {
284 ty_fld_algn_bits = 1;
285 }
286 } else {
287 // Some targets ignore the alignment of the underlying type when laying out
288 // zero-sized bit-fields. See test case 0073.
289 if (target_util.ignoreZeroSizedBitfieldTypeAlignment(self.comp.target)) {
290 ty_fld_algn_bits = 1;
291 }
292 // Some targets have a minimum alignment of zero-sized bit-fields. See test case
293 // 0074.
294 if (target_util.minZeroWidthBitfieldAlignment(self.comp.target)) |target_align| {
295 ty_fld_algn_bits = @max(ty_fld_algn_bits, target_align);
296 }
297 }
298
299 // __attribute__((packed)) on the record is identical to __attribute__((packed)) on each
300 // field. See test case 0067.
301 const attr_packed = self.attr_packed or isPacked(fld_attrs);
302 const has_packing_annotation = attr_packed or self.max_field_align_bits != null;
303
304 const annotation_alignment: u32 = if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| anno * BITS_PER_BYTE else 1;
305
306 const first_unused_bit: u64 = if (self.is_union) 0 else self.size_bits;
307 var field_align_bits: u64 = 1;
308
309 if (bit_width == 0) {
310 field_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
311 } else if (self.comp.langopts.emulate == .gcc) {
312 // On GCC, the field alignment is at least the alignment requested by annotations
313 // except as restricted by #pragma pack. See test case 0083.
314 field_align_bits = annotation_alignment;
315 if (self.max_field_align_bits) |max_bits| {
316 field_align_bits = @min(annotation_alignment, max_bits);
317 }
318
319 // On GCC, if there are no packing annotations and
320 // - the field would otherwise start at an offset such that it would cross a
321 // storage boundary or
322 // - the alignment of the type is larger than its size,
323 // then it is aligned to the type's field alignment. See test case 0083.
324 if (!has_packing_annotation) {
325 const start_bit = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
326
327 const does_field_cross_boundary = start_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
328
329 if (ty_fld_algn_bits > ty_size_bits or does_field_cross_boundary) {
330 field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
331 }
332 }
333 } else {
334 std.debug.assert(self.comp.langopts.emulate == .clang);
335
336 // On Clang, the alignment requested by annotations is not respected if it is
337 // larger than the value of #pragma pack. See test case 0083.
338 if (annotation_alignment <= self.max_field_align_bits orelse std.math.maxInt(u29)) {
339 field_align_bits = @max(field_align_bits, annotation_alignment);
340 }
341 // On Clang, if there are no packing annotations and the field would cross a
342 // storage boundary if it were positioned at the first unused bit in the record,
343 // it is aligned to the type's field alignment. See test case 0083.
344 if (!has_packing_annotation) {
345 const does_field_cross_boundary = first_unused_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
346
347 if (does_field_cross_boundary)
348 field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
349 }
350 }
351
352 const offset_bits = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
353 self.size_bits = @max(self.size_bits, offset_bits + bit_width);
354
355 // Unnamed fields do not contribute to the record alignment except on a few targets.
356 // See test case 0079.
357 if (is_named or target_util.unnamedFieldAffectsAlignment(self.comp.target)) {
358 var inherited_align_bits: u32 = undefined;
359
360 if (bit_width == 0) {
361 // If the width is 0, #pragma pack and __attribute__((packed)) are ignored.
362 // See test case 0075.
363 inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
364 } else if (self.max_field_align_bits) |max_align_bits| {
365 // Otherwise, if a #pragma pack is in effect, __attribute__((packed)) on the field or
366 // record is ignored. See test case 0076.
367 inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
368 inherited_align_bits = @intCast(@min(inherited_align_bits, max_align_bits));
369 } else if (attr_packed) {
370 // Otherwise, if the field or the record is packed, the field alignment is 1 bit unless
371 // it is explicitly increased with __attribute__((aligned)). See test case 0077.
372 inherited_align_bits = annotation_alignment;
373 } else {
374 // Otherwise, the field alignment is the field alignment of the underlying type unless
375 // it is explicitly increased with __attribute__((aligned)). See test case 0078.
376 inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
377 }
378 self.aligned_bits = @max(self.aligned_bits, inherited_align_bits);
379 }
380
381 if (!is_named) return .{};
382 return .{
383 .size_bits = bit_width,
384 .offset_bits = offset_bits,
385 };
386 }
387};
388
389const MsvcContext = struct {
390 req_align_bits: u32,
391 max_field_align_bits: ?u32,
392 /// The alignment of pointers that point to an object of this type. This is greater than or equal
393 /// to the required alignment. Once all fields have been laid out, the size of the record will be
394 /// rounded up to this value.
395 pointer_align_bits: u32,
396 /// The alignment of this type when it is used as a record field. This is greater than or equal to
397 /// the pointer alignment.
398 field_align_bits: u32,
399 size_bits: u64,
400 ongoing_bitfield: ?OngoingBitfield,
401 contains_non_bitfield: bool,
402 is_union: bool,
403 comp: *const Compilation,
404
405 fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) MsvcContext {
406 var pack_value: ?u32 = null;
407 if (ty.hasAttribute(.@"packed")) {
408 // __attribute__((packed)) behaves like #pragma pack(1) in clang. See test case 0056.
409 pack_value = BITS_PER_BYTE;
410 }
411 if (pack_value == null) {
412 if (pragma_pack) |pack| {
413 pack_value = pack * BITS_PER_BYTE;
414 }
415 }
416 if (pack_value) |pack| {
417 pack_value = msvcPragmaPack(comp, pack);
418 }
419
420 // The required alignment can be increased by adding a __declspec(align)
421 // annotation. See test case 0023.
422 var must_align: u29 = BITS_PER_BYTE;
423 if (ty.requestedAlignment(comp)) |req_align| {
424 must_align = req_align * BITS_PER_BYTE;
425 }
426 return MsvcContext{
427 .req_align_bits = must_align,
428 .pointer_align_bits = must_align,
429 .field_align_bits = must_align,
430 .size_bits = 0,
431 .max_field_align_bits = pack_value,
432 .ongoing_bitfield = null,
433 .contains_non_bitfield = false,
434 .is_union = ty.is(.@"union"),
435 .comp = comp,
436 };
437 }
438
439 fn layoutField(self: *MsvcContext, fld: *const Field, fld_attrs: ?[]const Attribute) FieldLayout {
440 const type_layout = computeLayout(fld.ty, self.comp);
441
442 // The required alignment of the field is the maximum of the required alignment of the
443 // underlying type and the __declspec(align) annotation on the field itself.
444 // See test case 0028.
445 var req_align = type_layout.required_alignment_bits;
446 if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
447 req_align = @max(anno * BITS_PER_BYTE, req_align);
448 }
449
450 // The required alignment of a record is the maximum of the required alignments of its
451 // fields except that the required alignment of bitfields is ignored.
452 // See test case 0029.
453 if (fld.isRegularField()) {
454 self.req_align_bits = @max(self.req_align_bits, req_align);
455 }
456
457 // The offset of the field is based on the field alignment of the underlying type.
458 // See test case 0027.
459 var fld_align_bits = type_layout.field_alignment_bits;
460 if (self.max_field_align_bits) |max_align| {
461 fld_align_bits = @min(fld_align_bits, max_align);
462 }
463 // check the requested alignment of the field type.
464 if (fld.ty.requestedAlignment(self.comp)) |type_req_align| {
465 fld_align_bits = @max(fld_align_bits, type_req_align * 8);
466 }
467
468 if (isPacked(fld_attrs)) {
469 // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
470 // pack(1) had been applied only to this field. See test case 0057.
471 fld_align_bits = BITS_PER_BYTE;
472 }
473 // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
474 // pack(1) had been applied only to this field. See test case 0057.
475 fld_align_bits = @max(fld_align_bits, req_align);
476 if (fld.isRegularField()) {
477 return self.layoutRegularField(type_layout.size_bits, fld_align_bits);
478 } else {
479 return self.layoutBitField(type_layout.size_bits, fld_align_bits, fld.specifiedBitWidth());
480 }
481 }
482
483 fn layoutBitField(self: *MsvcContext, ty_size_bits: u64, field_align: u32, bit_width: u32) FieldLayout {
484 if (bit_width == 0) {
485 // A zero-sized bit-field that does not follow a non-zero-sized bit-field does not affect
486 // the overall layout of the record. Even in a union where the order would otherwise
487 // not matter. See test case 0035.
488 if (self.ongoing_bitfield) |_| {
489 self.ongoing_bitfield = null;
490 } else {
491 // this field takes 0 space.
492 return .{ .offset_bits = self.size_bits, .size_bits = bit_width };
493 }
494 } else {
495 std.debug.assert(bit_width <= ty_size_bits);
496 // If there is an ongoing bit-field in a struct whose underlying type has the same size and
497 // if there is enough space left to place this bit-field, then this bit-field is placed in
498 // the ongoing bit-field and the overall layout of the struct is not affected by this
499 // bit-field. See test case 0037.
500 if (!self.is_union) {
501 if (self.ongoing_bitfield) |*p| {
502 if (p.size_bits == ty_size_bits and p.unused_size_bits >= bit_width) {
503 const offset_bits = self.size_bits - p.unused_size_bits;
504 p.unused_size_bits -= bit_width;
505 return .{ .offset_bits = offset_bits, .size_bits = bit_width };
506 }
507 }
508 }
509 // Otherwise this field is part of a new ongoing bit-field.
510 self.ongoing_bitfield = .{ .size_bits = ty_size_bits, .unused_size_bits = ty_size_bits - bit_width };
511 }
512 const offset_bits = if (!self.is_union) bits: {
513 // This is the one place in the layout of a record where the pointer alignment might
514 // get assigned a smaller value than the field alignment. This can only happen if
515 // the field or the type of the field has a required alignment. Otherwise the value
516 // of field_alignment_bits is already bound by max_field_alignment_bits.
517 // See test case 0038.
518 const p_align = if (self.max_field_align_bits) |max_fld_align|
519 @min(max_fld_align, field_align)
520 else
521 field_align;
522 self.pointer_align_bits = @max(self.pointer_align_bits, p_align);
523 self.field_align_bits = @max(self.field_align_bits, field_align);
524
525 const offset_bits = std.mem.alignForward(u64, self.size_bits, field_align);
526 self.size_bits = if (bit_width == 0) offset_bits else offset_bits + ty_size_bits;
527
528 break :bits offset_bits;
529 } else bits: {
530 // Bit-fields do not affect the alignment of a union. See test case 0041.
531 self.size_bits = @max(self.size_bits, ty_size_bits);
532 break :bits 0;
533 };
534 return .{ .offset_bits = offset_bits, .size_bits = bit_width };
535 }
536
537 fn layoutRegularField(self: *MsvcContext, size_bits: u64, field_align: u32) FieldLayout {
538 self.contains_non_bitfield = true;
539 self.ongoing_bitfield = null;
540 // The alignment of the field affects both the pointer alignment and the field
541 // alignment of the record. See test case 0032.
542 self.pointer_align_bits = @max(self.pointer_align_bits, field_align);
543 self.field_align_bits = @max(self.field_align_bits, field_align);
544 const offset_bits = switch (self.is_union) {
545 true => 0,
546 false => std.mem.alignForward(u64, self.size_bits, field_align),
547 };
548 self.size_bits = @max(self.size_bits, offset_bits + size_bits);
549 return .{ .offset_bits = offset_bits, .size_bits = size_bits };
550 }
551 fn handleZeroSizedRecord(self: *MsvcContext) void {
552 if (self.is_union) {
553 // MSVC does not allow unions without fields.
554 // If all fields in a union have size 0, the size of the union is set to
555 // - its field alignment if it contains at least one non-bitfield
556 // - 4 bytes if it contains only bitfields
557 // See test case 0025.
558 if (self.contains_non_bitfield) {
559 self.size_bits = self.field_align_bits;
560 } else {
561 self.size_bits = 4 * BITS_PER_BYTE;
562 }
563 } else {
564 // If all fields in a struct have size 0, its size is set to its required alignment
565 // but at least to 4 bytes. See test case 0026.
566 self.size_bits = @max(self.req_align_bits, 4 * BITS_PER_BYTE);
567 self.pointer_align_bits = @intCast(@min(self.pointer_align_bits, self.size_bits));
568 }
569 }
570};
571
572pub fn compute(rec: *Type.Record, ty: Type, comp: *const Compilation, pragma_pack: ?u8) void {
573 switch (comp.langopts.emulate) {
574 .gcc, .clang => {
575 var context = SysVContext.init(ty, comp, pragma_pack);
576
577 context.layoutFields(rec);
578
579 context.size_bits = std.mem.alignForward(u64, context.size_bits, context.aligned_bits);
580
581 rec.type_layout = .{
582 .size_bits = context.size_bits,
583 .field_alignment_bits = context.aligned_bits,
584 .pointer_alignment_bits = context.aligned_bits,
585 .required_alignment_bits = BITS_PER_BYTE,
586 };
587 },
588 .msvc => {
589 var context = MsvcContext.init(ty, comp, pragma_pack);
590 for (rec.fields, 0..) |*fld, fld_indx| {
591 if (fld.ty.specifier == .invalid) continue;
592 var field_attrs: ?[]const Attribute = null;
593 if (rec.field_attributes) |attrs| {
594 field_attrs = attrs[fld_indx];
595 }
596
597 fld.layout = context.layoutField(fld, field_attrs);
598 }
599 if (context.size_bits == 0) {
600 // As an extension, MSVC allows records that only contain zero-sized bitfields and empty
601 // arrays. Such records would be zero-sized but this case is handled here separately to
602 // ensure that there are no zero-sized records.
603 context.handleZeroSizedRecord();
604 }
605 context.size_bits = std.mem.alignForward(u64, context.size_bits, context.pointer_align_bits);
606 rec.type_layout = .{
607 .size_bits = context.size_bits,
608 .field_alignment_bits = context.field_align_bits,
609 .pointer_alignment_bits = context.pointer_align_bits,
610 .required_alignment_bits = context.req_align_bits,
611 };
612 },
613 }
614}
615
616fn computeLayout(ty: Type, comp: *const Compilation) TypeLayout {
617 if (ty.getRecord()) |rec| {
618 const requested = BITS_PER_BYTE * (ty.requestedAlignment(comp) orelse 0);
619 return .{
620 .size_bits = rec.type_layout.size_bits,
621 .pointer_alignment_bits = @max(requested, rec.type_layout.pointer_alignment_bits),
622 .field_alignment_bits = @max(requested, rec.type_layout.field_alignment_bits),
623 .required_alignment_bits = rec.type_layout.required_alignment_bits,
624 };
625 } else {
626 const type_align = ty.alignof(comp) * BITS_PER_BYTE;
627 return .{
628 .size_bits = ty.bitSizeof(comp) orelse 0,
629 .pointer_alignment_bits = type_align,
630 .field_alignment_bits = type_align,
631 .required_alignment_bits = BITS_PER_BYTE,
632 };
633 }
634}
635
636fn isPacked(attrs: ?[]const Attribute) bool {
637 const a = attrs orelse return false;
638
639 for (a) |attribute| {
640 if (attribute.tag != .@"packed") continue;
641 return true;
642 }
643 return false;
644}
645
646// The effect of #pragma pack(N) depends on the target.
647//
648// x86: By default, there is no maximum field alignment. N={1,2,4} set the maximum field
649// alignment to that value. All other N activate the default.
650// x64: By default, there is no maximum field alignment. N={1,2,4,8} set the maximum field
651// alignment to that value. All other N activate the default.
652// arm: By default, the maximum field alignment is 8. N={1,2,4,8,16} set the maximum field
653// alignment to that value. All other N activate the default.
654// arm64: By default, the maximum field alignment is 8. N={1,2,4,8} set the maximum field
655// alignment to that value. N=16 disables the maximum field alignment. All other N
656// activate the default.
657//
658// See test case 0020.
659pub fn msvcPragmaPack(comp: *const Compilation, pack: u32) ?u32 {
660 return switch (pack) {
661 8, 16, 32 => pack,
662 64 => if (comp.target.cpu.arch == .x86) null else pack,
663 128 => if (comp.target.cpu.arch == .thumb) pack else null,
664 else => {
665 return switch (comp.target.cpu.arch) {
666 .thumb, .aarch64 => 64,
667 else => null,
668 };
669 },
670 };
671}
deps/aro/aro/target.zig deleted-830
......@@ -1,830 +0,0 @@
1const std = @import("std");
2const LangOpts = @import("LangOpts.zig");
3const Type = @import("Type.zig");
4const TargetSet = @import("Builtins/Properties.zig").TargetSet;
5
6/// intmax_t for this target
7pub fn intMaxType(target: std.Target) Type {
8 switch (target.cpu.arch) {
9 .aarch64,
10 .aarch64_be,
11 .sparc64,
12 => if (target.os.tag != .openbsd) return .{ .specifier = .long },
13
14 .bpfel,
15 .bpfeb,
16 .loongarch64,
17 .riscv64,
18 .powerpc64,
19 .powerpc64le,
20 .tce,
21 .tcele,
22 .ve,
23 => return .{ .specifier = .long },
24
25 .x86_64 => switch (target.os.tag) {
26 .windows, .openbsd => {},
27 else => switch (target.abi) {
28 .gnux32, .muslx32 => {},
29 else => return .{ .specifier = .long },
30 },
31 },
32
33 else => {},
34 }
35 return .{ .specifier = .long_long };
36}
37
38/// intptr_t for this target
39pub fn intPtrType(target: std.Target) Type {
40 switch (target.os.tag) {
41 .haiku => return .{ .specifier = .long },
42 .nacl => return .{ .specifier = .int },
43 else => {},
44 }
45
46 switch (target.cpu.arch) {
47 .aarch64, .aarch64_be => switch (target.os.tag) {
48 .windows => return .{ .specifier = .long_long },
49 else => {},
50 },
51
52 .msp430,
53 .csky,
54 .loongarch32,
55 .riscv32,
56 .xcore,
57 .hexagon,
58 .tce,
59 .tcele,
60 .m68k,
61 .spir,
62 .spirv32,
63 .arc,
64 .avr,
65 => return .{ .specifier = .int },
66
67 .sparc, .sparcel => switch (target.os.tag) {
68 .netbsd, .openbsd => {},
69 else => return .{ .specifier = .int },
70 },
71
72 .powerpc, .powerpcle => switch (target.os.tag) {
73 .linux, .freebsd, .netbsd => return .{ .specifier = .int },
74 else => {},
75 },
76
77 // 32-bit x86 Darwin, OpenBSD, and RTEMS use long (the default); others use int
78 .x86 => switch (target.os.tag) {
79 .openbsd, .rtems => {},
80 else => if (!target.os.tag.isDarwin()) return .{ .specifier = .int },
81 },
82
83 .x86_64 => switch (target.os.tag) {
84 .windows => return .{ .specifier = .long_long },
85 else => switch (target.abi) {
86 .gnux32, .muslx32 => return .{ .specifier = .int },
87 else => {},
88 },
89 },
90
91 else => {},
92 }
93
94 return .{ .specifier = .long };
95}
96
97/// int16_t for this target
98pub fn int16Type(target: std.Target) Type {
99 return switch (target.cpu.arch) {
100 .avr => .{ .specifier = .int },
101 else => .{ .specifier = .short },
102 };
103}
104
105/// int64_t for this target
106pub fn int64Type(target: std.Target) Type {
107 switch (target.cpu.arch) {
108 .loongarch64,
109 .ve,
110 .riscv64,
111 .powerpc64,
112 .powerpc64le,
113 .bpfel,
114 .bpfeb,
115 => return .{ .specifier = .long },
116
117 .sparc64 => return intMaxType(target),
118
119 .x86, .x86_64 => if (!target.isDarwin()) return intMaxType(target),
120 .aarch64, .aarch64_be => if (!target.isDarwin() and target.os.tag != .openbsd and target.os.tag != .windows) return .{ .specifier = .long },
121 else => {},
122 }
123 return .{ .specifier = .long_long };
124}
125
126/// This function returns 1 if function alignment is not observable or settable.
127pub fn defaultFunctionAlignment(target: std.Target) u8 {
128 return switch (target.cpu.arch) {
129 .arm, .armeb => 4,
130 .aarch64, .aarch64_32, .aarch64_be => 4,
131 .sparc, .sparcel, .sparc64 => 4,
132 .riscv64 => 2,
133 else => 1,
134 };
135}
136
137pub fn isTlsSupported(target: std.Target) bool {
138 if (target.isDarwin()) {
139 var supported = false;
140 switch (target.os.tag) {
141 .macos => supported = !(target.os.isAtLeast(.macos, .{ .major = 10, .minor = 7, .patch = 0 }) orelse false),
142 else => {},
143 }
144 return supported;
145 }
146 return switch (target.cpu.arch) {
147 .tce, .tcele, .bpfel, .bpfeb, .msp430, .nvptx, .nvptx64, .x86, .arm, .armeb, .thumb, .thumbeb => false,
148 else => true,
149 };
150}
151
152pub fn ignoreNonZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
153 switch (target.cpu.arch) {
154 .avr => return true,
155 .arm => {
156 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
157 switch (target.os.tag) {
158 .ios => return true,
159 else => return false,
160 }
161 }
162 },
163 else => return false,
164 }
165 return false;
166}
167
168pub fn ignoreZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
169 switch (target.cpu.arch) {
170 .avr => return true,
171 else => return false,
172 }
173}
174
175pub fn minZeroWidthBitfieldAlignment(target: std.Target) ?u29 {
176 switch (target.cpu.arch) {
177 .avr => return 8,
178 .arm => {
179 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
180 switch (target.os.tag) {
181 .ios => return 32,
182 else => return null,
183 }
184 } else return null;
185 },
186 else => return null,
187 }
188}
189
190pub fn unnamedFieldAffectsAlignment(target: std.Target) bool {
191 switch (target.cpu.arch) {
192 .aarch64 => {
193 if (target.isDarwin() or target.os.tag == .windows) return false;
194 return true;
195 },
196 .armeb => {
197 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
198 if (std.Target.Abi.default(target.cpu.arch, target.os) == .eabi) return true;
199 }
200 },
201 .arm => return true,
202 .avr => return true,
203 .thumb => {
204 if (target.os.tag == .windows) return false;
205 return true;
206 },
207 else => return false,
208 }
209 return false;
210}
211
212pub fn packAllEnums(target: std.Target) bool {
213 return switch (target.cpu.arch) {
214 .hexagon => true,
215 else => false,
216 };
217}
218
219/// Default alignment (in bytes) for __attribute__((aligned)) when no alignment is specified
220pub fn defaultAlignment(target: std.Target) u29 {
221 switch (target.cpu.arch) {
222 .avr => return 1,
223 .arm => if (target.isAndroid() or target.os.tag == .ios) return 16 else return 8,
224 .sparc => if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) return 16 else return 8,
225 .mips, .mipsel => switch (target.abi) {
226 .none, .gnuabi64 => return 16,
227 else => return 8,
228 },
229 .s390x, .armeb, .thumbeb, .thumb => return 8,
230 else => return 16,
231 }
232}
233pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
234 // Android is linux but not gcc, so these checks go first
235 // the rest for documentation as fn returns .clang
236 if (target.isDarwin() or
237 target.isAndroid() or
238 target.isBSD() or
239 target.os.tag == .fuchsia or
240 target.os.tag == .solaris or
241 target.os.tag == .haiku or
242 target.cpu.arch == .hexagon)
243 {
244 return .clang;
245 }
246 if (target.os.tag == .uefi) return .msvc;
247 // this is before windows to grab WindowsGnu
248 if (target.abi.isGnu() or
249 target.os.tag == .linux)
250 {
251 return .gcc;
252 }
253 if (target.os.tag == .windows) {
254 return .msvc;
255 }
256 if (target.cpu.arch == .avr) return .gcc;
257 return .clang;
258}
259
260pub fn hasFloat128(target: std.Target) bool {
261 if (target.cpu.arch.isWasm()) return true;
262 if (target.isDarwin()) return false;
263 if (target.cpu.arch.isPPC() or target.cpu.arch.isPPC64()) return std.Target.powerpc.featureSetHas(target.cpu.features, .float128);
264 return switch (target.os.tag) {
265 .dragonfly,
266 .haiku,
267 .linux,
268 .openbsd,
269 .solaris,
270 => target.cpu.arch.isX86(),
271 else => false,
272 };
273}
274
275pub fn hasInt128(target: std.Target) bool {
276 if (target.cpu.arch == .wasm32) return true;
277 if (target.cpu.arch == .x86_64) return true;
278 return target.ptrBitWidth() >= 64;
279}
280
281pub fn hasHalfPrecisionFloatABI(target: std.Target) bool {
282 return switch (target.cpu.arch) {
283 .thumb, .thumbeb, .arm, .aarch64 => true,
284 else => false,
285 };
286}
287
288pub const FPSemantics = enum {
289 None,
290 IEEEHalf,
291 BFloat,
292 IEEESingle,
293 IEEEDouble,
294 IEEEQuad,
295 /// Minifloat 5-bit exponent 2-bit mantissa
296 E5M2,
297 /// Minifloat 4-bit exponent 3-bit mantissa
298 E4M3,
299 x87ExtendedDouble,
300 IBMExtendedDouble,
301
302 /// Only intended for generating float.h macros for the preprocessor
303 pub fn forType(ty: std.Target.CType, target: std.Target) FPSemantics {
304 std.debug.assert(ty == .float or ty == .double or ty == .longdouble);
305 return switch (target.c_type_bit_size(ty)) {
306 32 => .IEEESingle,
307 64 => .IEEEDouble,
308 80 => .x87ExtendedDouble,
309 128 => switch (target.cpu.arch) {
310 .powerpc, .powerpcle, .powerpc64, .powerpc64le => .IBMExtendedDouble,
311 else => .IEEEQuad,
312 },
313 else => unreachable,
314 };
315 }
316
317 pub fn halfPrecisionType(target: std.Target) ?FPSemantics {
318 switch (target.cpu.arch) {
319 .aarch64,
320 .aarch64_32,
321 .aarch64_be,
322 .arm,
323 .armeb,
324 .hexagon,
325 .riscv32,
326 .riscv64,
327 .spirv32,
328 .spirv64,
329 => return .IEEEHalf,
330 .x86, .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .sse2)) return .IEEEHalf,
331 else => {},
332 }
333 return null;
334 }
335
336 pub fn chooseValue(self: FPSemantics, comptime T: type, values: [6]T) T {
337 return switch (self) {
338 .IEEEHalf => values[0],
339 .IEEESingle => values[1],
340 .IEEEDouble => values[2],
341 .x87ExtendedDouble => values[3],
342 .IBMExtendedDouble => values[4],
343 .IEEEQuad => values[5],
344 else => unreachable,
345 };
346 }
347};
348
349pub fn isLP64(target: std.Target) bool {
350 return target.c_type_bit_size(.int) == 32 and target.ptrBitWidth() == 64;
351}
352
353pub fn isKnownWindowsMSVCEnvironment(target: std.Target) bool {
354 return target.os.tag == .windows and target.abi == .msvc;
355}
356
357pub fn isWindowsMSVCEnvironment(target: std.Target) bool {
358 return target.os.tag == .windows and (target.abi == .msvc or target.abi == .none);
359}
360
361pub fn isCygwinMinGW(target: std.Target) bool {
362 return target.os.tag == .windows and (target.abi == .gnu or target.abi == .cygnus);
363}
364
365pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool {
366 var it = enabled_for.iterator();
367 while (it.next()) |val| {
368 switch (val) {
369 .basic => return true,
370 .x86_64 => if (target.cpu.arch == .x86_64) return true,
371 .aarch64 => if (target.cpu.arch == .aarch64) return true,
372 .arm => if (target.cpu.arch == .arm) return true,
373 .ppc => switch (target.cpu.arch) {
374 .powerpc, .powerpc64, .powerpc64le => return true,
375 else => {},
376 },
377 else => {
378 // Todo: handle other target predicates
379 },
380 }
381 }
382 return false;
383}
384
385pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {
386 if (target.os.tag == .aix) return .double;
387 switch (target.cpu.arch) {
388 .x86, .x86_64 => {
389 if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) {
390 if (target.os.version_range.semver.min.order(.{ .major = 6, .minor = 99, .patch = 26 }) != .gt) {
391 // NETBSD <= 6.99.26 on 32-bit x86 defaults to double
392 return .double;
393 }
394 }
395 if (std.Target.x86.featureSetHas(target.cpu.features, .sse)) {
396 return .source;
397 }
398 return .extended;
399 },
400 else => {},
401 }
402 return .source;
403}
404
405/// Value of the `-m` flag for `ld` for this target
406pub fn ldEmulationOption(target: std.Target, arm_endianness: ?std.builtin.Endian) ?[]const u8 {
407 return switch (target.cpu.arch) {
408 .x86 => if (target.os.tag == .elfiamcu) "elf_iamcu" else "elf_i386",
409 .arm,
410 .armeb,
411 .thumb,
412 .thumbeb,
413 => switch (arm_endianness orelse target.cpu.arch.endian()) {
414 .little => "armelf_linux_eabi",
415 .big => "armelfb_linux_eabi",
416 },
417 .aarch64 => "aarch64linux",
418 .aarch64_be => "aarch64linuxb",
419 .m68k => "m68kelf",
420 .powerpc => if (target.os.tag == .linux) "elf32ppclinux" else "elf32ppc",
421 .powerpcle => if (target.os.tag == .linux) "elf32lppclinux" else "elf32lppc",
422 .powerpc64 => "elf64ppc",
423 .powerpc64le => "elf64lppc",
424 .riscv32 => "elf32lriscv",
425 .riscv64 => "elf64lriscv",
426 .sparc, .sparcel => "elf32_sparc",
427 .sparc64 => "elf64_sparc",
428 .loongarch32 => "elf32loongarch",
429 .loongarch64 => "elf64loongarch",
430 .mips => "elf32btsmip",
431 .mipsel => "elf32ltsmip",
432 .mips64 => if (target.abi == .gnuabin32) "elf32btsmipn32" else "elf64btsmip",
433 .mips64el => if (target.abi == .gnuabin32) "elf32ltsmipn32" else "elf64ltsmip",
434 .x86_64 => if (target.abi == .gnux32 or target.abi == .muslx32) "elf32_x86_64" else "elf_x86_64",
435 .ve => "elf64ve",
436 .csky => "cskyelf_linux",
437 else => null,
438 };
439}
440
441pub fn get32BitArchVariant(target: std.Target) ?std.Target {
442 var copy = target;
443 switch (target.cpu.arch) {
444 .amdgcn,
445 .avr,
446 .msp430,
447 .spu_2,
448 .ve,
449 .bpfel,
450 .bpfeb,
451 .s390x,
452 => return null,
453
454 .arc,
455 .arm,
456 .armeb,
457 .csky,
458 .hexagon,
459 .m68k,
460 .le32,
461 .mips,
462 .mipsel,
463 .powerpc,
464 .powerpcle,
465 .r600,
466 .riscv32,
467 .sparc,
468 .sparcel,
469 .tce,
470 .tcele,
471 .thumb,
472 .thumbeb,
473 .x86,
474 .xcore,
475 .nvptx,
476 .amdil,
477 .hsail,
478 .spir,
479 .kalimba,
480 .shave,
481 .lanai,
482 .wasm32,
483 .renderscript32,
484 .aarch64_32,
485 .spirv32,
486 .loongarch32,
487 .dxil,
488 .xtensa,
489 => {}, // Already 32 bit
490
491 .aarch64 => copy.cpu.arch = .arm,
492 .aarch64_be => copy.cpu.arch = .armeb,
493 .le64 => copy.cpu.arch = .le32,
494 .amdil64 => copy.cpu.arch = .amdil,
495 .nvptx64 => copy.cpu.arch = .nvptx,
496 .wasm64 => copy.cpu.arch = .wasm32,
497 .hsail64 => copy.cpu.arch = .hsail,
498 .spir64 => copy.cpu.arch = .spir,
499 .spirv64 => copy.cpu.arch = .spirv32,
500 .renderscript64 => copy.cpu.arch = .renderscript32,
501 .loongarch64 => copy.cpu.arch = .loongarch32,
502 .mips64 => copy.cpu.arch = .mips,
503 .mips64el => copy.cpu.arch = .mipsel,
504 .powerpc64 => copy.cpu.arch = .powerpc,
505 .powerpc64le => copy.cpu.arch = .powerpcle,
506 .riscv64 => copy.cpu.arch = .riscv32,
507 .sparc64 => copy.cpu.arch = .sparc,
508 .x86_64 => copy.cpu.arch = .x86,
509 }
510 return copy;
511}
512
513pub fn get64BitArchVariant(target: std.Target) ?std.Target {
514 var copy = target;
515 switch (target.cpu.arch) {
516 .arc,
517 .avr,
518 .csky,
519 .dxil,
520 .hexagon,
521 .kalimba,
522 .lanai,
523 .m68k,
524 .msp430,
525 .r600,
526 .shave,
527 .sparcel,
528 .spu_2,
529 .tce,
530 .tcele,
531 .xcore,
532 .xtensa,
533 => return null,
534
535 .aarch64,
536 .aarch64_be,
537 .amdgcn,
538 .bpfeb,
539 .bpfel,
540 .le64,
541 .amdil64,
542 .nvptx64,
543 .wasm64,
544 .hsail64,
545 .spir64,
546 .spirv64,
547 .renderscript64,
548 .loongarch64,
549 .mips64,
550 .mips64el,
551 .powerpc64,
552 .powerpc64le,
553 .riscv64,
554 .s390x,
555 .sparc64,
556 .ve,
557 .x86_64,
558 => {}, // Already 64 bit
559
560 .aarch64_32 => copy.cpu.arch = .aarch64,
561 .amdil => copy.cpu.arch = .amdil64,
562 .arm => copy.cpu.arch = .aarch64,
563 .armeb => copy.cpu.arch = .aarch64_be,
564 .hsail => copy.cpu.arch = .hsail64,
565 .le32 => copy.cpu.arch = .le64,
566 .loongarch32 => copy.cpu.arch = .loongarch64,
567 .mips => copy.cpu.arch = .mips64,
568 .mipsel => copy.cpu.arch = .mips64el,
569 .nvptx => copy.cpu.arch = .nvptx64,
570 .powerpc => copy.cpu.arch = .powerpc64,
571 .powerpcle => copy.cpu.arch = .powerpc64le,
572 .renderscript32 => copy.cpu.arch = .renderscript64,
573 .riscv32 => copy.cpu.arch = .riscv64,
574 .sparc => copy.cpu.arch = .sparc64,
575 .spir => copy.cpu.arch = .spir64,
576 .spirv32 => copy.cpu.arch = .spirv64,
577 .thumb => copy.cpu.arch = .aarch64,
578 .thumbeb => copy.cpu.arch = .aarch64_be,
579 .wasm32 => copy.cpu.arch = .wasm64,
580 .x86 => copy.cpu.arch = .x86_64,
581 }
582 return copy;
583}
584
585/// Adapted from Zig's src/codegen/llvm.zig
586pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
587 // 64 bytes is assumed to be large enough to hold any target triple; increase if necessary
588 std.debug.assert(buf.len >= 64);
589
590 var stream = std.io.fixedBufferStream(buf);
591 const writer = stream.writer();
592
593 const llvm_arch = switch (target.cpu.arch) {
594 .arm => "arm",
595 .armeb => "armeb",
596 .aarch64 => "aarch64",
597 .aarch64_be => "aarch64_be",
598 .aarch64_32 => "aarch64_32",
599 .arc => "arc",
600 .avr => "avr",
601 .bpfel => "bpfel",
602 .bpfeb => "bpfeb",
603 .csky => "csky",
604 .dxil => "dxil",
605 .hexagon => "hexagon",
606 .loongarch32 => "loongarch32",
607 .loongarch64 => "loongarch64",
608 .m68k => "m68k",
609 .mips => "mips",
610 .mipsel => "mipsel",
611 .mips64 => "mips64",
612 .mips64el => "mips64el",
613 .msp430 => "msp430",
614 .powerpc => "powerpc",
615 .powerpcle => "powerpcle",
616 .powerpc64 => "powerpc64",
617 .powerpc64le => "powerpc64le",
618 .r600 => "r600",
619 .amdgcn => "amdgcn",
620 .riscv32 => "riscv32",
621 .riscv64 => "riscv64",
622 .sparc => "sparc",
623 .sparc64 => "sparc64",
624 .sparcel => "sparcel",
625 .s390x => "s390x",
626 .tce => "tce",
627 .tcele => "tcele",
628 .thumb => "thumb",
629 .thumbeb => "thumbeb",
630 .x86 => "i386",
631 .x86_64 => "x86_64",
632 .xcore => "xcore",
633 .xtensa => "xtensa",
634 .nvptx => "nvptx",
635 .nvptx64 => "nvptx64",
636 .le32 => "le32",
637 .le64 => "le64",
638 .amdil => "amdil",
639 .amdil64 => "amdil64",
640 .hsail => "hsail",
641 .hsail64 => "hsail64",
642 .spir => "spir",
643 .spir64 => "spir64",
644 .spirv32 => "spirv32",
645 .spirv64 => "spirv64",
646 .kalimba => "kalimba",
647 .shave => "shave",
648 .lanai => "lanai",
649 .wasm32 => "wasm32",
650 .wasm64 => "wasm64",
651 .renderscript32 => "renderscript32",
652 .renderscript64 => "renderscript64",
653 .ve => "ve",
654 // Note: spu_2 is not supported in LLVM; this is the Zig arch name
655 .spu_2 => "spu_2",
656 };
657 writer.writeAll(llvm_arch) catch unreachable;
658 writer.writeByte('-') catch unreachable;
659
660 const llvm_os = switch (target.os.tag) {
661 .freestanding => "unknown",
662 .ananas => "ananas",
663 .cloudabi => "cloudabi",
664 .dragonfly => "dragonfly",
665 .freebsd => "freebsd",
666 .fuchsia => "fuchsia",
667 .kfreebsd => "kfreebsd",
668 .linux => "linux",
669 .lv2 => "lv2",
670 .netbsd => "netbsd",
671 .openbsd => "openbsd",
672 .solaris => "solaris",
673 .illumos => "illumos",
674 .windows => "windows",
675 .zos => "zos",
676 .haiku => "haiku",
677 .minix => "minix",
678 .rtems => "rtems",
679 .nacl => "nacl",
680 .aix => "aix",
681 .cuda => "cuda",
682 .nvcl => "nvcl",
683 .amdhsa => "amdhsa",
684 .ps4 => "ps4",
685 .ps5 => "ps5",
686 .elfiamcu => "elfiamcu",
687 .mesa3d => "mesa3d",
688 .contiki => "contiki",
689 .amdpal => "amdpal",
690 .hermit => "hermit",
691 .hurd => "hurd",
692 .wasi => "wasi",
693 .emscripten => "emscripten",
694 .uefi => "windows",
695 .macos => "macosx",
696 .ios => "ios",
697 .tvos => "tvos",
698 .watchos => "watchos",
699 .driverkit => "driverkit",
700 .shadermodel => "shadermodel",
701 .liteos => "liteos",
702 .opencl,
703 .glsl450,
704 .vulkan,
705 .plan9,
706 .other,
707 => "unknown",
708 };
709 writer.writeAll(llvm_os) catch unreachable;
710
711 if (target.os.tag.isDarwin()) {
712 const min_version = target.os.version_range.semver.min;
713 writer.print("{d}.{d}.{d}", .{
714 min_version.major,
715 min_version.minor,
716 min_version.patch,
717 }) catch unreachable;
718 }
719 writer.writeByte('-') catch unreachable;
720
721 const llvm_abi = switch (target.abi) {
722 .none => "unknown",
723 .gnu => "gnu",
724 .gnuabin32 => "gnuabin32",
725 .gnuabi64 => "gnuabi64",
726 .gnueabi => "gnueabi",
727 .gnueabihf => "gnueabihf",
728 .gnuf32 => "gnuf32",
729 .gnuf64 => "gnuf64",
730 .gnusf => "gnusf",
731 .gnux32 => "gnux32",
732 .gnuilp32 => "gnuilp32",
733 .code16 => "code16",
734 .eabi => "eabi",
735 .eabihf => "eabihf",
736 .android => "android",
737 .musl => "musl",
738 .musleabi => "musleabi",
739 .musleabihf => "musleabihf",
740 .muslx32 => "muslx32",
741 .msvc => "msvc",
742 .itanium => "itanium",
743 .cygnus => "cygnus",
744 .coreclr => "coreclr",
745 .simulator => "simulator",
746 .macabi => "macabi",
747 .pixel => "pixel",
748 .vertex => "vertex",
749 .geometry => "geometry",
750 .hull => "hull",
751 .domain => "domain",
752 .compute => "compute",
753 .library => "library",
754 .raygeneration => "raygeneration",
755 .intersection => "intersection",
756 .anyhit => "anyhit",
757 .closesthit => "closesthit",
758 .miss => "miss",
759 .callable => "callable",
760 .mesh => "mesh",
761 .amplification => "amplification",
762 };
763 writer.writeAll(llvm_abi) catch unreachable;
764 return stream.getWritten();
765}
766
767test "alignment functions - smoke test" {
768 var target: std.Target = undefined;
769 const x86 = std.Target.Cpu.Arch.x86_64;
770 target.cpu = std.Target.Cpu.baseline(x86);
771 target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
772 target.abi = std.Target.Abi.default(x86, target.os);
773
774 try std.testing.expect(isTlsSupported(target));
775 try std.testing.expect(!ignoreNonZeroSizedBitfieldTypeAlignment(target));
776 try std.testing.expect(minZeroWidthBitfieldAlignment(target) == null);
777 try std.testing.expect(!unnamedFieldAffectsAlignment(target));
778 try std.testing.expect(defaultAlignment(target) == 16);
779 try std.testing.expect(!packAllEnums(target));
780 try std.testing.expect(systemCompiler(target) == .gcc);
781
782 const arm = std.Target.Cpu.Arch.arm;
783 target.cpu = std.Target.Cpu.baseline(arm);
784 target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
785 target.abi = std.Target.Abi.default(arm, target.os);
786
787 try std.testing.expect(!isTlsSupported(target));
788 try std.testing.expect(ignoreNonZeroSizedBitfieldTypeAlignment(target));
789 try std.testing.expectEqual(@as(?u29, 32), minZeroWidthBitfieldAlignment(target));
790 try std.testing.expect(unnamedFieldAffectsAlignment(target));
791 try std.testing.expect(defaultAlignment(target) == 16);
792 try std.testing.expect(!packAllEnums(target));
793 try std.testing.expect(systemCompiler(target) == .clang);
794}
795
796test "target size/align tests" {
797 var comp: @import("Compilation.zig") = undefined;
798
799 const x86 = std.Target.Cpu.Arch.x86;
800 comp.target.cpu.arch = x86;
801 comp.target.cpu.model = &std.Target.x86.cpu.i586;
802 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
803 comp.target.abi = std.Target.Abi.gnu;
804
805 const tt: Type = .{
806 .specifier = .long_long,
807 };
808
809 try std.testing.expectEqual(@as(u64, 8), tt.sizeof(&comp).?);
810 try std.testing.expectEqual(@as(u64, 4), tt.alignof(&comp));
811
812 const arm = std.Target.Cpu.Arch.arm;
813 comp.target.cpu = std.Target.Cpu.Model.toCpu(&std.Target.arm.cpu.cortex_r4, arm);
814 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
815 comp.target.abi = std.Target.Abi.none;
816
817 const ct: Type = .{
818 .specifier = .char,
819 };
820
821 try std.testing.expectEqual(true, std.Target.arm.featureSetHas(comp.target.cpu.features, .has_v7));
822 try std.testing.expectEqual(@as(u64, 1), ct.sizeof(&comp).?);
823 try std.testing.expectEqual(@as(u64, 1), ct.alignof(&comp));
824 try std.testing.expectEqual(true, ignoreNonZeroSizedBitfieldTypeAlignment(comp.target));
825}
826
827/// The canonical integer representation of nullptr_t.
828pub fn nullRepr(_: std.Target) u64 {
829 return 0;
830}
deps/aro/aro/text_literal.zig deleted-383
......@@ -1,383 +0,0 @@
1//! Parsing and classification of string and character literals
2
3const std = @import("std");
4const Compilation = @import("Compilation.zig");
5const Type = @import("Type.zig");
6const Diagnostics = @import("Diagnostics.zig");
7const Tokenizer = @import("Tokenizer.zig");
8const mem = std.mem;
9
10pub const Item = union(enum) {
11 /// decoded hex or character escape
12 value: u32,
13 /// validated unicode codepoint
14 codepoint: u21,
15 /// Char literal in the source text is not utf8 encoded
16 improperly_encoded: []const u8,
17 /// 1 or more unescaped bytes
18 utf8_text: std.unicode.Utf8View,
19};
20
21const CharDiagnostic = struct {
22 tag: Diagnostics.Tag,
23 extra: Diagnostics.Message.Extra,
24};
25
26pub const Kind = enum {
27 char,
28 wide,
29 utf_8,
30 utf_16,
31 utf_32,
32 /// Error kind that halts parsing
33 unterminated,
34
35 pub fn classify(id: Tokenizer.Token.Id, context: enum { string_literal, char_literal }) ?Kind {
36 return switch (context) {
37 .string_literal => switch (id) {
38 .string_literal => .char,
39 .string_literal_utf_8 => .utf_8,
40 .string_literal_wide => .wide,
41 .string_literal_utf_16 => .utf_16,
42 .string_literal_utf_32 => .utf_32,
43 .unterminated_string_literal => .unterminated,
44 else => null,
45 },
46 .char_literal => switch (id) {
47 .char_literal => .char,
48 .char_literal_utf_8 => .utf_8,
49 .char_literal_wide => .wide,
50 .char_literal_utf_16 => .utf_16,
51 .char_literal_utf_32 => .utf_32,
52 else => null,
53 },
54 };
55 }
56
57 /// Should only be called for string literals. Determines the result kind of two adjacent string
58 /// literals
59 pub fn concat(self: Kind, other: Kind) !Kind {
60 if (self == .unterminated or other == .unterminated) return .unterminated;
61 if (self == other) return self; // can always concat with own kind
62 if (self == .char) return other; // char + X -> X
63 if (other == .char) return self; // X + char -> X
64 return error.CannotConcat;
65 }
66
67 /// Largest unicode codepoint that can be represented by this character kind
68 /// May be smaller than the largest value that can be represented.
69 /// For example u8 char literals may only specify 0-127 via literals or
70 /// character escapes, but may specify up to \xFF via hex escapes.
71 pub fn maxCodepoint(kind: Kind, comp: *const Compilation) u21 {
72 return @intCast(switch (kind) {
73 .char => std.math.maxInt(u7),
74 .wide => @min(0x10FFFF, comp.types.wchar.maxInt(comp)),
75 .utf_8 => std.math.maxInt(u7),
76 .utf_16 => std.math.maxInt(u16),
77 .utf_32 => 0x10FFFF,
78 .unterminated => unreachable,
79 });
80 }
81
82 /// Largest integer that can be represented by this character kind
83 pub fn maxInt(kind: Kind, comp: *const Compilation) u32 {
84 return @intCast(switch (kind) {
85 .char, .utf_8 => std.math.maxInt(u8),
86 .wide => comp.types.wchar.maxInt(comp),
87 .utf_16 => std.math.maxInt(u16),
88 .utf_32 => std.math.maxInt(u32),
89 .unterminated => unreachable,
90 });
91 }
92
93 /// The C type of a character literal of this kind
94 pub fn charLiteralType(kind: Kind, comp: *const Compilation) Type {
95 return switch (kind) {
96 .char => Type.int,
97 .wide => comp.types.wchar,
98 .utf_8 => .{ .specifier = .uchar },
99 .utf_16 => comp.types.uint_least16_t,
100 .utf_32 => comp.types.uint_least32_t,
101 .unterminated => unreachable,
102 };
103 }
104
105 /// Return the actual contents of the literal with leading / trailing quotes and
106 /// specifiers removed
107 pub fn contentSlice(kind: Kind, delimited: []const u8) []const u8 {
108 const end = delimited.len - 1; // remove trailing quote
109 return switch (kind) {
110 .char => delimited[1..end],
111 .wide => delimited[2..end],
112 .utf_8 => delimited[3..end],
113 .utf_16 => delimited[2..end],
114 .utf_32 => delimited[2..end],
115 .unterminated => unreachable,
116 };
117 }
118
119 /// The size of a character unit for a string literal of this kind
120 pub fn charUnitSize(kind: Kind, comp: *const Compilation) Compilation.CharUnitSize {
121 return switch (kind) {
122 .char => .@"1",
123 .wide => switch (comp.types.wchar.sizeof(comp).?) {
124 2 => .@"2",
125 4 => .@"4",
126 else => unreachable,
127 },
128 .utf_8 => .@"1",
129 .utf_16 => .@"2",
130 .utf_32 => .@"4",
131 .unterminated => unreachable,
132 };
133 }
134
135 /// Required alignment within aro (on compiler host) for writing to Interner.strings.
136 pub fn internalStorageAlignment(kind: Kind, comp: *const Compilation) usize {
137 return switch (kind.charUnitSize(comp)) {
138 inline else => |size| @alignOf(size.Type()),
139 };
140 }
141
142 /// The C type of an element of a string literal of this kind
143 pub fn elementType(kind: Kind, comp: *const Compilation) Type {
144 return switch (kind) {
145 .unterminated => unreachable,
146 .char => .{ .specifier = .char },
147 .utf_8 => if (comp.langopts.hasChar8_T()) .{ .specifier = .uchar } else .{ .specifier = .char },
148 else => kind.charLiteralType(comp),
149 };
150 }
151};
152
153pub const Parser = struct {
154 literal: []const u8,
155 i: usize = 0,
156 kind: Kind,
157 max_codepoint: u21,
158 /// We only want to issue a max of 1 error per char literal
159 errored: bool = false,
160 errors_buffer: [4]CharDiagnostic,
161 errors_len: usize,
162 comp: *const Compilation,
163
164 pub fn init(literal: []const u8, kind: Kind, max_codepoint: u21, comp: *const Compilation) Parser {
165 return .{
166 .literal = literal,
167 .comp = comp,
168 .kind = kind,
169 .max_codepoint = max_codepoint,
170 .errors_buffer = undefined,
171 .errors_len = 0,
172 };
173 }
174
175 fn prefixLen(self: *const Parser) usize {
176 return switch (self.kind) {
177 .unterminated => unreachable,
178 .char => 0,
179 .utf_8 => 2,
180 .wide, .utf_16, .utf_32 => 1,
181 };
182 }
183
184 pub fn errors(p: *Parser) []CharDiagnostic {
185 return p.errors_buffer[0..p.errors_len];
186 }
187
188 pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void {
189 if (self.errored) return;
190 self.errored = true;
191 const diagnostic = .{ .tag = tag, .extra = extra };
192 if (self.errors_len == self.errors_buffer.len) {
193 self.errors_buffer[self.errors_buffer.len - 1] = diagnostic;
194 } else {
195 self.errors_buffer[self.errors_len] = diagnostic;
196 self.errors_len += 1;
197 }
198 }
199
200 pub fn warn(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void {
201 if (self.errored) return;
202 if (self.errors_len < self.errors_buffer.len) {
203 self.errors_buffer[self.errors_len] = .{ .tag = tag, .extra = extra };
204 self.errors_len += 1;
205 }
206 }
207
208 pub fn next(self: *Parser) ?Item {
209 if (self.i >= self.literal.len) return null;
210
211 const start = self.i;
212 if (self.literal[start] != '\\') {
213 self.i = mem.indexOfScalarPos(u8, self.literal, start + 1, '\\') orelse self.literal.len;
214 const unescaped_slice = self.literal[start..self.i];
215
216 const view = std.unicode.Utf8View.init(unescaped_slice) catch {
217 if (self.kind != .char) {
218 self.err(.illegal_char_encoding_error, .{ .none = {} });
219 return null;
220 }
221 self.warn(.illegal_char_encoding_warning, .{ .none = {} });
222 return .{ .improperly_encoded = self.literal[start..self.i] };
223 };
224 return .{ .utf8_text = view };
225 }
226 switch (self.literal[start + 1]) {
227 'u', 'U' => return self.parseUnicodeEscape(),
228 else => return self.parseEscapedChar(),
229 }
230 }
231
232 fn parseUnicodeEscape(self: *Parser) ?Item {
233 const start = self.i;
234
235 std.debug.assert(self.literal[self.i] == '\\');
236
237 const kind = self.literal[self.i + 1];
238 std.debug.assert(kind == 'u' or kind == 'U');
239
240 self.i += 2;
241 if (self.i >= self.literal.len or !std.ascii.isHex(self.literal[self.i])) {
242 self.err(.missing_hex_escape, .{ .ascii = @intCast(kind) });
243 return null;
244 }
245 const expected_len: usize = if (kind == 'u') 4 else 8;
246 var overflowed = false;
247 var count: usize = 0;
248 var val: u32 = 0;
249
250 for (self.literal[self.i..], 0..) |c, i| {
251 if (i == expected_len) break;
252
253 const char = std.fmt.charToDigit(c, 16) catch {
254 break;
255 };
256
257 val, const overflow = @shlWithOverflow(val, 4);
258 overflowed = overflowed or overflow != 0;
259 val |= char;
260 count += 1;
261 }
262 self.i += expected_len;
263
264 if (overflowed) {
265 self.err(.escape_sequence_overflow, .{ .offset = start + self.prefixLen() });
266 return null;
267 }
268
269 if (count != expected_len) {
270 self.err(.incomplete_universal_character, .{ .none = {} });
271 return null;
272 }
273
274 if (val > std.math.maxInt(u21) or !std.unicode.utf8ValidCodepoint(@intCast(val))) {
275 self.err(.invalid_universal_character, .{ .offset = start + self.prefixLen() });
276 return null;
277 }
278
279 if (val > self.max_codepoint) {
280 self.err(.char_too_large, .{ .none = {} });
281 return null;
282 }
283
284 if (val < 0xA0 and (val != '$' and val != '@' and val != '`')) {
285 const is_error = !self.comp.langopts.standard.atLeast(.c23);
286 if (val >= 0x20 and val <= 0x7F) {
287 if (is_error) {
288 self.err(.ucn_basic_char_error, .{ .ascii = @intCast(val) });
289 } else {
290 self.warn(.ucn_basic_char_warning, .{ .ascii = @intCast(val) });
291 }
292 } else {
293 if (is_error) {
294 self.err(.ucn_control_char_error, .{ .none = {} });
295 } else {
296 self.warn(.ucn_control_char_warning, .{ .none = {} });
297 }
298 }
299 }
300
301 self.warn(.c89_ucn_in_literal, .{ .none = {} });
302 return .{ .codepoint = @intCast(val) };
303 }
304
305 fn parseEscapedChar(self: *Parser) Item {
306 self.i += 1;
307 const c = self.literal[self.i];
308 defer if (c != 'x' and (c < '0' or c > '7')) {
309 self.i += 1;
310 };
311
312 switch (c) {
313 '\n' => unreachable, // removed by line splicing
314 '\r' => unreachable, // removed by line splicing
315 '\'', '\"', '\\', '?' => return .{ .value = c },
316 'n' => return .{ .value = '\n' },
317 'r' => return .{ .value = '\r' },
318 't' => return .{ .value = '\t' },
319 'a' => return .{ .value = 0x07 },
320 'b' => return .{ .value = 0x08 },
321 'e', 'E' => {
322 self.warn(.non_standard_escape_char, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } });
323 return .{ .value = 0x1B };
324 },
325 '(', '{', '[', '%' => {
326 self.warn(.non_standard_escape_char, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } });
327 return .{ .value = c };
328 },
329 'f' => return .{ .value = 0x0C },
330 'v' => return .{ .value = 0x0B },
331 'x' => return .{ .value = self.parseNumberEscape(.hex) },
332 '0'...'7' => return .{ .value = self.parseNumberEscape(.octal) },
333 'u', 'U' => unreachable, // handled by parseUnicodeEscape
334 else => {
335 self.warn(.unknown_escape_sequence, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } });
336 return .{ .value = c };
337 },
338 }
339 }
340
341 fn parseNumberEscape(self: *Parser, base: EscapeBase) u32 {
342 var val: u32 = 0;
343 var count: usize = 0;
344 var overflowed = false;
345 const start = self.i;
346 defer self.i += count;
347 const slice = switch (base) {
348 .octal => self.literal[self.i..@min(self.literal.len, self.i + 3)], // max 3 chars
349 .hex => blk: {
350 self.i += 1;
351 break :blk self.literal[self.i..]; // skip over 'x'; could have an arbitrary number of chars
352 },
353 };
354 for (slice) |c| {
355 const char = std.fmt.charToDigit(c, @intFromEnum(base)) catch break;
356 val, const overflow = @shlWithOverflow(val, base.log2());
357 if (overflow != 0) overflowed = true;
358 val += char;
359 count += 1;
360 }
361 if (overflowed or val > self.kind.maxInt(self.comp)) {
362 self.err(.escape_sequence_overflow, .{ .offset = start + self.prefixLen() });
363 return 0;
364 }
365 if (count == 0) {
366 std.debug.assert(base == .hex);
367 self.err(.missing_hex_escape, .{ .ascii = 'x' });
368 }
369 return val;
370 }
371};
372
373const EscapeBase = enum(u8) {
374 octal = 8,
375 hex = 16,
376
377 fn log2(base: EscapeBase) u4 {
378 return switch (base) {
379 .octal => 3,
380 .hex => 4,
381 };
382 }
383};
deps/aro/aro/toolchains/Linux.zig deleted-483
......@@ -1,483 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const GCCDetector = @import("../Driver/GCCDetector.zig");
5const Toolchain = @import("../Toolchain.zig");
6const Driver = @import("../Driver.zig");
7const Distro = @import("../Driver/Distro.zig");
8const target_util = @import("../target.zig");
9const system_defaults = @import("system_defaults");
10
11const Linux = @This();
12
13distro: Distro.Tag = .unknown,
14extra_opts: std.ArrayListUnmanaged([]const u8) = .{},
15gcc_detector: GCCDetector = .{},
16
17pub fn discover(self: *Linux, tc: *Toolchain) !void {
18 self.distro = Distro.detect(tc.getTarget(), tc.filesystem);
19 try self.gcc_detector.discover(tc);
20 tc.selected_multilib = self.gcc_detector.selected;
21
22 try self.gcc_detector.appendToolPath(tc);
23 try self.buildExtraOpts(tc);
24 try self.findPaths(tc);
25}
26
27fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void {
28 const gpa = tc.driver.comp.gpa;
29 const target = tc.getTarget();
30 const is_android = target.isAndroid();
31 if (self.distro.isAlpine() or is_android) {
32 try self.extra_opts.ensureUnusedCapacity(gpa, 2);
33 self.extra_opts.appendAssumeCapacity("-z");
34 self.extra_opts.appendAssumeCapacity("now");
35 }
36
37 if (self.distro.isOpenSUSE() or self.distro.isUbuntu() or self.distro.isAlpine() or is_android) {
38 try self.extra_opts.ensureUnusedCapacity(gpa, 2);
39 self.extra_opts.appendAssumeCapacity("-z");
40 self.extra_opts.appendAssumeCapacity("relro");
41 }
42
43 if (target.cpu.arch.isARM() or target.cpu.arch.isAARCH64() or is_android) {
44 try self.extra_opts.ensureUnusedCapacity(gpa, 2);
45 self.extra_opts.appendAssumeCapacity("-z");
46 self.extra_opts.appendAssumeCapacity("max-page-size=4096");
47 }
48
49 if (target.cpu.arch == .arm or target.cpu.arch == .thumb) {
50 try self.extra_opts.append(gpa, "-X");
51 }
52
53 if (!target.cpu.arch.isMIPS() and target.cpu.arch != .hexagon) {
54 const hash_style = if (is_android) .both else self.distro.getHashStyle();
55 try self.extra_opts.append(gpa, switch (hash_style) {
56 inline else => |tag| "--hash-style=" ++ @tagName(tag),
57 });
58 }
59
60 if (system_defaults.enable_linker_build_id) {
61 try self.extra_opts.append(gpa, "--build-id");
62 }
63}
64
65fn addMultiLibPaths(self: *Linux, tc: *Toolchain, sysroot: []const u8, os_lib_dir: []const u8) !void {
66 if (!self.gcc_detector.is_valid) return;
67 const gcc_triple = self.gcc_detector.gcc_triple;
68 const lib_path = self.gcc_detector.parent_lib_path;
69
70 // Add lib/gcc/$triple/$version, with an optional /multilib suffix.
71 try tc.addPathIfExists(&.{ self.gcc_detector.install_path, tc.selected_multilib.gcc_suffix }, .file);
72
73 // Add lib/gcc/$triple/$libdir
74 // For GCC built with --enable-version-specific-runtime-libs.
75 try tc.addPathIfExists(&.{ self.gcc_detector.install_path, "..", os_lib_dir }, .file);
76
77 try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", "..", os_lib_dir, tc.selected_multilib.os_suffix }, .file);
78
79 // If the GCC installation we found is inside of the sysroot, we want to
80 // prefer libraries installed in the parent prefix of the GCC installation.
81 // It is important to *not* use these paths when the GCC installation is
82 // outside of the system root as that can pick up unintended libraries.
83 // This usually happens when there is an external cross compiler on the
84 // host system, and a more minimal sysroot available that is the target of
85 // the cross. Note that GCC does include some of these directories in some
86 // configurations but this seems somewhere between questionable and simply
87 // a bug.
88 if (mem.startsWith(u8, lib_path, sysroot)) {
89 try tc.addPathIfExists(&.{ lib_path, "..", os_lib_dir }, .file);
90 }
91}
92
93fn addMultiArchPaths(self: *Linux, tc: *Toolchain) !void {
94 if (!self.gcc_detector.is_valid) return;
95 const lib_path = self.gcc_detector.parent_lib_path;
96 const gcc_triple = self.gcc_detector.gcc_triple;
97 const multilib = self.gcc_detector.selected;
98 try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", multilib.os_suffix }, .file);
99}
100
101/// TODO: Very incomplete
102fn findPaths(self: *Linux, tc: *Toolchain) !void {
103 const target = tc.getTarget();
104 const sysroot = tc.getSysroot();
105
106 var output: [64]u8 = undefined;
107
108 const os_lib_dir = getOSLibDir(target);
109 const multiarch_triple = getMultiarchTriple(target) orelse target_util.toLLVMTriple(target, &output);
110
111 try self.addMultiLibPaths(tc, sysroot, os_lib_dir);
112
113 try tc.addPathIfExists(&.{ sysroot, "/lib", multiarch_triple }, .file);
114 try tc.addPathIfExists(&.{ sysroot, "/lib", "..", os_lib_dir }, .file);
115
116 if (target.isAndroid()) {
117 // TODO
118 }
119 try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", multiarch_triple }, .file);
120 try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", "..", os_lib_dir }, .file);
121
122 try self.addMultiArchPaths(tc);
123
124 try tc.addPathIfExists(&.{ sysroot, "/lib" }, .file);
125 try tc.addPathIfExists(&.{ sysroot, "/usr", "lib" }, .file);
126}
127
128pub fn deinit(self: *Linux, allocator: std.mem.Allocator) void {
129 self.extra_opts.deinit(allocator);
130}
131
132fn isPIEDefault(self: *const Linux) bool {
133 _ = self;
134 return false;
135}
136
137fn getPIE(self: *const Linux, d: *const Driver) bool {
138 if (d.shared or d.static or d.relocatable or d.static_pie) {
139 return false;
140 }
141 return d.pie orelse self.isPIEDefault();
142}
143
144fn getStaticPIE(self: *const Linux, d: *Driver) !bool {
145 _ = self;
146 if (d.static_pie and d.pie != null) {
147 try d.err("cannot specify 'nopie' along with 'static-pie'");
148 }
149 return d.static_pie;
150}
151
152fn getStatic(self: *const Linux, d: *const Driver) bool {
153 _ = self;
154 return d.static and !d.static_pie;
155}
156
157pub fn getDefaultLinker(self: *const Linux, target: std.Target) []const u8 {
158 _ = self;
159 if (target.isAndroid()) {
160 return "ld.lld";
161 }
162 return "ld";
163}
164
165pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.ArrayList([]const u8)) Compilation.Error!void {
166 const d = tc.driver;
167 const target = tc.getTarget();
168
169 const is_pie = self.getPIE(d);
170 const is_static_pie = try self.getStaticPIE(d);
171 const is_static = self.getStatic(d);
172 const is_android = target.isAndroid();
173 const is_iamcu = target.os.tag == .elfiamcu;
174 const is_ve = target.cpu.arch == .ve;
175 const has_crt_begin_end_files = target.abi != .none; // TODO: clang checks for MIPS vendor
176
177 if (is_pie) {
178 try argv.append("-pie");
179 }
180 if (is_static_pie) {
181 try argv.appendSlice(&.{ "-static", "-pie", "--no-dynamic-linker", "-z", "text" });
182 }
183
184 if (d.rdynamic) {
185 try argv.append("-export-dynamic");
186 }
187
188 if (d.strip) {
189 try argv.append("-s");
190 }
191
192 try argv.appendSlice(self.extra_opts.items);
193 try argv.append("--eh-frame-hdr");
194
195 // Todo: Driver should parse `-EL`/`-EB` for arm to set endianness for arm targets
196 if (target_util.ldEmulationOption(d.comp.target, null)) |emulation| {
197 try argv.appendSlice(&.{ "-m", emulation });
198 } else {
199 try d.err("Unknown target triple");
200 return;
201 }
202 if (d.comp.target.cpu.arch.isRISCV()) {
203 try argv.append("-X");
204 }
205 if (d.shared) {
206 try argv.append("-shared");
207 }
208 if (is_static) {
209 try argv.append("-static");
210 } else {
211 if (d.rdynamic) {
212 try argv.append("-export-dynamic");
213 }
214 if (!d.shared and !is_static_pie and !d.relocatable) {
215 const dynamic_linker = d.comp.target.standardDynamicLinkerPath();
216 // todo: check for --dyld-prefix
217 if (dynamic_linker.get()) |path| {
218 try argv.appendSlice(&.{ "-dynamic-linker", try tc.arena.dupe(u8, path) });
219 } else {
220 try d.err("Could not find dynamic linker path");
221 }
222 }
223 }
224
225 try argv.appendSlice(&.{ "-o", d.output_name orelse "a.out" });
226
227 if (!d.nostdlib and !d.nostartfiles and !d.relocatable) {
228 if (!is_android and !is_iamcu) {
229 if (!d.shared) {
230 const crt1 = if (is_pie)
231 "Scrt1.o"
232 else if (is_static_pie)
233 "rcrt1.o"
234 else
235 "crt1.o";
236 try argv.append(try tc.getFilePath(crt1));
237 }
238 try argv.append(try tc.getFilePath("crti.o"));
239 }
240 if (is_ve) {
241 try argv.appendSlice(&.{ "-z", "max-page-size=0x4000000" });
242 }
243
244 if (is_iamcu) {
245 try argv.append(try tc.getFilePath("crt0.o"));
246 } else if (has_crt_begin_end_files) {
247 var path: []const u8 = "";
248 if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
249 const crt_begin = try tc.getCompilerRt("crtbegin", .object);
250 if (tc.filesystem.exists(crt_begin)) {
251 path = crt_begin;
252 }
253 }
254 if (path.len == 0) {
255 const crt_begin = if (tc.driver.shared)
256 if (is_android) "crtbegin_so.o" else "crtbeginS.o"
257 else if (is_static)
258 if (is_android) "crtbegin_static.o" else "crtbeginT.o"
259 else if (is_pie or is_static_pie)
260 if (is_android) "crtbegin_dynamic.o" else "crtbeginS.o"
261 else if (is_android) "crtbegin_dynamic.o" else "crtbegin.o";
262 path = try tc.getFilePath(crt_begin);
263 }
264 try argv.append(path);
265 }
266 }
267
268 // TODO add -L opts
269 // TODO add -u opts
270
271 try tc.addFilePathLibArgs(argv);
272
273 // TODO handle LTO
274
275 try argv.appendSlice(d.link_objects.items);
276
277 if (!d.nostdlib and !d.relocatable) {
278 if (!d.nodefaultlibs) {
279 if (is_static or is_static_pie) {
280 try argv.append("--start-group");
281 }
282 try tc.addRuntimeLibs(argv);
283
284 // TODO: add pthread if needed
285 if (!d.nolibc) {
286 try argv.append("-lc");
287 }
288 if (is_iamcu) {
289 try argv.append("-lgloss");
290 }
291 if (is_static or is_static_pie) {
292 try argv.append("--end-group");
293 } else {
294 try tc.addRuntimeLibs(argv);
295 }
296 if (is_iamcu) {
297 try argv.appendSlice(&.{ "--as-needed", "-lsoftfp", "--no-as-needed" });
298 }
299 }
300 if (!d.nostartfiles and !is_iamcu) {
301 if (has_crt_begin_end_files) {
302 var path: []const u8 = "";
303 if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
304 const crt_end = try tc.getCompilerRt("crtend", .object);
305 if (tc.filesystem.exists(crt_end)) {
306 path = crt_end;
307 }
308 }
309 if (path.len == 0) {
310 const crt_end = if (d.shared)
311 if (is_android) "crtend_so.o" else "crtendS.o"
312 else if (is_pie or is_static_pie)
313 if (is_android) "crtend_android.o" else "crtendS.o"
314 else if (is_android) "crtend_android.o" else "crtend.o";
315 path = try tc.getFilePath(crt_end);
316 }
317 try argv.append(path);
318 }
319 if (!is_android) {
320 try argv.append(try tc.getFilePath("crtn.o"));
321 }
322 }
323 }
324
325 // TODO add -T args
326}
327
328fn getMultiarchTriple(target: std.Target) ?[]const u8 {
329 const is_android = target.isAndroid();
330 const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6);
331 return switch (target.cpu.arch) {
332 .arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi",
333 .armeb, .thumbeb => if (target.abi == .gnueabihf) "armeb-linux-gnueabihf" else "armeb-linux-gnueabi",
334 .aarch64 => if (is_android) "aarch64-linux-android" else "aarch64-linux-gnu",
335 .aarch64_be => "aarch64_be-linux-gnu",
336 .x86 => if (is_android) "i686-linux-android" else "i386-linux-gnu",
337 .x86_64 => if (is_android) "x86_64-linux-android" else if (target.abi == .gnux32) "x86_64-linux-gnux32" else "x86_64-linux-gnu",
338 .m68k => "m68k-linux-gnu",
339 .mips => if (is_mips_r6) "mipsisa32r6-linux-gnu" else "mips-linux-gnu",
340 .mipsel => if (is_android) "mipsel-linux-android" else if (is_mips_r6) "mipsisa32r6el-linux-gnu" else "mipsel-linux-gnu",
341 .powerpcle => "powerpcle-linux-gnu",
342 .powerpc64 => "powerpc64-linux-gnu",
343 .powerpc64le => "powerpc64le-linux-gnu",
344 .riscv64 => "riscv64-linux-gnu",
345 .sparc => "sparc-linux-gnu",
346 .sparc64 => "sparc64-linux-gnu",
347 .s390x => "s390x-linux-gnu",
348
349 // TODO: expand this
350 else => null,
351 };
352}
353
354fn getOSLibDir(target: std.Target) []const u8 {
355 switch (target.cpu.arch) {
356 .x86,
357 .powerpc,
358 .powerpcle,
359 .sparc,
360 .sparcel,
361 => return "lib32",
362 else => {},
363 }
364 if (target.cpu.arch == .x86_64 and (target.abi == .gnux32 or target.abi == .muslx32)) {
365 return "libx32";
366 }
367 if (target.cpu.arch == .riscv32) {
368 return "lib32";
369 }
370 if (target.ptrBitWidth() == 32) {
371 return "lib";
372 }
373 return "lib64";
374}
375
376test Linux {
377 if (@import("builtin").os.tag == .windows) return error.SkipZigTest;
378
379 var arena_instance = std.heap.ArenaAllocator.init(std.testing.allocator);
380 defer arena_instance.deinit();
381 const arena = arena_instance.allocator();
382
383 var comp = Compilation.init(std.testing.allocator);
384 defer comp.deinit();
385 comp.environment = .{
386 .path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
387 };
388 defer comp.environment = .{};
389
390 const raw_triple = "x86_64-linux-gnu";
391 const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = raw_triple }) catch unreachable;
392 comp.target = cross.toTarget(); // TODO deprecated
393 comp.langopts.setEmulatedCompiler(.gcc);
394
395 var driver: Driver = .{ .comp = &comp };
396 defer driver.deinit();
397 driver.raw_target_triple = raw_triple;
398
399 const link_obj = try driver.comp.gpa.dupe(u8, "/tmp/foo.o");
400 try driver.link_objects.append(driver.comp.gpa, link_obj);
401 driver.temp_file_count += 1;
402
403 var toolchain: Toolchain = .{ .driver = &driver, .arena = arena, .filesystem = .{ .fake = &.{
404 .{ .path = "/tmp" },
405 .{ .path = "/usr" },
406 .{ .path = "/usr/lib64" },
407 .{ .path = "/usr/bin" },
408 .{ .path = "/usr/bin/ld", .executable = true },
409 .{ .path = "/lib" },
410 .{ .path = "/lib/x86_64-linux-gnu" },
411 .{ .path = "/lib/x86_64-linux-gnu/crt1.o" },
412 .{ .path = "/lib/x86_64-linux-gnu/crti.o" },
413 .{ .path = "/lib/x86_64-linux-gnu/crtn.o" },
414 .{ .path = "/lib64" },
415 .{ .path = "/usr/lib" },
416 .{ .path = "/usr/lib/gcc" },
417 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu" },
418 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9" },
419 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o" },
420 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o" },
421 .{ .path = "/usr/lib/x86_64-linux-gnu" },
422 .{ .path = "/etc/lsb-release", .contents =
423 \\DISTRIB_ID=Ubuntu
424 \\DISTRIB_RELEASE=20.04
425 \\DISTRIB_CODENAME=focal
426 \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
427 \\
428 },
429 } } };
430 defer toolchain.deinit();
431
432 try toolchain.discover();
433
434 var argv = std.ArrayList([]const u8).init(driver.comp.gpa);
435 defer argv.deinit();
436
437 var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
438 const linker_path = try toolchain.getLinkerPath(&linker_path_buf);
439 try argv.append(linker_path);
440
441 try toolchain.buildLinkerArgs(&argv);
442
443 const expected = [_][]const u8{
444 "/usr/bin/ld",
445 "-z",
446 "relro",
447 "--hash-style=gnu",
448 "--eh-frame-hdr",
449 "-m",
450 "elf_x86_64",
451 "-dynamic-linker",
452 "/lib64/ld-linux-x86-64.so.2",
453 "-o",
454 "a.out",
455 "/lib/x86_64-linux-gnu/crt1.o",
456 "/lib/x86_64-linux-gnu/crti.o",
457 "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o",
458 "-L/usr/lib/gcc/x86_64-linux-gnu/9",
459 "-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64",
460 "-L/lib/x86_64-linux-gnu",
461 "-L/lib/../lib64",
462 "-L/usr/lib/x86_64-linux-gnu",
463 "-L/usr/lib/../lib64",
464 "-L/lib",
465 "-L/usr/lib",
466 link_obj,
467 "-lgcc",
468 "--as-needed",
469 "-lgcc_s",
470 "--no-as-needed",
471 "-lc",
472 "-lgcc",
473 "--as-needed",
474 "-lgcc_s",
475 "--no-as-needed",
476 "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o",
477 "/lib/x86_64-linux-gnu/crtn.o",
478 };
479 try std.testing.expectEqual(expected.len, argv.items.len);
480 for (expected, argv.items) |expected_item, actual_item| {
481 try std.testing.expectEqualStrings(expected_item, actual_item);
482 }
483}
deps/aro/aro/tracy.zig deleted-310
......@@ -1,310 +0,0 @@
1//! Copied from https://github.com/ziglang/zig/blob/c9006d9479c619d9ed555164831e11a04d88d382/src/tracy.zig
2
3const std = @import("std");
4const builtin = @import("builtin");
5const build_options = @import("build_options");
6
7pub const enable = if (builtin.is_test) false else build_options.enable_tracy;
8pub const enable_allocation = enable and build_options.enable_tracy_allocation;
9pub const enable_callstack = enable and build_options.enable_tracy_callstack;
10
11// TODO: make this configurable
12const callstack_depth = 10;
13
14const ___tracy_c_zone_context = extern struct {
15 id: u32,
16 active: c_int,
17
18 pub inline fn end(self: @This()) void {
19 ___tracy_emit_zone_end(self);
20 }
21
22 pub inline fn addText(self: @This(), text: []const u8) void {
23 ___tracy_emit_zone_text(self, text.ptr, text.len);
24 }
25
26 pub inline fn setName(self: @This(), name: []const u8) void {
27 ___tracy_emit_zone_name(self, name.ptr, name.len);
28 }
29
30 pub inline fn setColor(self: @This(), color: u32) void {
31 ___tracy_emit_zone_color(self, color);
32 }
33
34 pub inline fn setValue(self: @This(), value: u64) void {
35 ___tracy_emit_zone_value(self, value);
36 }
37};
38
39pub const Ctx = if (enable) ___tracy_c_zone_context else struct {
40 pub inline fn end(self: @This()) void {
41 _ = self;
42 }
43
44 pub inline fn addText(self: @This(), text: []const u8) void {
45 _ = self;
46 _ = text;
47 }
48
49 pub inline fn setName(self: @This(), name: []const u8) void {
50 _ = self;
51 _ = name;
52 }
53
54 pub inline fn setColor(self: @This(), color: u32) void {
55 _ = self;
56 _ = color;
57 }
58
59 pub inline fn setValue(self: @This(), value: u64) void {
60 _ = self;
61 _ = value;
62 }
63};
64
65pub inline fn trace(comptime src: std.builtin.SourceLocation) Ctx {
66 if (!enable) return .{};
67
68 if (enable_callstack) {
69 return ___tracy_emit_zone_begin_callstack(&.{
70 .name = null,
71 .function = src.fn_name.ptr,
72 .file = src.file.ptr,
73 .line = src.line,
74 .color = 0,
75 }, callstack_depth, 1);
76 } else {
77 return ___tracy_emit_zone_begin(&.{
78 .name = null,
79 .function = src.fn_name.ptr,
80 .file = src.file.ptr,
81 .line = src.line,
82 .color = 0,
83 }, 1);
84 }
85}
86
87pub inline fn traceNamed(comptime src: std.builtin.SourceLocation, comptime name: [:0]const u8) Ctx {
88 if (!enable) return .{};
89
90 if (enable_callstack) {
91 return ___tracy_emit_zone_begin_callstack(&.{
92 .name = name.ptr,
93 .function = src.fn_name.ptr,
94 .file = src.file.ptr,
95 .line = src.line,
96 .color = 0,
97 }, callstack_depth, 1);
98 } else {
99 return ___tracy_emit_zone_begin(&.{
100 .name = name.ptr,
101 .function = src.fn_name.ptr,
102 .file = src.file.ptr,
103 .line = src.line,
104 .color = 0,
105 }, 1);
106 }
107}
108
109pub fn tracyAllocator(allocator: std.mem.Allocator) TracyAllocator(null) {
110 return TracyAllocator(null).init(allocator);
111}
112
113pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
114 return struct {
115 parent_allocator: std.mem.Allocator,
116
117 const Self = @This();
118
119 pub fn init(parent_allocator: std.mem.Allocator) Self {
120 return .{
121 .parent_allocator = parent_allocator,
122 };
123 }
124
125 pub fn allocator(self: *Self) std.mem.Allocator {
126 return std.mem.Allocator.init(self, allocFn, resizeFn, freeFn);
127 }
128
129 fn allocFn(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 {
130 const result = self.parent_allocator.rawAlloc(len, ptr_align, len_align, ret_addr);
131 if (result) |data| {
132 if (data.len != 0) {
133 if (name) |n| {
134 allocNamed(data.ptr, data.len, n);
135 } else {
136 alloc(data.ptr, data.len);
137 }
138 }
139 } else |_| {
140 messageColor("allocation failed", 0xFF0000);
141 }
142 return result;
143 }
144
145 fn resizeFn(self: *Self, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
146 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ret_addr)) |resized_len| {
147 if (name) |n| {
148 freeNamed(buf.ptr, n);
149 allocNamed(buf.ptr, resized_len, n);
150 } else {
151 free(buf.ptr);
152 alloc(buf.ptr, resized_len);
153 }
154
155 return resized_len;
156 }
157
158 // during normal operation the compiler hits this case thousands of times due to this
159 // emitting messages for it is both slow and causes clutter
160 return null;
161 }
162
163 fn freeFn(self: *Self, buf: []u8, buf_align: u29, ret_addr: usize) void {
164 self.parent_allocator.rawFree(buf, buf_align, ret_addr);
165 // this condition is to handle free being called on an empty slice that was never even allocated
166 // example case: `std.process.getSelfExeSharedLibPaths` can return `&[_][:0]u8{}`
167 if (buf.len != 0) {
168 if (name) |n| {
169 freeNamed(buf.ptr, n);
170 } else {
171 free(buf.ptr);
172 }
173 }
174 }
175 };
176}
177
178// This function only accepts comptime known strings, see `messageCopy` for runtime strings
179pub inline fn message(comptime msg: [:0]const u8) void {
180 if (!enable) return;
181 ___tracy_emit_messageL(msg.ptr, if (enable_callstack) callstack_depth else 0);
182}
183
184// This function only accepts comptime known strings, see `messageColorCopy` for runtime strings
185pub inline fn messageColor(comptime msg: [:0]const u8, color: u32) void {
186 if (!enable) return;
187 ___tracy_emit_messageLC(msg.ptr, color, if (enable_callstack) callstack_depth else 0);
188}
189
190pub inline fn messageCopy(msg: []const u8) void {
191 if (!enable) return;
192 ___tracy_emit_message(msg.ptr, msg.len, if (enable_callstack) callstack_depth else 0);
193}
194
195pub inline fn messageColorCopy(msg: [:0]const u8, color: u32) void {
196 if (!enable) return;
197 ___tracy_emit_messageC(msg.ptr, msg.len, color, if (enable_callstack) callstack_depth else 0);
198}
199
200pub inline fn frameMark() void {
201 if (!enable) return;
202 ___tracy_emit_frame_mark(null);
203}
204
205pub inline fn frameMarkNamed(comptime name: [:0]const u8) void {
206 if (!enable) return;
207 ___tracy_emit_frame_mark(name.ptr);
208}
209
210pub inline fn namedFrame(comptime name: [:0]const u8) Frame(name) {
211 frameMarkStart(name);
212 return .{};
213}
214
215pub fn Frame(comptime name: [:0]const u8) type {
216 return struct {
217 pub fn end(_: @This()) void {
218 frameMarkEnd(name);
219 }
220 };
221}
222
223inline fn frameMarkStart(comptime name: [:0]const u8) void {
224 if (!enable) return;
225 ___tracy_emit_frame_mark_start(name.ptr);
226}
227
228inline fn frameMarkEnd(comptime name: [:0]const u8) void {
229 if (!enable) return;
230 ___tracy_emit_frame_mark_end(name.ptr);
231}
232
233extern fn ___tracy_emit_frame_mark_start(name: [*:0]const u8) void;
234extern fn ___tracy_emit_frame_mark_end(name: [*:0]const u8) void;
235
236inline fn alloc(ptr: [*]u8, len: usize) void {
237 if (!enable) return;
238
239 if (enable_callstack) {
240 ___tracy_emit_memory_alloc_callstack(ptr, len, callstack_depth, 0);
241 } else {
242 ___tracy_emit_memory_alloc(ptr, len, 0);
243 }
244}
245
246inline fn allocNamed(ptr: [*]u8, len: usize, comptime name: [:0]const u8) void {
247 if (!enable) return;
248
249 if (enable_callstack) {
250 ___tracy_emit_memory_alloc_callstack_named(ptr, len, callstack_depth, 0, name.ptr);
251 } else {
252 ___tracy_emit_memory_alloc_named(ptr, len, 0, name.ptr);
253 }
254}
255
256inline fn free(ptr: [*]u8) void {
257 if (!enable) return;
258
259 if (enable_callstack) {
260 ___tracy_emit_memory_free_callstack(ptr, callstack_depth, 0);
261 } else {
262 ___tracy_emit_memory_free(ptr, 0);
263 }
264}
265
266inline fn freeNamed(ptr: [*]u8, comptime name: [:0]const u8) void {
267 if (!enable) return;
268
269 if (enable_callstack) {
270 ___tracy_emit_memory_free_callstack_named(ptr, callstack_depth, 0, name.ptr);
271 } else {
272 ___tracy_emit_memory_free_named(ptr, 0, name.ptr);
273 }
274}
275
276extern fn ___tracy_emit_zone_begin(
277 srcloc: *const ___tracy_source_location_data,
278 active: c_int,
279) ___tracy_c_zone_context;
280extern fn ___tracy_emit_zone_begin_callstack(
281 srcloc: *const ___tracy_source_location_data,
282 depth: c_int,
283 active: c_int,
284) ___tracy_c_zone_context;
285extern fn ___tracy_emit_zone_text(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
286extern fn ___tracy_emit_zone_name(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
287extern fn ___tracy_emit_zone_color(ctx: ___tracy_c_zone_context, color: u32) void;
288extern fn ___tracy_emit_zone_value(ctx: ___tracy_c_zone_context, value: u64) void;
289extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void;
290extern fn ___tracy_emit_memory_alloc(ptr: *const anyopaque, size: usize, secure: c_int) void;
291extern fn ___tracy_emit_memory_alloc_callstack(ptr: *const anyopaque, size: usize, depth: c_int, secure: c_int) void;
292extern fn ___tracy_emit_memory_free(ptr: *const anyopaque, secure: c_int) void;
293extern fn ___tracy_emit_memory_free_callstack(ptr: *const anyopaque, depth: c_int, secure: c_int) void;
294extern fn ___tracy_emit_memory_alloc_named(ptr: *const anyopaque, size: usize, secure: c_int, name: [*:0]const u8) void;
295extern fn ___tracy_emit_memory_alloc_callstack_named(ptr: *const anyopaque, size: usize, depth: c_int, secure: c_int, name: [*:0]const u8) void;
296extern fn ___tracy_emit_memory_free_named(ptr: *const anyopaque, secure: c_int, name: [*:0]const u8) void;
297extern fn ___tracy_emit_memory_free_callstack_named(ptr: *const anyopaque, depth: c_int, secure: c_int, name: [*:0]const u8) void;
298extern fn ___tracy_emit_message(txt: [*]const u8, size: usize, callstack: c_int) void;
299extern fn ___tracy_emit_messageL(txt: [*:0]const u8, callstack: c_int) void;
300extern fn ___tracy_emit_messageC(txt: [*]const u8, size: usize, color: u32, callstack: c_int) void;
301extern fn ___tracy_emit_messageLC(txt: [*:0]const u8, color: u32, callstack: c_int) void;
302extern fn ___tracy_emit_frame_mark(name: ?[*:0]const u8) void;
303
304const ___tracy_source_location_data = extern struct {
305 name: ?[*:0]const u8,
306 function: [*:0]const u8,
307 file: [*:0]const u8,
308 line: u32,
309 color: u32,
310};
deps/aro/backend.zig deleted-13
......@@ -1,13 +0,0 @@
1pub const Interner = @import("backend/Interner.zig");
2pub const Ir = @import("backend/Ir.zig");
3pub const Object = @import("backend/Object.zig");
4
5pub const CallingConvention = enum {
6 C,
7 stdcall,
8 thiscall,
9 vectorcall,
10};
11
12pub const version_str = @import("build_options").version_str;
13pub const version = @import("std").SemanticVersion.parse(version_str) catch unreachable;
deps/aro/backend/Interner.zig deleted-647
......@@ -1,647 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const BigIntConst = std.math.big.int.Const;
5const BigIntMutable = std.math.big.int.Mutable;
6const Hash = std.hash.Wyhash;
7const Limb = std.math.big.Limb;
8
9const Interner = @This();
10
11map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
12items: std.MultiArrayList(struct {
13 tag: Tag,
14 data: u32,
15}) = .{},
16extra: std.ArrayListUnmanaged(u32) = .{},
17limbs: std.ArrayListUnmanaged(Limb) = .{},
18strings: std.ArrayListUnmanaged(u8) = .{},
19
20const KeyAdapter = struct {
21 interner: *const Interner,
22
23 pub fn eql(adapter: KeyAdapter, a: Key, b_void: void, b_map_index: usize) bool {
24 _ = b_void;
25 return adapter.interner.get(@as(Ref, @enumFromInt(b_map_index))).eql(a);
26 }
27
28 pub fn hash(adapter: KeyAdapter, a: Key) u32 {
29 _ = adapter;
30 return a.hash();
31 }
32};
33
34pub const Key = union(enum) {
35 int_ty: u16,
36 float_ty: u16,
37 ptr_ty,
38 noreturn_ty,
39 void_ty,
40 func_ty,
41 array_ty: struct {
42 len: u64,
43 child: Ref,
44 },
45 vector_ty: struct {
46 len: u32,
47 child: Ref,
48 },
49 record_ty: []const Ref,
50 /// May not be zero
51 null,
52 int: union(enum) {
53 u64: u64,
54 i64: i64,
55 big_int: BigIntConst,
56
57 pub fn toBigInt(repr: @This(), space: *Tag.Int.BigIntSpace) BigIntConst {
58 return switch (repr) {
59 .big_int => |x| x,
60 inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(),
61 };
62 }
63 },
64 float: Float,
65 bytes: []const u8,
66
67 pub const Float = union(enum) {
68 f16: f16,
69 f32: f32,
70 f64: f64,
71 f80: f80,
72 f128: f128,
73 };
74
75 pub fn hash(key: Key) u32 {
76 var hasher = Hash.init(0);
77 const tag = std.meta.activeTag(key);
78 std.hash.autoHash(&hasher, tag);
79 switch (key) {
80 .bytes => |bytes| {
81 hasher.update(bytes);
82 },
83 .record_ty => |elems| for (elems) |elem| {
84 std.hash.autoHash(&hasher, elem);
85 },
86 .float => |repr| switch (repr) {
87 inline else => |data| std.hash.autoHash(
88 &hasher,
89 @as(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(data))), @bitCast(data)),
90 ),
91 },
92 .int => |repr| {
93 var space: Tag.Int.BigIntSpace = undefined;
94 const big = repr.toBigInt(&space);
95 std.hash.autoHash(&hasher, big.positive);
96 for (big.limbs) |limb| std.hash.autoHash(&hasher, limb);
97 },
98 inline else => |info| {
99 std.hash.autoHash(&hasher, info);
100 },
101 }
102 return @truncate(hasher.final());
103 }
104
105 pub fn eql(a: Key, b: Key) bool {
106 const KeyTag = std.meta.Tag(Key);
107 const a_tag: KeyTag = a;
108 const b_tag: KeyTag = b;
109 if (a_tag != b_tag) return false;
110 switch (a) {
111 .record_ty => |a_elems| {
112 const b_elems = b.record_ty;
113 if (a_elems.len != b_elems.len) return false;
114 for (a_elems, b_elems) |a_elem, b_elem| {
115 if (a_elem != b_elem) return false;
116 }
117 return true;
118 },
119 .bytes => |a_bytes| {
120 const b_bytes = b.bytes;
121 return std.mem.eql(u8, a_bytes, b_bytes);
122 },
123 .int => |a_repr| {
124 var a_space: Tag.Int.BigIntSpace = undefined;
125 const a_big = a_repr.toBigInt(&a_space);
126 var b_space: Tag.Int.BigIntSpace = undefined;
127 const b_big = b.int.toBigInt(&b_space);
128
129 return a_big.eql(b_big);
130 },
131 inline else => |a_info, tag| {
132 const b_info = @field(b, @tagName(tag));
133 return std.meta.eql(a_info, b_info);
134 },
135 }
136 }
137
138 fn toRef(key: Key) ?Ref {
139 switch (key) {
140 .int_ty => |bits| switch (bits) {
141 1 => return .i1,
142 8 => return .i8,
143 16 => return .i16,
144 32 => return .i32,
145 64 => return .i64,
146 128 => return .i128,
147 else => {},
148 },
149 .float_ty => |bits| switch (bits) {
150 16 => return .f16,
151 32 => return .f32,
152 64 => return .f64,
153 80 => return .f80,
154 128 => return .f128,
155 else => unreachable,
156 },
157 .ptr_ty => return .ptr,
158 .func_ty => return .func,
159 .noreturn_ty => return .noreturn,
160 .void_ty => return .void,
161 .int => |repr| {
162 var space: Tag.Int.BigIntSpace = undefined;
163 const big = repr.toBigInt(&space);
164 if (big.eqlZero()) return .zero;
165 const big_one = BigIntConst{ .limbs = &.{1}, .positive = true };
166 if (big.eql(big_one)) return .one;
167 },
168 .float => |repr| switch (repr) {
169 inline else => |data| {
170 if (std.math.isPositiveZero(data)) return .zero;
171 if (data == 1) return .one;
172 },
173 },
174 .null => return .null,
175 else => {},
176 }
177 return null;
178 }
179};
180
181pub const Ref = enum(u32) {
182 const max = std.math.maxInt(u32);
183
184 ptr = max - 1,
185 noreturn = max - 2,
186 void = max - 3,
187 i1 = max - 4,
188 i8 = max - 5,
189 i16 = max - 6,
190 i32 = max - 7,
191 i64 = max - 8,
192 i128 = max - 9,
193 f16 = max - 10,
194 f32 = max - 11,
195 f64 = max - 12,
196 f80 = max - 13,
197 f128 = max - 14,
198 func = max - 15,
199 zero = max - 16,
200 one = max - 17,
201 null = max - 18,
202 _,
203};
204
205pub const OptRef = enum(u32) {
206 const max = std.math.maxInt(u32);
207
208 none = max - 0,
209 ptr = max - 1,
210 noreturn = max - 2,
211 void = max - 3,
212 i1 = max - 4,
213 i8 = max - 5,
214 i16 = max - 6,
215 i32 = max - 7,
216 i64 = max - 8,
217 i128 = max - 9,
218 f16 = max - 10,
219 f32 = max - 11,
220 f64 = max - 12,
221 f80 = max - 13,
222 f128 = max - 14,
223 func = max - 15,
224 zero = max - 16,
225 one = max - 17,
226 null = max - 18,
227 _,
228};
229
230pub const Tag = enum(u8) {
231 /// `data` is `u16`
232 int_ty,
233 /// `data` is `u16`
234 float_ty,
235 /// `data` is index to `Array`
236 array_ty,
237 /// `data` is index to `Vector`
238 vector_ty,
239 /// `data` is `u32`
240 u32,
241 /// `data` is `i32`
242 i32,
243 /// `data` is `Int`
244 int_positive,
245 /// `data` is `Int`
246 int_negative,
247 /// `data` is `f16`
248 f16,
249 /// `data` is `f32`
250 f32,
251 /// `data` is `F64`
252 f64,
253 /// `data` is `F80`
254 f80,
255 /// `data` is `F128`
256 f128,
257 /// `data` is `Bytes`
258 bytes,
259 /// `data` is `Record`
260 record_ty,
261
262 pub const Array = struct {
263 len0: u32,
264 len1: u32,
265 child: Ref,
266
267 pub fn getLen(a: Array) u64 {
268 return (PackedU64{
269 .a = a.len0,
270 .b = a.len1,
271 }).get();
272 }
273 };
274
275 pub const Vector = struct {
276 len: u32,
277 child: Ref,
278 };
279
280 pub const Int = struct {
281 limbs_index: u32,
282 limbs_len: u32,
283
284 /// Big enough to fit any non-BigInt value
285 pub const BigIntSpace = struct {
286 /// The +1 is headroom so that operations such as incrementing once
287 /// or decrementing once are possible without using an allocator.
288 limbs: [(@sizeOf(u64) / @sizeOf(std.math.big.Limb)) + 1]std.math.big.Limb,
289 };
290 };
291
292 pub const F64 = struct {
293 piece0: u32,
294 piece1: u32,
295
296 pub fn get(self: F64) f64 {
297 const int_bits = @as(u64, self.piece0) | (@as(u64, self.piece1) << 32);
298 return @bitCast(int_bits);
299 }
300
301 fn pack(val: f64) F64 {
302 const bits = @as(u64, @bitCast(val));
303 return .{
304 .piece0 = @as(u32, @truncate(bits)),
305 .piece1 = @as(u32, @truncate(bits >> 32)),
306 };
307 }
308 };
309
310 pub const F80 = struct {
311 piece0: u32,
312 piece1: u32,
313 piece2: u32, // u16 part, top bits
314
315 pub fn get(self: F80) f80 {
316 const int_bits = @as(u80, self.piece0) |
317 (@as(u80, self.piece1) << 32) |
318 (@as(u80, self.piece2) << 64);
319 return @bitCast(int_bits);
320 }
321
322 fn pack(val: f80) F80 {
323 const bits = @as(u80, @bitCast(val));
324 return .{
325 .piece0 = @as(u32, @truncate(bits)),
326 .piece1 = @as(u32, @truncate(bits >> 32)),
327 .piece2 = @as(u16, @truncate(bits >> 64)),
328 };
329 }
330 };
331
332 pub const F128 = struct {
333 piece0: u32,
334 piece1: u32,
335 piece2: u32,
336 piece3: u32,
337
338 pub fn get(self: F128) f128 {
339 const int_bits = @as(u128, self.piece0) |
340 (@as(u128, self.piece1) << 32) |
341 (@as(u128, self.piece2) << 64) |
342 (@as(u128, self.piece3) << 96);
343 return @bitCast(int_bits);
344 }
345
346 fn pack(val: f128) F128 {
347 const bits = @as(u128, @bitCast(val));
348 return .{
349 .piece0 = @as(u32, @truncate(bits)),
350 .piece1 = @as(u32, @truncate(bits >> 32)),
351 .piece2 = @as(u32, @truncate(bits >> 64)),
352 .piece3 = @as(u32, @truncate(bits >> 96)),
353 };
354 }
355 };
356
357 pub const Bytes = struct {
358 strings_index: u32,
359 len: u32,
360 };
361
362 pub const Record = struct {
363 elements_len: u32,
364 // trailing
365 // [elements_len]Ref
366 };
367};
368
369pub const PackedU64 = packed struct(u64) {
370 a: u32,
371 b: u32,
372
373 pub fn get(x: PackedU64) u64 {
374 return @bitCast(x);
375 }
376
377 pub fn init(x: u64) PackedU64 {
378 return @bitCast(x);
379 }
380};
381
382pub fn deinit(i: *Interner, gpa: Allocator) void {
383 i.map.deinit(gpa);
384 i.items.deinit(gpa);
385 i.extra.deinit(gpa);
386 i.limbs.deinit(gpa);
387 i.strings.deinit(gpa);
388}
389
390pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref {
391 if (key.toRef()) |some| return some;
392 const adapter: KeyAdapter = .{ .interner = i };
393 const gop = try i.map.getOrPutAdapted(gpa, key, adapter);
394 if (gop.found_existing) return @enumFromInt(gop.index);
395 try i.items.ensureUnusedCapacity(gpa, 1);
396
397 switch (key) {
398 .int_ty => |bits| {
399 i.items.appendAssumeCapacity(.{
400 .tag = .int_ty,
401 .data = bits,
402 });
403 },
404 .float_ty => |bits| {
405 i.items.appendAssumeCapacity(.{
406 .tag = .float_ty,
407 .data = bits,
408 });
409 },
410 .array_ty => |info| {
411 const split_len = PackedU64.init(info.len);
412 i.items.appendAssumeCapacity(.{
413 .tag = .array_ty,
414 .data = try i.addExtra(gpa, Tag.Array{
415 .len0 = split_len.a,
416 .len1 = split_len.b,
417 .child = info.child,
418 }),
419 });
420 },
421 .vector_ty => |info| {
422 i.items.appendAssumeCapacity(.{
423 .tag = .vector_ty,
424 .data = try i.addExtra(gpa, Tag.Vector{
425 .len = info.len,
426 .child = info.child,
427 }),
428 });
429 },
430 .int => |repr| int: {
431 var space: Tag.Int.BigIntSpace = undefined;
432 const big = repr.toBigInt(&space);
433 switch (repr) {
434 .u64 => |data| if (std.math.cast(u32, data)) |small| {
435 i.items.appendAssumeCapacity(.{
436 .tag = .u32,
437 .data = small,
438 });
439 break :int;
440 },
441 .i64 => |data| if (std.math.cast(i32, data)) |small| {
442 i.items.appendAssumeCapacity(.{
443 .tag = .i32,
444 .data = @bitCast(small),
445 });
446 break :int;
447 },
448 .big_int => |data| {
449 if (data.fitsInTwosComp(.unsigned, 32)) {
450 i.items.appendAssumeCapacity(.{
451 .tag = .u32,
452 .data = data.to(u32) catch unreachable,
453 });
454 break :int;
455 } else if (data.fitsInTwosComp(.signed, 32)) {
456 i.items.appendAssumeCapacity(.{
457 .tag = .i32,
458 .data = @bitCast(data.to(i32) catch unreachable),
459 });
460 break :int;
461 }
462 },
463 }
464 const limbs_index: u32 = @intCast(i.limbs.items.len);
465 try i.limbs.appendSlice(gpa, big.limbs);
466 i.items.appendAssumeCapacity(.{
467 .tag = if (big.positive) .int_positive else .int_negative,
468 .data = try i.addExtra(gpa, Tag.Int{
469 .limbs_index = limbs_index,
470 .limbs_len = @intCast(big.limbs.len),
471 }),
472 });
473 },
474 .float => |repr| switch (repr) {
475 .f16 => |data| i.items.appendAssumeCapacity(.{
476 .tag = .f16,
477 .data = @as(u16, @bitCast(data)),
478 }),
479 .f32 => |data| i.items.appendAssumeCapacity(.{
480 .tag = .f32,
481 .data = @as(u32, @bitCast(data)),
482 }),
483 .f64 => |data| i.items.appendAssumeCapacity(.{
484 .tag = .f64,
485 .data = try i.addExtra(gpa, Tag.F64.pack(data)),
486 }),
487 .f80 => |data| i.items.appendAssumeCapacity(.{
488 .tag = .f64,
489 .data = try i.addExtra(gpa, Tag.F80.pack(data)),
490 }),
491 .f128 => |data| i.items.appendAssumeCapacity(.{
492 .tag = .f64,
493 .data = try i.addExtra(gpa, Tag.F128.pack(data)),
494 }),
495 },
496 .bytes => |bytes| {
497 const strings_index: u32 = @intCast(i.strings.items.len);
498 try i.strings.appendSlice(gpa, bytes);
499 i.items.appendAssumeCapacity(.{
500 .tag = .bytes,
501 .data = try i.addExtra(gpa, Tag.Bytes{
502 .strings_index = strings_index,
503 .len = @intCast(bytes.len),
504 }),
505 });
506 },
507 .record_ty => |elems| {
508 try i.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.Record).Struct.fields.len +
509 elems.len);
510 i.items.appendAssumeCapacity(.{
511 .tag = .record_ty,
512 .data = i.addExtraAssumeCapacity(Tag.Record{
513 .elements_len = @intCast(elems.len),
514 }),
515 });
516 i.extra.appendSliceAssumeCapacity(@ptrCast(elems));
517 },
518 .ptr_ty,
519 .noreturn_ty,
520 .void_ty,
521 .func_ty,
522 .null,
523 => unreachable,
524 }
525
526 return @enumFromInt(gop.index);
527}
528
529fn addExtra(i: *Interner, gpa: Allocator, extra: anytype) Allocator.Error!u32 {
530 const fields = @typeInfo(@TypeOf(extra)).Struct.fields;
531 try i.extra.ensureUnusedCapacity(gpa, fields.len);
532 return i.addExtraAssumeCapacity(extra);
533}
534
535fn addExtraAssumeCapacity(i: *Interner, extra: anytype) u32 {
536 const result = @as(u32, @intCast(i.extra.items.len));
537 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {
538 i.extra.appendAssumeCapacity(switch (field.type) {
539 Ref => @intFromEnum(@field(extra, field.name)),
540 u32 => @field(extra, field.name),
541 else => @compileError("bad field type: " ++ @typeName(field.type)),
542 });
543 }
544 return result;
545}
546
547pub fn get(i: *const Interner, ref: Ref) Key {
548 switch (ref) {
549 .ptr => return .ptr_ty,
550 .func => return .func_ty,
551 .noreturn => return .noreturn_ty,
552 .void => return .void_ty,
553 .i1 => return .{ .int_ty = 1 },
554 .i8 => return .{ .int_ty = 8 },
555 .i16 => return .{ .int_ty = 16 },
556 .i32 => return .{ .int_ty = 32 },
557 .i64 => return .{ .int_ty = 64 },
558 .i128 => return .{ .int_ty = 128 },
559 .f16 => return .{ .float_ty = 16 },
560 .f32 => return .{ .float_ty = 32 },
561 .f64 => return .{ .float_ty = 64 },
562 .f80 => return .{ .float_ty = 80 },
563 .f128 => return .{ .float_ty = 128 },
564 .zero => return .{ .int = .{ .u64 = 0 } },
565 .one => return .{ .int = .{ .u64 = 1 } },
566 .null => return .null,
567 else => {},
568 }
569
570 const item = i.items.get(@intFromEnum(ref));
571 const data = item.data;
572 return switch (item.tag) {
573 .int_ty => .{ .int_ty = @intCast(data) },
574 .float_ty => .{ .float_ty = @intCast(data) },
575 .array_ty => {
576 const array_ty = i.extraData(Tag.Array, data);
577 return .{ .array_ty = .{
578 .len = array_ty.getLen(),
579 .child = array_ty.child,
580 } };
581 },
582 .vector_ty => {
583 const vector_ty = i.extraData(Tag.Vector, data);
584 return .{ .vector_ty = .{
585 .len = vector_ty.len,
586 .child = vector_ty.child,
587 } };
588 },
589 .u32 => .{ .int = .{ .u64 = data } },
590 .i32 => .{ .int = .{ .i64 = @as(i32, @bitCast(data)) } },
591 .int_positive, .int_negative => {
592 const int_info = i.extraData(Tag.Int, data);
593 const limbs = i.limbs.items[int_info.limbs_index..][0..int_info.limbs_len];
594 return .{ .int = .{
595 .big_int = .{
596 .positive = item.tag == .int_positive,
597 .limbs = limbs,
598 },
599 } };
600 },
601 .f16 => .{ .float = .{ .f16 = @bitCast(@as(u16, @intCast(data))) } },
602 .f32 => .{ .float = .{ .f32 = @bitCast(data) } },
603 .f64 => {
604 const float = i.extraData(Tag.F64, data);
605 return .{ .float = .{ .f64 = float.get() } };
606 },
607 .f80 => {
608 const float = i.extraData(Tag.F80, data);
609 return .{ .float = .{ .f80 = float.get() } };
610 },
611 .f128 => {
612 const float = i.extraData(Tag.F128, data);
613 return .{ .float = .{ .f128 = float.get() } };
614 },
615 .bytes => {
616 const bytes = i.extraData(Tag.Bytes, data);
617 return .{ .bytes = i.strings.items[bytes.strings_index..][0..bytes.len] };
618 },
619 .record_ty => {
620 const extra = i.extraDataTrail(Tag.Record, data);
621 return .{
622 .record_ty = @ptrCast(i.extra.items[extra.end..][0..extra.data.elements_len]),
623 };
624 },
625 };
626}
627
628fn extraData(i: *const Interner, comptime T: type, index: usize) T {
629 return i.extraDataTrail(T, index).data;
630}
631
632fn extraDataTrail(i: *const Interner, comptime T: type, index: usize) struct { data: T, end: u32 } {
633 var result: T = undefined;
634 const fields = @typeInfo(T).Struct.fields;
635 inline for (fields, 0..) |field, field_i| {
636 const int32 = i.extra.items[field_i + index];
637 @field(result, field.name) = switch (field.type) {
638 Ref => @enumFromInt(int32),
639 u32 => int32,
640 else => @compileError("bad field type: " ++ @typeName(field.type)),
641 };
642 }
643 return .{
644 .data = result,
645 .end = @intCast(index + fields.len),
646 };
647}
deps/aro/backend/Ir.zig deleted-696
......@@ -1,696 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const Interner = @import("Interner.zig");
5const Object = @import("Object.zig");
6
7const Ir = @This();
8
9interner: *Interner,
10decls: std.StringArrayHashMapUnmanaged(Decl),
11
12pub const Decl = struct {
13 instructions: std.MultiArrayList(Inst),
14 body: std.ArrayListUnmanaged(Ref),
15 arena: std.heap.ArenaAllocator.State,
16
17 pub fn deinit(decl: *Decl, gpa: Allocator) void {
18 decl.instructions.deinit(gpa);
19 decl.body.deinit(gpa);
20 decl.arena.promote(gpa).deinit();
21 }
22};
23
24pub const Builder = struct {
25 gpa: Allocator,
26 arena: std.heap.ArenaAllocator,
27 interner: *Interner,
28
29 decls: std.StringArrayHashMapUnmanaged(Decl) = .{},
30 instructions: std.MultiArrayList(Ir.Inst) = .{},
31 body: std.ArrayListUnmanaged(Ref) = .{},
32 alloc_count: u32 = 0,
33 arg_count: u32 = 0,
34 current_label: Ref = undefined,
35
36 pub fn deinit(b: *Builder) void {
37 for (b.decls.values()) |*decl| {
38 decl.deinit(b.gpa);
39 }
40 b.arena.deinit();
41 b.instructions.deinit(b.gpa);
42 b.body.deinit(b.gpa);
43 b.* = undefined;
44 }
45
46 pub fn finish(b: *Builder) Ir {
47 return .{
48 .interner = b.interner,
49 .decls = b.decls.move(),
50 };
51 }
52
53 pub fn startFn(b: *Builder) Allocator.Error!void {
54 const entry = try b.makeLabel("entry");
55 try b.body.append(b.gpa, entry);
56 b.current_label = entry;
57 }
58
59 pub fn finishFn(b: *Builder, name: []const u8) !void {
60 var duped_instructions = try b.instructions.clone(b.gpa);
61 errdefer duped_instructions.deinit(b.gpa);
62 var duped_body = try b.body.clone(b.gpa);
63 errdefer duped_body.deinit(b.gpa);
64
65 try b.decls.put(b.gpa, name, .{
66 .instructions = duped_instructions,
67 .body = duped_body,
68 .arena = b.arena.state,
69 });
70 b.instructions.shrinkRetainingCapacity(0);
71 b.body.shrinkRetainingCapacity(0);
72 b.arena = std.heap.ArenaAllocator.init(b.gpa);
73 b.alloc_count = 0;
74 b.arg_count = 0;
75 }
76
77 pub fn startBlock(b: *Builder, label: Ref) !void {
78 try b.body.append(b.gpa, label);
79 b.current_label = label;
80 }
81
82 pub fn addArg(b: *Builder, ty: Interner.Ref) Allocator.Error!Ref {
83 const ref: Ref = @enumFromInt(b.instructions.len);
84 try b.instructions.append(b.gpa, .{ .tag = .arg, .data = .{ .none = {} }, .ty = ty });
85 try b.body.insert(b.gpa, b.arg_count, ref);
86 b.arg_count += 1;
87 return ref;
88 }
89
90 pub fn addAlloc(b: *Builder, size: u32, @"align": u32) Allocator.Error!Ref {
91 const ref: Ref = @enumFromInt(b.instructions.len);
92 try b.instructions.append(b.gpa, .{
93 .tag = .alloc,
94 .data = .{ .alloc = .{ .size = size, .@"align" = @"align" } },
95 .ty = .ptr,
96 });
97 try b.body.insert(b.gpa, b.alloc_count + b.arg_count + 1, ref);
98 b.alloc_count += 1;
99 return ref;
100 }
101
102 pub fn addInst(b: *Builder, tag: Ir.Inst.Tag, data: Ir.Inst.Data, ty: Interner.Ref) Allocator.Error!Ref {
103 const ref: Ref = @enumFromInt(b.instructions.len);
104 try b.instructions.append(b.gpa, .{ .tag = tag, .data = data, .ty = ty });
105 try b.body.append(b.gpa, ref);
106 return ref;
107 }
108
109 pub fn makeLabel(b: *Builder, name: [*:0]const u8) Allocator.Error!Ref {
110 const ref: Ref = @enumFromInt(b.instructions.len);
111 try b.instructions.append(b.gpa, .{ .tag = .label, .data = .{ .label = name }, .ty = .void });
112 return ref;
113 }
114
115 pub fn addJump(b: *Builder, label: Ref) Allocator.Error!void {
116 _ = try b.addInst(.jmp, .{ .un = label }, .noreturn);
117 }
118
119 pub fn addBranch(b: *Builder, cond: Ref, true_label: Ref, false_label: Ref) Allocator.Error!void {
120 const branch = try b.arena.allocator().create(Ir.Inst.Branch);
121 branch.* = .{
122 .cond = cond,
123 .then = true_label,
124 .@"else" = false_label,
125 };
126 _ = try b.addInst(.branch, .{ .branch = branch }, .noreturn);
127 }
128
129 pub fn addSwitch(b: *Builder, target: Ref, values: []Interner.Ref, labels: []Ref, default: Ref) Allocator.Error!void {
130 assert(values.len == labels.len);
131 const a = b.arena.allocator();
132 const @"switch" = try a.create(Ir.Inst.Switch);
133 @"switch".* = .{
134 .target = target,
135 .cases_len = @intCast(values.len),
136 .case_vals = (try a.dupe(Interner.Ref, values)).ptr,
137 .case_labels = (try a.dupe(Ref, labels)).ptr,
138 .default = default,
139 };
140 _ = try b.addInst(.@"switch", .{ .@"switch" = @"switch" }, .noreturn);
141 }
142
143 pub fn addStore(b: *Builder, ptr: Ref, val: Ref) Allocator.Error!void {
144 _ = try b.addInst(.store, .{ .bin = .{ .lhs = ptr, .rhs = val } }, .void);
145 }
146
147 pub fn addConstant(b: *Builder, val: Interner.Ref, ty: Interner.Ref) Allocator.Error!Ref {
148 const ref: Ref = @enumFromInt(b.instructions.len);
149 try b.instructions.append(b.gpa, .{
150 .tag = .constant,
151 .data = .{ .constant = val },
152 .ty = ty,
153 });
154 return ref;
155 }
156
157 pub fn addPhi(b: *Builder, inputs: []const Inst.Phi.Input, ty: Interner.Ref) Allocator.Error!Ref {
158 const a = b.arena.allocator();
159 const input_refs = try a.alloc(Ref, inputs.len * 2 + 1);
160 input_refs[0] = @enumFromInt(inputs.len);
161 @memcpy(input_refs[1..], std.mem.bytesAsSlice(Ref, std.mem.sliceAsBytes(inputs)));
162
163 return b.addInst(.phi, .{ .phi = .{ .ptr = input_refs.ptr } }, ty);
164 }
165
166 pub fn addSelect(b: *Builder, cond: Ref, then: Ref, @"else": Ref, ty: Interner.Ref) Allocator.Error!Ref {
167 const branch = try b.arena.allocator().create(Ir.Inst.Branch);
168 branch.* = .{
169 .cond = cond,
170 .then = then,
171 .@"else" = @"else",
172 };
173 return b.addInst(.select, .{ .branch = branch }, ty);
174 }
175};
176
177pub const Renderer = struct {
178 gpa: Allocator,
179 obj: *Object,
180 ir: *const Ir,
181 errors: ErrorList = .{},
182
183 pub const ErrorList = std.StringArrayHashMapUnmanaged([]const u8);
184
185 pub const Error = Allocator.Error || error{LowerFail};
186
187 pub fn deinit(r: *Renderer) void {
188 for (r.errors.values()) |msg| r.gpa.free(msg);
189 r.errors.deinit(r.gpa);
190 }
191
192 pub fn render(r: *Renderer) !void {
193 switch (r.obj.target.cpu.arch) {
194 .x86, .x86_64 => return @import("Ir/x86/Renderer.zig").render(r),
195 else => unreachable,
196 }
197 }
198
199 pub fn fail(
200 r: *Renderer,
201 name: []const u8,
202 comptime format: []const u8,
203 args: anytype,
204 ) Error {
205 try r.errors.ensureUnusedCapacity(r.gpa, 1);
206 r.errors.putAssumeCapacity(name, try std.fmt.allocPrint(r.gpa, format, args));
207 return error.LowerFail;
208 }
209};
210
211pub fn render(
212 ir: *const Ir,
213 gpa: Allocator,
214 target: std.Target,
215 errors: ?*Renderer.ErrorList,
216) !*Object {
217 const obj = try Object.create(gpa, target);
218 errdefer obj.deinit();
219
220 var renderer: Renderer = .{
221 .gpa = gpa,
222 .obj = obj,
223 .ir = ir,
224 };
225 defer {
226 if (errors) |some| {
227 some.* = renderer.errors.move();
228 }
229 renderer.deinit();
230 }
231
232 try renderer.render();
233 return obj;
234}
235
236pub const Ref = enum(u32) { none = std.math.maxInt(u32), _ };
237
238pub const Inst = struct {
239 tag: Tag,
240 data: Data,
241 ty: Interner.Ref,
242
243 pub const Tag = enum {
244 // data.constant
245 // not included in blocks
246 constant,
247
248 // data.arg
249 // not included in blocks
250 arg,
251 symbol,
252
253 // data.label
254 label,
255
256 // data.block
257 label_addr,
258 jmp,
259
260 // data.switch
261 @"switch",
262
263 // data.branch
264 branch,
265 select,
266
267 // data.un
268 jmp_val,
269
270 // data.call
271 call,
272
273 // data.alloc
274 alloc,
275
276 // data.phi
277 phi,
278
279 // data.bin
280 store,
281 bit_or,
282 bit_xor,
283 bit_and,
284 bit_shl,
285 bit_shr,
286 cmp_eq,
287 cmp_ne,
288 cmp_lt,
289 cmp_lte,
290 cmp_gt,
291 cmp_gte,
292 add,
293 sub,
294 mul,
295 div,
296 mod,
297
298 // data.un
299 ret,
300 load,
301 bit_not,
302 negate,
303 trunc,
304 zext,
305 sext,
306 };
307
308 pub const Data = union {
309 constant: Interner.Ref,
310 none: void,
311 bin: struct {
312 lhs: Ref,
313 rhs: Ref,
314 },
315 un: Ref,
316 arg: u32,
317 alloc: struct {
318 size: u32,
319 @"align": u32,
320 },
321 @"switch": *Switch,
322 call: *Call,
323 label: [*:0]const u8,
324 branch: *Branch,
325 phi: Phi,
326 };
327
328 pub const Branch = struct {
329 cond: Ref,
330 then: Ref,
331 @"else": Ref,
332 };
333
334 pub const Switch = struct {
335 target: Ref,
336 cases_len: u32,
337 default: Ref,
338 case_vals: [*]Interner.Ref,
339 case_labels: [*]Ref,
340 };
341
342 pub const Call = struct {
343 func: Ref,
344 args_len: u32,
345 args_ptr: [*]Ref,
346
347 pub fn args(c: Call) []Ref {
348 return c.args_ptr[0..c.args_len];
349 }
350 };
351
352 pub const Phi = struct {
353 ptr: [*]Ir.Ref,
354
355 pub const Input = struct {
356 label: Ir.Ref,
357 value: Ir.Ref,
358 };
359
360 pub fn inputs(p: Phi) []Input {
361 const len = @intFromEnum(p.ptr[0]) * 2;
362 const slice = (p.ptr + 1)[0..len];
363 return std.mem.bytesAsSlice(Input, std.mem.sliceAsBytes(slice));
364 }
365 };
366};
367
368pub fn deinit(ir: *Ir, gpa: std.mem.Allocator) void {
369 for (ir.decls.values()) |*decl| {
370 decl.deinit(gpa);
371 }
372 ir.decls.deinit(gpa);
373 ir.* = undefined;
374}
375
376const TYPE = std.io.tty.Color.bright_magenta;
377const INST = std.io.tty.Color.bright_cyan;
378const REF = std.io.tty.Color.bright_blue;
379const LITERAL = std.io.tty.Color.bright_green;
380const ATTRIBUTE = std.io.tty.Color.bright_yellow;
381
382const RefMap = std.AutoArrayHashMap(Ref, void);
383
384pub fn dump(ir: *const Ir, gpa: Allocator, config: std.io.tty.Config, w: anytype) !void {
385 for (ir.decls.keys(), ir.decls.values()) |name, *decl| {
386 try ir.dumpDecl(decl, gpa, name, config, w);
387 }
388}
389
390fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8, config: std.io.tty.Config, w: anytype) !void {
391 const tags = decl.instructions.items(.tag);
392 const data = decl.instructions.items(.data);
393
394 var ref_map = RefMap.init(gpa);
395 defer ref_map.deinit();
396
397 var label_map = RefMap.init(gpa);
398 defer label_map.deinit();
399
400 const ret_inst = decl.body.items[decl.body.items.len - 1];
401 const ret_operand = data[@intFromEnum(ret_inst)].un;
402 const ret_ty = decl.instructions.items(.ty)[@intFromEnum(ret_operand)];
403 try ir.writeType(ret_ty, config, w);
404 try config.setColor(w, REF);
405 try w.print(" @{s}", .{name});
406 try config.setColor(w, .reset);
407 try w.writeAll("(");
408
409 var arg_count: u32 = 0;
410 while (true) : (arg_count += 1) {
411 const ref = decl.body.items[arg_count];
412 if (tags[@intFromEnum(ref)] != .arg) break;
413 if (arg_count != 0) try w.writeAll(", ");
414 try ref_map.put(ref, {});
415 try ir.writeRef(decl, &ref_map, ref, config, w);
416 try config.setColor(w, .reset);
417 }
418 try w.writeAll(") {\n");
419 for (decl.body.items[arg_count..]) |ref| {
420 switch (tags[@intFromEnum(ref)]) {
421 .label => try label_map.put(ref, {}),
422 else => {},
423 }
424 }
425
426 for (decl.body.items[arg_count..]) |ref| {
427 const i = @intFromEnum(ref);
428 const tag = tags[i];
429 switch (tag) {
430 .arg, .constant, .symbol => unreachable,
431 .label => {
432 const label_index = label_map.getIndex(ref).?;
433 try config.setColor(w, REF);
434 try w.print("{s}.{d}:\n", .{ data[i].label, label_index });
435 },
436 // .label_val => {
437 // const un = data[i].un;
438 // try w.print(" %{d} = label.{d}\n", .{ i, @intFromEnum(un) });
439 // },
440 .jmp => {
441 const un = data[i].un;
442 try config.setColor(w, INST);
443 try w.writeAll(" jmp ");
444 try writeLabel(decl, &label_map, un, config, w);
445 try w.writeByte('\n');
446 },
447 .branch => {
448 const br = data[i].branch;
449 try config.setColor(w, INST);
450 try w.writeAll(" branch ");
451 try ir.writeRef(decl, &ref_map, br.cond, config, w);
452 try config.setColor(w, .reset);
453 try w.writeAll(", ");
454 try writeLabel(decl, &label_map, br.then, config, w);
455 try config.setColor(w, .reset);
456 try w.writeAll(", ");
457 try writeLabel(decl, &label_map, br.@"else", config, w);
458 try w.writeByte('\n');
459 },
460 .select => {
461 const br = data[i].branch;
462 try ir.writeNewRef(decl, &ref_map, ref, config, w);
463 try w.writeAll("select ");
464 try ir.writeRef(decl, &ref_map, br.cond, config, w);
465 try config.setColor(w, .reset);
466 try w.writeAll(", ");
467 try ir.writeRef(decl, &ref_map, br.then, config, w);
468 try config.setColor(w, .reset);
469 try w.writeAll(", ");
470 try ir.writeRef(decl, &ref_map, br.@"else", config, w);
471 try w.writeByte('\n');
472 },
473 // .jmp_val => {
474 // const bin = data[i].bin;
475 // try w.print(" %{s} %{d} label.{d}\n", .{ @tagName(tag), @intFromEnum(bin.lhs), @intFromEnum(bin.rhs) });
476 // },
477 .@"switch" => {
478 const @"switch" = data[i].@"switch";
479 try config.setColor(w, INST);
480 try w.writeAll(" switch ");
481 try ir.writeRef(decl, &ref_map, @"switch".target, config, w);
482 try config.setColor(w, .reset);
483 try w.writeAll(" {");
484 for (@"switch".case_vals[0..@"switch".cases_len], @"switch".case_labels) |val_ref, label_ref| {
485 try w.writeAll("\n ");
486 try ir.writeValue(val_ref, config, w);
487 try config.setColor(w, .reset);
488 try w.writeAll(" => ");
489 try writeLabel(decl, &label_map, label_ref, config, w);
490 try config.setColor(w, .reset);
491 }
492 try config.setColor(w, LITERAL);
493 try w.writeAll("\n default ");
494 try config.setColor(w, .reset);
495 try w.writeAll("=> ");
496 try writeLabel(decl, &label_map, @"switch".default, config, w);
497 try config.setColor(w, .reset);
498 try w.writeAll("\n }\n");
499 },
500 .call => {
501 const call = data[i].call;
502 try ir.writeNewRef(decl, &ref_map, ref, config, w);
503 try w.writeAll("call ");
504 try ir.writeRef(decl, &ref_map, call.func, config, w);
505 try config.setColor(w, .reset);
506 try w.writeAll("(");
507 for (call.args(), 0..) |arg, arg_i| {
508 if (arg_i != 0) try w.writeAll(", ");
509 try ir.writeRef(decl, &ref_map, arg, config, w);
510 try config.setColor(w, .reset);
511 }
512 try w.writeAll(")\n");
513 },
514 .alloc => {
515 const alloc = data[i].alloc;
516 try ir.writeNewRef(decl, &ref_map, ref, config, w);
517 try w.writeAll("alloc ");
518 try config.setColor(w, ATTRIBUTE);
519 try w.writeAll("size ");
520 try config.setColor(w, LITERAL);
521 try w.print("{d}", .{alloc.size});
522 try config.setColor(w, ATTRIBUTE);
523 try w.writeAll(" align ");
524 try config.setColor(w, LITERAL);
525 try w.print("{d}", .{alloc.@"align"});
526 try w.writeByte('\n');
527 },
528 .phi => {
529 try ir.writeNewRef(decl, &ref_map, ref, config, w);
530 try w.writeAll("phi");
531 try config.setColor(w, .reset);
532 try w.writeAll(" {");
533 for (data[i].phi.inputs()) |input| {
534 try w.writeAll("\n ");
535 try writeLabel(decl, &label_map, input.label, config, w);
536 try config.setColor(w, .reset);
537 try w.writeAll(" => ");
538 try ir.writeRef(decl, &ref_map, input.value, config, w);
539 try config.setColor(w, .reset);
540 }
541 try config.setColor(w, .reset);
542 try w.writeAll("\n }\n");
543 },
544 .store => {
545 const bin = data[i].bin;
546 try config.setColor(w, INST);
547 try w.writeAll(" store ");
548 try ir.writeRef(decl, &ref_map, bin.lhs, config, w);
549 try config.setColor(w, .reset);
550 try w.writeAll(", ");
551 try ir.writeRef(decl, &ref_map, bin.rhs, config, w);
552 try w.writeByte('\n');
553 },
554 .ret => {
555 try config.setColor(w, INST);
556 try w.writeAll(" ret ");
557 if (data[i].un != .none) try ir.writeRef(decl, &ref_map, data[i].un, config, w);
558 try w.writeByte('\n');
559 },
560 .load => {
561 try ir.writeNewRef(decl, &ref_map, ref, config, w);
562 try w.writeAll("load ");
563 try ir.writeRef(decl, &ref_map, data[i].un, config, w);
564 try w.writeByte('\n');
565 },
566 .bit_or,
567 .bit_xor,
568 .bit_and,
569 .bit_shl,
570 .bit_shr,
571 .cmp_eq,
572 .cmp_ne,
573 .cmp_lt,
574 .cmp_lte,
575 .cmp_gt,
576 .cmp_gte,
577 .add,
578 .sub,
579 .mul,
580 .div,
581 .mod,
582 => {
583 const bin = data[i].bin;
584 try ir.writeNewRef(decl, &ref_map, ref, config, w);
585 try w.print("{s} ", .{@tagName(tag)});
586 try ir.writeRef(decl, &ref_map, bin.lhs, config, w);
587 try config.setColor(w, .reset);
588 try w.writeAll(", ");
589 try ir.writeRef(decl, &ref_map, bin.rhs, config, w);
590 try w.writeByte('\n');
591 },
592 .bit_not,
593 .negate,
594 .trunc,
595 .zext,
596 .sext,
597 => {
598 const un = data[i].un;
599 try ir.writeNewRef(decl, &ref_map, ref, config, w);
600 try w.print("{s} ", .{@tagName(tag)});
601 try ir.writeRef(decl, &ref_map, un, config, w);
602 try w.writeByte('\n');
603 },
604 .label_addr, .jmp_val => {},
605 }
606 }
607 try config.setColor(w, .reset);
608 try w.writeAll("}\n\n");
609}
610
611fn writeType(ir: Ir, ty_ref: Interner.Ref, config: std.io.tty.Config, w: anytype) !void {
612 const ty = ir.interner.get(ty_ref);
613 try config.setColor(w, TYPE);
614 switch (ty) {
615 .ptr_ty, .noreturn_ty, .void_ty, .func_ty => try w.writeAll(@tagName(ty)),
616 .int_ty => |bits| try w.print("i{d}", .{bits}),
617 .float_ty => |bits| try w.print("f{d}", .{bits}),
618 .array_ty => |info| {
619 try w.print("[{d} * ", .{info.len});
620 try ir.writeType(info.child, .no_color, w);
621 try w.writeByte(']');
622 },
623 .vector_ty => |info| {
624 try w.print("<{d} * ", .{info.len});
625 try ir.writeType(info.child, .no_color, w);
626 try w.writeByte('>');
627 },
628 .record_ty => |elems| {
629 // TODO collect into buffer and only print once
630 try w.writeAll("{ ");
631 for (elems, 0..) |elem, i| {
632 if (i != 0) try w.writeAll(", ");
633 try ir.writeType(elem, config, w);
634 }
635 try w.writeAll(" }");
636 },
637 else => unreachable, // not a type
638 }
639}
640
641fn writeValue(ir: Ir, val: Interner.Ref, config: std.io.tty.Config, w: anytype) !void {
642 try config.setColor(w, LITERAL);
643 const key = ir.interner.get(val);
644 switch (key) {
645 .null => return w.writeAll("nullptr_t"),
646 .int => |repr| switch (repr) {
647 inline else => |x| return w.print("{d}", .{x}),
648 },
649 .float => |repr| switch (repr) {
650 inline else => |x| return w.print("{d}", .{@as(f64, @floatCast(x))}),
651 },
652 .bytes => |b| return std.zig.fmt.stringEscape(b, "", .{}, w),
653 else => unreachable, // not a value
654 }
655}
656
657fn writeRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void {
658 assert(ref != .none);
659 const index = @intFromEnum(ref);
660 const ty_ref = decl.instructions.items(.ty)[index];
661 if (decl.instructions.items(.tag)[index] == .constant) {
662 try ir.writeType(ty_ref, config, w);
663 const v_ref = decl.instructions.items(.data)[index].constant;
664 try w.writeByte(' ');
665 try ir.writeValue(v_ref, config, w);
666 return;
667 } else if (decl.instructions.items(.tag)[index] == .symbol) {
668 const name = decl.instructions.items(.data)[index].label;
669 try ir.writeType(ty_ref, config, w);
670 try config.setColor(w, REF);
671 try w.print(" @{s}", .{name});
672 return;
673 }
674 try ir.writeType(ty_ref, config, w);
675 try config.setColor(w, REF);
676 const ref_index = ref_map.getIndex(ref).?;
677 try w.print(" %{d}", .{ref_index});
678}
679
680fn writeNewRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void {
681 try ref_map.put(ref, {});
682 try w.writeAll(" ");
683 try ir.writeRef(decl, ref_map, ref, config, w);
684 try config.setColor(w, .reset);
685 try w.writeAll(" = ");
686 try config.setColor(w, INST);
687}
688
689fn writeLabel(decl: *const Decl, label_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void {
690 assert(ref != .none);
691 const index = @intFromEnum(ref);
692 const label = decl.instructions.items(.data)[index].label;
693 try config.setColor(w, REF);
694 const label_index = label_map.getIndex(ref).?;
695 try w.print("{s}.{d}", .{ label, label_index });
696}
deps/aro/backend/Ir/x86/Renderer.zig deleted-65
......@@ -1,65 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const Interner = @import("../../Interner.zig");
5const Ir = @import("../../Ir.zig");
6const BaseRenderer = Ir.Renderer;
7const zig = @import("zig");
8const abi = zig.arch.x86_64.abi;
9const bits = zig.arch.x86_64.bits;
10
11const Condition = bits.Condition;
12const Immediate = bits.Immediate;
13const Memory = bits.Memory;
14const Register = bits.Register;
15const RegisterLock = RegisterManager.RegisterLock;
16const FrameIndex = bits.FrameIndex;
17
18const RegisterManager = zig.RegisterManager(Renderer, Register, Ir.Ref, abi.allocatable_regs);
19
20// Register classes
21const RegisterBitSet = RegisterManager.RegisterBitSet;
22const RegisterClass = struct {
23 const gp: RegisterBitSet = blk: {
24 var set = RegisterBitSet.initEmpty();
25 for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
26 break :blk set;
27 };
28 const x87: RegisterBitSet = blk: {
29 var set = RegisterBitSet.initEmpty();
30 for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
31 break :blk set;
32 };
33 const sse: RegisterBitSet = blk: {
34 var set = RegisterBitSet.initEmpty();
35 for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index);
36 break :blk set;
37 };
38};
39
40const Renderer = @This();
41
42base: *BaseRenderer,
43interner: *Interner,
44
45register_manager: RegisterManager = .{},
46
47pub fn render(base: *BaseRenderer) !void {
48 var renderer: Renderer = .{
49 .base = base,
50 .interner = base.ir.interner,
51 };
52
53 for (renderer.base.ir.decls.keys(), renderer.base.ir.decls.values()) |name, decl| {
54 renderer.renderFn(name, decl) catch |e| switch (e) {
55 error.OutOfMemory => return e,
56 error.LowerFail => continue,
57 };
58 }
59 if (renderer.base.errors.entries.len != 0) return error.LowerFail;
60}
61
62fn renderFn(r: *Renderer, name: []const u8, decl: Ir.Decl) !void {
63 _ = decl;
64 return r.base.fail(name, "TODO implement lowering functions", .{});
65}
deps/aro/backend/Object.zig deleted-73
......@@ -1,73 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const Elf = @import("Object/Elf.zig");
4
5const Object = @This();
6
7format: std.Target.ObjectFormat,
8target: std.Target,
9
10pub fn create(gpa: Allocator, target: std.Target) !*Object {
11 switch (target.ofmt) {
12 .elf => return Elf.create(gpa, target),
13 else => unreachable,
14 }
15}
16
17pub fn deinit(obj: *Object) void {
18 switch (obj.format) {
19 .elf => @fieldParentPtr(Elf, "obj", obj).deinit(),
20 else => unreachable,
21 }
22}
23
24pub const Section = union(enum) {
25 undefined,
26 data,
27 read_only_data,
28 func,
29 strings,
30 custom: []const u8,
31};
32
33pub fn getSection(obj: *Object, section: Section) !*std.ArrayList(u8) {
34 switch (obj.format) {
35 .elf => return @fieldParentPtr(Elf, "obj", obj).getSection(section),
36 else => unreachable,
37 }
38}
39
40pub const SymbolType = enum {
41 func,
42 variable,
43 external,
44};
45
46pub fn declareSymbol(
47 obj: *Object,
48 section: Section,
49 name: ?[]const u8,
50 linkage: std.builtin.GlobalLinkage,
51 @"type": SymbolType,
52 offset: u64,
53 size: u64,
54) ![]const u8 {
55 switch (obj.format) {
56 .elf => return @fieldParentPtr(Elf, "obj", obj).declareSymbol(section, name, linkage, @"type", offset, size),
57 else => unreachable,
58 }
59}
60
61pub fn addRelocation(obj: *Object, name: []const u8, section: Section, address: u64, addend: i64) !void {
62 switch (obj.format) {
63 .elf => return @fieldParentPtr(Elf, "obj", obj).addRelocation(name, section, address, addend),
64 else => unreachable,
65 }
66}
67
68pub fn finish(obj: *Object, file: std.fs.File) !void {
69 switch (obj.format) {
70 .elf => return @fieldParentPtr(Elf, "obj", obj).finish(file),
71 else => unreachable,
72 }
73}
deps/aro/backend/Object/Elf.zig deleted-378
......@@ -1,378 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const Target = std.Target;
4const Object = @import("../Object.zig");
5
6const Section = struct {
7 data: std.ArrayList(u8),
8 relocations: std.ArrayListUnmanaged(Relocation) = .{},
9 flags: u64,
10 type: u32,
11 index: u16 = undefined,
12};
13
14const Symbol = struct {
15 section: ?*Section,
16 size: u64,
17 offset: u64,
18 index: u16 = undefined,
19 info: u8,
20};
21
22const Relocation = struct {
23 symbol: *Symbol,
24 addend: i64,
25 offset: u48,
26 type: u8,
27};
28
29const additional_sections = 3; // null section, strtab, symtab
30const strtab_index = 1;
31const symtab_index = 2;
32const strtab_default = "\x00.strtab\x00.symtab\x00";
33const strtab_name = 1;
34const symtab_name = "\x00.strtab\x00".len;
35
36const Elf = @This();
37
38obj: Object,
39/// The keys are owned by the Codegen.tree
40sections: std.StringHashMapUnmanaged(*Section) = .{},
41local_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
42global_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
43unnamed_symbol_mangle: u32 = 0,
44strtab_len: u64 = strtab_default.len,
45arena: std.heap.ArenaAllocator,
46
47pub fn create(gpa: Allocator, target: Target) !*Object {
48 const elf = try gpa.create(Elf);
49 elf.* = .{
50 .obj = .{ .format = .elf, .target = target },
51 .arena = std.heap.ArenaAllocator.init(gpa),
52 };
53 return &elf.obj;
54}
55
56pub fn deinit(elf: *Elf) void {
57 const gpa = elf.arena.child_allocator;
58 {
59 var it = elf.sections.valueIterator();
60 while (it.next()) |sect| {
61 sect.*.data.deinit();
62 sect.*.relocations.deinit(gpa);
63 }
64 }
65 elf.sections.deinit(gpa);
66 elf.local_symbols.deinit(gpa);
67 elf.global_symbols.deinit(gpa);
68 elf.arena.deinit();
69 gpa.destroy(elf);
70}
71
72fn sectionString(sec: Object.Section) []const u8 {
73 return switch (sec) {
74 .undefined => unreachable,
75 .data => "data",
76 .read_only_data => "rodata",
77 .func => "text",
78 .strings => "rodata.str",
79 .custom => |name| name,
80 };
81}
82
83pub fn getSection(elf: *Elf, section_kind: Object.Section) !*std.ArrayList(u8) {
84 const section_name = sectionString(section_kind);
85 const section = elf.sections.get(section_name) orelse blk: {
86 const section = try elf.arena.allocator().create(Section);
87 section.* = .{
88 .data = std.ArrayList(u8).init(elf.arena.child_allocator),
89 .type = std.elf.SHT_PROGBITS,
90 .flags = switch (section_kind) {
91 .func, .custom => std.elf.SHF_ALLOC + std.elf.SHF_EXECINSTR,
92 .strings => std.elf.SHF_ALLOC + std.elf.SHF_MERGE + std.elf.SHF_STRINGS,
93 .read_only_data => std.elf.SHF_ALLOC,
94 .data => std.elf.SHF_ALLOC + std.elf.SHF_WRITE,
95 .undefined => unreachable,
96 },
97 };
98 try elf.sections.putNoClobber(elf.arena.child_allocator, section_name, section);
99 elf.strtab_len += section_name.len + ".\x00".len;
100 break :blk section;
101 };
102 return &section.data;
103}
104
105pub fn declareSymbol(
106 elf: *Elf,
107 section_kind: Object.Section,
108 maybe_name: ?[]const u8,
109 linkage: std.builtin.GlobalLinkage,
110 @"type": Object.SymbolType,
111 offset: u64,
112 size: u64,
113) ![]const u8 {
114 const section = blk: {
115 if (section_kind == .undefined) break :blk null;
116 const section_name = sectionString(section_kind);
117 break :blk elf.sections.get(section_name);
118 };
119 const binding: u8 = switch (linkage) {
120 .Internal => std.elf.STB_LOCAL,
121 .Strong => std.elf.STB_GLOBAL,
122 .Weak => std.elf.STB_WEAK,
123 .LinkOnce => unreachable,
124 };
125 const sym_type: u8 = switch (@"type") {
126 .func => std.elf.STT_FUNC,
127 .variable => std.elf.STT_OBJECT,
128 .external => std.elf.STT_NOTYPE,
129 };
130 const name = if (maybe_name) |some| some else blk: {
131 defer elf.unnamed_symbol_mangle += 1;
132 break :blk try std.fmt.allocPrint(elf.arena.allocator(), ".L.{d}", .{elf.unnamed_symbol_mangle});
133 };
134
135 const gop = if (linkage == .Internal)
136 try elf.local_symbols.getOrPut(elf.arena.child_allocator, name)
137 else
138 try elf.global_symbols.getOrPut(elf.arena.child_allocator, name);
139
140 if (!gop.found_existing) {
141 gop.value_ptr.* = try elf.arena.allocator().create(Symbol);
142 elf.strtab_len += name.len + 1; // +1 for null byte
143 }
144 gop.value_ptr.*.* = .{
145 .section = section,
146 .size = size,
147 .offset = offset,
148 .info = (binding << 4) + sym_type,
149 };
150 return name;
151}
152
153pub fn addRelocation(elf: *Elf, name: []const u8, section_kind: Object.Section, address: u64, addend: i64) !void {
154 const section_name = sectionString(section_kind);
155 const symbol = elf.local_symbols.get(name) orelse elf.global_symbols.get(name).?; // reference to undeclared symbol
156 const section = elf.sections.get(section_name).?;
157 if (section.relocations.items.len == 0) elf.strtab_len += ".rela".len;
158
159 try section.relocations.append(elf.arena.child_allocator, .{
160 .symbol = symbol,
161 .offset = @intCast(address),
162 .addend = addend,
163 .type = if (symbol.section == null) 4 else 2, // TODO
164 });
165}
166
167/// elf header
168/// sections contents
169/// symbols
170/// relocations
171/// strtab
172/// section headers
173pub fn finish(elf: *Elf, file: std.fs.File) !void {
174 var buf_writer = std.io.bufferedWriter(file.writer());
175 const w = buf_writer.writer();
176
177 var num_sections: std.elf.Elf64_Half = additional_sections;
178 var relocations_len: std.elf.Elf64_Off = 0;
179 var sections_len: std.elf.Elf64_Off = 0;
180 {
181 var it = elf.sections.valueIterator();
182 while (it.next()) |sect| {
183 sections_len += sect.*.data.items.len;
184 relocations_len += sect.*.relocations.items.len * @sizeOf(std.elf.Elf64_Rela);
185 sect.*.index = num_sections;
186 num_sections += 1;
187 num_sections += @intFromBool(sect.*.relocations.items.len != 0);
188 }
189 }
190 const symtab_len = (elf.local_symbols.count() + elf.global_symbols.count() + 1) * @sizeOf(std.elf.Elf64_Sym);
191
192 const symtab_offset = @sizeOf(std.elf.Elf64_Ehdr) + sections_len;
193 const symtab_offset_aligned = std.mem.alignForward(u64, symtab_offset, 8);
194 const rela_offset = symtab_offset_aligned + symtab_len;
195 const strtab_offset = rela_offset + relocations_len;
196 const sh_offset = strtab_offset + elf.strtab_len;
197 const sh_offset_aligned = std.mem.alignForward(u64, sh_offset, 16);
198
199 const elf_header = std.elf.Elf64_Ehdr{
200 .e_ident = .{ 0x7F, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
201 .e_type = std.elf.ET.REL, // we only produce relocatables
202 .e_machine = elf.obj.target.cpu.arch.toElfMachine(),
203 .e_version = 1,
204 .e_entry = 0, // linker will handle this
205 .e_phoff = 0, // no program header
206 .e_shoff = sh_offset_aligned, // section headers offset
207 .e_flags = 0, // no flags
208 .e_ehsize = @sizeOf(std.elf.Elf64_Ehdr),
209 .e_phentsize = 0, // no program header
210 .e_phnum = 0, // no program header
211 .e_shentsize = @sizeOf(std.elf.Elf64_Shdr),
212 .e_shnum = num_sections,
213 .e_shstrndx = strtab_index,
214 };
215 try w.writeStruct(elf_header);
216
217 // write contents of sections
218 {
219 var it = elf.sections.valueIterator();
220 while (it.next()) |sect| try w.writeAll(sect.*.data.items);
221 }
222
223 // pad to 8 bytes
224 try w.writeByteNTimes(0, @intCast(symtab_offset_aligned - symtab_offset));
225
226 var name_offset: u32 = strtab_default.len;
227 // write symbols
228 {
229 // first symbol must be null
230 try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Sym));
231
232 var sym_index: u16 = 1;
233 var it = elf.local_symbols.iterator();
234 while (it.next()) |entry| {
235 const sym = entry.value_ptr.*;
236 try w.writeStruct(std.elf.Elf64_Sym{
237 .st_name = name_offset,
238 .st_info = sym.info,
239 .st_other = 0,
240 .st_shndx = if (sym.section) |some| some.index else 0,
241 .st_value = sym.offset,
242 .st_size = sym.size,
243 });
244 sym.index = sym_index;
245 sym_index += 1;
246 name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
247 }
248 it = elf.global_symbols.iterator();
249 while (it.next()) |entry| {
250 const sym = entry.value_ptr.*;
251 try w.writeStruct(std.elf.Elf64_Sym{
252 .st_name = name_offset,
253 .st_info = sym.info,
254 .st_other = 0,
255 .st_shndx = if (sym.section) |some| some.index else 0,
256 .st_value = sym.offset,
257 .st_size = sym.size,
258 });
259 sym.index = sym_index;
260 sym_index += 1;
261 name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
262 }
263 }
264
265 // write relocations
266 {
267 var it = elf.sections.valueIterator();
268 while (it.next()) |sect| {
269 for (sect.*.relocations.items) |rela| {
270 try w.writeStruct(std.elf.Elf64_Rela{
271 .r_offset = rela.offset,
272 .r_addend = rela.addend,
273 .r_info = (@as(u64, rela.symbol.index) << 32) | rela.type,
274 });
275 }
276 }
277 }
278
279 // write strtab
280 try w.writeAll(strtab_default);
281 {
282 var it = elf.local_symbols.keyIterator();
283 while (it.next()) |key| try w.print("{s}\x00", .{key.*});
284 it = elf.global_symbols.keyIterator();
285 while (it.next()) |key| try w.print("{s}\x00", .{key.*});
286 }
287 {
288 var it = elf.sections.iterator();
289 while (it.next()) |entry| {
290 if (entry.value_ptr.*.relocations.items.len != 0) try w.writeAll(".rela");
291 try w.print(".{s}\x00", .{entry.key_ptr.*});
292 }
293 }
294
295 // pad to 16 bytes
296 try w.writeByteNTimes(0, @intCast(sh_offset_aligned - sh_offset));
297 // mandatory null header
298 try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Shdr));
299
300 // write strtab section header
301 {
302 const sect_header = std.elf.Elf64_Shdr{
303 .sh_name = strtab_name,
304 .sh_type = std.elf.SHT_STRTAB,
305 .sh_flags = 0,
306 .sh_addr = 0,
307 .sh_offset = strtab_offset,
308 .sh_size = elf.strtab_len,
309 .sh_link = 0,
310 .sh_info = 0,
311 .sh_addralign = 1,
312 .sh_entsize = 0,
313 };
314 try w.writeStruct(sect_header);
315 }
316
317 // write symtab section header
318 {
319 const sect_header = std.elf.Elf64_Shdr{
320 .sh_name = symtab_name,
321 .sh_type = std.elf.SHT_SYMTAB,
322 .sh_flags = 0,
323 .sh_addr = 0,
324 .sh_offset = symtab_offset_aligned,
325 .sh_size = symtab_len,
326 .sh_link = strtab_index,
327 .sh_info = elf.local_symbols.size + 1,
328 .sh_addralign = 8,
329 .sh_entsize = @sizeOf(std.elf.Elf64_Sym),
330 };
331 try w.writeStruct(sect_header);
332 }
333
334 // remaining section headers
335 {
336 var sect_offset: u64 = @sizeOf(std.elf.Elf64_Ehdr);
337 var rela_sect_offset: u64 = rela_offset;
338 var it = elf.sections.iterator();
339 while (it.next()) |entry| {
340 const sect = entry.value_ptr.*;
341 const rela_count = sect.relocations.items.len;
342 const rela_name_offset: u32 = if (rela_count != 0) @truncate(".rela".len) else 0;
343 try w.writeStruct(std.elf.Elf64_Shdr{
344 .sh_name = rela_name_offset + name_offset,
345 .sh_type = sect.type,
346 .sh_flags = sect.flags,
347 .sh_addr = 0,
348 .sh_offset = sect_offset,
349 .sh_size = sect.data.items.len,
350 .sh_link = 0,
351 .sh_info = 0,
352 .sh_addralign = if (sect.flags & std.elf.SHF_EXECINSTR != 0) 16 else 1,
353 .sh_entsize = 0,
354 });
355
356 if (rela_count != 0) {
357 const size = rela_count * @sizeOf(std.elf.Elf64_Rela);
358 try w.writeStruct(std.elf.Elf64_Shdr{
359 .sh_name = name_offset,
360 .sh_type = std.elf.SHT_RELA,
361 .sh_flags = 0,
362 .sh_addr = 0,
363 .sh_offset = rela_sect_offset,
364 .sh_size = rela_count * @sizeOf(std.elf.Elf64_Rela),
365 .sh_link = symtab_index,
366 .sh_info = sect.index,
367 .sh_addralign = 8,
368 .sh_entsize = @sizeOf(std.elf.Elf64_Rela),
369 });
370 rela_sect_offset += size;
371 }
372
373 sect_offset += sect.data.items.len;
374 name_offset += @as(u32, @intCast(entry.key_ptr.len + ".\x00".len)) + rela_name_offset;
375 }
376 }
377 try buf_writer.flush();
378}
deps/aro/build/GenerateDef.zig deleted-683
......@@ -1,683 +0,0 @@
1const std = @import("std");
2const Step = std.Build.Step;
3const Allocator = std.mem.Allocator;
4const GeneratedFile = std.Build.GeneratedFile;
5
6const GenerateDef = @This();
7
8step: Step,
9path: []const u8,
10name: []const u8,
11kind: Options.Kind,
12generated_file: GeneratedFile,
13
14pub const base_id: Step.Id = .custom;
15
16pub const Options = struct {
17 name: []const u8,
18 src_prefix: []const u8 = "src/aro",
19 kind: Kind = .dafsa,
20
21 pub const Kind = enum { dafsa, named };
22};
23
24pub fn create(owner: *std.Build, options: Options) std.Build.Module.Import {
25 const self = owner.allocator.create(GenerateDef) catch @panic("OOM");
26 const path = owner.pathJoin(&.{ options.src_prefix, options.name });
27
28 const name = owner.fmt("GenerateDef {s}", .{options.name});
29 self.* = .{
30 .step = Step.init(.{
31 .id = base_id,
32 .name = name,
33 .owner = owner,
34 .makeFn = make,
35 }),
36 .path = path,
37 .name = options.name,
38 .kind = options.kind,
39 .generated_file = .{ .step = &self.step },
40 };
41 const module = self.step.owner.createModule(.{
42 .root_source_file = .{ .generated = &self.generated_file },
43 });
44 return .{
45 .module = module,
46 .name = self.name,
47 };
48}
49
50fn make(step: *Step, prog_node: *std.Progress.Node) !void {
51 _ = prog_node;
52 const b = step.owner;
53 const self = @fieldParentPtr(GenerateDef, "step", step);
54 const arena = b.allocator;
55
56 var man = b.graph.cache.obtain();
57 defer man.deinit();
58
59 // Random bytes to make GenerateDef unique. Refresh this with new
60 // random bytes when GenerateDef implementation is modified in a
61 // non-backwards-compatible way.
62 man.hash.add(@as(u32, 0xDCC14144));
63
64 const contents = try b.build_root.handle.readFileAlloc(arena, self.path, std.math.maxInt(u32));
65 man.hash.addBytes(contents);
66
67 const out_name = b.fmt("{s}.zig", .{std.fs.path.stem(self.path)});
68 if (try step.cacheHit(&man)) {
69 const digest = man.final();
70 self.generated_file.path = try b.cache_root.join(arena, &.{
71 "o", &digest, out_name,
72 });
73 return;
74 }
75
76 const digest = man.final();
77
78 const sub_path = try std.fs.path.join(arena, &.{ "o", &digest, out_name });
79 const sub_path_dirname = std.fs.path.dirname(sub_path).?;
80
81 b.cache_root.handle.makePath(sub_path_dirname) catch |err| {
82 return step.fail("unable to make path '{}{s}': {s}", .{
83 b.cache_root, sub_path_dirname, @errorName(err),
84 });
85 };
86
87 const output = try self.generate(contents);
88 b.cache_root.handle.writeFile(sub_path, output) catch |err| {
89 return step.fail("unable to write file '{}{s}': {s}", .{
90 b.cache_root, sub_path, @errorName(err),
91 });
92 };
93
94 self.generated_file.path = try b.cache_root.join(arena, &.{sub_path});
95 try man.writeManifest();
96}
97
98const Value = struct {
99 name: []const u8,
100 properties: []const []const u8,
101};
102
103fn generate(self: *GenerateDef, input: []const u8) ![]const u8 {
104 const arena = self.step.owner.allocator;
105
106 var values = std.StringArrayHashMap([]const []const u8).init(arena);
107 defer values.deinit();
108 var properties = std.ArrayList([]const u8).init(arena);
109 defer properties.deinit();
110 var headers = std.ArrayList([]const u8).init(arena);
111 defer headers.deinit();
112
113 var value_name: ?[]const u8 = null;
114 var it = std.mem.tokenizeAny(u8, input, "\r\n");
115 while (it.next()) |line_untrimmed| {
116 const line = std.mem.trim(u8, line_untrimmed, " \t");
117 if (line.len == 0 or line[0] == '#') continue;
118 if (std.mem.startsWith(u8, line, "const ") or std.mem.startsWith(u8, line, "pub const ")) {
119 try headers.append(line);
120 continue;
121 }
122 if (line[0] == '.') {
123 if (value_name == null) {
124 return self.step.fail("property not attached to a value:\n\"{s}\"", .{line});
125 }
126 try properties.append(line);
127 continue;
128 }
129
130 if (value_name) |name| {
131 const old = try values.fetchPut(name, try properties.toOwnedSlice());
132 if (old != null) return self.step.fail("duplicate value \"{s}\"", .{name});
133 }
134 value_name = line;
135 }
136
137 if (value_name) |name| {
138 const old = try values.fetchPut(name, try properties.toOwnedSlice());
139 if (old != null) return self.step.fail("duplicate value \"{s}\"", .{name});
140 }
141
142 {
143 const sorted_list = try arena.dupe([]const u8, values.keys());
144 defer arena.free(sorted_list);
145 std.mem.sort([]const u8, sorted_list, {}, struct {
146 pub fn lessThan(_: void, a: []const u8, b: []const u8) bool {
147 return std.mem.lessThan(u8, a, b);
148 }
149 }.lessThan);
150
151 var longest_name: usize = 0;
152 var shortest_name: usize = std.math.maxInt(usize);
153
154 var builder = try DafsaBuilder.init(arena);
155 defer builder.deinit();
156 for (sorted_list) |name| {
157 try builder.insert(name);
158 longest_name = @max(name.len, longest_name);
159 shortest_name = @min(name.len, shortest_name);
160 }
161 try builder.finish();
162 builder.calcNumbers();
163
164 // As a sanity check, confirm that the minimal perfect hashing doesn't
165 // have any collisions
166 {
167 var index_set = std.AutoHashMap(usize, void).init(arena);
168 defer index_set.deinit();
169
170 for (values.keys()) |name| {
171 const index = builder.getUniqueIndex(name).?;
172 const result = try index_set.getOrPut(index);
173 if (result.found_existing) {
174 return self.step.fail("clobbered {}, name={s}\n", .{ index, name });
175 }
176 }
177 }
178
179 var out_buf = std.ArrayList(u8).init(arena);
180 defer out_buf.deinit();
181 const writer = out_buf.writer();
182
183 try writer.print(
184 \\//! Autogenerated by GenerateDef from {s}, do not edit
185 \\
186 \\const std = @import("std");
187 \\
188 \\pub fn with(comptime Properties: type) type {{
189 \\return struct {{
190 \\
191 , .{self.path});
192 for (headers.items) |line| {
193 try writer.print("{s}\n", .{line});
194 }
195 if (self.kind == .named) {
196 try writer.writeAll("pub const Tag = enum {\n");
197 for (values.keys()) |property| {
198 try writer.print(" {s},\n", .{std.zig.fmtId(property)});
199 }
200 try writer.writeAll(
201 \\
202 \\ pub fn property(tag: Tag) Properties {
203 \\ return named_data[@intFromEnum(tag)];
204 \\ }
205 \\
206 \\ const named_data = [_]Properties{
207 \\
208 );
209 for (values.values()) |val_props| {
210 try writer.writeAll(" .{");
211 for (val_props, 0..) |val_prop, j| {
212 if (j != 0) try writer.writeByte(',');
213 try writer.writeByte(' ');
214 try writer.writeAll(val_prop);
215 }
216 try writer.writeAll(" },\n");
217 }
218 try writer.writeAll(
219 \\ };
220 \\};
221 \\};
222 \\}
223 \\
224 );
225
226 return out_buf.toOwnedSlice();
227 }
228
229 var values_array = try arena.alloc(Value, values.count());
230 defer arena.free(values_array);
231
232 for (values.keys(), values.values()) |name, props| {
233 const unique_index = builder.getUniqueIndex(name).?;
234 const data_index = unique_index - 1;
235 values_array[data_index] = .{ .name = name, .properties = props };
236 }
237
238 try writer.writeAll(
239 \\
240 \\tag: Tag,
241 \\properties: Properties,
242 \\
243 \\/// Integer starting at 0 derived from the unique index,
244 \\/// corresponds with the data array index.
245 \\pub const Tag = enum(u16) { _ };
246 \\
247 \\const Self = @This();
248 \\
249 \\pub fn fromName(name: []const u8) ?@This() {
250 \\ const data_index = tagFromName(name) orelse return null;
251 \\ return data[@intFromEnum(data_index)];
252 \\}
253 \\
254 \\pub fn tagFromName(name: []const u8) ?Tag {
255 \\ const unique_index = uniqueIndex(name) orelse return null;
256 \\ return @enumFromInt(unique_index - 1);
257 \\}
258 \\
259 \\pub fn fromTag(tag: Tag) @This() {
260 \\ return data[@intFromEnum(tag)];
261 \\}
262 \\
263 \\pub fn nameFromTagIntoBuf(tag: Tag, name_buf: []u8) []u8 {
264 \\ std.debug.assert(name_buf.len >= longest_name);
265 \\ const unique_index = @intFromEnum(tag) + 1;
266 \\ return nameFromUniqueIndex(unique_index, name_buf);
267 \\}
268 \\
269 \\pub fn nameFromTag(tag: Tag) NameBuf {
270 \\ var name_buf: NameBuf = undefined;
271 \\ const unique_index = @intFromEnum(tag) + 1;
272 \\ const name = nameFromUniqueIndex(unique_index, &name_buf.buf);
273 \\ name_buf.len = @intCast(name.len);
274 \\ return name_buf;
275 \\}
276 \\
277 \\pub const NameBuf = struct {
278 \\ buf: [longest_name]u8 = undefined,
279 \\ len: std.math.IntFittingRange(0, longest_name),
280 \\
281 \\ pub fn span(self: *const NameBuf) []const u8 {
282 \\ return self.buf[0..self.len];
283 \\ }
284 \\};
285 \\
286 \\pub fn exists(name: []const u8) bool {
287 \\ if (name.len < shortest_name or name.len > longest_name) return false;
288 \\
289 \\ var index: u16 = 0;
290 \\ for (name) |c| {
291 \\ index = findInList(dafsa[index].child_index, c) orelse return false;
292 \\ }
293 \\ return dafsa[index].end_of_word;
294 \\}
295 \\
296 \\
297 );
298 try writer.print("pub const shortest_name = {};\n", .{shortest_name});
299 try writer.print("pub const longest_name = {};\n\n", .{longest_name});
300 try writer.writeAll(
301 \\/// Search siblings of `first_child_index` for the `char`
302 \\/// If found, returns the index of the node within the `dafsa` array.
303 \\/// Otherwise, returns `null`.
304 \\pub fn findInList(first_child_index: u16, char: u8) ?u16 {
305 \\ var index = first_child_index;
306 \\ while (true) {
307 \\ if (dafsa[index].char == char) return index;
308 \\ if (dafsa[index].end_of_list) return null;
309 \\ index += 1;
310 \\ }
311 \\ unreachable;
312 \\}
313 \\
314 \\/// Returns a unique (minimal perfect hash) index (starting at 1) for the `name`,
315 \\/// or null if the name was not found.
316 \\pub fn uniqueIndex(name: []const u8) ?u16 {
317 \\ if (name.len < shortest_name or name.len > longest_name) return null;
318 \\
319 \\ var index: u16 = 0;
320 \\ var node_index: u16 = 0;
321 \\
322 \\ for (name) |c| {
323 \\ const child_index = findInList(dafsa[node_index].child_index, c) orelse return null;
324 \\ var sibling_index = dafsa[node_index].child_index;
325 \\ while (true) {
326 \\ const sibling_c = dafsa[sibling_index].char;
327 \\ std.debug.assert(sibling_c != 0);
328 \\ if (sibling_c < c) {
329 \\ index += dafsa[sibling_index].number;
330 \\ }
331 \\ if (dafsa[sibling_index].end_of_list) break;
332 \\ sibling_index += 1;
333 \\ }
334 \\ node_index = child_index;
335 \\ if (dafsa[node_index].end_of_word) index += 1;
336 \\ }
337 \\
338 \\ if (!dafsa[node_index].end_of_word) return null;
339 \\
340 \\ return index;
341 \\}
342 \\
343 \\/// Returns a slice of `buf` with the name associated with the given `index`.
344 \\/// This function should only be called with an `index` that
345 \\/// is already known to exist within the `dafsa`, e.g. an index
346 \\/// returned from `uniqueIndex`.
347 \\pub fn nameFromUniqueIndex(index: u16, buf: []u8) []u8 {
348 \\ std.debug.assert(index >= 1 and index <= data.len);
349 \\
350 \\ var node_index: u16 = 0;
351 \\ var count: u16 = index;
352 \\ var fbs = std.io.fixedBufferStream(buf);
353 \\ const w = fbs.writer();
354 \\
355 \\ while (true) {
356 \\ var sibling_index = dafsa[node_index].child_index;
357 \\ while (true) {
358 \\ if (dafsa[sibling_index].number > 0 and dafsa[sibling_index].number < count) {
359 \\ count -= dafsa[sibling_index].number;
360 \\ } else {
361 \\ w.writeByte(dafsa[sibling_index].char) catch unreachable;
362 \\ node_index = sibling_index;
363 \\ if (dafsa[node_index].end_of_word) {
364 \\ count -= 1;
365 \\ }
366 \\ break;
367 \\ }
368 \\
369 \\ if (dafsa[sibling_index].end_of_list) break;
370 \\ sibling_index += 1;
371 \\ }
372 \\ if (count == 0) break;
373 \\ }
374 \\
375 \\ return fbs.getWritten();
376 \\}
377 \\
378 \\
379 );
380 try writer.writeAll(
381 \\/// We're 1 bit shy of being able to fit this in a u32:
382 \\/// - char only contains 0-9, a-z, A-Z, and _, so it could use a enum(u6) with a way to convert <-> u8
383 \\/// (note: this would have a performance cost that may make the u32 not worth it)
384 \\/// - number has a max value of > 2047 and < 4095 (the first _ node has the largest number),
385 \\/// so it could fit into a u12
386 \\/// - child_index currently has a max of > 4095 and < 8191, so it could fit into a u13
387 \\///
388 \\/// with the end_of_word/end_of_list 2 bools, that makes 33 bits total
389 \\const Node = packed struct(u64) {
390 \\ char: u8,
391 \\ /// Nodes are numbered with "an integer which gives the number of words that
392 \\ /// would be accepted by the automaton starting from that state." This numbering
393 \\ /// allows calculating "a one-to-one correspondence between the integers 1 to L
394 \\ /// (L is the number of words accepted by the automaton) and the words themselves."
395 \\ ///
396 \\ /// Essentially, this allows us to have a minimal perfect hashing scheme such that
397 \\ /// it's possible to store & lookup the properties of each builtin using a separate array.
398 \\ number: u16,
399 \\ /// If true, this node is the end of a valid builtin.
400 \\ /// Note: This does not necessarily mean that this node does not have child nodes.
401 \\ end_of_word: bool,
402 \\ /// If true, this node is the end of a sibling list.
403 \\ /// If false, then (index + 1) will contain the next sibling.
404 \\ end_of_list: bool,
405 \\ /// Padding bits to get to u64, unsure if there's some way to use these to improve something.
406 \\ _extra: u22 = 0,
407 \\ /// Index of the first child of this node.
408 \\ child_index: u16,
409 \\};
410 \\
411 \\
412 );
413 try builder.writeDafsa(writer);
414 try writeData(writer, values_array);
415 try writer.writeAll(
416 \\};
417 \\}
418 \\
419 );
420
421 return out_buf.toOwnedSlice();
422 }
423}
424
425fn writeData(writer: anytype, values: []const Value) !void {
426 try writer.writeAll("pub const data = blk: {\n");
427 try writer.print(" @setEvalBranchQuota({});\n", .{values.len});
428 try writer.writeAll(" break :blk [_]@This(){\n");
429 for (values, 0..) |value, i| {
430 try writer.print(" // {s}\n", .{value.name});
431 try writer.print(" .{{ .tag = @enumFromInt({}), .properties = .{{", .{i});
432 for (value.properties, 0..) |property, j| {
433 if (j != 0) try writer.writeByte(',');
434 try writer.writeByte(' ');
435 try writer.writeAll(property);
436 }
437 if (value.properties.len != 0) try writer.writeByte(' ');
438 try writer.writeAll("} },\n");
439 }
440 try writer.writeAll(" };\n");
441 try writer.writeAll("};\n");
442}
443
444const DafsaBuilder = struct {
445 root: *Node,
446 arena: std.heap.ArenaAllocator.State,
447 allocator: Allocator,
448 unchecked_nodes: std.ArrayListUnmanaged(UncheckedNode),
449 minimized_nodes: std.HashMapUnmanaged(*Node, *Node, Node.DuplicateContext, std.hash_map.default_max_load_percentage),
450 previous_word_buf: [128]u8 = undefined,
451 previous_word: []u8 = &[_]u8{},
452
453 const UncheckedNode = struct {
454 parent: *Node,
455 char: u8,
456 child: *Node,
457 };
458
459 pub fn init(allocator: Allocator) !DafsaBuilder {
460 var arena = std.heap.ArenaAllocator.init(allocator);
461 errdefer arena.deinit();
462
463 const root = try arena.allocator().create(Node);
464 root.* = .{};
465 return DafsaBuilder{
466 .root = root,
467 .allocator = allocator,
468 .arena = arena.state,
469 .unchecked_nodes = .{},
470 .minimized_nodes = .{},
471 };
472 }
473
474 pub fn deinit(self: *DafsaBuilder) void {
475 self.arena.promote(self.allocator).deinit();
476 self.unchecked_nodes.deinit(self.allocator);
477 self.minimized_nodes.deinit(self.allocator);
478 self.* = undefined;
479 }
480
481 const Node = struct {
482 children: [256]?*Node = [_]?*Node{null} ** 256,
483 is_terminal: bool = false,
484 number: usize = 0,
485
486 const DuplicateContext = struct {
487 pub fn hash(ctx: @This(), key: *Node) u64 {
488 _ = ctx;
489 var hasher = std.hash.Wyhash.init(0);
490 std.hash.autoHash(&hasher, key.children);
491 std.hash.autoHash(&hasher, key.is_terminal);
492 return hasher.final();
493 }
494
495 pub fn eql(ctx: @This(), a: *Node, b: *Node) bool {
496 _ = ctx;
497 return a.is_terminal == b.is_terminal and std.mem.eql(?*Node, &a.children, &b.children);
498 }
499 };
500
501 pub fn calcNumbers(self: *Node) void {
502 self.number = @intFromBool(self.is_terminal);
503 for (self.children) |maybe_child| {
504 const child = maybe_child orelse continue;
505 // A node's number is the sum of the
506 // numbers of its immediate child nodes.
507 child.calcNumbers();
508 self.number += child.number;
509 }
510 }
511
512 pub fn numDirectChildren(self: *const Node) u8 {
513 var num: u8 = 0;
514 for (self.children) |child| {
515 if (child != null) num += 1;
516 }
517 return num;
518 }
519 };
520
521 pub fn insert(self: *DafsaBuilder, str: []const u8) !void {
522 if (std.mem.order(u8, str, self.previous_word) == .lt) {
523 @panic("insertion order must be sorted");
524 }
525
526 var common_prefix_len: usize = 0;
527 for (0..@min(str.len, self.previous_word.len)) |i| {
528 if (str[i] != self.previous_word[i]) break;
529 common_prefix_len += 1;
530 }
531
532 try self.minimize(common_prefix_len);
533
534 var node = if (self.unchecked_nodes.items.len == 0)
535 self.root
536 else
537 self.unchecked_nodes.getLast().child;
538
539 for (str[common_prefix_len..]) |c| {
540 std.debug.assert(node.children[c] == null);
541
542 var arena = self.arena.promote(self.allocator);
543 const child = try arena.allocator().create(Node);
544 self.arena = arena.state;
545
546 child.* = .{};
547 node.children[c] = child;
548 try self.unchecked_nodes.append(self.allocator, .{
549 .parent = node,
550 .char = c,
551 .child = child,
552 });
553 node = node.children[c].?;
554 }
555 node.is_terminal = true;
556
557 self.previous_word = self.previous_word_buf[0..str.len];
558 @memcpy(self.previous_word, str);
559 }
560
561 pub fn minimize(self: *DafsaBuilder, down_to: usize) !void {
562 if (self.unchecked_nodes.items.len == 0) return;
563 while (self.unchecked_nodes.items.len > down_to) {
564 const unchecked_node = self.unchecked_nodes.pop();
565 if (self.minimized_nodes.getPtr(unchecked_node.child)) |child| {
566 unchecked_node.parent.children[unchecked_node.char] = child.*;
567 } else {
568 try self.minimized_nodes.put(self.allocator, unchecked_node.child, unchecked_node.child);
569 }
570 }
571 }
572
573 pub fn finish(self: *DafsaBuilder) !void {
574 try self.minimize(0);
575 }
576
577 fn nodeCount(self: *const DafsaBuilder) usize {
578 return self.minimized_nodes.count();
579 }
580
581 fn edgeCount(self: *const DafsaBuilder) usize {
582 var count: usize = 0;
583 var it = self.minimized_nodes.iterator();
584 while (it.next()) |entry| {
585 for (entry.key_ptr.*.children) |child| {
586 if (child != null) count += 1;
587 }
588 }
589 return count;
590 }
591
592 fn contains(self: *const DafsaBuilder, str: []const u8) bool {
593 var node = self.root;
594 for (str) |c| {
595 node = node.children[c] orelse return false;
596 }
597 return node.is_terminal;
598 }
599
600 fn calcNumbers(self: *const DafsaBuilder) void {
601 self.root.calcNumbers();
602 }
603
604 fn getUniqueIndex(self: *const DafsaBuilder, str: []const u8) ?usize {
605 var index: usize = 0;
606 var node = self.root;
607
608 for (str) |c| {
609 const child = node.children[c] orelse return null;
610 for (node.children, 0..) |sibling, sibling_c| {
611 if (sibling == null) continue;
612 if (sibling_c < c) {
613 index += sibling.?.number;
614 }
615 }
616 node = child;
617 if (node.is_terminal) index += 1;
618 }
619
620 return index;
621 }
622
623 fn writeDafsa(self: *const DafsaBuilder, writer: anytype) !void {
624 try writer.writeAll("const dafsa = [_]Node{\n");
625
626 // write root
627 try writer.writeAll(" .{ .char = 0, .end_of_word = false, .end_of_list = true, .number = 0, .child_index = 1 },\n");
628
629 var queue = std.ArrayList(*Node).init(self.allocator);
630 defer queue.deinit();
631
632 var child_indexes = std.AutoHashMap(*Node, usize).init(self.allocator);
633 defer child_indexes.deinit();
634
635 try child_indexes.ensureTotalCapacity(@intCast(self.edgeCount()));
636
637 var first_available_index: usize = self.root.numDirectChildren() + 1;
638 first_available_index = try writeDafsaChildren(self.root, writer, &queue, &child_indexes, first_available_index);
639
640 while (queue.items.len > 0) {
641 // TODO: something with better time complexity
642 const node = queue.orderedRemove(0);
643
644 first_available_index = try writeDafsaChildren(node, writer, &queue, &child_indexes, first_available_index);
645 }
646
647 try writer.writeAll("};\n");
648 }
649
650 fn writeDafsaChildren(
651 node: *Node,
652 writer: anytype,
653 queue: *std.ArrayList(*Node),
654 child_indexes: *std.AutoHashMap(*Node, usize),
655 first_available_index: usize,
656 ) !usize {
657 var cur_available_index = first_available_index;
658 const num_children = node.numDirectChildren();
659 var child_i: usize = 0;
660 for (node.children, 0..) |maybe_child, c_usize| {
661 const child = maybe_child orelse continue;
662 const c: u8 = @intCast(c_usize);
663 const is_last_child = child_i == num_children - 1;
664
665 if (!child_indexes.contains(child)) {
666 const child_num_children = child.numDirectChildren();
667 if (child_num_children > 0) {
668 child_indexes.putAssumeCapacityNoClobber(child, cur_available_index);
669 cur_available_index += child_num_children;
670 }
671 try queue.append(child);
672 }
673
674 try writer.print(
675 " .{{ .char = '{c}', .end_of_word = {}, .end_of_list = {}, .number = {}, .child_index = {} }},\n",
676 .{ c, child.is_terminal, is_last_child, child.number, child_indexes.get(child) orelse 0 },
677 );
678
679 child_i += 1;
680 }
681 return cur_available_index;
682 }
683};
lib/compiler/aro/README.md created+27
......@@ -0,0 +1,27 @@
1<img src="https://aro.vexu.eu/aro-logo.svg" alt="Aro" width="120px"/>
2
3# Aro
4
5A C compiler with the goal of providing fast compilation and low memory usage with good diagnostics.
6
7Aro is included as an alternative C frontend in the [Zig compiler](https://github.com/ziglang/zig)
8for `translate-c` and eventually compiling C files by translating them to Zig first.
9Aro is developed in https://github.com/Vexu/arocc and the Zig dependency is
10updated from there when needed.
11
12Currently most of standard C is supported up to C23 and as are many of the common
13extensions from GNU, MSVC, and Clang
14
15Basic code generation is supported for x86-64 linux and can produce a valid hello world:
16```sh-session
17$ cat hello.c
18extern int printf(const char *restrict fmt, ...);
19int main(void) {
20 printf("Hello, world!\n");
21 return 0;
22}
23$ zig build run -- hello.c -o hello
24$ ./hello
25Hello, world!
26$
27```
lib/compiler/aro/aro.zig created+38
......@@ -0,0 +1,38 @@
1pub const CodeGen = @import("aro/CodeGen.zig");
2pub const Compilation = @import("aro/Compilation.zig");
3pub const Diagnostics = @import("aro/Diagnostics.zig");
4pub const Driver = @import("aro/Driver.zig");
5pub const Parser = @import("aro/Parser.zig");
6pub const Preprocessor = @import("aro/Preprocessor.zig");
7pub const Source = @import("aro/Source.zig");
8pub const Tokenizer = @import("aro/Tokenizer.zig");
9pub const Toolchain = @import("aro/Toolchain.zig");
10pub const Tree = @import("aro/Tree.zig");
11pub const Type = @import("aro/Type.zig");
12pub const TypeMapper = @import("aro/StringInterner.zig").TypeMapper;
13pub const target_util = @import("aro/target.zig");
14pub const Value = @import("aro/Value.zig");
15
16const backend = @import("backend.zig");
17pub const Interner = backend.Interner;
18pub const Ir = backend.Ir;
19pub const Object = backend.Object;
20pub const CallingConvention = backend.CallingConvention;
21
22pub const version_str = backend.version_str;
23pub const version = backend.version;
24
25test {
26 _ = @import("aro/Builtins.zig");
27 _ = @import("aro/char_info.zig");
28 _ = @import("aro/Compilation.zig");
29 _ = @import("aro/Driver/Distro.zig");
30 _ = @import("aro/Driver/Filesystem.zig");
31 _ = @import("aro/Driver/GCCVersion.zig");
32 _ = @import("aro/InitList.zig");
33 _ = @import("aro/Preprocessor.zig");
34 _ = @import("aro/target.zig");
35 _ = @import("aro/Tokenizer.zig");
36 _ = @import("aro/toolchains/Linux.zig");
37 _ = @import("aro/Value.zig");
38}
lib/compiler/aro/aro/Attribute.zig created+1070
......@@ -0,0 +1,1070 @@
1const std = @import("std");
2const mem = std.mem;
3const ZigType = std.builtin.Type;
4const CallingConvention = @import("../backend.zig").CallingConvention;
5const Compilation = @import("Compilation.zig");
6const Diagnostics = @import("Diagnostics.zig");
7const Parser = @import("Parser.zig");
8const Tree = @import("Tree.zig");
9const NodeIndex = Tree.NodeIndex;
10const TokenIndex = Tree.TokenIndex;
11const Type = @import("Type.zig");
12const Value = @import("Value.zig");
13
14const Attribute = @This();
15
16tag: Tag,
17syntax: Syntax,
18args: Arguments,
19
20pub const Syntax = enum {
21 c23,
22 declspec,
23 gnu,
24 keyword,
25};
26
27pub const Kind = enum {
28 c23,
29 declspec,
30 gnu,
31
32 pub fn toSyntax(kind: Kind) Syntax {
33 return switch (kind) {
34 .c23 => .c23,
35 .declspec => .declspec,
36 .gnu => .gnu,
37 };
38 }
39};
40
41pub const ArgumentType = enum {
42 string,
43 identifier,
44 int,
45 alignment,
46 float,
47 expression,
48 nullptr_t,
49
50 pub fn toString(self: ArgumentType) []const u8 {
51 return switch (self) {
52 .string => "a string",
53 .identifier => "an identifier",
54 .int, .alignment => "an integer constant",
55 .nullptr_t => "nullptr",
56 .float => "a floating point number",
57 .expression => "an expression",
58 };
59 }
60};
61
62/// number of required arguments
63pub fn requiredArgCount(attr: Tag) u32 {
64 switch (attr) {
65 inline else => |tag| {
66 comptime var needed = 0;
67 comptime {
68 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
69 for (fields) |arg_field| {
70 if (!mem.eql(u8, arg_field.name, "__name_tok") and @typeInfo(arg_field.type) != .Optional) needed += 1;
71 }
72 }
73 return needed;
74 },
75 }
76}
77
78/// maximum number of args that can be passed
79pub fn maxArgCount(attr: Tag) u32 {
80 switch (attr) {
81 inline else => |tag| {
82 comptime var max = 0;
83 comptime {
84 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
85 for (fields) |arg_field| {
86 if (!mem.eql(u8, arg_field.name, "__name_tok")) max += 1;
87 }
88 }
89 return max;
90 },
91 }
92}
93
94fn UnwrapOptional(comptime T: type) type {
95 return switch (@typeInfo(T)) {
96 .Optional => |optional| optional.child,
97 else => T,
98 };
99}
100
101pub const Formatting = struct {
102 /// The quote char (single or double) to use when printing identifiers/strings corresponding
103 /// to the enum in the first field of the `attr`. Identifier enums use single quotes, string enums
104 /// use double quotes
105 fn quoteChar(attr: Tag) []const u8 {
106 switch (attr) {
107 .calling_convention => unreachable,
108 inline else => |tag| {
109 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
110
111 if (fields.len == 0) unreachable;
112 const Unwrapped = UnwrapOptional(fields[0].type);
113 if (@typeInfo(Unwrapped) != .Enum) unreachable;
114
115 return if (Unwrapped.opts.enum_kind == .identifier) "'" else "\"";
116 },
117 }
118 }
119
120 /// returns a comma-separated string of quoted enum values, representing the valid
121 /// choices for the string or identifier enum of the first field of the `attr`.
122 pub fn choices(attr: Tag) []const u8 {
123 switch (attr) {
124 .calling_convention => unreachable,
125 inline else => |tag| {
126 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
127
128 if (fields.len == 0) unreachable;
129 const Unwrapped = UnwrapOptional(fields[0].type);
130 if (@typeInfo(Unwrapped) != .Enum) unreachable;
131
132 const enum_fields = @typeInfo(Unwrapped).Enum.fields;
133 @setEvalBranchQuota(3000);
134 const quote = comptime quoteChar(@enumFromInt(@intFromEnum(tag)));
135 comptime var values: []const u8 = quote ++ enum_fields[0].name ++ quote;
136 inline for (enum_fields[1..]) |enum_field| {
137 values = values ++ ", ";
138 values = values ++ quote ++ enum_field.name ++ quote;
139 }
140 return values;
141 },
142 }
143 }
144};
145
146/// Checks if the first argument (if it exists) is an identifier enum
147pub fn wantsIdentEnum(attr: Tag) bool {
148 switch (attr) {
149 .calling_convention => return false,
150 inline else => |tag| {
151 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
152
153 if (fields.len == 0) return false;
154 const Unwrapped = UnwrapOptional(fields[0].type);
155 if (@typeInfo(Unwrapped) != .Enum) return false;
156
157 return Unwrapped.opts.enum_kind == .identifier;
158 },
159 }
160}
161
162pub fn diagnoseIdent(attr: Tag, arguments: *Arguments, ident: []const u8) ?Diagnostics.Message {
163 switch (attr) {
164 inline else => |tag| {
165 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
166 if (fields.len == 0) unreachable;
167 const Unwrapped = UnwrapOptional(fields[0].type);
168 if (@typeInfo(Unwrapped) != .Enum) unreachable;
169 if (std.meta.stringToEnum(Unwrapped, normalize(ident))) |enum_val| {
170 @field(@field(arguments, @tagName(tag)), fields[0].name) = enum_val;
171 return null;
172 }
173 return Diagnostics.Message{
174 .tag = .unknown_attr_enum,
175 .extra = .{ .attr_enum = .{ .tag = attr } },
176 };
177 },
178 }
179}
180
181pub fn wantsAlignment(attr: Tag, idx: usize) bool {
182 switch (attr) {
183 inline else => |tag| {
184 const fields = std.meta.fields(@field(attributes, @tagName(tag)));
185 if (fields.len == 0) return false;
186
187 return switch (idx) {
188 inline 0...fields.len - 1 => |i| UnwrapOptional(fields[i].type) == Alignment,
189 else => false,
190 };
191 },
192 }
193}
194
195pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, p: *Parser) !?Diagnostics.Message {
196 switch (attr) {
197 inline else => |tag| {
198 const arg_fields = std.meta.fields(@field(attributes, @tagName(tag)));
199 if (arg_fields.len == 0) unreachable;
200
201 switch (arg_idx) {
202 inline 0...arg_fields.len - 1 => |arg_i| {
203 if (UnwrapOptional(arg_fields[arg_i].type) != Alignment) unreachable;
204
205 if (!res.val.is(.int, p.comp)) return Diagnostics.Message{ .tag = .alignas_unavailable };
206 if (res.val.compare(.lt, Value.zero, p.comp)) {
207 return Diagnostics.Message{ .tag = .negative_alignment, .extra = .{ .str = try res.str(p) } };
208 }
209 const requested = res.val.toInt(u29, p.comp) orelse {
210 return Diagnostics.Message{ .tag = .maximum_alignment, .extra = .{ .str = try res.str(p) } };
211 };
212 if (!std.mem.isValidAlign(requested)) return Diagnostics.Message{ .tag = .non_pow2_align };
213
214 @field(@field(arguments, @tagName(tag)), arg_fields[arg_i].name) = Alignment{ .requested = requested };
215 return null;
216 },
217 else => unreachable,
218 }
219 },
220 }
221}
222
223fn diagnoseField(
224 comptime decl: ZigType.Declaration,
225 comptime field: ZigType.StructField,
226 comptime Wanted: type,
227 arguments: *Arguments,
228 res: Parser.Result,
229 node: Tree.Node,
230 p: *Parser,
231) !?Diagnostics.Message {
232 if (res.val.opt_ref == .none) {
233 if (Wanted == Identifier and node.tag == .decl_ref_expr) {
234 @field(@field(arguments, decl.name), field.name) = Identifier{ .tok = node.data.decl_ref };
235 return null;
236 }
237 return invalidArgMsg(Wanted, .expression);
238 }
239 const key = p.comp.interner.get(res.val.ref());
240 switch (key) {
241 .int => {
242 if (@typeInfo(Wanted) == .Int) {
243 @field(@field(arguments, decl.name), field.name) = res.val.toInt(Wanted, p.comp) orelse return .{
244 .tag = .attribute_int_out_of_range,
245 .extra = .{ .str = try res.str(p) },
246 };
247 return null;
248 }
249 },
250 .bytes => |bytes| {
251 if (Wanted == Value) {
252 std.debug.assert(node.tag == .string_literal_expr);
253 if (!node.ty.elemType().is(.char) and !node.ty.elemType().is(.uchar)) {
254 return .{
255 .tag = .attribute_requires_string,
256 .extra = .{ .str = decl.name },
257 };
258 }
259 @field(@field(arguments, decl.name), field.name) = try p.removeNull(res.val);
260 return null;
261 } else if (@typeInfo(Wanted) == .Enum and @hasDecl(Wanted, "opts") and Wanted.opts.enum_kind == .string) {
262 const str = bytes[0 .. bytes.len - 1];
263 if (std.meta.stringToEnum(Wanted, str)) |enum_val| {
264 @field(@field(arguments, decl.name), field.name) = enum_val;
265 return null;
266 } else {
267 @setEvalBranchQuota(3000);
268 return .{
269 .tag = .unknown_attr_enum,
270 .extra = .{ .attr_enum = .{ .tag = std.meta.stringToEnum(Tag, decl.name).? } },
271 };
272 }
273 }
274 },
275 else => {},
276 }
277 return invalidArgMsg(Wanted, switch (key) {
278 .int => .int,
279 .bytes => .string,
280 .float => .float,
281 .null => .nullptr_t,
282 else => unreachable,
283 });
284}
285
286fn invalidArgMsg(comptime Expected: type, actual: ArgumentType) Diagnostics.Message {
287 return .{
288 .tag = .attribute_arg_invalid,
289 .extra = .{ .attr_arg_type = .{ .expected = switch (Expected) {
290 Value => .string,
291 Identifier => .identifier,
292 u32 => .int,
293 Alignment => .alignment,
294 CallingConvention => .identifier,
295 else => switch (@typeInfo(Expected)) {
296 .Enum => if (Expected.opts.enum_kind == .string) .string else .identifier,
297 else => unreachable,
298 },
299 }, .actual = actual } },
300 };
301}
302
303pub fn diagnose(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, node: Tree.Node, p: *Parser) !?Diagnostics.Message {
304 switch (attr) {
305 inline else => |tag| {
306 const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
307 const max_arg_count = comptime maxArgCount(tag);
308 if (arg_idx >= max_arg_count) return Diagnostics.Message{
309 .tag = .attribute_too_many_args,
310 .extra = .{ .attr_arg_count = .{ .attribute = attr, .expected = max_arg_count } },
311 };
312 const arg_fields = std.meta.fields(@field(attributes, decl.name));
313 switch (arg_idx) {
314 inline 0...arg_fields.len - 1 => |arg_i| {
315 return diagnoseField(decl, arg_fields[arg_i], UnwrapOptional(arg_fields[arg_i].type), arguments, res, node, p);
316 },
317 else => unreachable,
318 }
319 },
320 }
321}
322
323const EnumTypes = enum {
324 string,
325 identifier,
326};
327pub const Alignment = struct {
328 node: NodeIndex = .none,
329 requested: u29,
330};
331pub const Identifier = struct {
332 tok: TokenIndex = 0,
333};
334
335const attributes = struct {
336 pub const access = struct {
337 access_mode: enum {
338 read_only,
339 read_write,
340 write_only,
341 none,
342
343 const opts = struct {
344 const enum_kind = .identifier;
345 };
346 },
347 ref_index: u32,
348 size_index: ?u32 = null,
349 };
350 pub const alias = struct {
351 alias: Value,
352 };
353 pub const aligned = struct {
354 alignment: ?Alignment = null,
355 __name_tok: TokenIndex,
356 };
357 pub const alloc_align = struct {
358 position: u32,
359 };
360 pub const alloc_size = struct {
361 position_1: u32,
362 position_2: ?u32 = null,
363 };
364 pub const allocate = struct {
365 segname: Value,
366 };
367 pub const allocator = struct {};
368 pub const always_inline = struct {};
369 pub const appdomain = struct {};
370 pub const artificial = struct {};
371 pub const assume_aligned = struct {
372 alignment: Alignment,
373 offset: ?u32 = null,
374 };
375 pub const cleanup = struct {
376 function: Identifier,
377 };
378 pub const code_seg = struct {
379 segname: Value,
380 };
381 pub const cold = struct {};
382 pub const common = struct {};
383 pub const @"const" = struct {};
384 pub const constructor = struct {
385 priority: ?u32 = null,
386 };
387 pub const copy = struct {
388 function: Identifier,
389 };
390 pub const deprecated = struct {
391 msg: ?Value = null,
392 __name_tok: TokenIndex,
393 };
394 pub const designated_init = struct {};
395 pub const destructor = struct {
396 priority: ?u32 = null,
397 };
398 pub const dllexport = struct {};
399 pub const dllimport = struct {};
400 pub const @"error" = struct {
401 msg: Value,
402 __name_tok: TokenIndex,
403 };
404 pub const externally_visible = struct {};
405 pub const fallthrough = struct {};
406 pub const flatten = struct {};
407 pub const format = struct {
408 archetype: enum {
409 printf,
410 scanf,
411 strftime,
412 strfmon,
413
414 const opts = struct {
415 const enum_kind = .identifier;
416 };
417 },
418 string_index: u32,
419 first_to_check: u32,
420 };
421 pub const format_arg = struct {
422 string_index: u32,
423 };
424 pub const gnu_inline = struct {};
425 pub const hot = struct {};
426 pub const ifunc = struct {
427 resolver: Value,
428 };
429 pub const interrupt = struct {};
430 pub const interrupt_handler = struct {};
431 pub const jitintrinsic = struct {};
432 pub const leaf = struct {};
433 pub const malloc = struct {};
434 pub const may_alias = struct {};
435 pub const mode = struct {
436 mode: enum {
437 // zig fmt: off
438 byte, word, pointer,
439 BI, QI, HI,
440 PSI, SI, PDI,
441 DI, TI, OI,
442 XI, QF, HF,
443 TQF, SF, DF,
444 XF, SD, DD,
445 TD, TF, QQ,
446 HQ, SQ, DQ,
447 TQ, UQQ, UHQ,
448 USQ, UDQ, UTQ,
449 HA, SA, DA,
450 TA, UHA, USA,
451 UDA, UTA, CC,
452 BLK, VOID, QC,
453 HC, SC, DC,
454 XC, TC, CQI,
455 CHI, CSI, CDI,
456 CTI, COI, CPSI,
457 BND32, BND64,
458 // zig fmt: on
459
460 const opts = struct {
461 const enum_kind = .identifier;
462 };
463 },
464 };
465 pub const naked = struct {};
466 pub const no_address_safety_analysis = struct {};
467 pub const no_icf = struct {};
468 pub const no_instrument_function = struct {};
469 pub const no_profile_instrument_function = struct {};
470 pub const no_reorder = struct {};
471 pub const no_sanitize = struct {
472 /// Todo: represent args as union?
473 alignment: Value,
474 object_size: ?Value = null,
475 };
476 pub const no_sanitize_address = struct {};
477 pub const no_sanitize_coverage = struct {};
478 pub const no_sanitize_thread = struct {};
479 pub const no_sanitize_undefined = struct {};
480 pub const no_split_stack = struct {};
481 pub const no_stack_limit = struct {};
482 pub const no_stack_protector = struct {};
483 pub const @"noalias" = struct {};
484 pub const noclone = struct {};
485 pub const nocommon = struct {};
486 pub const nodiscard = struct {};
487 pub const noinit = struct {};
488 pub const @"noinline" = struct {};
489 pub const noipa = struct {};
490 // TODO: arbitrary number of arguments
491 // const nonnull = struct {
492 // // arg_index: []const u32,
493 // };
494 // };
495 pub const nonstring = struct {};
496 pub const noplt = struct {};
497 pub const @"noreturn" = struct {};
498 // TODO: union args ?
499 // const optimize = struct {
500 // // optimize, // u32 | []const u8 -- optimize?
501 // };
502 // };
503 pub const @"packed" = struct {};
504 pub const patchable_function_entry = struct {};
505 pub const persistent = struct {};
506 pub const process = struct {};
507 pub const pure = struct {};
508 pub const reproducible = struct {};
509 pub const restrict = struct {};
510 pub const retain = struct {};
511 pub const returns_nonnull = struct {};
512 pub const returns_twice = struct {};
513 pub const safebuffers = struct {};
514 pub const scalar_storage_order = struct {
515 order: enum {
516 @"little-endian",
517 @"big-endian",
518
519 const opts = struct {
520 const enum_kind = .string;
521 };
522 },
523 };
524 pub const section = struct {
525 name: Value,
526 };
527 pub const selectany = struct {};
528 pub const sentinel = struct {
529 position: ?u32 = null,
530 };
531 pub const simd = struct {
532 mask: ?enum {
533 notinbranch,
534 inbranch,
535
536 const opts = struct {
537 const enum_kind = .string;
538 };
539 } = null,
540 };
541 pub const spectre = struct {
542 arg: enum {
543 nomitigation,
544
545 const opts = struct {
546 const enum_kind = .identifier;
547 };
548 },
549 };
550 pub const stack_protect = struct {};
551 pub const symver = struct {
552 version: Value, // TODO: validate format "name2@nodename"
553
554 };
555 pub const target = struct {
556 options: Value, // TODO: multiple arguments
557
558 };
559 pub const target_clones = struct {
560 options: Value, // TODO: multiple arguments
561
562 };
563 pub const thread = struct {};
564 pub const tls_model = struct {
565 model: enum {
566 @"global-dynamic",
567 @"local-dynamic",
568 @"initial-exec",
569 @"local-exec",
570
571 const opts = struct {
572 const enum_kind = .string;
573 };
574 },
575 };
576 pub const transparent_union = struct {};
577 pub const unavailable = struct {
578 msg: ?Value = null,
579 __name_tok: TokenIndex,
580 };
581 pub const uninitialized = struct {};
582 pub const unsequenced = struct {};
583 pub const unused = struct {};
584 pub const used = struct {};
585 pub const uuid = struct {
586 uuid: Value,
587 };
588 pub const vector_size = struct {
589 bytes: u32, // TODO: validate "The bytes argument must be a positive power-of-two multiple of the base type size"
590
591 };
592 pub const visibility = struct {
593 visibility_type: enum {
594 default,
595 hidden,
596 internal,
597 protected,
598
599 const opts = struct {
600 const enum_kind = .string;
601 };
602 },
603 };
604 pub const warn_if_not_aligned = struct {
605 alignment: Alignment,
606 };
607 pub const warn_unused_result = struct {};
608 pub const warning = struct {
609 msg: Value,
610 __name_tok: TokenIndex,
611 };
612 pub const weak = struct {};
613 pub const weakref = struct {
614 target: ?Value = null,
615 };
616 pub const zero_call_used_regs = struct {
617 choice: enum {
618 skip,
619 used,
620 @"used-gpr",
621 @"used-arg",
622 @"used-gpr-arg",
623 all,
624 @"all-gpr",
625 @"all-arg",
626 @"all-gpr-arg",
627
628 const opts = struct {
629 const enum_kind = .string;
630 };
631 },
632 };
633 pub const asm_label = struct {
634 name: Value,
635 };
636 pub const calling_convention = struct {
637 cc: CallingConvention,
638 };
639};
640
641pub const Tag = std.meta.DeclEnum(attributes);
642
643pub const Arguments = blk: {
644 const decls = @typeInfo(attributes).Struct.decls;
645 var union_fields: [decls.len]ZigType.UnionField = undefined;
646 for (decls, &union_fields) |decl, *field| {
647 field.* = .{
648 .name = decl.name ++ "",
649 .type = @field(attributes, decl.name),
650 .alignment = 0,
651 };
652 }
653
654 break :blk @Type(.{
655 .Union = .{
656 .layout = .Auto,
657 .tag_type = null,
658 .fields = &union_fields,
659 .decls = &.{},
660 },
661 });
662};
663
664pub fn ArgumentsForTag(comptime tag: Tag) type {
665 const decl = @typeInfo(attributes).Struct.decls[@intFromEnum(tag)];
666 return @field(attributes, decl.name);
667}
668
669pub fn initArguments(tag: Tag, name_tok: TokenIndex) Arguments {
670 switch (tag) {
671 inline else => |arg_tag| {
672 const union_element = @field(attributes, @tagName(arg_tag));
673 const init = std.mem.zeroInit(union_element, .{});
674 var args = @unionInit(Arguments, @tagName(arg_tag), init);
675 if (@hasField(@field(attributes, @tagName(arg_tag)), "__name_tok")) {
676 @field(args, @tagName(arg_tag)).__name_tok = name_tok;
677 }
678 return args;
679 },
680 }
681}
682
683pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag {
684 const Properties = struct {
685 tag: Tag,
686 gnu: bool = false,
687 declspec: bool = false,
688 c23: bool = false,
689 };
690 const attribute_names = @import("Attribute/names.zig").with(Properties);
691
692 const normalized = normalize(name);
693 const actual_kind: Kind = if (namespace) |ns| blk: {
694 const normalized_ns = normalize(ns);
695 if (mem.eql(u8, normalized_ns, "gnu")) {
696 break :blk .gnu;
697 }
698 return null;
699 } else kind;
700
701 const tag_and_opts = attribute_names.fromName(normalized) orelse return null;
702 switch (actual_kind) {
703 inline else => |tag| {
704 if (@field(tag_and_opts.properties, @tagName(tag)))
705 return tag_and_opts.properties.tag;
706 },
707 }
708 return null;
709}
710
711pub fn normalize(name: []const u8) []const u8 {
712 if (name.len >= 4 and mem.startsWith(u8, name, "__") and mem.endsWith(u8, name, "__")) {
713 return name[2 .. name.len - 2];
714 }
715 return name;
716}
717
718fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void {
719 const strings_top = p.strings.items.len;
720 defer p.strings.items.len = strings_top;
721
722 try p.strings.writer().print("attribute '{s}' ignored on {s}", .{ @tagName(attr), context });
723 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
724 try p.errStr(.ignored_attribute, tok, str);
725}
726
727pub const applyParameterAttributes = applyVariableAttributes;
728pub fn applyVariableAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
729 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
730 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
731 p.attr_application_buf.items.len = 0;
732 var base_ty = ty;
733 if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
734 var common = false;
735 var nocommon = false;
736 for (attrs, toks) |attr, tok| switch (attr.tag) {
737 // zig fmt: off
738 .alias, .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .weak, .used,
739 .noinit, .retain, .persistent, .section, .mode, .asm_label,
740 => try p.attr_application_buf.append(p.gpa, attr),
741 // zig fmt: on
742 .common => if (nocommon) {
743 try p.errTok(.ignore_common, tok);
744 } else {
745 try p.attr_application_buf.append(p.gpa, attr);
746 common = true;
747 },
748 .nocommon => if (common) {
749 try p.errTok(.ignore_nocommon, tok);
750 } else {
751 try p.attr_application_buf.append(p.gpa, attr);
752 nocommon = true;
753 },
754 .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
755 .aligned => try attr.applyAligned(p, base_ty, tag),
756 .nonstring => if (!base_ty.isArray() or !(base_ty.is(.char) or base_ty.is(.uchar) or base_ty.is(.schar))) {
757 try p.errStr(.non_string_ignored, tok, try p.typeStr(ty));
758 } else {
759 try p.attr_application_buf.append(p.gpa, attr);
760 },
761 .uninitialized => if (p.func.ty == null) {
762 try p.errStr(.local_variable_attribute, tok, "uninitialized");
763 } else {
764 try p.attr_application_buf.append(p.gpa, attr);
765 },
766 .cleanup => if (p.func.ty == null) {
767 try p.errStr(.local_variable_attribute, tok, "cleanup");
768 } else {
769 try p.attr_application_buf.append(p.gpa, attr);
770 },
771 .alloc_size,
772 .copy,
773 .tls_model,
774 .visibility,
775 => std.debug.panic("apply variable attribute {s}", .{@tagName(attr.tag)}),
776 else => try ignoredAttrErr(p, tok, attr.tag, "variables"),
777 };
778 const existing = ty.getAttributes();
779 if (existing.len == 0 and p.attr_application_buf.items.len == 0) return base_ty;
780 if (existing.len == 0) return base_ty.withAttributes(p.arena, p.attr_application_buf.items);
781
782 const attributed_type = try Type.Attributed.create(p.arena, base_ty, existing, p.attr_application_buf.items);
783 return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } };
784}
785
786pub fn applyFieldAttributes(p: *Parser, field_ty: *Type, attr_buf_start: usize) ![]const Attribute {
787 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
788 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
789 p.attr_application_buf.items.len = 0;
790 for (attrs, toks) |attr, tok| switch (attr.tag) {
791 // zig fmt: off
792 .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
793 => try p.attr_application_buf.append(p.gpa, attr),
794 // zig fmt: on
795 .vector_size => try attr.applyVectorSize(p, tok, field_ty),
796 .aligned => try attr.applyAligned(p, field_ty.*, null),
797 else => try ignoredAttrErr(p, tok, attr.tag, "fields"),
798 };
799 if (p.attr_application_buf.items.len == 0) return &[0]Attribute{};
800 return p.arena.dupe(Attribute, p.attr_application_buf.items);
801}
802
803pub fn applyTypeAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type {
804 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
805 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
806 p.attr_application_buf.items.len = 0;
807 var base_ty = ty;
808 if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
809 for (attrs, toks) |attr, tok| switch (attr.tag) {
810 // zig fmt: off
811 .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
812 => try p.attr_application_buf.append(p.gpa, attr),
813 // zig fmt: on
814 .transparent_union => try attr.applyTransparentUnion(p, tok, base_ty),
815 .vector_size => try attr.applyVectorSize(p, tok, &base_ty),
816 .aligned => try attr.applyAligned(p, base_ty, tag),
817 .designated_init => if (base_ty.is(.@"struct")) {
818 try p.attr_application_buf.append(p.gpa, attr);
819 } else {
820 try p.errTok(.designated_init_invalid, tok);
821 },
822 .alloc_size,
823 .copy,
824 .scalar_storage_order,
825 .nonstring,
826 => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
827 else => try ignoredAttrErr(p, tok, attr.tag, "types"),
828 };
829
830 const existing = ty.getAttributes();
831 // TODO: the alignment annotation on a type should override
832 // the decl it refers to. This might not be true for others. Maybe bug.
833
834 // if there are annotations on this type def use those.
835 if (p.attr_application_buf.items.len > 0) {
836 return try base_ty.withAttributes(p.arena, p.attr_application_buf.items);
837 } else if (existing.len > 0) {
838 // else use the ones on the typedef decl we were refering to.
839 return try base_ty.withAttributes(p.arena, existing);
840 }
841 return base_ty;
842}
843
844pub fn applyFunctionAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
845 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
846 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
847 p.attr_application_buf.items.len = 0;
848 var base_ty = ty;
849 if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
850 var hot = false;
851 var cold = false;
852 var @"noinline" = false;
853 var always_inline = false;
854 for (attrs, toks) |attr, tok| switch (attr.tag) {
855 // zig fmt: off
856 .noreturn, .unused, .used, .warning, .deprecated, .unavailable, .weak, .pure, .leaf,
857 .@"const", .warn_unused_result, .section, .returns_nonnull, .returns_twice, .@"error",
858 .externally_visible, .retain, .flatten, .gnu_inline, .alias, .asm_label, .nodiscard,
859 .reproducible, .unsequenced,
860 => try p.attr_application_buf.append(p.gpa, attr),
861 // zig fmt: on
862 .hot => if (cold) {
863 try p.errTok(.ignore_hot, tok);
864 } else {
865 try p.attr_application_buf.append(p.gpa, attr);
866 hot = true;
867 },
868 .cold => if (hot) {
869 try p.errTok(.ignore_cold, tok);
870 } else {
871 try p.attr_application_buf.append(p.gpa, attr);
872 cold = true;
873 },
874 .always_inline => if (@"noinline") {
875 try p.errTok(.ignore_always_inline, tok);
876 } else {
877 try p.attr_application_buf.append(p.gpa, attr);
878 always_inline = true;
879 },
880 .@"noinline" => if (always_inline) {
881 try p.errTok(.ignore_noinline, tok);
882 } else {
883 try p.attr_application_buf.append(p.gpa, attr);
884 @"noinline" = true;
885 },
886 .aligned => try attr.applyAligned(p, base_ty, null),
887 .format => try attr.applyFormat(p, base_ty),
888 .calling_convention => switch (attr.args.calling_convention.cc) {
889 .C => continue,
890 .stdcall, .thiscall => switch (p.comp.target.cpu.arch) {
891 .x86 => try p.attr_application_buf.append(p.gpa, attr),
892 else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
893 },
894 .vectorcall => switch (p.comp.target.cpu.arch) {
895 .x86, .aarch64, .aarch64_be, .aarch64_32 => try p.attr_application_buf.append(p.gpa, attr),
896 else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?),
897 },
898 },
899 .access,
900 .alloc_align,
901 .alloc_size,
902 .artificial,
903 .assume_aligned,
904 .constructor,
905 .copy,
906 .destructor,
907 .format_arg,
908 .ifunc,
909 .interrupt,
910 .interrupt_handler,
911 .malloc,
912 .no_address_safety_analysis,
913 .no_icf,
914 .no_instrument_function,
915 .no_profile_instrument_function,
916 .no_reorder,
917 .no_sanitize,
918 .no_sanitize_address,
919 .no_sanitize_coverage,
920 .no_sanitize_thread,
921 .no_sanitize_undefined,
922 .no_split_stack,
923 .no_stack_limit,
924 .no_stack_protector,
925 .noclone,
926 .noipa,
927 // .nonnull,
928 .noplt,
929 // .optimize,
930 .patchable_function_entry,
931 .sentinel,
932 .simd,
933 .stack_protect,
934 .symver,
935 .target,
936 .target_clones,
937 .visibility,
938 .weakref,
939 .zero_call_used_regs,
940 => std.debug.panic("apply type attribute {s}", .{@tagName(attr.tag)}),
941 else => try ignoredAttrErr(p, tok, attr.tag, "functions"),
942 };
943 return ty.withAttributes(p.arena, p.attr_application_buf.items);
944}
945
946pub fn applyLabelAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
947 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
948 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
949 p.attr_application_buf.items.len = 0;
950 var hot = false;
951 var cold = false;
952 for (attrs, toks) |attr, tok| switch (attr.tag) {
953 .unused => try p.attr_application_buf.append(p.gpa, attr),
954 .hot => if (cold) {
955 try p.errTok(.ignore_hot, tok);
956 } else {
957 try p.attr_application_buf.append(p.gpa, attr);
958 hot = true;
959 },
960 .cold => if (hot) {
961 try p.errTok(.ignore_cold, tok);
962 } else {
963 try p.attr_application_buf.append(p.gpa, attr);
964 cold = true;
965 },
966 else => try ignoredAttrErr(p, tok, attr.tag, "labels"),
967 };
968 return ty.withAttributes(p.arena, p.attr_application_buf.items);
969}
970
971pub fn applyStatementAttributes(p: *Parser, ty: Type, expr_start: TokenIndex, attr_buf_start: usize) !Type {
972 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
973 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
974 p.attr_application_buf.items.len = 0;
975 for (attrs, toks) |attr, tok| switch (attr.tag) {
976 .fallthrough => if (p.tok_ids[p.tok_i] != .keyword_case and p.tok_ids[p.tok_i] != .keyword_default) {
977 // TODO: this condition is not completely correct; the last statement of a compound
978 // statement is also valid if it precedes a switch label (so intervening '}' are ok,
979 // but only if they close a compound statement)
980 try p.errTok(.invalid_fallthrough, expr_start);
981 } else {
982 try p.attr_application_buf.append(p.gpa, attr);
983 },
984 else => try p.errStr(.cannot_apply_attribute_to_statement, tok, @tagName(attr.tag)),
985 };
986 return ty.withAttributes(p.arena, p.attr_application_buf.items);
987}
988
989pub fn applyEnumeratorAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
990 const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
991 const toks = p.attr_buf.items(.tok)[attr_buf_start..];
992 p.attr_application_buf.items.len = 0;
993 for (attrs, toks) |attr, tok| switch (attr.tag) {
994 .deprecated, .unavailable => try p.attr_application_buf.append(p.gpa, attr),
995 else => try ignoredAttrErr(p, tok, attr.tag, "enums"),
996 };
997 return ty.withAttributes(p.arena, p.attr_application_buf.items);
998}
999
1000fn applyAligned(attr: Attribute, p: *Parser, ty: Type, tag: ?Diagnostics.Tag) !void {
1001 const base = ty.canonicalize(.standard);
1002 if (attr.args.aligned.alignment) |alignment| alignas: {
1003 if (attr.syntax != .keyword) break :alignas;
1004
1005 const align_tok = attr.args.aligned.__name_tok;
1006 if (tag) |t| try p.errTok(t, align_tok);
1007
1008 const default_align = base.alignof(p.comp);
1009 if (ty.isFunc()) {
1010 try p.errTok(.alignas_on_func, align_tok);
1011 } else if (alignment.requested < default_align) {
1012 try p.errExtra(.minimum_alignment, align_tok, .{ .unsigned = default_align });
1013 }
1014 }
1015 try p.attr_application_buf.append(p.gpa, attr);
1016}
1017
1018fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type) !void {
1019 const union_ty = ty.get(.@"union") orelse {
1020 return p.errTok(.transparent_union_wrong_type, tok);
1021 };
1022 // TODO validate union defined at end
1023 if (union_ty.data.record.isIncomplete()) return;
1024 const fields = union_ty.data.record.fields;
1025 if (fields.len == 0) {
1026 return p.errTok(.transparent_union_one_field, tok);
1027 }
1028 const first_field_size = fields[0].ty.bitSizeof(p.comp).?;
1029 for (fields[1..]) |field| {
1030 const field_size = field.ty.bitSizeof(p.comp).?;
1031 if (field_size == first_field_size) continue;
1032 const mapper = p.comp.string_interner.getSlowTypeMapper();
1033 const str = try std.fmt.allocPrint(
1034 p.comp.diagnostics.arena.allocator(),
1035 "'{s}' ({d}",
1036 .{ mapper.lookup(field.name), field_size },
1037 );
1038 try p.errStr(.transparent_union_size, field.name_tok, str);
1039 return p.errExtra(.transparent_union_size_note, fields[0].name_tok, .{ .unsigned = first_field_size });
1040 }
1041
1042 try p.attr_application_buf.append(p.gpa, attr);
1043}
1044
1045fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !void {
1046 if (!(ty.isInt() or ty.isFloat()) or !ty.isReal()) {
1047 const orig_ty = try p.typeStr(ty.*);
1048 ty.* = Type.invalid;
1049 return p.errStr(.invalid_vec_elem_ty, tok, orig_ty);
1050 }
1051 const vec_bytes = attr.args.vector_size.bytes;
1052 const ty_size = ty.sizeof(p.comp).?;
1053 if (vec_bytes % ty_size != 0) {
1054 return p.errTok(.vec_size_not_multiple, tok);
1055 }
1056 const vec_size = vec_bytes / ty_size;
1057
1058 const arr_ty = try p.arena.create(Type.Array);
1059 arr_ty.* = .{ .elem = ty.*, .len = vec_size };
1060 ty.* = Type{
1061 .specifier = .vector,
1062 .data = .{ .array = arr_ty },
1063 };
1064}
1065
1066fn applyFormat(attr: Attribute, p: *Parser, ty: Type) !void {
1067 // TODO validate
1068 _ = ty;
1069 try p.attr_application_buf.append(p.gpa, attr);
1070}
lib/compiler/aro/aro/Attribute/names.zig created+1010
......@@ -0,0 +1,1010 @@
1//! Autogenerated by GenerateDef from deps/aro/aro/Attribute/names.def, do not edit
2
3const std = @import("std");
4
5pub fn with(comptime Properties: type) type {
6return struct {
7
8tag: Tag,
9properties: Properties,
10
11/// Integer starting at 0 derived from the unique index,
12/// corresponds with the data array index.
13pub const Tag = enum(u16) { _ };
14
15const Self = @This();
16
17pub fn fromName(name: []const u8) ?@This() {
18 const data_index = tagFromName(name) orelse return null;
19 return data[@intFromEnum(data_index)];
20}
21
22pub fn tagFromName(name: []const u8) ?Tag {
23 const unique_index = uniqueIndex(name) orelse return null;
24 return @enumFromInt(unique_index - 1);
25}
26
27pub fn fromTag(tag: Tag) @This() {
28 return data[@intFromEnum(tag)];
29}
30
31pub fn nameFromTagIntoBuf(tag: Tag, name_buf: []u8) []u8 {
32 std.debug.assert(name_buf.len >= longest_name);
33 const unique_index = @intFromEnum(tag) + 1;
34 return nameFromUniqueIndex(unique_index, name_buf);
35}
36
37pub fn nameFromTag(tag: Tag) NameBuf {
38 var name_buf: NameBuf = undefined;
39 const unique_index = @intFromEnum(tag) + 1;
40 const name = nameFromUniqueIndex(unique_index, &name_buf.buf);
41 name_buf.len = @intCast(name.len);
42 return name_buf;
43}
44
45pub const NameBuf = struct {
46 buf: [longest_name]u8 = undefined,
47 len: std.math.IntFittingRange(0, longest_name),
48
49 pub fn span(self: *const NameBuf) []const u8 {
50 return self.buf[0..self.len];
51 }
52};
53
54pub fn exists(name: []const u8) bool {
55 if (name.len < shortest_name or name.len > longest_name) return false;
56
57 var index: u16 = 0;
58 for (name) |c| {
59 index = findInList(dafsa[index].child_index, c) orelse return false;
60 }
61 return dafsa[index].end_of_word;
62}
63
64pub const shortest_name = 3;
65pub const longest_name = 30;
66
67/// Search siblings of `first_child_index` for the `char`
68/// If found, returns the index of the node within the `dafsa` array.
69/// Otherwise, returns `null`.
70pub fn findInList(first_child_index: u16, char: u8) ?u16 {
71 var index = first_child_index;
72 while (true) {
73 if (dafsa[index].char == char) return index;
74 if (dafsa[index].end_of_list) return null;
75 index += 1;
76 }
77 unreachable;
78}
79
80/// Returns a unique (minimal perfect hash) index (starting at 1) for the `name`,
81/// or null if the name was not found.
82pub fn uniqueIndex(name: []const u8) ?u16 {
83 if (name.len < shortest_name or name.len > longest_name) return null;
84
85 var index: u16 = 0;
86 var node_index: u16 = 0;
87
88 for (name) |c| {
89 const child_index = findInList(dafsa[node_index].child_index, c) orelse return null;
90 var sibling_index = dafsa[node_index].child_index;
91 while (true) {
92 const sibling_c = dafsa[sibling_index].char;
93 std.debug.assert(sibling_c != 0);
94 if (sibling_c < c) {
95 index += dafsa[sibling_index].number;
96 }
97 if (dafsa[sibling_index].end_of_list) break;
98 sibling_index += 1;
99 }
100 node_index = child_index;
101 if (dafsa[node_index].end_of_word) index += 1;
102 }
103
104 if (!dafsa[node_index].end_of_word) return null;
105
106 return index;
107}
108
109/// Returns a slice of `buf` with the name associated with the given `index`.
110/// This function should only be called with an `index` that
111/// is already known to exist within the `dafsa`, e.g. an index
112/// returned from `uniqueIndex`.
113pub fn nameFromUniqueIndex(index: u16, buf: []u8) []u8 {
114 std.debug.assert(index >= 1 and index <= data.len);
115
116 var node_index: u16 = 0;
117 var count: u16 = index;
118 var fbs = std.io.fixedBufferStream(buf);
119 const w = fbs.writer();
120
121 while (true) {
122 var sibling_index = dafsa[node_index].child_index;
123 while (true) {
124 if (dafsa[sibling_index].number > 0 and dafsa[sibling_index].number < count) {
125 count -= dafsa[sibling_index].number;
126 } else {
127 w.writeByte(dafsa[sibling_index].char) catch unreachable;
128 node_index = sibling_index;
129 if (dafsa[node_index].end_of_word) {
130 count -= 1;
131 }
132 break;
133 }
134
135 if (dafsa[sibling_index].end_of_list) break;
136 sibling_index += 1;
137 }
138 if (count == 0) break;
139 }
140
141 return fbs.getWritten();
142}
143
144/// We're 1 bit shy of being able to fit this in a u32:
145/// - char only contains 0-9, a-z, A-Z, and _, so it could use a enum(u6) with a way to convert <-> u8
146/// (note: this would have a performance cost that may make the u32 not worth it)
147/// - number has a max value of > 2047 and < 4095 (the first _ node has the largest number),
148/// so it could fit into a u12
149/// - child_index currently has a max of > 4095 and < 8191, so it could fit into a u13
150///
151/// with the end_of_word/end_of_list 2 bools, that makes 33 bits total
152const Node = packed struct(u64) {
153 char: u8,
154 /// Nodes are numbered with "an integer which gives the number of words that
155 /// would be accepted by the automaton starting from that state." This numbering
156 /// allows calculating "a one-to-one correspondence between the integers 1 to L
157 /// (L is the number of words accepted by the automaton) and the words themselves."
158 ///
159 /// Essentially, this allows us to have a minimal perfect hashing scheme such that
160 /// it's possible to store & lookup the properties of each builtin using a separate array.
161 number: u16,
162 /// If true, this node is the end of a valid builtin.
163 /// Note: This does not necessarily mean that this node does not have child nodes.
164 end_of_word: bool,
165 /// If true, this node is the end of a sibling list.
166 /// If false, then (index + 1) will contain the next sibling.
167 end_of_list: bool,
168 /// Padding bits to get to u64, unsure if there's some way to use these to improve something.
169 _extra: u22 = 0,
170 /// Index of the first child of this node.
171 child_index: u16,
172};
173
174const dafsa = [_]Node{
175 .{ .char = 0, .end_of_word = false, .end_of_list = true, .number = 0, .child_index = 1 },
176 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 21 },
177 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 26 },
178 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 28 },
179 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 30 },
180 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 32 },
181 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 35 },
182 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 36 },
183 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 37 },
184 .{ .char = 'j', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 39 },
185 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 40 },
186 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 41 },
187 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 43 },
188 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 45 },
189 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 49 },
190 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 50 },
191 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 57 },
192 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 61 },
193 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 64 },
194 .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 66 },
195 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 68 },
196 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 69 },
197 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 70 },
198 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 73 },
199 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 74 },
200 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 75 },
201 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 76 },
202 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 77 },
203 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 82 },
204 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 84 },
205 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 85 },
206 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 86 },
207 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 87 },
208 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 88 },
209 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 89 },
210 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 90 },
211 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 },
212 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 92 },
213 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 93 },
214 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 94 },
215 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 95 },
216 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 96 },
217 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 98 },
218 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 99 },
219 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 23, .child_index = 100 },
220 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 108 },
221 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 110 },
222 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 111 },
223 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 112 },
224 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 113 },
225 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 116 },
226 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 117 },
227 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 118 },
228 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 121 },
229 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 122 },
230 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 123 },
231 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 124 },
232 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 125 },
233 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 126 },
234 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 127 },
235 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 128 },
236 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 129 },
237 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 133 },
238 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 134 },
239 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 135 },
240 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 136 },
241 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 137 },
242 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 138 },
243 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 139 },
244 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 140 },
245 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 141 },
246 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 143 },
247 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 144 },
248 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 145 },
249 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 146 },
250 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 147 },
251 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 148 },
252 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 149 },
253 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 150 },
254 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 151 },
255 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 152 },
256 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 },
257 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 154 },
258 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 155 },
259 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 157 },
260 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 159 },
261 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 160 },
262 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 161 },
263 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 162 },
264 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 163 },
265 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 164 },
266 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
267 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 165 },
268 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 166 },
269 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 167 },
270 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 168 },
271 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 169 },
272 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 170 },
273 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 },
274 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 },
275 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 173 },
276 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 178 },
277 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 179 },
278 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 181 },
279 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 182 },
280 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 184 },
281 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 185 },
282 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 186 },
283 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 99 },
284 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 187 },
285 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 188 },
286 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 69 },
287 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 },
288 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 189 },
289 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 190 },
290 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 191 },
291 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 193 },
292 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 194 },
293 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 195 },
294 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 196 },
295 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 197 },
296 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 },
297 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 198 },
298 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 199 },
299 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 200 },
300 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 201 },
301 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 202 },
302 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 203 },
303 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 204 },
304 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 205 },
305 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 206 },
306 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 207 },
307 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 208 },
308 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 },
309 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 },
310 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 209 },
311 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 },
312 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 211 },
313 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 212 },
314 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 213 },
315 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 214 },
316 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 215 },
317 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 216 },
318 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 217 },
319 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 218 },
320 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 219 },
321 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 220 },
322 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 221 },
323 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 222 },
324 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 223 },
325 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
326 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 224 },
327 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 225 },
328 .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
329 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 226 },
330 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 227 },
331 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 228 },
332 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 229 },
333 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 230 },
334 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 231 },
335 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 232 },
336 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 233 },
337 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 234 },
338 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 235 },
339 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 236 },
340 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 237 },
341 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 238 },
342 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 239 },
343 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
344 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 240 },
345 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 241 },
346 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 242 },
347 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
348 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 243 },
349 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 244 },
350 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 246 },
351 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 247 },
352 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 248 },
353 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 251 },
354 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 252 },
355 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 253 },
356 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 254 },
357 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 255 },
358 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 257 },
359 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 258 },
360 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 },
361 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 259 },
362 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 260 },
363 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 261 },
364 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 262 },
365 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 263 },
366 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 264 },
367 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 265 },
368 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 266 },
369 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 267 },
370 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 268 },
371 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 269 },
372 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 270 },
373 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 271 },
374 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 272 },
375 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 273 },
376 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 274 },
377 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 275 },
378 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 276 },
379 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 277 },
380 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 278 },
381 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 279 },
382 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 280 },
383 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 },
384 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 281 },
385 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 282 },
386 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 283 },
387 .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 285 },
388 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 286 },
389 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 },
390 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
391 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 287 },
392 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 288 },
393 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 290 },
394 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
395 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 },
396 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 293 },
397 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 294 },
398 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 295 },
399 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 },
400 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 297 },
401 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 298 },
402 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 299 },
403 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 300 },
404 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 301 },
405 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 301 },
406 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
407 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 302 },
408 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 303 },
409 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 304 },
410 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 305 },
411 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 306 },
412 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
413 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 307 },
414 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 308 },
415 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 237 },
416 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 },
417 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 309 },
418 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 310 },
419 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 168 },
420 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
421 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 312 },
422 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 313 },
423 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 314 },
424 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 315 },
425 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 316 },
426 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 317 },
427 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 318 },
428 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 151 },
429 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 319 },
430 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 91 },
431 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 320 },
432 .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
433 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 321 },
434 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 322 },
435 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 },
436 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 324 },
437 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 325 },
438 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 326 },
439 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 },
440 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 327 },
441 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 328 },
442 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 329 },
443 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 224 },
444 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 330 },
445 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 331 },
446 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 112 },
447 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 332 },
448 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 231 },
449 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 333 },
450 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 },
451 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 334 },
452 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 335 },
453 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 336 },
454 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 337 },
455 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 338 },
456 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 339 },
457 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 340 },
458 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 341 },
459 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 343 },
460 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
461 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 345 },
462 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 },
463 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 346 },
464 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 348 },
465 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 164 },
466 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 349 },
467 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 350 },
468 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 351 },
469 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 },
470 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 353 },
471 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
472 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 300 },
473 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 354 },
474 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 355 },
475 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 356 },
476 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 357 },
477 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 358 },
478 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 359 },
479 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 },
480 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 360 },
481 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 361 },
482 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 362 },
483 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 363 },
484 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 364 },
485 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 365 },
486 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 366 },
487 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 367 },
488 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 368 },
489 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 369 },
490 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 370 },
491 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 371 },
492 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 },
493 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 },
494 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 372 },
495 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 318 },
496 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 373 },
497 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 374 },
498 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 375 },
499 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 376 },
500 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 377 },
501 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 378 },
502 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 379 },
503 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 380 },
504 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 381 },
505 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 382 },
506 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 383 },
507 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 384 },
508 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 385 },
509 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 386 },
510 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 387 },
511 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 388 },
512 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 389 },
513 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 390 },
514 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 391 },
515 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 392 },
516 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 393 },
517 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 394 },
518 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 395 },
519 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 168 },
520 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 396 },
521 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 397 },
522 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 398 },
523 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 399 },
524 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 264 },
525 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 401 },
526 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 402 },
527 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
528 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 395 },
529 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 403 },
530 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 404 },
531 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 405 },
532 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 406 },
533 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 407 },
534 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 408 },
535 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 409 },
536 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 320 },
537 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 410 },
538 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 411 },
539 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
540 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 413 },
541 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 414 },
542 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 415 },
543 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 416 },
544 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 417 },
545 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 418 },
546 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 419 },
547 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 420 },
548 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 343 },
549 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 },
550 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 421 },
551 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 422 },
552 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 423 },
553 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 },
554 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 424 },
555 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 425 },
556 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 426 },
557 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 427 },
558 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 428 },
559 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 429 },
560 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 430 },
561 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 383 },
562 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 431 },
563 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 432 },
564 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 433 },
565 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 434 },
566 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 435 },
567 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 436 },
568 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 437 },
569 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 438 },
570 .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
571 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 439 },
572 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 440 },
573 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 441 },
574 .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
575 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 231 },
576 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 442 },
577 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 443 },
578 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 },
579 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 444 },
580 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 159 },
581 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 },
582 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 445 },
583 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 446 },
584 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 447 },
585 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 448 },
586 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 449 },
587 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
588 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 },
589 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 452 },
590 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 453 },
591 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 273 },
592 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 454 },
593 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 455 },
594 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 456 },
595 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 },
596 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
597 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
598 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 },
599 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 460 },
600 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 462 },
601 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
602 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 },
603 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
604 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 464 },
605 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 465 },
606 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 466 },
607 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 467 },
608 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 468 },
609 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 469 },
610 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 398 },
611 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 470 },
612 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 471 },
613 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 472 },
614 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 473 },
615 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 474 },
616 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 },
617 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 428 },
618 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 475 },
619 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 476 },
620 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 477 },
621 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 478 },
622 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 395 },
623 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 479 },
624 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 480 },
625 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 208 },
626 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 481 },
627 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 482 },
628 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 483 },
629 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 484 },
630 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 485 },
631 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 486 },
632 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 488 },
633 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 },
634 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 467 },
635 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 489 },
636 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 490 },
637 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 491 },
638 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 492 },
639 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 493 },
640 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 494 },
641 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 495 },
642 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
643 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 497 },
644 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 },
645 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 },
646 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 498 },
647 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 499 },
648 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 500 },
649 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 },
650 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 501 },
651 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 502 },
652 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 503 },
653 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 504 },
654 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 505 },
655 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 506 },
656 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 507 },
657 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 508 },
658 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 509 },
659 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 510 },
660 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 511 },
661 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 512 },
662 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 513 },
663 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 514 },
664 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 515 },
665 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 516 },
666 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 },
667 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 517 },
668 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 518 },
669 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 },
670 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 520 },
671 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 },
672 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 },
673 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 522 },
674 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 523 },
675 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 524 },
676 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 525 },
677 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 526 },
678 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 527 },
679 .{ .char = 'h', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
680 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 528 },
681 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 237 },
682 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 529 },
683 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 530 },
684 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 531 },
685 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 532 },
686 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 533 },
687 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 534 },
688 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 535 },
689 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 536 },
690 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 537 },
691 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 538 },
692 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 539 },
693 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 378 },
694 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 540 },
695 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 541 },
696 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 },
697 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 351 },
698 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 542 },
699 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 543 },
700 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 },
701 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 544 },
702 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 545 },
703 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 546 },
704 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 547 },
705 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 548 },
706 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 549 },
707 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 550 },
708 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 554 },
709 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 555 },
710 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 556 },
711 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 557 },
712 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 558 },
713 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 },
714 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 559 },
715 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 },
716 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 560 },
717 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 561 },
718 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 562 },
719 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 555 },
720 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 563 },
721 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 564 },
722 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 565 },
723 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 566 },
724 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
725 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 567 },
726 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 568 },
727 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 },
728 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 570 },
729 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 571 },
730 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 },
731 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
732 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 573 },
733 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 574 },
734 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 575 },
735 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 576 },
736 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 577 },
737 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 578 },
738 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 },
739 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 },
740 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 },
741 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 581 },
742 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 582 },
743 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 583 },
744 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 126 },
745 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 584 },
746 .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
747 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 356 },
748 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
749 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 428 },
750 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 586 },
751 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 268 },
752 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 587 },
753 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 588 },
754 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 273 },
755 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 589 },
756 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 590 },
757 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 591 },
758 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 592 },
759 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 593 },
760 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 594 },
761 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 313 },
762 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 595 },
763 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 596 },
764 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 597 },
765 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 598 },
766 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 140 },
767 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 599 },
768 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 600 },
769 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 601 },
770 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 185 },
771 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 602 },
772 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 603 },
773 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 604 },
774 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 605 },
775 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 606 },
776 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 607 },
777 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 608 },
778 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 609 },
779 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 195 },
780 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 610 },
781 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 525 },
782 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 611 },
783 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 },
784 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 612 },
785 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 },
786 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 613 },
787 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 614 },
788 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 615 },
789 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 616 },
790 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 617 },
791 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 618 },
792 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 619 },
793 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 620 },
794 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 },
795 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 621 },
796 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 },
797};
798pub const data = blk: {
799 @setEvalBranchQuota(103);
800 break :blk [_]@This(){
801 // access
802 .{ .tag = @enumFromInt(0), .properties = .{ .tag = .access, .gnu = true } },
803 // alias
804 .{ .tag = @enumFromInt(1), .properties = .{ .tag = .alias, .gnu = true } },
805 // align
806 .{ .tag = @enumFromInt(2), .properties = .{ .tag = .aligned, .declspec = true } },
807 // aligned
808 .{ .tag = @enumFromInt(3), .properties = .{ .tag = .aligned, .gnu = true } },
809 // alloc_align
810 .{ .tag = @enumFromInt(4), .properties = .{ .tag = .alloc_align, .gnu = true } },
811 // alloc_size
812 .{ .tag = @enumFromInt(5), .properties = .{ .tag = .alloc_size, .gnu = true } },
813 // allocate
814 .{ .tag = @enumFromInt(6), .properties = .{ .tag = .allocate, .declspec = true } },
815 // allocator
816 .{ .tag = @enumFromInt(7), .properties = .{ .tag = .allocator, .declspec = true } },
817 // always_inline
818 .{ .tag = @enumFromInt(8), .properties = .{ .tag = .always_inline, .gnu = true } },
819 // appdomain
820 .{ .tag = @enumFromInt(9), .properties = .{ .tag = .appdomain, .declspec = true } },
821 // artificial
822 .{ .tag = @enumFromInt(10), .properties = .{ .tag = .artificial, .gnu = true } },
823 // assume_aligned
824 .{ .tag = @enumFromInt(11), .properties = .{ .tag = .assume_aligned, .gnu = true } },
825 // cleanup
826 .{ .tag = @enumFromInt(12), .properties = .{ .tag = .cleanup, .gnu = true } },
827 // code_seg
828 .{ .tag = @enumFromInt(13), .properties = .{ .tag = .code_seg, .declspec = true } },
829 // cold
830 .{ .tag = @enumFromInt(14), .properties = .{ .tag = .cold, .gnu = true } },
831 // common
832 .{ .tag = @enumFromInt(15), .properties = .{ .tag = .common, .gnu = true } },
833 // const
834 .{ .tag = @enumFromInt(16), .properties = .{ .tag = .@"const", .gnu = true } },
835 // constructor
836 .{ .tag = @enumFromInt(17), .properties = .{ .tag = .constructor, .gnu = true } },
837 // copy
838 .{ .tag = @enumFromInt(18), .properties = .{ .tag = .copy, .gnu = true } },
839 // deprecated
840 .{ .tag = @enumFromInt(19), .properties = .{ .tag = .deprecated, .c23 = true, .gnu = true, .declspec = true } },
841 // designated_init
842 .{ .tag = @enumFromInt(20), .properties = .{ .tag = .designated_init, .gnu = true } },
843 // destructor
844 .{ .tag = @enumFromInt(21), .properties = .{ .tag = .destructor, .gnu = true } },
845 // dllexport
846 .{ .tag = @enumFromInt(22), .properties = .{ .tag = .dllexport, .declspec = true } },
847 // dllimport
848 .{ .tag = @enumFromInt(23), .properties = .{ .tag = .dllimport, .declspec = true } },
849 // error
850 .{ .tag = @enumFromInt(24), .properties = .{ .tag = .@"error", .gnu = true } },
851 // externally_visible
852 .{ .tag = @enumFromInt(25), .properties = .{ .tag = .externally_visible, .gnu = true } },
853 // fallthrough
854 .{ .tag = @enumFromInt(26), .properties = .{ .tag = .fallthrough, .c23 = true, .gnu = true } },
855 // flatten
856 .{ .tag = @enumFromInt(27), .properties = .{ .tag = .flatten, .gnu = true } },
857 // format
858 .{ .tag = @enumFromInt(28), .properties = .{ .tag = .format, .gnu = true } },
859 // format_arg
860 .{ .tag = @enumFromInt(29), .properties = .{ .tag = .format_arg, .gnu = true } },
861 // gnu_inline
862 .{ .tag = @enumFromInt(30), .properties = .{ .tag = .gnu_inline, .gnu = true } },
863 // hot
864 .{ .tag = @enumFromInt(31), .properties = .{ .tag = .hot, .gnu = true } },
865 // ifunc
866 .{ .tag = @enumFromInt(32), .properties = .{ .tag = .ifunc, .gnu = true } },
867 // interrupt
868 .{ .tag = @enumFromInt(33), .properties = .{ .tag = .interrupt, .gnu = true } },
869 // interrupt_handler
870 .{ .tag = @enumFromInt(34), .properties = .{ .tag = .interrupt_handler, .gnu = true } },
871 // jitintrinsic
872 .{ .tag = @enumFromInt(35), .properties = .{ .tag = .jitintrinsic, .declspec = true } },
873 // leaf
874 .{ .tag = @enumFromInt(36), .properties = .{ .tag = .leaf, .gnu = true } },
875 // malloc
876 .{ .tag = @enumFromInt(37), .properties = .{ .tag = .malloc, .gnu = true } },
877 // may_alias
878 .{ .tag = @enumFromInt(38), .properties = .{ .tag = .may_alias, .gnu = true } },
879 // maybe_unused
880 .{ .tag = @enumFromInt(39), .properties = .{ .tag = .unused, .c23 = true } },
881 // mode
882 .{ .tag = @enumFromInt(40), .properties = .{ .tag = .mode, .gnu = true } },
883 // naked
884 .{ .tag = @enumFromInt(41), .properties = .{ .tag = .naked, .declspec = true } },
885 // no_address_safety_analysis
886 .{ .tag = @enumFromInt(42), .properties = .{ .tag = .no_address_safety_analysis, .gnu = true } },
887 // no_icf
888 .{ .tag = @enumFromInt(43), .properties = .{ .tag = .no_icf, .gnu = true } },
889 // no_instrument_function
890 .{ .tag = @enumFromInt(44), .properties = .{ .tag = .no_instrument_function, .gnu = true } },
891 // no_profile_instrument_function
892 .{ .tag = @enumFromInt(45), .properties = .{ .tag = .no_profile_instrument_function, .gnu = true } },
893 // no_reorder
894 .{ .tag = @enumFromInt(46), .properties = .{ .tag = .no_reorder, .gnu = true } },
895 // no_sanitize
896 .{ .tag = @enumFromInt(47), .properties = .{ .tag = .no_sanitize, .gnu = true } },
897 // no_sanitize_address
898 .{ .tag = @enumFromInt(48), .properties = .{ .tag = .no_sanitize_address, .gnu = true, .declspec = true } },
899 // no_sanitize_coverage
900 .{ .tag = @enumFromInt(49), .properties = .{ .tag = .no_sanitize_coverage, .gnu = true } },
901 // no_sanitize_thread
902 .{ .tag = @enumFromInt(50), .properties = .{ .tag = .no_sanitize_thread, .gnu = true } },
903 // no_sanitize_undefined
904 .{ .tag = @enumFromInt(51), .properties = .{ .tag = .no_sanitize_undefined, .gnu = true } },
905 // no_split_stack
906 .{ .tag = @enumFromInt(52), .properties = .{ .tag = .no_split_stack, .gnu = true } },
907 // no_stack_limit
908 .{ .tag = @enumFromInt(53), .properties = .{ .tag = .no_stack_limit, .gnu = true } },
909 // no_stack_protector
910 .{ .tag = @enumFromInt(54), .properties = .{ .tag = .no_stack_protector, .gnu = true } },
911 // noalias
912 .{ .tag = @enumFromInt(55), .properties = .{ .tag = .@"noalias", .declspec = true } },
913 // noclone
914 .{ .tag = @enumFromInt(56), .properties = .{ .tag = .noclone, .gnu = true } },
915 // nocommon
916 .{ .tag = @enumFromInt(57), .properties = .{ .tag = .nocommon, .gnu = true } },
917 // nodiscard
918 .{ .tag = @enumFromInt(58), .properties = .{ .tag = .nodiscard, .c23 = true } },
919 // noinit
920 .{ .tag = @enumFromInt(59), .properties = .{ .tag = .noinit, .gnu = true } },
921 // noinline
922 .{ .tag = @enumFromInt(60), .properties = .{ .tag = .@"noinline", .gnu = true, .declspec = true } },
923 // noipa
924 .{ .tag = @enumFromInt(61), .properties = .{ .tag = .noipa, .gnu = true } },
925 // nonstring
926 .{ .tag = @enumFromInt(62), .properties = .{ .tag = .nonstring, .gnu = true } },
927 // noplt
928 .{ .tag = @enumFromInt(63), .properties = .{ .tag = .noplt, .gnu = true } },
929 // noreturn
930 .{ .tag = @enumFromInt(64), .properties = .{ .tag = .@"noreturn", .c23 = true, .gnu = true, .declspec = true } },
931 // packed
932 .{ .tag = @enumFromInt(65), .properties = .{ .tag = .@"packed", .gnu = true } },
933 // patchable_function_entry
934 .{ .tag = @enumFromInt(66), .properties = .{ .tag = .patchable_function_entry, .gnu = true } },
935 // persistent
936 .{ .tag = @enumFromInt(67), .properties = .{ .tag = .persistent, .gnu = true } },
937 // process
938 .{ .tag = @enumFromInt(68), .properties = .{ .tag = .process, .declspec = true } },
939 // pure
940 .{ .tag = @enumFromInt(69), .properties = .{ .tag = .pure, .gnu = true } },
941 // reproducible
942 .{ .tag = @enumFromInt(70), .properties = .{ .tag = .reproducible, .c23 = true } },
943 // restrict
944 .{ .tag = @enumFromInt(71), .properties = .{ .tag = .restrict, .declspec = true } },
945 // retain
946 .{ .tag = @enumFromInt(72), .properties = .{ .tag = .retain, .gnu = true } },
947 // returns_nonnull
948 .{ .tag = @enumFromInt(73), .properties = .{ .tag = .returns_nonnull, .gnu = true } },
949 // returns_twice
950 .{ .tag = @enumFromInt(74), .properties = .{ .tag = .returns_twice, .gnu = true } },
951 // safebuffers
952 .{ .tag = @enumFromInt(75), .properties = .{ .tag = .safebuffers, .declspec = true } },
953 // scalar_storage_order
954 .{ .tag = @enumFromInt(76), .properties = .{ .tag = .scalar_storage_order, .gnu = true } },
955 // section
956 .{ .tag = @enumFromInt(77), .properties = .{ .tag = .section, .gnu = true } },
957 // selectany
958 .{ .tag = @enumFromInt(78), .properties = .{ .tag = .selectany, .declspec = true } },
959 // sentinel
960 .{ .tag = @enumFromInt(79), .properties = .{ .tag = .sentinel, .gnu = true } },
961 // simd
962 .{ .tag = @enumFromInt(80), .properties = .{ .tag = .simd, .gnu = true } },
963 // spectre
964 .{ .tag = @enumFromInt(81), .properties = .{ .tag = .spectre, .declspec = true } },
965 // stack_protect
966 .{ .tag = @enumFromInt(82), .properties = .{ .tag = .stack_protect, .gnu = true } },
967 // symver
968 .{ .tag = @enumFromInt(83), .properties = .{ .tag = .symver, .gnu = true } },
969 // target
970 .{ .tag = @enumFromInt(84), .properties = .{ .tag = .target, .gnu = true } },
971 // target_clones
972 .{ .tag = @enumFromInt(85), .properties = .{ .tag = .target_clones, .gnu = true } },
973 // thread
974 .{ .tag = @enumFromInt(86), .properties = .{ .tag = .thread, .declspec = true } },
975 // tls_model
976 .{ .tag = @enumFromInt(87), .properties = .{ .tag = .tls_model, .gnu = true } },
977 // transparent_union
978 .{ .tag = @enumFromInt(88), .properties = .{ .tag = .transparent_union, .gnu = true } },
979 // unavailable
980 .{ .tag = @enumFromInt(89), .properties = .{ .tag = .unavailable, .gnu = true } },
981 // uninitialized
982 .{ .tag = @enumFromInt(90), .properties = .{ .tag = .uninitialized, .gnu = true } },
983 // unsequenced
984 .{ .tag = @enumFromInt(91), .properties = .{ .tag = .unsequenced, .c23 = true } },
985 // unused
986 .{ .tag = @enumFromInt(92), .properties = .{ .tag = .unused, .gnu = true } },
987 // used
988 .{ .tag = @enumFromInt(93), .properties = .{ .tag = .used, .gnu = true } },
989 // uuid
990 .{ .tag = @enumFromInt(94), .properties = .{ .tag = .uuid, .declspec = true } },
991 // vector_size
992 .{ .tag = @enumFromInt(95), .properties = .{ .tag = .vector_size, .gnu = true } },
993 // visibility
994 .{ .tag = @enumFromInt(96), .properties = .{ .tag = .visibility, .gnu = true } },
995 // warn_if_not_aligned
996 .{ .tag = @enumFromInt(97), .properties = .{ .tag = .warn_if_not_aligned, .gnu = true } },
997 // warn_unused_result
998 .{ .tag = @enumFromInt(98), .properties = .{ .tag = .warn_unused_result, .gnu = true } },
999 // warning
1000 .{ .tag = @enumFromInt(99), .properties = .{ .tag = .warning, .gnu = true } },
1001 // weak
1002 .{ .tag = @enumFromInt(100), .properties = .{ .tag = .weak, .gnu = true } },
1003 // weakref
1004 .{ .tag = @enumFromInt(101), .properties = .{ .tag = .weakref, .gnu = true } },
1005 // zero_call_used_regs
1006 .{ .tag = @enumFromInt(102), .properties = .{ .tag = .zero_call_used_regs, .gnu = true } },
1007 };
1008};
1009};
1010}
lib/compiler/aro/aro/Builtins.zig created+397
......@@ -0,0 +1,397 @@
1const std = @import("std");
2const Compilation = @import("Compilation.zig");
3const Type = @import("Type.zig");
4const TypeDescription = @import("Builtins/TypeDescription.zig");
5const target_util = @import("target.zig");
6const StringId = @import("StringInterner.zig").StringId;
7const LangOpts = @import("LangOpts.zig");
8const Parser = @import("Parser.zig");
9
10const Properties = @import("Builtins/Properties.zig");
11pub const Builtin = @import("Builtins/Builtin.zig").with(Properties);
12
13const Expanded = struct {
14 ty: Type,
15 builtin: Builtin,
16};
17
18const NameToTypeMap = std.StringHashMapUnmanaged(Type);
19
20const Builtins = @This();
21
22_name_to_type_map: NameToTypeMap = .{},
23
24pub fn deinit(b: *Builtins, gpa: std.mem.Allocator) void {
25 b._name_to_type_map.deinit(gpa);
26}
27
28fn specForSize(comp: *const Compilation, size_bits: u32) Type.Builder.Specifier {
29 var ty = Type{ .specifier = .short };
30 if (ty.sizeof(comp).? * 8 == size_bits) return .short;
31
32 ty.specifier = .int;
33 if (ty.sizeof(comp).? * 8 == size_bits) return .int;
34
35 ty.specifier = .long;
36 if (ty.sizeof(comp).? * 8 == size_bits) return .long;
37
38 ty.specifier = .long_long;
39 if (ty.sizeof(comp).? * 8 == size_bits) return .long_long;
40
41 unreachable;
42}
43
44fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *const Compilation, allocator: std.mem.Allocator) !Type {
45 var builder: Type.Builder = .{ .error_on_invalid = true };
46 var require_native_int32 = false;
47 var require_native_int64 = false;
48 for (desc.prefix) |prefix| {
49 switch (prefix) {
50 .L => builder.combine(undefined, .long, 0) catch unreachable,
51 .LL => {
52 builder.combine(undefined, .long, 0) catch unreachable;
53 builder.combine(undefined, .long, 0) catch unreachable;
54 },
55 .LLL => {
56 switch (builder.specifier) {
57 .none => builder.specifier = .int128,
58 .signed => builder.specifier = .sint128,
59 .unsigned => builder.specifier = .uint128,
60 else => unreachable,
61 }
62 },
63 .Z => require_native_int32 = true,
64 .W => require_native_int64 = true,
65 .N => {
66 std.debug.assert(desc.spec == .i);
67 if (!target_util.isLP64(comp.target)) {
68 builder.combine(undefined, .long, 0) catch unreachable;
69 }
70 },
71 .O => {
72 builder.combine(undefined, .long, 0) catch unreachable;
73 if (comp.target.os.tag != .opencl) {
74 builder.combine(undefined, .long, 0) catch unreachable;
75 }
76 },
77 .S => builder.combine(undefined, .signed, 0) catch unreachable,
78 .U => builder.combine(undefined, .unsigned, 0) catch unreachable,
79 .I => {
80 // Todo: compile-time constant integer
81 },
82 }
83 }
84 switch (desc.spec) {
85 .v => builder.combine(undefined, .void, 0) catch unreachable,
86 .b => builder.combine(undefined, .bool, 0) catch unreachable,
87 .c => builder.combine(undefined, .char, 0) catch unreachable,
88 .s => builder.combine(undefined, .short, 0) catch unreachable,
89 .i => {
90 if (require_native_int32) {
91 builder.specifier = specForSize(comp, 32);
92 } else if (require_native_int64) {
93 builder.specifier = specForSize(comp, 64);
94 } else {
95 switch (builder.specifier) {
96 .int128, .sint128, .uint128 => {},
97 else => builder.combine(undefined, .int, 0) catch unreachable,
98 }
99 }
100 },
101 .h => builder.combine(undefined, .fp16, 0) catch unreachable,
102 .x => {
103 // Todo: _Float16
104 return .{ .specifier = .invalid };
105 },
106 .y => {
107 // Todo: __bf16
108 return .{ .specifier = .invalid };
109 },
110 .f => builder.combine(undefined, .float, 0) catch unreachable,
111 .d => {
112 if (builder.specifier == .long_long) {
113 builder.specifier = .float128;
114 } else {
115 builder.combine(undefined, .double, 0) catch unreachable;
116 }
117 },
118 .z => {
119 std.debug.assert(builder.specifier == .none);
120 builder.specifier = Type.Builder.fromType(comp.types.size);
121 },
122 .w => {
123 std.debug.assert(builder.specifier == .none);
124 builder.specifier = Type.Builder.fromType(comp.types.wchar);
125 },
126 .F => {
127 std.debug.assert(builder.specifier == .none);
128 builder.specifier = Type.Builder.fromType(comp.types.ns_constant_string.ty);
129 },
130 .G => {
131 // Todo: id
132 return .{ .specifier = .invalid };
133 },
134 .H => {
135 // Todo: SEL
136 return .{ .specifier = .invalid };
137 },
138 .M => {
139 // Todo: struct objc_super
140 return .{ .specifier = .invalid };
141 },
142 .a => {
143 std.debug.assert(builder.specifier == .none);
144 std.debug.assert(desc.suffix.len == 0);
145 builder.specifier = Type.Builder.fromType(comp.types.va_list);
146 },
147 .A => {
148 std.debug.assert(builder.specifier == .none);
149 std.debug.assert(desc.suffix.len == 0);
150 var va_list = comp.types.va_list;
151 if (va_list.isArray()) va_list.decayArray();
152 builder.specifier = Type.Builder.fromType(va_list);
153 },
154 .V => |element_count| {
155 std.debug.assert(desc.suffix.len == 0);
156 const child_desc = it.next().?;
157 const child_ty = try createType(child_desc, undefined, comp, allocator);
158 const arr_ty = try allocator.create(Type.Array);
159 arr_ty.* = .{
160 .len = element_count,
161 .elem = child_ty,
162 };
163 const vector_ty = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
164 builder.specifier = Type.Builder.fromType(vector_ty);
165 },
166 .q => {
167 // Todo: scalable vector
168 return .{ .specifier = .invalid };
169 },
170 .E => {
171 // Todo: ext_vector (OpenCL vector)
172 return .{ .specifier = .invalid };
173 },
174 .X => |child| {
175 builder.combine(undefined, .complex, 0) catch unreachable;
176 switch (child) {
177 .float => builder.combine(undefined, .float, 0) catch unreachable,
178 .double => builder.combine(undefined, .double, 0) catch unreachable,
179 .longdouble => {
180 builder.combine(undefined, .long, 0) catch unreachable;
181 builder.combine(undefined, .double, 0) catch unreachable;
182 },
183 }
184 },
185 .Y => {
186 std.debug.assert(builder.specifier == .none);
187 std.debug.assert(desc.suffix.len == 0);
188 builder.specifier = Type.Builder.fromType(comp.types.ptrdiff);
189 },
190 .P => {
191 std.debug.assert(builder.specifier == .none);
192 if (comp.types.file.specifier == .invalid) {
193 return comp.types.file;
194 }
195 builder.specifier = Type.Builder.fromType(comp.types.file);
196 },
197 .J => {
198 std.debug.assert(builder.specifier == .none);
199 std.debug.assert(desc.suffix.len == 0);
200 if (comp.types.jmp_buf.specifier == .invalid) {
201 return comp.types.jmp_buf;
202 }
203 builder.specifier = Type.Builder.fromType(comp.types.jmp_buf);
204 },
205 .SJ => {
206 std.debug.assert(builder.specifier == .none);
207 std.debug.assert(desc.suffix.len == 0);
208 if (comp.types.sigjmp_buf.specifier == .invalid) {
209 return comp.types.sigjmp_buf;
210 }
211 builder.specifier = Type.Builder.fromType(comp.types.sigjmp_buf);
212 },
213 .K => {
214 std.debug.assert(builder.specifier == .none);
215 if (comp.types.ucontext_t.specifier == .invalid) {
216 return comp.types.ucontext_t;
217 }
218 builder.specifier = Type.Builder.fromType(comp.types.ucontext_t);
219 },
220 .p => {
221 std.debug.assert(builder.specifier == .none);
222 std.debug.assert(desc.suffix.len == 0);
223 builder.specifier = Type.Builder.fromType(comp.types.pid_t);
224 },
225 .@"!" => return .{ .specifier = .invalid },
226 }
227 for (desc.suffix) |suffix| {
228 switch (suffix) {
229 .@"*" => |address_space| {
230 _ = address_space; // TODO: handle address space
231 const elem_ty = try allocator.create(Type);
232 elem_ty.* = builder.finish(undefined) catch unreachable;
233 const ty = Type{
234 .specifier = .pointer,
235 .data = .{ .sub_type = elem_ty },
236 };
237 builder.qual = .{};
238 builder.specifier = Type.Builder.fromType(ty);
239 },
240 .C => builder.qual.@"const" = 0,
241 .D => builder.qual.@"volatile" = 0,
242 .R => builder.qual.restrict = 0,
243 }
244 }
245 return builder.finish(undefined) catch unreachable;
246}
247
248fn createBuiltin(comp: *const Compilation, builtin: Builtin, type_arena: std.mem.Allocator) !Type {
249 var it = TypeDescription.TypeIterator.init(builtin.properties.param_str);
250
251 const ret_ty_desc = it.next().?;
252 if (ret_ty_desc.spec == .@"!") {
253 // Todo: handle target-dependent definition
254 }
255 const ret_ty = try createType(ret_ty_desc, &it, comp, type_arena);
256 var param_count: usize = 0;
257 var params: [Builtin.max_param_count]Type.Func.Param = undefined;
258 while (it.next()) |desc| : (param_count += 1) {
259 params[param_count] = .{ .name_tok = 0, .ty = try createType(desc, &it, comp, type_arena), .name = .empty };
260 }
261
262 const duped_params = try type_arena.dupe(Type.Func.Param, params[0..param_count]);
263 const func = try type_arena.create(Type.Func);
264
265 func.* = .{
266 .return_type = ret_ty,
267 .params = duped_params,
268 };
269 return .{
270 .specifier = if (builtin.properties.isVarArgs()) .var_args_func else .func,
271 .data = .{ .func = func },
272 };
273}
274
275/// Asserts that the builtin has already been created
276pub fn lookup(b: *const Builtins, name: []const u8) Expanded {
277 const builtin = Builtin.fromName(name).?;
278 const ty = b._name_to_type_map.get(name).?;
279 return .{
280 .builtin = builtin,
281 .ty = ty,
282 };
283}
284
285pub fn getOrCreate(b: *Builtins, comp: *Compilation, name: []const u8, type_arena: std.mem.Allocator) !?Expanded {
286 const ty = b._name_to_type_map.get(name) orelse {
287 const builtin = Builtin.fromName(name) orelse return null;
288 if (!comp.hasBuiltinFunction(builtin)) return null;
289
290 try b._name_to_type_map.ensureUnusedCapacity(comp.gpa, 1);
291 const ty = try createBuiltin(comp, builtin, type_arena);
292 b._name_to_type_map.putAssumeCapacity(name, ty);
293
294 return .{
295 .builtin = builtin,
296 .ty = ty,
297 };
298 };
299 const builtin = Builtin.fromName(name).?;
300 return .{
301 .builtin = builtin,
302 .ty = ty,
303 };
304}
305
306pub const Iterator = struct {
307 index: u16 = 1,
308 name_buf: [Builtin.longest_name]u8 = undefined,
309
310 pub const Entry = struct {
311 /// Memory of this slice is overwritten on every call to `next`
312 name: []const u8,
313 builtin: Builtin,
314 };
315
316 pub fn next(self: *Iterator) ?Entry {
317 if (self.index > Builtin.data.len) return null;
318 const index = self.index;
319 const data_index = index - 1;
320 self.index += 1;
321 return .{
322 .name = Builtin.nameFromUniqueIndex(index, &self.name_buf),
323 .builtin = Builtin.data[data_index],
324 };
325 }
326};
327
328test Iterator {
329 var it = Iterator{};
330
331 var seen = std.StringHashMap(Builtin).init(std.testing.allocator);
332 defer seen.deinit();
333
334 var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);
335 defer arena_state.deinit();
336 const arena = arena_state.allocator();
337
338 while (it.next()) |entry| {
339 const index = Builtin.uniqueIndex(entry.name).?;
340 var buf: [Builtin.longest_name]u8 = undefined;
341 const name_from_index = Builtin.nameFromUniqueIndex(index, &buf);
342 try std.testing.expectEqualStrings(entry.name, name_from_index);
343
344 if (seen.contains(entry.name)) {
345 std.debug.print("iterated over {s} twice\n", .{entry.name});
346 std.debug.print("current data: {}\n", .{entry.builtin});
347 std.debug.print("previous data: {}\n", .{seen.get(entry.name).?});
348 return error.TestExpectedUniqueEntries;
349 }
350 try seen.put(try arena.dupe(u8, entry.name), entry.builtin);
351 }
352 try std.testing.expectEqual(@as(usize, Builtin.data.len), seen.count());
353}
354
355test "All builtins" {
356 var comp = Compilation.init(std.testing.allocator);
357 defer comp.deinit();
358 _ = try comp.generateBuiltinMacros(.include_system_defines);
359 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
360 defer arena.deinit();
361
362 const type_arena = arena.allocator();
363
364 var builtin_it = Iterator{};
365 while (builtin_it.next()) |entry| {
366 const name = try type_arena.dupe(u8, entry.name);
367 if (try comp.builtins.getOrCreate(&comp, name, type_arena)) |func_ty| {
368 const get_again = (try comp.builtins.getOrCreate(&comp, name, std.testing.failing_allocator)).?;
369 const found_by_lookup = comp.builtins.lookup(name);
370 try std.testing.expectEqual(func_ty.builtin.tag, get_again.builtin.tag);
371 try std.testing.expectEqual(func_ty.builtin.tag, found_by_lookup.builtin.tag);
372 }
373 }
374}
375
376test "Allocation failures" {
377 const Test = struct {
378 fn testOne(allocator: std.mem.Allocator) !void {
379 var comp = Compilation.init(allocator);
380 defer comp.deinit();
381 _ = try comp.generateBuiltinMacros(.include_system_defines);
382 var arena = std.heap.ArenaAllocator.init(comp.gpa);
383 defer arena.deinit();
384
385 const type_arena = arena.allocator();
386
387 const num_builtins = 40;
388 var builtin_it = Iterator{};
389 for (0..num_builtins) |_| {
390 const entry = builtin_it.next().?;
391 _ = try comp.builtins.getOrCreate(&comp, entry.name, type_arena);
392 }
393 }
394 };
395
396 try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.testOne, .{});
397}
lib/compiler/aro/aro/Builtins/Builtin.zig created+13144
......@@ -0,0 +1,13144 @@
1//! Autogenerated by GenerateDef from deps/aro/aro/Builtins/Builtin.def, do not edit
2
3const std = @import("std");
4
5pub fn with(comptime Properties: type) type {
6return struct {
7const TargetSet = Properties.TargetSet;
8pub const max_param_count = 12;
9
10tag: Tag,
11properties: Properties,
12
13/// Integer starting at 0 derived from the unique index,
14/// corresponds with the data array index.
15pub const Tag = enum(u16) { _ };
16
17const Self = @This();
18
19pub fn fromName(name: []const u8) ?@This() {
20 const data_index = tagFromName(name) orelse return null;
21 return data[@intFromEnum(data_index)];
22}
23
24pub fn tagFromName(name: []const u8) ?Tag {
25 const unique_index = uniqueIndex(name) orelse return null;
26 return @enumFromInt(unique_index - 1);
27}
28
29pub fn fromTag(tag: Tag) @This() {
30 return data[@intFromEnum(tag)];
31}
32
33pub fn nameFromTagIntoBuf(tag: Tag, name_buf: []u8) []u8 {
34 std.debug.assert(name_buf.len >= longest_name);
35 const unique_index = @intFromEnum(tag) + 1;
36 return nameFromUniqueIndex(unique_index, name_buf);
37}
38
39pub fn nameFromTag(tag: Tag) NameBuf {
40 var name_buf: NameBuf = undefined;
41 const unique_index = @intFromEnum(tag) + 1;
42 const name = nameFromUniqueIndex(unique_index, &name_buf.buf);
43 name_buf.len = @intCast(name.len);
44 return name_buf;
45}
46
47pub const NameBuf = struct {
48 buf: [longest_name]u8 = undefined,
49 len: std.math.IntFittingRange(0, longest_name),
50
51 pub fn span(self: *const NameBuf) []const u8 {
52 return self.buf[0..self.len];
53 }
54};
55
56pub fn exists(name: []const u8) bool {
57 if (name.len < shortest_name or name.len > longest_name) return false;
58
59 var index: u16 = 0;
60 for (name) |c| {
61 index = findInList(dafsa[index].child_index, c) orelse return false;
62 }
63 return dafsa[index].end_of_word;
64}
65
66pub const shortest_name = 3;
67pub const longest_name = 43;
68
69/// Search siblings of `first_child_index` for the `char`
70/// If found, returns the index of the node within the `dafsa` array.
71/// Otherwise, returns `null`.
72pub fn findInList(first_child_index: u16, char: u8) ?u16 {
73 var index = first_child_index;
74 while (true) {
75 if (dafsa[index].char == char) return index;
76 if (dafsa[index].end_of_list) return null;
77 index += 1;
78 }
79 unreachable;
80}
81
82/// Returns a unique (minimal perfect hash) index (starting at 1) for the `name`,
83/// or null if the name was not found.
84pub fn uniqueIndex(name: []const u8) ?u16 {
85 if (name.len < shortest_name or name.len > longest_name) return null;
86
87 var index: u16 = 0;
88 var node_index: u16 = 0;
89
90 for (name) |c| {
91 const child_index = findInList(dafsa[node_index].child_index, c) orelse return null;
92 var sibling_index = dafsa[node_index].child_index;
93 while (true) {
94 const sibling_c = dafsa[sibling_index].char;
95 std.debug.assert(sibling_c != 0);
96 if (sibling_c < c) {
97 index += dafsa[sibling_index].number;
98 }
99 if (dafsa[sibling_index].end_of_list) break;
100 sibling_index += 1;
101 }
102 node_index = child_index;
103 if (dafsa[node_index].end_of_word) index += 1;
104 }
105
106 if (!dafsa[node_index].end_of_word) return null;
107
108 return index;
109}
110
111/// Returns a slice of `buf` with the name associated with the given `index`.
112/// This function should only be called with an `index` that
113/// is already known to exist within the `dafsa`, e.g. an index
114/// returned from `uniqueIndex`.
115pub fn nameFromUniqueIndex(index: u16, buf: []u8) []u8 {
116 std.debug.assert(index >= 1 and index <= data.len);
117
118 var node_index: u16 = 0;
119 var count: u16 = index;
120 var fbs = std.io.fixedBufferStream(buf);
121 const w = fbs.writer();
122
123 while (true) {
124 var sibling_index = dafsa[node_index].child_index;
125 while (true) {
126 if (dafsa[sibling_index].number > 0 and dafsa[sibling_index].number < count) {
127 count -= dafsa[sibling_index].number;
128 } else {
129 w.writeByte(dafsa[sibling_index].char) catch unreachable;
130 node_index = sibling_index;
131 if (dafsa[node_index].end_of_word) {
132 count -= 1;
133 }
134 break;
135 }
136
137 if (dafsa[sibling_index].end_of_list) break;
138 sibling_index += 1;
139 }
140 if (count == 0) break;
141 }
142
143 return fbs.getWritten();
144}
145
146/// We're 1 bit shy of being able to fit this in a u32:
147/// - char only contains 0-9, a-z, A-Z, and _, so it could use a enum(u6) with a way to convert <-> u8
148/// (note: this would have a performance cost that may make the u32 not worth it)
149/// - number has a max value of > 2047 and < 4095 (the first _ node has the largest number),
150/// so it could fit into a u12
151/// - child_index currently has a max of > 4095 and < 8191, so it could fit into a u13
152///
153/// with the end_of_word/end_of_list 2 bools, that makes 33 bits total
154const Node = packed struct(u64) {
155 char: u8,
156 /// Nodes are numbered with "an integer which gives the number of words that
157 /// would be accepted by the automaton starting from that state." This numbering
158 /// allows calculating "a one-to-one correspondence between the integers 1 to L
159 /// (L is the number of words accepted by the automaton) and the words themselves."
160 ///
161 /// Essentially, this allows us to have a minimal perfect hashing scheme such that
162 /// it's possible to store & lookup the properties of each builtin using a separate array.
163 number: u16,
164 /// If true, this node is the end of a valid builtin.
165 /// Note: This does not necessarily mean that this node does not have child nodes.
166 end_of_word: bool,
167 /// If true, this node is the end of a sibling list.
168 /// If false, then (index + 1) will contain the next sibling.
169 end_of_list: bool,
170 /// Padding bits to get to u64, unsure if there's some way to use these to improve something.
171 _extra: u22 = 0,
172 /// Index of the first child of this node.
173 child_index: u16,
174};
175
176const dafsa = [_]Node{
177 .{ .char = 0, .end_of_word = false, .end_of_list = true, .number = 0, .child_index = 1 },
178 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3639, .child_index = 19 },
179 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 32 },
180 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 37 },
181 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 82, .child_index = 39 },
182 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 50 },
183 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 33, .child_index = 52 },
184 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 62 },
185 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 63 },
186 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 64 },
187 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 67 },
188 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 73 },
189 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 76 },
190 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 78 },
191 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 17, .child_index = 80 },
192 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 54, .child_index = 83 },
193 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 92 },
194 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 96 },
195 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 100 },
196 .{ .char = 'B', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 102 },
197 .{ .char = 'E', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 103 },
198 .{ .char = 'I', .end_of_word = false, .end_of_list = false, .number = 29, .child_index = 104 },
199 .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 105 },
200 .{ .char = 'R', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 106 },
201 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3563, .child_index = 107 },
202 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 125 },
203 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 127 },
204 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 129 },
205 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 130 },
206 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 131 },
207 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 133 },
208 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 134 },
209 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 135 },
210 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 },
211 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 138 },
212 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 140 },
213 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 141 },
214 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 142 },
215 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 144 },
216 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 145 },
217 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 151 },
218 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 },
219 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 152 },
220 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 154 },
221 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 155 },
222 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 156 },
223 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 159 },
224 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 161 },
225 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 162 },
226 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 164 },
227 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 165 },
228 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 166 },
229 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 168 },
230 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 169 },
231 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 170 },
232 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 171 },
233 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 172 },
234 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 175 },
235 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 },
236 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 177 },
237 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 178 },
238 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 179 },
239 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 180 },
240 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 181 },
241 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 182 },
242 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 183 },
243 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 184 },
244 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 194 },
245 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 195 },
246 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 196 },
247 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 197 },
248 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 199 },
249 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 201 },
250 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 203 },
251 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 204 },
252 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 205 },
253 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 206 },
254 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 207 },
255 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 209 },
256 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 },
257 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 211 },
258 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 213 },
259 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 214 },
260 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 215 },
261 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 216 },
262 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 217 },
263 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 218 },
264 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 220 },
265 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 },
266 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 151 },
267 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 178 },
268 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 31, .child_index = 221 },
269 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 223 },
270 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 196 },
271 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 224 },
272 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 226 },
273 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 227 },
274 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 228 },
275 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 },
276 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 231 },
277 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 235 },
278 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 236 },
279 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 237 },
280 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 },
281 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 239 },
282 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 240 },
283 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 241 },
284 .{ .char = 'G', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 242 },
285 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 34, .child_index = 243 },
286 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2967, .child_index = 248 },
287 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 249 },
288 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 252 },
289 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 255 },
290 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 257 },
291 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 259 },
292 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 260 },
293 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 390, .child_index = 262 },
294 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 264 },
295 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 265 },
296 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 113, .child_index = 266 },
297 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 269 },
298 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 270 },
299 .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 271 },
300 .{ .char = 'x', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 273 },
301 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 274 },
302 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 275 },
303 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 276 },
304 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 277 },
305 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 278 },
306 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 279 },
307 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 281 },
308 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 282 },
309 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 283 },
310 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 284 },
311 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 285 },
312 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 286 },
313 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
314 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 287 },
315 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 288 },
316 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 289 },
317 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 223 },
318 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 290 },
319 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 },
320 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 },
321 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 293 },
322 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 294 },
323 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 },
324 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 295 },
325 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 296 },
326 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 140 },
327 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 164 },
328 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 },
329 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 298 },
330 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 },
331 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 300 },
332 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 296 },
333 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 301 },
334 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 302 },
335 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 },
336 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 209 },
337 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 306 },
338 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 307 },
339 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 223 },
340 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 151 },
341 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 223 },
342 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 308 },
343 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 },
344 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 312 },
345 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 294 },
346 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 316 },
347 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 317 },
348 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 318 },
349 .{ .char = 'a', .end_of_word = true, .end_of_list = false, .number = 6, .child_index = 319 },
350 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 206 },
351 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 322 },
352 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 },
353 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 },
354 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 324 },
355 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 327 },
356 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 328 },
357 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 329 },
358 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 330 },
359 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 331 },
360 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 332 },
361 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 333 },
362 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 334 },
363 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 335 },
364 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 336 },
365 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 337 },
366 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 338 },
367 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 339 },
368 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 341 },
369 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 342 },
370 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 343 },
371 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
372 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 345 },
373 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 346 },
374 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 194 },
375 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 201 },
376 .{ .char = 'g', .end_of_word = true, .end_of_list = false, .number = 15, .child_index = 347 },
377 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 },
378 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 353 },
379 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 354 },
380 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 295 },
381 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 355 },
382 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 360 },
383 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
384 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 363 },
385 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 364 },
386 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
387 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 365 },
388 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 203 },
389 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 366 },
390 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 368 },
391 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 370 },
392 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 371 },
393 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 372 },
394 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 374 },
395 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 375 },
396 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 },
397 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 176 },
398 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 377 },
399 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 379 },
400 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 },
401 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 338 },
402 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 342 },
403 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 389 },
404 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 390 },
405 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 393 },
406 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 },
407 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 },
408 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 327 },
409 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 220 },
410 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 },
411 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 },
412 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 394 },
413 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 397 },
414 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 398 },
415 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
416 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 399 },
417 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 400 },
418 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 401 },
419 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 402 },
420 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 275 },
421 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 403 },
422 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 404 },
423 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 405 },
424 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 406 },
425 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 407 },
426 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 17, .child_index = 408 },
427 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 409 },
428 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 410 },
429 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 411 },
430 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 },
431 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
432 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 238 },
433 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 413 },
434 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 415 },
435 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 170 },
436 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 416 },
437 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 418 },
438 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 419 },
439 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 420 },
440 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 421 },
441 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 422 },
442 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 423 },
443 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 424 },
444 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 425 },
445 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 427 },
446 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 428 },
447 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 429 },
448 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 430 },
449 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 431 },
450 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 433 },
451 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 434 },
452 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 435 },
453 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 289 },
454 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 436 },
455 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 437 },
456 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 438 },
457 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
458 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 439 },
459 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 },
460 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 440 },
461 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 441 },
462 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 443 },
463 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
464 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 },
465 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 444 },
466 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 445 },
467 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 446 },
468 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
469 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
470 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 },
471 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
472 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 452 },
473 .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
474 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
475 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
476 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
477 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 296 },
478 .{ .char = 'j', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
479 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 453 },
480 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
481 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
482 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
483 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 301 },
484 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 298 },
485 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
486 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
487 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
488 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
489 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
490 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
491 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
492 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 454 },
493 .{ .char = 'm', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
494 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 455 },
495 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 456 },
496 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
497 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
498 .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
499 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
500 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
501 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 },
502 .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
503 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 },
504 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 },
505 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 },
506 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 461 },
507 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 },
508 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 462 },
509 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
510 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 464 },
511 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 466 },
512 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 467 },
513 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 468 },
514 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 469 },
515 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 470 },
516 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 471 },
517 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 472 },
518 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 473 },
519 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 474 },
520 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 336 },
521 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
522 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 },
523 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 475 },
524 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 476 },
525 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
526 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
527 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
528 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
529 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 374 },
530 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 },
531 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 478 },
532 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 479 },
533 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 480 },
534 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 484 },
535 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 485 },
536 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 486 },
537 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
538 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
539 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
540 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 487 },
541 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 488 },
542 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 490 },
543 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 491 },
544 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 492 },
545 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 },
546 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
547 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 493 },
548 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 494 },
549 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 495 },
550 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
551 .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 497 },
552 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 498 },
553 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 499 },
554 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 292 },
555 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 485 },
556 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 500 },
557 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 505 },
558 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 506 },
559 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 507 },
560 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 509 },
561 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 511 },
562 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 512 },
563 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 513 },
564 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 515 },
565 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 516 },
566 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 517 },
567 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 518 },
568 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 519 },
569 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 520 },
570 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 },
571 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 522 },
572 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 323 },
573 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 524 },
574 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 525 },
575 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 527 },
576 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 528 },
577 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 529 },
578 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 531 },
579 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 532 },
580 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 533 },
581 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 534 },
582 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 535 },
583 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 536 },
584 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 537 },
585 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 538 },
586 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 539 },
587 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 540 },
588 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 541 },
589 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
590 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 438 },
591 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 542 },
592 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 543 },
593 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
594 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 544 },
595 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 545 },
596 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 546 },
597 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
598 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 547 },
599 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 419 },
600 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 548 },
601 .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 },
602 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 550 },
603 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 540 },
604 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 551 },
605 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 540 },
606 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 552 },
607 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 553 },
608 .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
609 .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
610 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 554 },
611 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 555 },
612 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 556 },
613 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 557 },
614 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 558 },
615 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 559 },
616 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 560 },
617 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 561 },
618 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 563 },
619 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 563 },
620 .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 566 },
621 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 567 },
622 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 },
623 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
624 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
625 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
626 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
627 .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
628 .{ .char = 'o', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
629 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
630 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 570 },
631 .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
632 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 571 },
633 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
634 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
635 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
636 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
637 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
638 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 573 },
639 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
640 .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
641 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 574 },
642 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 575 },
643 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 576 },
644 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 577 },
645 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 },
646 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 578 },
647 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 },
648 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 },
649 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 581 },
650 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 582 },
651 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 },
652 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 583 },
653 .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
654 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
655 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 322 },
656 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 584 },
657 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 292 },
658 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
659 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 },
660 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
661 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 586 },
662 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 },
663 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
664 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 587 },
665 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 588 },
666 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 589 },
667 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
668 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 590 },
669 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 591 },
670 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 592 },
671 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 595 },
672 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 596 },
673 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
674 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
675 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 282 },
676 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 217 },
677 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 598 },
678 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
679 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 },
680 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 450 },
681 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 600 },
682 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
683 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 601 },
684 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 602 },
685 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
686 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 604 },
687 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 505 },
688 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 393 },
689 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 607 },
690 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 },
691 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
692 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 608 },
693 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 613 },
694 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
695 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 },
696 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
697 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 614 },
698 .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
699 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
700 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
701 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 497 },
702 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 615 },
703 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 484 },
704 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 618 },
705 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 619 },
706 .{ .char = 'F', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 620 },
707 .{ .char = 'T', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 621 },
708 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 622 },
709 .{ .char = 'E', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 623 },
710 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 624 },
711 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 625 },
712 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 626 },
713 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 627 },
714 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 628 },
715 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 629 },
716 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 630 },
717 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 631 },
718 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 632 },
719 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 633 },
720 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 634 },
721 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 635 },
722 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 636 },
723 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 637 },
724 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 638 },
725 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
726 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
727 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 499 },
728 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 639 },
729 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 520 },
730 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 641 },
731 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 642 },
732 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
733 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 643 },
734 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 644 },
735 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 645 },
736 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 646 },
737 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 647 },
738 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
739 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
740 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
741 .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 },
742 .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
743 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 650 },
744 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 651 },
745 .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
746 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
747 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 652 },
748 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
749 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
750 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 653 },
751 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
752 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 },
753 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 },
754 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
755 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 656 },
756 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
757 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
758 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
759 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
760 .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
761 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 657 },
762 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
763 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
764 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 658 },
765 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 659 },
766 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 660 },
767 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 661 },
768 .{ .char = 'o', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
769 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 662 },
770 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
771 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
772 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
773 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 206 },
774 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 },
775 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 663 },
776 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
777 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
778 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 },
779 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 },
780 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
781 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 598 },
782 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 },
783 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
784 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
785 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
786 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
787 .{ .char = 'k', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
788 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 665 },
789 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 667 },
790 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
791 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 286 },
792 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
793 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 },
794 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
795 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 668 },
796 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 669 },
797 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 670 },
798 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 671 },
799 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 672 },
800 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 673 },
801 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 674 },
802 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 675 },
803 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
804 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 676 },
805 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 677 },
806 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 678 },
807 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 679 },
808 .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 },
809 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 681 },
810 .{ .char = '0', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 },
811 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 682 },
812 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 683 },
813 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
814 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 684 },
815 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 686 },
816 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 107, .child_index = 701 },
817 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 710 },
818 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 711 },
819 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 712 },
820 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 714 },
821 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 715 },
822 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 716 },
823 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 717 },
824 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 718 },
825 .{ .char = '6', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
826 .{ .char = '4', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
827 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 719 },
828 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 720 },
829 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 206 },
830 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 721 },
831 .{ .char = 'm', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
832 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
833 .{ .char = 'h', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
834 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
835 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 353 },
836 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 722 },
837 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 723 },
838 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 722 },
839 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 724 },
840 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 524 },
841 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
842 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
843 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
844 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 },
845 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 725 },
846 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 726 },
847 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 727 },
848 .{ .char = 'C', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 728 },
849 .{ .char = 'A', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 729 },
850 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 730 },
851 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 731 },
852 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 732 },
853 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 733 },
854 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 734 },
855 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 735 },
856 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 736 },
857 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
858 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 737 },
859 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 738 },
860 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 739 },
861 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
862 .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 },
863 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 48, .child_index = 740 },
864 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 742 },
865 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 744 },
866 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 40, .child_index = 746 },
867 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 748 },
868 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 58, .child_index = 749 },
869 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 753 },
870 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 84, .child_index = 755 },
871 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 23, .child_index = 759 },
872 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 761 },
873 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 53, .child_index = 762 },
874 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 29, .child_index = 766 },
875 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 770 },
876 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 771 },
877 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 773 },
878 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 774 },
879 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 776 },
880 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 40, .child_index = 777 },
881 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 778 },
882 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 779 },
883 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 780 },
884 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 781 },
885 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 784 },
886 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 785 },
887 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 786 },
888 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 787 },
889 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 788 },
890 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 789 },
891 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 790 },
892 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 791 },
893 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 793 },
894 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 794 },
895 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 795 },
896 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
897 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 796 },
898 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 797 },
899 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 456 },
900 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 798 },
901 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 206 },
902 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 799 },
903 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 800 },
904 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 671 },
905 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 801 },
906 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 802 },
907 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 803 },
908 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 804 },
909 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 805 },
910 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 806 },
911 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 818 },
912 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 819 },
913 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 820 },
914 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 821 },
915 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
916 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 822 },
917 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 823 },
918 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 824 },
919 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 825 },
920 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 826 },
921 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 827 },
922 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 828 },
923 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 26, .child_index = 830 },
924 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 834 },
925 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 835 },
926 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 34, .child_index = 836 },
927 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 840 },
928 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 841 },
929 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 842 },
930 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 844 },
931 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 846 },
932 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 72, .child_index = 847 },
933 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 835 },
934 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 849 },
935 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 850 },
936 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 851 },
937 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 852 },
938 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 853 },
939 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 854 },
940 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 33, .child_index = 855 },
941 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 856 },
942 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 857 },
943 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 858 },
944 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 860 },
945 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 861 },
946 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 862 },
947 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 863 },
948 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 849 },
949 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 864 },
950 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 865 },
951 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 866 },
952 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 866 },
953 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 867 },
954 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 868 },
955 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 869 },
956 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 870 },
957 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 871 },
958 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 872 },
959 .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 873 },
960 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 874 },
961 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 875 },
962 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 780 },
963 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 876 },
964 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 877 },
965 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 878 },
966 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 879 },
967 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 880 },
968 .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 },
969 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 881 },
970 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 882 },
971 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 883 },
972 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 884 },
973 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 203 },
974 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
975 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 322 },
976 .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 885 },
977 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 886 },
978 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 887 },
979 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 888 },
980 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 889 },
981 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 890 },
982 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 891 },
983 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 892 },
984 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 895 },
985 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 897 },
986 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 898 },
987 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 899 },
988 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 900 },
989 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 901 },
990 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 903 },
991 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 904 },
992 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 905 },
993 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 908 },
994 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 910 },
995 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 911 },
996 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 932 },
997 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 933 },
998 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 934 },
999 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 935 },
1000 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 936 },
1001 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 937 },
1002 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 938 },
1003 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 940 },
1004 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 941 },
1005 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 942 },
1006 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 943 },
1007 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 944 },
1008 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 945 },
1009 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 946 },
1010 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 947 },
1011 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 949 },
1012 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 950 },
1013 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 951 },
1014 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 944 },
1015 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 952 },
1016 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 953 },
1017 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 955 },
1018 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 956 },
1019 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 957 },
1020 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 959 },
1021 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 960 },
1022 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 960 },
1023 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 961 },
1024 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 962 },
1025 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 962 },
1026 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 844 },
1027 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 963 },
1028 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 964 },
1029 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 967 },
1030 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
1031 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 970 },
1032 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 971 },
1033 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 972 },
1034 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 973 },
1035 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 974 },
1036 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 975 },
1037 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 976 },
1038 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 943 },
1039 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 977 },
1040 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 978 },
1041 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 849 },
1042 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 979 },
1043 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 871 },
1044 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 875 },
1045 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 980 },
1046 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 981 },
1047 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 866 },
1048 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 982 },
1049 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 871 },
1050 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 983 },
1051 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 984 },
1052 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 985 },
1053 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 986 },
1054 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 987 },
1055 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 988 },
1056 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 989 },
1057 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 990 },
1058 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 991 },
1059 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 992 },
1060 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 993 },
1061 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 994 },
1062 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 995 },
1063 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 996 },
1064 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 997 },
1065 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 998 },
1066 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 999 },
1067 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
1068 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1000 },
1069 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1001 },
1070 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1002 },
1071 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1001 },
1072 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1003 },
1073 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1004 },
1074 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1005 },
1075 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1006 },
1076 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1007 },
1077 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1008 },
1078 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1009 },
1079 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1010 },
1080 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1011 },
1081 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 },
1082 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1013 },
1083 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1014 },
1084 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1015 },
1085 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1016 },
1086 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1017 },
1087 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 904 },
1088 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 1018 },
1089 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 302, .child_index = 1019 },
1090 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1028 },
1091 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 114, .child_index = 1032 },
1092 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1044 },
1093 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 58, .child_index = 1049 },
1094 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 49, .child_index = 1053 },
1095 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1061 },
1096 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1062 },
1097 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 27, .child_index = 1064 },
1098 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 52, .child_index = 1068 },
1099 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 686, .child_index = 1074 },
1100 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 1080 },
1101 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1083 },
1102 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 142, .child_index = 1086 },
1103 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 52, .child_index = 1091 },
1104 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 71, .child_index = 1095 },
1105 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 1107 },
1106 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 1111 },
1107 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 1273, .child_index = 1115 },
1108 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 22, .child_index = 1120 },
1109 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1123 },
1110 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1124 },
1111 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 },
1112 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1125 },
1113 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1126 },
1114 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 1127 },
1115 .{ .char = '0', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1128 },
1116 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1129 },
1117 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1130 },
1118 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1119 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1132 },
1120 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1133 },
1121 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1134 },
1122 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1135 },
1123 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 960 },
1124 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 960 },
1125 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 946 },
1126 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1138 },
1127 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1140 },
1128 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1141 },
1129 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 944 },
1130 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 944 },
1131 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 952 },
1132 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1133 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1142 },
1134 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1126 },
1135 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1136 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1137 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1143 },
1138 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1144 },
1139 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 1145 },
1140 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1153 },
1141 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1154 },
1142 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 292 },
1143 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 486 },
1144 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1155 },
1145 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1126 },
1146 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1156 },
1147 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1157 },
1148 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1159 },
1149 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1160 },
1150 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1161 },
1151 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1162 },
1152 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1164 },
1153 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1165 },
1154 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 949 },
1155 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1166 },
1156 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1167 },
1157 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1168 },
1158 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1169 },
1159 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1170 },
1160 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 },
1161 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1172 },
1162 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1173 },
1163 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1174 },
1164 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1175 },
1165 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1176 },
1166 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1177 },
1167 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1178 },
1168 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1179 },
1169 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1182 },
1170 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1185 },
1171 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1187 },
1172 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1188 },
1173 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 1189 },
1174 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1196 },
1175 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 },
1176 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1198 },
1177 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1199 },
1178 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 },
1179 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1200 },
1180 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1201 },
1181 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1202 },
1182 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1203 },
1183 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1204 },
1184 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1205 },
1185 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1206 },
1186 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 },
1187 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 },
1188 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1001 },
1189 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1207 },
1190 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1208 },
1191 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1209 },
1192 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 },
1193 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1210 },
1194 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1211 },
1195 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 1212 },
1196 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 135 },
1197 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1221 },
1198 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1222 },
1199 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1223 },
1200 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 122, .child_index = 1225 },
1201 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 403 },
1202 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 134, .child_index = 1226 },
1203 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1227 },
1204 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1229 },
1205 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 142 },
1206 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1230 },
1207 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1231 },
1208 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 144 },
1209 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 1232 },
1210 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1239 },
1211 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 },
1212 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1240 },
1213 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1242 },
1214 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 154 },
1215 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1243 },
1216 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 1247 },
1217 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1251 },
1218 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 161 },
1219 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 162 },
1220 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1254 },
1221 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1256 },
1222 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1257 },
1223 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1258 },
1224 .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1259 },
1225 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1260 },
1226 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1261 },
1227 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 1262 },
1228 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1263 },
1229 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 23, .child_index = 1264 },
1230 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1266 },
1231 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1267 },
1232 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1268 },
1233 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1269 },
1234 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 1271 },
1235 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1274 },
1236 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1276 },
1237 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 },
1238 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1279 },
1239 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1280 },
1240 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1281 },
1241 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1282 },
1242 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1283 },
1243 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1284 },
1244 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 1287 },
1245 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1294 },
1246 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1296 },
1247 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1297 },
1248 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1298 },
1249 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 1300 },
1250 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1302 },
1251 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1304 },
1252 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1306 },
1253 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 135, .child_index = 1307 },
1254 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1308 },
1255 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 534, .child_index = 1309 },
1256 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1310 },
1257 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 1311 },
1258 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1312 },
1259 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1314 },
1260 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1315 },
1261 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1316 },
1262 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1317 },
1263 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1318 },
1264 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1320 },
1265 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 108, .child_index = 1322 },
1266 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1323 },
1267 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 1325 },
1268 .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1326 },
1269 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 1327 },
1270 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1331 },
1271 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 1332 },
1272 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1334 },
1273 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1335 },
1274 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1336 },
1275 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1337 },
1276 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1338 },
1277 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1340 },
1278 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 220 },
1279 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1341 },
1280 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1343 },
1281 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1344 },
1282 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 1346 },
1283 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1349 },
1284 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1350 },
1285 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1297 },
1286 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1351 },
1287 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1352 },
1288 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1334 },
1289 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1340 },
1290 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1354 },
1291 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1357 },
1292 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 227 },
1293 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1263, .child_index = 1358 },
1294 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1359 },
1295 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 },
1296 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 231 },
1297 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 1361 },
1298 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 235 },
1299 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 236 },
1300 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1362 },
1301 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
1302 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1363 },
1303 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1364 },
1304 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 1368 },
1305 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1376 },
1306 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 },
1307 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1380 },
1308 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1381 },
1309 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1383 },
1310 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1384 },
1311 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1385 },
1312 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1389 },
1313 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 451 },
1314 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1390 },
1315 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1384 },
1316 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1364 },
1317 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1394 },
1318 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1395 },
1319 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1320 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1390 },
1321 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1396 },
1322 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 },
1323 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1399 },
1324 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 },
1325 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1399 },
1326 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 },
1327 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1400 },
1328 .{ .char = 's', .end_of_word = true, .end_of_list = false, .number = 6, .child_index = 1402 },
1329 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 1405 },
1330 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1409 },
1331 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1410 },
1332 .{ .char = '4', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 974 },
1333 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1411 },
1334 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1412 },
1335 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1364 },
1336 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1413 },
1337 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1338 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 950 },
1339 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1340 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 },
1341 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1414 },
1342 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1415 },
1343 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1344 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1419 },
1345 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1422 },
1346 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1423 },
1347 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1425 },
1348 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1426 },
1349 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1430 },
1350 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1431 },
1351 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
1352 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1432 },
1353 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1433 },
1354 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1434 },
1355 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1435 },
1356 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1436 },
1357 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1437 },
1358 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1438 },
1359 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1439 },
1360 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1440 },
1361 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1441 },
1362 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1442 },
1363 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1443 },
1364 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1444 },
1365 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1445 },
1366 .{ .char = 'A', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1446 },
1367 .{ .char = 'C', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1447 },
1368 .{ .char = 'D', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1448 },
1369 .{ .char = 'E', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 1449 },
1370 .{ .char = 'I', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1450 },
1371 .{ .char = 'O', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1451 },
1372 .{ .char = 'X', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1452 },
1373 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1453 },
1374 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
1375 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1454 },
1376 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1455 },
1377 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1456 },
1378 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
1379 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1457 },
1380 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1458 },
1381 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1459 },
1382 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1460 },
1383 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1461 },
1384 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1462 },
1385 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1463 },
1386 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1464 },
1387 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1465 },
1388 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1466 },
1389 .{ .char = 'C', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1467 },
1390 .{ .char = 'N', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1468 },
1391 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1469 },
1392 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 },
1393 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1471 },
1394 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1472 },
1395 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1473 },
1396 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 1474 },
1397 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1477 },
1398 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1480 },
1399 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1481 },
1400 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1483 },
1401 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1484 },
1402 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 1485 },
1403 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 134, .child_index = 1486 },
1404 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1350 },
1405 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1487 },
1406 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1488 },
1407 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1489 },
1408 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1490 },
1409 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 294 },
1410 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 },
1411 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1491 },
1412 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1492 },
1413 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 296 },
1414 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 140 },
1415 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 164 },
1416 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1493 },
1417 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1494 },
1418 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 },
1419 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1495 },
1420 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1496 },
1421 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 296 },
1422 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1497 },
1423 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1498 },
1424 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1500 },
1425 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1501 },
1426 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1504 },
1427 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 1505 },
1428 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 209 },
1429 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 306 },
1430 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1508 },
1431 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 223 },
1432 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1498 },
1433 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
1434 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1509 },
1435 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1510 },
1436 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1511 },
1437 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1512 },
1438 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1513 },
1439 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 1514 },
1440 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1515 },
1441 .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 21, .child_index = 1518 },
1442 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1524 },
1443 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1526 },
1444 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1527 },
1445 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 },
1446 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1529 },
1447 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1530 },
1448 .{ .char = 'a', .end_of_word = true, .end_of_list = false, .number = 10, .child_index = 1531 },
1449 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1534 },
1450 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1535 },
1451 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1536 },
1452 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 },
1453 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1537 },
1454 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1538 },
1455 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1540 },
1456 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1541 },
1457 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1543 },
1458 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1544 },
1459 .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1545 },
1460 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1546 },
1461 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 },
1462 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 },
1463 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1549 },
1464 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1550 },
1465 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1551 },
1466 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1553 },
1467 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1554 },
1468 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1555 },
1469 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1556 },
1470 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1558 },
1471 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 },
1472 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1559 },
1473 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1560 },
1474 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1561 },
1475 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 194 },
1476 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1302 },
1477 .{ .char = 'g', .end_of_word = true, .end_of_list = false, .number = 23, .child_index = 1562 },
1478 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 },
1479 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1567 },
1480 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1568 },
1481 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 295 },
1482 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1569 },
1483 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1570 },
1484 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 135, .child_index = 1574 },
1485 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1575 },
1486 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 534, .child_index = 1576 },
1487 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1577 },
1488 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 10, .child_index = 1578 },
1489 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1581 },
1490 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1582 },
1491 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1583 },
1492 .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1585 },
1493 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1587 },
1494 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1588 },
1495 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1589 },
1496 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1590 },
1497 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1591 },
1498 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1592 },
1499 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 1595 },
1500 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1596 },
1501 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 365 },
1502 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 1598 },
1503 .{ .char = '0', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 1599 },
1504 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1600 },
1505 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1602 },
1506 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1603 },
1507 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1605 },
1508 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1606 },
1509 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1608 },
1510 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1609 },
1511 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1610 },
1512 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 1611 },
1513 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1613 },
1514 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1618 },
1515 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1619 },
1516 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 1505 },
1517 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1620 },
1518 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1621 },
1519 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 },
1520 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1622 },
1521 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 327 },
1522 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1623 },
1523 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1624 },
1524 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 377 },
1525 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1625 },
1526 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1481 },
1527 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1632 },
1528 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1635 },
1529 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 },
1530 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1636 },
1531 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1637 },
1532 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1639 },
1533 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1640 },
1534 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1623 },
1535 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 1641 },
1536 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 },
1537 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 },
1538 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1642 },
1539 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1643 },
1540 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1650 },
1541 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1131 },
1542 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1131 },
1543 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1131 },
1544 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
1545 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1651 },
1546 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1653 },
1547 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1654 },
1548 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1655 },
1549 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1656 },
1550 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1658 },
1551 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1659 },
1552 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1660 },
1553 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 519 },
1554 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
1555 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1662 },
1556 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1663 },
1557 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1664 },
1558 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1559 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1665 },
1560 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1666 },
1561 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1667 },
1562 .{ .char = 'm', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1668 },
1563 .{ .char = 'n', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1668 },
1564 .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1668 },
1565 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1668 },
1566 .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1567 .{ .char = 'm', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1568 .{ .char = 'n', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1569 .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1570 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1571 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1669 },
1572 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1668 },
1573 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1670 },
1574 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1575 .{ .char = '4', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1576 .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1577 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1578 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 },
1579 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1580 .{ .char = '4', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1581 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1397 },
1582 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 },
1583 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 },
1584 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1400 },
1585 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1397 },
1586 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1671 },
1587 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1672 },
1588 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1673 },
1589 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1676 },
1590 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1677 },
1591 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1678 },
1592 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1679 },
1593 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1680 },
1594 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1681 },
1595 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1682 },
1596 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1683 },
1597 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1685 },
1598 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1686 },
1599 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1687 },
1600 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1688 },
1601 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1689 },
1602 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1690 },
1603 .{ .char = '1', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1691 },
1604 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1605 .{ .char = '4', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1606 .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1607 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1692 },
1608 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1693 },
1609 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1694 },
1610 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1434 },
1611 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1695 },
1612 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1696 },
1613 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1697 },
1614 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1698 },
1615 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1699 },
1616 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1700 },
1617 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1701 },
1618 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1702 },
1619 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1703 },
1620 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1704 },
1621 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1705 },
1622 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1706 },
1623 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1708 },
1624 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1709 },
1625 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1710 },
1626 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1711 },
1627 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1710 },
1628 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1712 },
1629 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1451 },
1630 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1714 },
1631 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1715 },
1632 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1716 },
1633 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 899 },
1634 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1717 },
1635 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1718 },
1636 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1719 },
1637 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1720 },
1638 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
1639 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1721 },
1640 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1722 },
1641 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1461 },
1642 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1723 },
1643 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1724 },
1644 .{ .char = 'F', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1725 },
1645 .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1725 },
1646 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 409 },
1647 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1473 },
1648 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1726 },
1649 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1727 },
1650 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1728 },
1651 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 },
1652 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1473 },
1653 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1729 },
1654 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 },
1655 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1473 },
1656 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1731 },
1657 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1632 },
1658 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1733 },
1659 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1734 },
1660 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1737 },
1661 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1738 },
1662 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 1739 },
1663 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 134, .child_index = 1740 },
1664 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1756 },
1665 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 12, .child_index = 1757 },
1666 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1761 },
1667 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1762 },
1668 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1763 },
1669 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1765 },
1670 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
1671 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1672 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1768 },
1673 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1769 },
1674 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1770 },
1675 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 },
1676 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1677 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1771 },
1678 .{ .char = 'j', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
1679 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1772 },
1680 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1773 },
1681 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1774 },
1682 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
1683 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 },
1684 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1685 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1776 },
1686 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1778 },
1687 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1779 },
1688 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1780 },
1689 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1781 },
1690 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1782 },
1691 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 1783 },
1692 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 },
1693 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 },
1694 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1695 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1785 },
1696 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 },
1697 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1786 },
1698 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
1699 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1700 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1787 },
1701 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1788 },
1702 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1789 },
1703 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1704 .{ .char = 'm', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
1705 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 },
1706 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1790 },
1707 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1791 },
1708 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
1709 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1710 .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1711 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1712 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1713 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1792 },
1714 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1793 },
1715 .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1716 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1794 },
1717 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1795 },
1718 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 },
1719 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
1720 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1796 },
1721 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1493 },
1722 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1797 },
1723 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1798 },
1724 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
1725 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1726 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1799 },
1727 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1800 },
1728 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1801 },
1729 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1802 },
1730 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1803 },
1731 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1804 },
1732 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1805 },
1733 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 },
1734 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1806 },
1735 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1807 },
1736 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1808 },
1737 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1794 },
1738 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1809 },
1739 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1810 },
1740 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 },
1741 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 },
1742 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
1743 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1744 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1493 },
1745 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1812 },
1746 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1813 },
1747 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1814 },
1748 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 484 },
1749 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 485 },
1750 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1817 },
1751 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 135, .child_index = 1818 },
1752 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
1753 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 534, .child_index = 1819 },
1754 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1733 },
1755 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
1756 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1757 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1758 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1834 },
1759 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1835 },
1760 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1837 },
1761 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1838 },
1762 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1839 },
1763 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1840 },
1764 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1841 },
1765 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1842 },
1766 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1843 },
1767 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1844 },
1768 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1845 },
1769 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
1770 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 },
1771 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1772 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 1846 },
1773 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1462 },
1774 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1859 },
1775 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 1860 },
1776 .{ .char = '0', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 1863 },
1777 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1864 },
1778 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 295 },
1779 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 1866 },
1780 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1867 },
1781 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1868 },
1782 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1869 },
1783 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 },
1784 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1785 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1870 },
1786 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1871 },
1787 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1872 },
1788 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1874 },
1789 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
1790 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1875 },
1791 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1876 },
1792 .{ .char = 'j', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 497 },
1793 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 },
1794 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 },
1795 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1877 },
1796 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1878 },
1797 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1872 },
1798 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1879 },
1799 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1800 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1872 },
1801 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1880 },
1802 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 500 },
1803 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 505 },
1804 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 323 },
1805 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 509 },
1806 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 511 },
1807 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 512 },
1808 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 513 },
1809 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 },
1810 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 },
1811 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1812 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1881 },
1813 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1882 },
1814 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1883 },
1815 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1884 },
1816 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1885 },
1817 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1886 },
1818 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 1887 },
1819 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1888 },
1820 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1889 },
1821 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1890 },
1822 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 898 },
1823 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1891 },
1824 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1893 },
1825 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1894 },
1826 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1896 },
1827 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1897 },
1828 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1898 },
1829 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1899 },
1830 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1900 },
1831 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1901 },
1832 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1901 },
1833 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1902 },
1834 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1903 },
1835 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 },
1836 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1905 },
1837 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1906 },
1838 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1658 },
1839 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1907 },
1840 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
1841 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1908 },
1842 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1909 },
1843 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1910 },
1844 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1911 },
1845 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1912 },
1846 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1913 },
1847 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1914 },
1848 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
1849 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1915 },
1850 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1851 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 },
1852 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1918 },
1853 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1920 },
1854 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1921 },
1855 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1922 },
1856 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1923 },
1857 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1924 },
1858 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1925 },
1859 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 },
1860 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 },
1861 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
1862 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1927 },
1863 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 },
1864 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1928 },
1865 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1929 },
1866 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1930 },
1867 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1931 },
1868 .{ .char = '6', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1869 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1932 },
1870 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1933 },
1871 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1934 },
1872 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1935 },
1873 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1936 },
1874 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1937 },
1875 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1438 },
1876 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1938 },
1877 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1939 },
1878 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1940 },
1879 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 286 },
1880 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
1881 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 },
1882 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1941 },
1883 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1942 },
1884 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1943 },
1885 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1712 },
1886 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1944 },
1887 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1945 },
1888 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1946 },
1889 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
1890 .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1891 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1947 },
1892 .{ .char = 'I', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1443 },
1893 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1948 },
1894 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1949 },
1895 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1950 },
1896 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1951 },
1897 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1957 },
1898 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1958 },
1899 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1199 },
1900 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1959 },
1901 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1199 },
1902 .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1960 },
1903 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1961 },
1904 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1962 },
1905 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1966 },
1906 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1967 },
1907 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1969 },
1908 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 },
1909 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1473 },
1910 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1972 },
1911 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
1912 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 },
1913 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1914 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1973 },
1915 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1974 },
1916 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 1975 },
1917 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1976 },
1918 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1979 },
1919 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1982 },
1920 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1983 },
1921 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1984 },
1922 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1985 },
1923 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 420 },
1924 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1987 },
1925 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1988 },
1926 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1991 },
1927 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 51, .child_index = 1993 },
1928 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2000 },
1929 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2003 },
1930 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2008 },
1931 .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2009 },
1932 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 274 },
1933 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2011 },
1934 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 },
1935 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 },
1936 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 },
1937 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1938 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2012 },
1939 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2013 },
1940 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2016 },
1941 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
1942 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2017 },
1943 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 },
1944 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
1945 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2018 },
1946 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2019 },
1947 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 },
1948 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 332 },
1949 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2020 },
1950 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2021 },
1951 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2022 },
1952 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2023 },
1953 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2025 },
1954 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2027 },
1955 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2028 },
1956 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2029 },
1957 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2030 },
1958 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2031 },
1959 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2032 },
1960 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 2033 },
1961 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2034 },
1962 .{ .char = '0', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1963 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2035 },
1964 .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
1965 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2036 },
1966 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2037 },
1967 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1968 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2038 },
1969 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2039 },
1970 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2040 },
1971 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
1972 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2041 },
1973 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2042 },
1974 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2043 },
1975 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
1976 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2044 },
1977 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2045 },
1978 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 328 },
1979 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2046 },
1980 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2047 },
1981 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2048 },
1982 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2049 },
1983 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2050 },
1984 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2051 },
1985 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 },
1986 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2052 },
1987 .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 },
1988 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
1989 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2053 },
1990 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2054 },
1991 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
1992 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 },
1993 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2055 },
1994 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2056 },
1995 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 135, .child_index = 2057 },
1996 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 50, .child_index = 2069 },
1997 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 56, .child_index = 2073 },
1998 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 50, .child_index = 2079 },
1999 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 26, .child_index = 2084 },
2000 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 106, .child_index = 2087 },
2001 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2098 },
2002 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2100 },
2003 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2102 },
2004 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 73, .child_index = 2103 },
2005 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2108 },
2006 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2110 },
2007 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2111 },
2008 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 97, .child_index = 2112 },
2009 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2119 },
2010 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2120 },
2011 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2121 },
2012 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2122 },
2013 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2123 },
2014 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2124 },
2015 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2125 },
2016 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2126 },
2017 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2127 },
2018 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2128 },
2019 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2129 },
2020 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2130 },
2021 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2131 },
2022 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2132 },
2023 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2133 },
2024 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2134 },
2025 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2136 },
2026 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2137 },
2027 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 41, .child_index = 2138 },
2028 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2144 },
2029 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2145 },
2030 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2147 },
2031 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 2150 },
2032 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2155 },
2033 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2156 },
2034 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2160 },
2035 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2163 },
2036 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2166 },
2037 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2167 },
2038 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2168 },
2039 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2169 },
2040 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 2170 },
2041 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2172 },
2042 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1876 },
2043 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2173 },
2044 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2174 },
2045 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2175 },
2046 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2176 },
2047 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2177 },
2048 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 10, .child_index = 2178 },
2049 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1733 },
2050 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2181 },
2051 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2183 },
2052 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2185 },
2053 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
2054 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2186 },
2055 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2187 },
2056 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2188 },
2057 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2189 },
2058 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2036 },
2059 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 },
2060 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1589 },
2061 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2190 },
2062 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2191 },
2063 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2192 },
2064 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 2193 },
2065 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 2194 },
2066 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2196 },
2067 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2197 },
2068 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 238 },
2069 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1007 },
2070 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2198 },
2071 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1013 },
2072 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2199 },
2073 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1017 },
2074 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2200 },
2075 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2202 },
2076 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 },
2077 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 },
2078 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2203 },
2079 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2204 },
2080 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2204 },
2081 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2205 },
2082 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 },
2083 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2206 },
2084 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
2085 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2207 },
2086 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2211 },
2087 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2212 },
2088 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2213 },
2089 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2214 },
2090 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2215 },
2091 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2216 },
2092 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2217 },
2093 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 },
2094 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2218 },
2095 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2096 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
2097 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2219 },
2098 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 2220 },
2099 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
2100 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2221 },
2101 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2222 },
2102 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 },
2103 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2223 },
2104 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2225 },
2105 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 2226 },
2106 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2227 },
2107 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2228 },
2108 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2229 },
2109 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 },
2110 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2231 },
2111 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2232 },
2112 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 },
2113 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2233 },
2114 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2234 },
2115 .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 },
2116 .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 },
2117 .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2118 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2235 },
2119 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2236 },
2120 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2237 },
2121 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2238 },
2122 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2239 },
2123 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2240 },
2124 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2241 },
2125 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 582 },
2126 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2242 },
2127 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1464 },
2128 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2243 },
2129 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2245 },
2130 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2247 },
2131 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
2132 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2248 },
2133 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 },
2134 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2249 },
2135 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 656 },
2136 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2250 },
2137 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2251 },
2138 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2252 },
2139 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2253 },
2140 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2255 },
2141 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2256 },
2142 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2257 },
2143 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2258 },
2144 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2259 },
2145 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2256 },
2146 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2260 },
2147 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2262 },
2148 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2262 },
2149 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2263 },
2150 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2264 },
2151 .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 2266 },
2152 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 2267 },
2153 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2268 },
2154 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2269 },
2155 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2272 },
2156 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1940 },
2157 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 },
2158 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
2159 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2273 },
2160 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
2161 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2274 },
2162 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2277 },
2163 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2278 },
2164 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2280 },
2165 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2281 },
2166 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2283 },
2167 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2284 },
2168 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2286 },
2169 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2287 },
2170 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2288 },
2171 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2290 },
2172 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2293 },
2173 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2295 },
2174 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2297 },
2175 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 2299 },
2176 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2302 },
2177 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2303 },
2178 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 520 },
2179 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2305 },
2180 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2288 },
2181 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2293 },
2182 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2293 },
2183 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 2306 },
2184 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2302 },
2185 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2308 },
2186 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 431 },
2187 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2287 },
2188 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 2309 },
2189 .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 2310 },
2190 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
2191 .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2311 },
2192 .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 },
2193 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2312 },
2194 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2313 },
2195 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2314 },
2196 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2315 },
2197 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2316 },
2198 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2317 },
2199 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2318 },
2200 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2319 },
2201 .{ .char = '6', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2202 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 238 },
2203 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2204 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2320 },
2205 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2321 },
2206 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2322 },
2207 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2323 },
2208 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2325 },
2209 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2326 },
2210 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 2327 },
2211 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2319 },
2212 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2328 },
2213 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2329 },
2214 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2330 },
2215 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2331 },
2216 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2332 },
2217 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2333 },
2218 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2334 },
2219 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2335 },
2220 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2336 },
2221 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2337 },
2222 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2338 },
2223 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2339 },
2224 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2340 },
2225 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2236 },
2226 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 2341 },
2227 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 },
2228 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2344 },
2229 .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
2230 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
2231 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2345 },
2232 .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2346 },
2233 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2346 },
2234 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 2347 },
2235 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2350 },
2236 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2353 },
2237 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2354 },
2238 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2355 },
2239 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2356 },
2240 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2357 },
2241 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2360 },
2242 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 21, .child_index = 2365 },
2243 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2368 },
2244 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 2371 },
2245 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2373 },
2246 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2374 },
2247 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2375 },
2248 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2376 },
2249 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2377 },
2250 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2378 },
2251 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2379 },
2252 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2380 },
2253 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 2382 },
2254 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2384 },
2255 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2385 },
2256 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2386 },
2257 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2387 },
2258 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 32, .child_index = 2388 },
2259 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2390 },
2260 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2387 },
2261 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2391 },
2262 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2392 },
2263 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2098 },
2264 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2393 },
2265 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2394 },
2266 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2400 },
2267 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2401 },
2268 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2402 },
2269 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2404 },
2270 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2405 },
2271 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 2406 },
2272 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2410 },
2273 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 26, .child_index = 2413 },
2274 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2420 },
2275 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2423 },
2276 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2424 },
2277 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2425 },
2278 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2426 },
2279 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2427 },
2280 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 2430 },
2281 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 2432 },
2282 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 2433 },
2283 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2435 },
2284 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2436 },
2285 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2437 },
2286 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2110 },
2287 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 },
2288 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2441 },
2289 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2443 },
2290 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2444 },
2291 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2445 },
2292 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2447 },
2293 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 32, .child_index = 2448 },
2294 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2450 },
2295 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 2452 },
2296 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2453 },
2297 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2110 },
2298 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2454 },
2299 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2455 },
2300 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2456 },
2301 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2457 },
2302 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2458 },
2303 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2459 },
2304 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2460 },
2305 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2461 },
2306 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2462 },
2307 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2463 },
2308 .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 },
2309 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2464 },
2310 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2465 },
2311 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2466 },
2312 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2467 },
2313 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2468 },
2314 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2469 },
2315 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2470 },
2316 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2472 },
2317 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2473 },
2318 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2474 },
2319 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 2476 },
2320 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2479 },
2321 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2481 },
2322 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2482 },
2323 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 },
2324 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2483 },
2325 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2484 },
2326 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2485 },
2327 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2487 },
2328 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2488 },
2329 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2491 },
2330 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2492 },
2331 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2495 },
2332 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2496 },
2333 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2497 },
2334 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2498 },
2335 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2499 },
2336 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2501 },
2337 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2502 },
2338 .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2506 },
2339 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1663 },
2340 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2507 },
2341 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2508 },
2342 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2343 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2509 },
2344 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2510 },
2345 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2511 },
2346 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2512 },
2347 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2513 },
2348 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2514 },
2349 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2515 },
2350 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2516 },
2351 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2517 },
2352 .{ .char = 'o', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
2353 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2040 },
2354 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2518 },
2355 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2520 },
2356 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 },
2357 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2358 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1733 },
2359 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1577 },
2360 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2521 },
2361 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
2362 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2522 },
2363 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2523 },
2364 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 },
2365 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2524 },
2366 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 429 },
2367 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2525 },
2368 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2526 },
2369 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2527 },
2370 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 2528 },
2371 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2540 },
2372 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2543 },
2373 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2544 },
2374 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2545 },
2375 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
2376 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2546 },
2377 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2547 },
2378 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2548 },
2379 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2549 },
2380 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2550 },
2381 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2551 },
2382 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2552 },
2383 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 },
2384 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2553 },
2385 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2554 },
2386 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2555 },
2387 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2556 },
2388 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
2389 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2557 },
2390 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2559 },
2391 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2560 },
2392 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2561 },
2393 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2562 },
2394 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 },
2395 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
2396 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2566 },
2397 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 2567 },
2398 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 },
2399 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 },
2400 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2568 },
2401 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2568 },
2402 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2569 },
2403 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 2570 },
2404 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2571 },
2405 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2572 },
2406 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2573 },
2407 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2574 },
2408 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2575 },
2409 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2576 },
2410 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 674 },
2411 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2577 },
2412 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2578 },
2413 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 584 },
2414 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2579 },
2415 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2580 },
2416 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2581 },
2417 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2582 },
2418 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2583 },
2419 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2584 },
2420 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 },
2421 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
2422 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 },
2423 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
2424 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 },
2425 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
2426 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2585 },
2427 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2586 },
2428 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2587 },
2429 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2588 },
2430 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2259 },
2431 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2589 },
2432 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2590 },
2433 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2259 },
2434 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2591 },
2435 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2592 },
2436 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2589 },
2437 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2591 },
2438 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2589 },
2439 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2260 },
2440 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2593 },
2441 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2594 },
2442 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
2443 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2595 },
2444 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 2597 },
2445 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 },
2446 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 },
2447 .{ .char = 's', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1938 },
2448 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1938 },
2449 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2614 },
2450 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2615 },
2451 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 },
2452 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 2616 },
2453 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2618 },
2454 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 2619 },
2455 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1399 },
2456 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2621 },
2457 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1207 },
2458 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1708 },
2459 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
2460 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
2461 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 },
2462 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2622 },
2463 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1699 },
2464 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 2623 },
2465 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2625 },
2466 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
2467 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2468 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2615 },
2469 .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 },
2470 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2288 },
2471 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2626 },
2472 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 2628 },
2473 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2630 },
2474 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2633 },
2475 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2635 },
2476 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 2616 },
2477 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 },
2478 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2618 },
2479 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2636 },
2480 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2638 },
2481 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2639 },
2482 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2640 },
2483 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2641 },
2484 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2635 },
2485 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2644 },
2486 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2645 },
2487 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2647 },
2488 .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2489 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2648 },
2490 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2649 },
2491 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2650 },
2492 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2651 },
2493 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2652 },
2494 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2653 },
2495 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1534 },
2496 .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2497 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2654 },
2498 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2655 },
2499 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2656 },
2500 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2657 },
2501 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2658 },
2502 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2659 },
2503 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2660 },
2504 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 2661 },
2505 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2662 },
2506 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2663 },
2507 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1795 },
2508 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2664 },
2509 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2665 },
2510 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 729 },
2511 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2666 },
2512 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1494 },
2513 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2667 },
2514 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2669 },
2515 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2670 },
2516 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 },
2517 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2671 },
2518 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2672 },
2519 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2673 },
2520 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
2521 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2674 },
2522 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2675 },
2523 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2677 },
2524 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2678 },
2525 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 2679 },
2526 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2680 },
2527 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 479 },
2528 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2681 },
2529 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2682 },
2530 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2683 },
2531 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2684 },
2532 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2686 },
2533 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2687 },
2534 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2688 },
2535 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 },
2536 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
2537 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2689 },
2538 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2691 },
2539 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2692 },
2540 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2693 },
2541 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 2694 },
2542 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2695 },
2543 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2696 },
2544 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 2697 },
2545 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2698 },
2546 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2699 },
2547 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2700 },
2548 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2701 },
2549 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 2704 },
2550 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2699 },
2551 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 2705 },
2552 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 },
2553 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2708 },
2554 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2709 },
2555 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2711 },
2556 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2712 },
2557 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2713 },
2558 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 },
2559 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2714 },
2560 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2385 },
2561 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2715 },
2562 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2717 },
2563 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2564 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2724 },
2565 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2725 },
2566 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2725 },
2567 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2727 },
2568 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 },
2569 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2729 },
2570 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2730 },
2571 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2731 },
2572 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 },
2573 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2733 },
2574 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2736 },
2575 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2737 },
2576 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2738 },
2577 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2741 },
2578 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2742 },
2579 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2745 },
2580 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2746 },
2581 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2748 },
2582 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2749 },
2583 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2750 },
2584 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2752 },
2585 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2753 },
2586 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2754 },
2587 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2755 },
2588 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2756 },
2589 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2757 },
2590 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2731 },
2591 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 },
2592 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2758 },
2593 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2736 },
2594 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2737 },
2595 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2760 },
2596 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2761 },
2597 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2745 },
2598 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2765 },
2599 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2766 },
2600 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2767 },
2601 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2768 },
2602 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2769 },
2603 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2773 },
2604 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 },
2605 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 },
2606 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2607 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2781 },
2608 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 20, .child_index = 2782 },
2609 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 20, .child_index = 2782 },
2610 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2728 },
2611 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2784 },
2612 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2785 },
2613 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2786 },
2614 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2789 },
2615 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2789 },
2616 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2790 },
2617 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2791 },
2618 .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2792 },
2619 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2794 },
2620 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 },
2621 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2795 },
2622 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2722 },
2623 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2624 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2796 },
2625 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2797 },
2626 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2797 },
2627 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 },
2628 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2629 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 2800 },
2630 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2802 },
2631 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1567 },
2632 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2803 },
2633 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2804 },
2634 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2805 },
2635 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2806 },
2636 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2807 },
2637 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2808 },
2638 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2809 },
2639 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2810 },
2640 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2811 },
2641 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2812 },
2642 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2813 },
2643 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
2644 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2814 },
2645 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2815 },
2646 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2819 },
2647 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2820 },
2648 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2822 },
2649 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2824 },
2650 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2825 },
2651 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2826 },
2652 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2827 },
2653 .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 },
2654 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 2830 },
2655 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2835 },
2656 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2836 },
2657 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2837 },
2658 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2838 },
2659 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2839 },
2660 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2840 },
2661 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2841 },
2662 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2840 },
2663 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 },
2664 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2842 },
2665 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2843 },
2666 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2844 },
2667 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2845 },
2668 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2842 },
2669 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2846 },
2670 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2843 },
2671 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2844 },
2672 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2847 },
2673 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2848 },
2674 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2850 },
2675 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2851 },
2676 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2852 },
2677 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2853 },
2678 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2855 },
2679 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2856 },
2680 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2857 },
2681 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2858 },
2682 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2856 },
2683 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2859 },
2684 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2685 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2860 },
2686 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2861 },
2687 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2862 },
2688 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2863 },
2689 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2864 },
2690 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2865 },
2691 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2866 },
2692 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2868 },
2693 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2869 },
2694 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2803 },
2695 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2873 },
2696 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2874 },
2697 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2875 },
2698 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
2699 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1530 },
2700 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2653 },
2701 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2876 },
2702 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2877 },
2703 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2878 },
2704 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2879 },
2705 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2880 },
2706 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2881 },
2707 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2883 },
2708 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2885 },
2709 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2886 },
2710 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2890 },
2711 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2892 },
2712 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 393, .child_index = 2893 },
2713 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2897 },
2714 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2899 },
2715 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 836, .child_index = 2901 },
2716 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2915 },
2717 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2916 },
2718 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2917 },
2719 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2918 },
2720 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2919 },
2721 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2920 },
2722 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2921 },
2723 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
2724 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2922 },
2725 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2923 },
2726 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2924 },
2727 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2925 },
2728 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2926 },
2729 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2927 },
2730 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2928 },
2731 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 },
2732 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
2733 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1671 },
2734 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 506 },
2735 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2929 },
2736 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2930 },
2737 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2738 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 },
2739 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2931 },
2740 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2932 },
2741 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2933 },
2742 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2934 },
2743 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2935 },
2744 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 2936 },
2745 .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2311 },
2746 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
2747 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 2937 },
2748 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2944 },
2749 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2945 },
2750 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2946 },
2751 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
2752 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2947 },
2753 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2948 },
2754 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2949 },
2755 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2950 },
2756 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2951 },
2757 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2952 },
2758 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2953 },
2759 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2954 },
2760 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 },
2761 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 897 },
2762 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2955 },
2763 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2956 },
2764 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2957 },
2765 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2958 },
2766 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 },
2767 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2960 },
2768 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 },
2769 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 },
2770 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2961 },
2771 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2962 },
2772 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2963 },
2773 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2964 },
2774 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2965 },
2775 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2967 },
2776 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 2968 },
2777 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 2972 },
2778 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2974 },
2779 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2976 },
2780 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2980 },
2781 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 2981 },
2782 .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2985 },
2783 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2986 },
2784 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2989 },
2785 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2992 },
2786 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 2994 },
2787 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 23, .child_index = 2997 },
2788 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3003 },
2789 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3004 },
2790 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3006 },
2791 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3008 },
2792 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3009 },
2793 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 },
2794 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2795 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3010 },
2796 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2797 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 },
2798 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 },
2799 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1712 },
2800 .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 },
2801 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2802 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3011 },
2803 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 },
2804 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2635 },
2805 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 3013 },
2806 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3018 },
2807 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3020 },
2808 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3021 },
2809 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3020 },
2810 .{ .char = 't', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3024 },
2811 .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2812 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3011 },
2813 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3025 },
2814 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 },
2815 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3027 },
2816 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3028 },
2817 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
2818 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3029 },
2819 .{ .char = 't', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3024 },
2820 .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2821 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3031 },
2822 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1800 },
2823 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3032 },
2824 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3033 },
2825 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3034 },
2826 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3035 },
2827 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 512 },
2828 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3036 },
2829 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3037 },
2830 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3038 },
2831 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3039 },
2832 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
2833 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3040 },
2834 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 },
2835 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3041 },
2836 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3042 },
2837 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3043 },
2838 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3044 },
2839 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3045 },
2840 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3046 },
2841 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1174 },
2842 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3047 },
2843 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3048 },
2844 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3049 },
2845 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3050 },
2846 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3051 },
2847 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3052 },
2848 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3053 },
2849 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3054 },
2850 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3055 },
2851 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3056 },
2852 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3057 },
2853 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3058 },
2854 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3059 },
2855 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3060 },
2856 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 15, .child_index = 3061 },
2857 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3065 },
2858 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3066 },
2859 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3067 },
2860 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3068 },
2861 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3071 },
2862 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3071 },
2863 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3075 },
2864 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 },
2865 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
2866 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3077 },
2867 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3078 },
2868 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3079 },
2869 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3080 },
2870 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3081 },
2871 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 3082 },
2872 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3087 },
2873 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3088 },
2874 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3089 },
2875 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3091 },
2876 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3092 },
2877 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3093 },
2878 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3094 },
2879 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3095 },
2880 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 3096 },
2881 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 3098 },
2882 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3100 },
2883 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3101 },
2884 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2885 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 },
2886 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3102 },
2887 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 },
2888 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2889 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3104 },
2890 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 },
2891 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2892 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2439 },
2893 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2894 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2895 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2896 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2897 .{ .char = 'v', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2898 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2899 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 },
2900 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
2901 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3106 },
2902 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3102 },
2903 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 },
2904 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 },
2905 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3102 },
2906 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3107 },
2907 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2908 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2909 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2910 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3108 },
2911 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 },
2912 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2913 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2914 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2915 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 },
2916 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2758 },
2917 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3109 },
2918 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2919 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3111 },
2920 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3112 },
2921 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3113 },
2922 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3114 },
2923 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 },
2924 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2925 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
2926 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3112 },
2927 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2730 },
2928 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3115 },
2929 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3115 },
2930 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3116 },
2931 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2932 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2933 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3117 },
2934 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2760 },
2935 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 },
2936 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
2937 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3117 },
2938 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 },
2939 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 },
2940 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2758 },
2941 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3109 },
2942 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3118 },
2943 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3120 },
2944 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3107 },
2945 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3107 },
2946 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3121 },
2947 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 },
2948 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3122 },
2949 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
2950 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3123 },
2951 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3124 },
2952 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2953 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2954 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
2955 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2956 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2775 },
2957 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3125 },
2958 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2786 },
2959 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3127 },
2960 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 },
2961 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3130 },
2962 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2786 },
2963 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3131 },
2964 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3132 },
2965 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
2966 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
2967 .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2968 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
2969 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3121 },
2970 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3122 },
2971 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
2972 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3133 },
2973 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3136 },
2974 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 },
2975 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 },
2976 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2977 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3137 },
2978 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
2979 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
2980 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3139 },
2981 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3140 },
2982 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3141 },
2983 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3142 },
2984 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3143 },
2985 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 },
2986 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3144 },
2987 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3145 },
2988 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3146 },
2989 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 },
2990 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3147 },
2991 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3148 },
2992 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3149 },
2993 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 },
2994 .{ .char = 't', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 3150 },
2995 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
2996 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 },
2997 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 },
2998 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
2999 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3152 },
3000 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3154 },
3001 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3156 },
3002 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3157 },
3003 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3158 },
3004 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3159 },
3005 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2825 },
3006 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3007 .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3008 .{ .char = 'm', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 },
3009 .{ .char = 'n', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 },
3010 .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 },
3011 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 },
3012 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3160 },
3013 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 },
3014 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3161 },
3015 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3162 },
3016 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3163 },
3017 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
3018 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3164 },
3019 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3166 },
3020 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
3021 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
3022 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3169 },
3023 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3170 },
3024 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3172 },
3025 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3174 },
3026 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3175 },
3027 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
3028 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3176 },
3029 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3177 },
3030 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3177 },
3031 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
3032 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3178 },
3033 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
3034 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 },
3035 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3179 },
3036 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3180 },
3037 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3181 },
3038 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3182 },
3039 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3183 },
3040 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3184 },
3041 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3185 },
3042 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3186 },
3043 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3187 },
3044 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3188 },
3045 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3189 },
3046 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2243 },
3047 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3190 },
3048 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
3049 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 },
3050 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3193 },
3051 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3194 },
3052 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1534 },
3053 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
3054 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3195 },
3055 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3196 },
3056 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3197 },
3057 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3198 },
3058 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3199 },
3059 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3200 },
3060 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3201 },
3061 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3202 },
3062 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3203 },
3063 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3204 },
3064 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3205 },
3065 .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3206 },
3066 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3208 },
3067 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3209 },
3068 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3198 },
3069 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3210 },
3070 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3211 },
3071 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3208 },
3072 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3212 },
3073 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 388, .child_index = 3213 },
3074 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3204 },
3075 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3225 },
3076 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3208 },
3077 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3227 },
3078 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 3228 },
3079 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 3230 },
3080 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 71, .child_index = 3231 },
3081 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 45, .child_index = 3234 },
3082 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3235 },
3083 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 294, .child_index = 3237 },
3084 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 32, .child_index = 3244 },
3085 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 35, .child_index = 3245 },
3086 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 81, .child_index = 3246 },
3087 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3251 },
3088 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3252 },
3089 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 42, .child_index = 3253 },
3090 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 163, .child_index = 3259 },
3091 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3267 },
3092 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2892 },
3093 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 },
3094 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3269 },
3095 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 },
3096 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3270 },
3097 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3271 },
3098 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3272 },
3099 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3273 },
3100 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3274 },
3101 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3275 },
3102 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3276 },
3103 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3277 },
3104 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3278 },
3105 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
3106 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3279 },
3107 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3280 },
3108 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3281 },
3109 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3282 },
3110 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3283 },
3111 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3284 },
3112 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3285 },
3113 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 3286 },
3114 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3287 },
3115 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2245 },
3116 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3289 },
3117 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3290 },
3118 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3291 },
3119 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3292 },
3120 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3293 },
3121 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3294 },
3122 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3295 },
3123 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3296 },
3124 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3297 },
3125 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3298 },
3126 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3299 },
3127 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3300 },
3128 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3301 },
3129 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3302 },
3130 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3303 },
3131 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3304 },
3132 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3305 },
3133 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 486 },
3134 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3306 },
3135 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3307 },
3136 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3308 },
3137 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 },
3138 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3309 },
3139 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
3140 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3310 },
3141 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3311 },
3142 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3312 },
3143 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3313 },
3144 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3314 },
3145 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3315 },
3146 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3316 },
3147 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3317 },
3148 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3318 },
3149 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3319 },
3150 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3321 },
3151 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3322 },
3152 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3323 },
3153 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3324 },
3154 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1948 },
3155 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3325 },
3156 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3326 },
3157 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3328 },
3158 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3330 },
3159 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2865 },
3160 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3331 },
3161 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3332 },
3162 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3333 },
3163 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3334 },
3164 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3335 },
3165 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3336 },
3166 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3337 },
3167 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3338 },
3168 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3339 },
3169 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3340 },
3170 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3341 },
3171 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3342 },
3172 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3343 },
3173 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3344 },
3174 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3345 },
3175 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3351 },
3176 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3352 },
3177 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3353 },
3178 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3354 },
3179 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3356 },
3180 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3357 },
3181 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3352 },
3182 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3358 },
3183 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3359 },
3184 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3360 },
3185 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3361 },
3186 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3362 },
3187 .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3181 },
3188 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
3189 .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3190 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 },
3191 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3365 },
3192 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3020 },
3193 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 },
3194 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3363 },
3195 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3365 },
3196 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3020 },
3197 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3365 },
3198 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 },
3199 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 },
3200 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3363 },
3201 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 648 },
3202 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 },
3203 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 648 },
3204 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3366 },
3205 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 },
3206 .{ .char = '8', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3207 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2319 },
3208 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3367 },
3209 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3368 },
3210 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3369 },
3211 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3370 },
3212 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3371 },
3213 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3372 },
3214 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
3215 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3373 },
3216 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3374 },
3217 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 581 },
3218 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3375 },
3219 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3376 },
3220 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3377 },
3221 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3378 },
3222 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3379 },
3223 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3380 },
3224 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
3225 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3381 },
3226 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
3227 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3382 },
3228 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3383 },
3229 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
3230 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3384 },
3231 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 },
3232 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3385 },
3233 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3052 },
3234 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3386 },
3235 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3387 },
3236 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3388 },
3237 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3389 },
3238 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3390 },
3239 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 },
3240 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3392 },
3241 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
3242 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 },
3243 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3394 },
3244 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3395 },
3245 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3396 },
3246 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3398 },
3247 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3400 },
3248 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 },
3249 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3402 },
3250 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3404 },
3251 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3405 },
3252 .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3406 },
3253 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3407 },
3254 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 },
3255 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3409 },
3256 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2248 },
3257 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 },
3258 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3410 },
3259 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3411 },
3260 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3413 },
3261 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3415 },
3262 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3416 },
3263 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 },
3264 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3417 },
3265 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 },
3266 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 17, .child_index = 3419 },
3267 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3065 },
3268 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3421 },
3269 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
3270 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 },
3271 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 },
3272 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3422 },
3273 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3423 },
3274 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 },
3275 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3390 },
3276 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3392 },
3277 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
3278 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3127 },
3279 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 },
3280 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
3281 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2722 },
3282 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
3283 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 },
3284 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3424 },
3285 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3426 },
3286 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3125 },
3287 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
3288 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2765 },
3289 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
3290 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2746 },
3291 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3427 },
3292 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3428 },
3293 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
3294 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
3295 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3296 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3297 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3431 },
3298 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
3299 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
3300 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2794 },
3301 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
3302 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3303 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3304 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 },
3305 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 },
3306 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
3307 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 },
3308 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2765 },
3309 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3131 },
3310 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3311 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3312 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3313 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 },
3314 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3102 },
3315 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3432 },
3316 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 },
3317 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2053 },
3318 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3434 },
3319 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3435 },
3320 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3436 },
3321 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3437 },
3322 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3439 },
3323 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3440 },
3324 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 },
3325 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3441 },
3326 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3442 },
3327 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3443 },
3328 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3329 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3444 },
3330 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3444 },
3331 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2560 },
3332 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2560 },
3333 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3445 },
3334 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 },
3335 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 },
3336 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3446 },
3337 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3447 },
3338 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 },
3339 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3448 },
3340 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3449 },
3341 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 },
3342 .{ .char = '4', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
3343 .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3344 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3345 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3346 .{ .char = 'u', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3347 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3450 },
3348 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3452 },
3349 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3408 },
3350 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 },
3351 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3453 },
3352 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3454 },
3353 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3455 },
3354 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 },
3355 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3456 },
3356 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3164 },
3357 .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 3458 },
3358 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3359 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3460 },
3360 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3461 },
3361 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3462 },
3362 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3463 },
3363 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3464 },
3364 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3465 },
3365 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3466 },
3366 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3467 },
3367 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 },
3368 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 },
3369 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
3370 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3468 },
3371 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3469 },
3372 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2878 },
3373 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3470 },
3374 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 },
3375 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3210 },
3376 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3210 },
3377 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3471 },
3378 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3472 },
3379 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3473 },
3380 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3474 },
3381 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3475 },
3382 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3476 },
3383 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3477 },
3384 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3478 },
3385 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3481 },
3386 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3482 },
3387 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3483 },
3388 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3484 },
3389 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3485 },
3390 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3486 },
3391 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3488 },
3392 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 3489 },
3393 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3491 },
3394 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 242, .child_index = 3492 },
3395 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 3497 },
3396 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3498 },
3397 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3500 },
3398 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 3501 },
3399 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3502 },
3400 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 42, .child_index = 3504 },
3401 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3508 },
3402 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3509 },
3403 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
3404 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3510 },
3405 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3511 },
3406 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3512 },
3407 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 15, .child_index = 3513 },
3408 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3515 },
3409 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3516 },
3410 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 3517 },
3411 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 45, .child_index = 3518 },
3412 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3519 },
3413 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3516 },
3414 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3520 },
3415 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3521 },
3416 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3522 },
3417 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 186, .child_index = 3523 },
3418 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 3528 },
3419 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3529 },
3420 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 20, .child_index = 3530 },
3421 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 32, .child_index = 3532 },
3422 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 35, .child_index = 3536 },
3423 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3542 },
3424 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3543 },
3425 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3544 },
3426 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 34, .child_index = 3545 },
3427 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3546 },
3428 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 },
3429 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3548 },
3430 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3549 },
3431 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3550 },
3432 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3551 },
3433 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3553 },
3434 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3554 },
3435 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3555 },
3436 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3556 },
3437 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3561 },
3438 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3562 },
3439 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3563 },
3440 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3564 },
3441 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3564 },
3442 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 48, .child_index = 3566 },
3443 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 3572 },
3444 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3251 },
3445 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3574 },
3446 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3575 },
3447 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3576 },
3448 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3577 },
3449 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3578 },
3450 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3579 },
3451 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3369 },
3452 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3583 },
3453 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3584 },
3454 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3585 },
3455 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3586 },
3456 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
3457 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1665 },
3458 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2640 },
3459 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3588 },
3460 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 },
3461 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3056 },
3462 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3589 },
3463 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 3590 },
3464 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3591 },
3465 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3591 },
3466 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3592 },
3467 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 },
3468 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3593 },
3469 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2245 },
3470 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3290 },
3471 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 },
3472 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3594 },
3473 .{ .char = 'h', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 },
3474 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3595 },
3475 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3596 },
3476 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3597 },
3477 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3598 },
3478 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
3479 .{ .char = 'E', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3599 },
3480 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3600 },
3481 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 10, .child_index = 3601 },
3482 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
3483 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3606 },
3484 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3607 },
3485 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3608 },
3486 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3609 },
3487 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3610 },
3488 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3611 },
3489 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3612 },
3490 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3613 },
3491 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3614 },
3492 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3615 },
3493 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
3494 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3616 },
3495 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3617 },
3496 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3618 },
3497 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3619 },
3498 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3620 },
3499 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3626 },
3500 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2555 },
3501 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 },
3502 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3627 },
3503 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3628 },
3504 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3629 },
3505 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3630 },
3506 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3631 },
3507 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3632 },
3508 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3633 },
3509 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3634 },
3510 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3636 },
3511 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3637 },
3512 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
3513 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3638 },
3514 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3640 },
3515 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3641 },
3516 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3642 },
3517 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3643 },
3518 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3644 },
3519 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 },
3520 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3645 },
3521 .{ .char = 'q', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 3646 },
3522 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3648 },
3523 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3649 },
3524 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3651 },
3525 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3652 },
3526 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3653 },
3527 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3655 },
3528 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3656 },
3529 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
3530 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3657 },
3531 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3658 },
3532 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
3533 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3659 },
3534 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3660 },
3535 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3658 },
3536 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3661 },
3537 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3662 },
3538 .{ .char = 'T', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3663 },
3539 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3664 },
3540 .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3541 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3542 .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3543 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
3544 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3456 },
3545 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3665 },
3546 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3579 },
3547 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3666 },
3548 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3667 },
3549 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3668 },
3550 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3669 },
3551 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3670 },
3552 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3671 },
3553 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3672 },
3554 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3673 },
3555 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3674 },
3556 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3675 },
3557 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3676 },
3558 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3677 },
3559 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3442 },
3560 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3678 },
3561 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2672 },
3562 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3679 },
3563 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3680 },
3564 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3681 },
3565 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3682 },
3566 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3683 },
3567 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3684 },
3568 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3686 },
3569 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3687 },
3570 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3690 },
3571 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 },
3572 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3691 },
3573 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3692 },
3574 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3693 },
3575 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3695 },
3576 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3400 },
3577 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3696 },
3578 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 },
3579 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3699 },
3580 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3700 },
3581 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3701 },
3582 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3401 },
3583 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
3584 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3702 },
3585 .{ .char = 'u', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3586 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3705 },
3587 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
3588 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
3589 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 },
3590 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3707 },
3591 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3708 },
3592 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3709 },
3593 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3711 },
3594 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3713 },
3595 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3714 },
3596 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 3716 },
3597 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 3718 },
3598 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3720 },
3599 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3721 },
3600 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3724 },
3601 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3727 },
3602 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3727 },
3603 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
3604 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3728 },
3605 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 },
3606 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3607 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3608 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3427 },
3609 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3730 },
3610 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3731 },
3611 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3732 },
3612 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3733 },
3613 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3734 },
3614 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3735 },
3615 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3736 },
3616 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3737 },
3617 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3738 },
3618 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3739 },
3619 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3620 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3740 },
3621 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3622 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3741 },
3623 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 },
3624 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3742 },
3625 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3743 },
3626 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3744 },
3627 .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3628 .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3629 .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3630 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
3631 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3745 },
3632 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3747 },
3633 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3634 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3635 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3748 },
3636 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3749 },
3637 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3750 },
3638 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3751 },
3639 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3752 },
3640 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3753 },
3641 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3754 },
3642 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3755 },
3643 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3756 },
3644 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3757 },
3645 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3579 },
3646 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3468 },
3647 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
3648 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3758 },
3649 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3759 },
3650 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3204 },
3651 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3760 },
3652 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3761 },
3653 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3762 },
3654 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3763 },
3655 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3765 },
3656 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3765 },
3657 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3765 },
3658 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3766 },
3659 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3767 },
3660 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3768 },
3661 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3770 },
3662 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3771 },
3663 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3772 },
3664 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3773 },
3665 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3774 },
3666 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3776 },
3667 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3777 },
3668 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3778 },
3669 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3779 },
3670 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3780 },
3671 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 206, .child_index = 3781 },
3672 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3786 },
3673 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3787 },
3674 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3788 },
3675 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3789 },
3676 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3790 },
3677 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
3678 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3792 },
3679 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3793 },
3680 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3794 },
3681 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3795 },
3682 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3796 },
3683 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3796 },
3684 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3798 },
3685 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3500 },
3686 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3799 },
3687 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3800 },
3688 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 3801 },
3689 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 },
3690 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3803 },
3691 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 },
3692 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 3801 },
3693 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3808 },
3694 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 3809 },
3695 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 45, .child_index = 3813 },
3696 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 },
3697 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3815 },
3698 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3816 },
3699 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3817 },
3700 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3818 },
3701 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3820 },
3702 .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 114, .child_index = 3821 },
3703 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3825 },
3704 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3826 },
3705 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 3827 },
3706 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3829 },
3707 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3831 },
3708 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3832 },
3709 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3834 },
3710 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3835 },
3711 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3837 },
3712 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3838 },
3713 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3840 },
3714 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3841 },
3715 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3842 },
3716 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3845 },
3717 .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3846 },
3718 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 },
3719 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3849 },
3720 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3849 },
3721 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3850 },
3722 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 34, .child_index = 3852 },
3723 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3854 },
3724 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3855 },
3725 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3856 },
3726 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3857 },
3727 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3858 },
3728 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3860 },
3729 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3861 },
3730 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 },
3731 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3863 },
3732 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3553 },
3733 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3864 },
3734 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3865 },
3735 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3868 },
3736 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3869 },
3737 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3865 },
3738 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3870 },
3739 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3871 },
3740 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3872 },
3741 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3873 },
3742 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3875 },
3743 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3876 },
3744 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 },
3745 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3878 },
3746 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3882 },
3747 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3883 },
3748 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3878 },
3749 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3801 },
3750 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3884 },
3751 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3886 },
3752 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3888 },
3753 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3889 },
3754 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3890 },
3755 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
3756 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
3757 .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2311 },
3758 .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 },
3759 .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3760 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3891 },
3761 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3894 },
3762 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3895 },
3763 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3764 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 },
3765 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 },
3766 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3898 },
3767 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 3899 },
3768 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 },
3769 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3591 },
3770 .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 },
3771 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3900 },
3772 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3901 },
3773 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 },
3774 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1699 },
3775 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3902 },
3776 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3903 },
3777 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3024 },
3778 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
3779 .{ .char = '8', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3780 .{ .char = 'A', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3904 },
3781 .{ .char = 'P', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3046 },
3782 .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3905 },
3783 .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3906 },
3784 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3907 },
3785 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 },
3786 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 },
3787 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3908 },
3788 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3909 },
3789 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3910 },
3790 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3911 },
3791 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3912 },
3792 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3913 },
3793 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3914 },
3794 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3918 },
3795 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3919 },
3796 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3920 },
3797 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3922 },
3798 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3923 },
3799 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3924 },
3800 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3925 },
3801 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3927 },
3802 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3928 },
3803 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3929 },
3804 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3930 },
3805 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3659 },
3806 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3931 },
3807 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3932 },
3808 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3933 },
3809 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3934 },
3810 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3935 },
3811 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3936 },
3812 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2934 },
3813 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3937 },
3814 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 },
3815 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3938 },
3816 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3817 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3939 },
3818 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3940 },
3819 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 },
3820 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3942 },
3821 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3943 },
3822 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3944 },
3823 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3947 },
3824 .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3825 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3948 },
3826 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3949 },
3827 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3950 },
3828 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3951 },
3829 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3950 },
3830 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3952 },
3831 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3954 },
3832 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3955 },
3833 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3956 },
3834 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3958 },
3835 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3959 },
3836 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 },
3837 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3960 },
3838 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3961 },
3839 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3962 },
3840 .{ .char = 'T', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 3964 },
3841 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3966 },
3842 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3967 },
3843 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3968 },
3844 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3969 },
3845 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3970 },
3846 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 },
3847 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
3848 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3971 },
3849 .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3972 },
3850 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3973 },
3851 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3974 },
3852 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3975 },
3853 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3679 },
3854 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3976 },
3855 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3977 },
3856 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 },
3857 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3978 },
3858 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2237 },
3859 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3979 },
3860 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3980 },
3861 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
3862 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 },
3863 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3982 },
3864 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
3865 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 },
3866 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 },
3867 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3985 },
3868 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2568 },
3869 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 },
3870 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3698 },
3871 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 },
3872 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3400 },
3873 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3987 },
3874 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3988 },
3875 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 578 },
3876 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3990 },
3877 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3992 },
3878 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3993 },
3879 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3994 },
3880 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3996 },
3881 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3882 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3997 },
3883 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3998 },
3884 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3999 },
3885 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4000 },
3886 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4001 },
3887 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 },
3888 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 },
3889 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4002 },
3890 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 },
3891 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
3892 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
3893 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4003 },
3894 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4005 },
3895 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4006 },
3896 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4008 },
3897 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4010 },
3898 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
3899 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 },
3900 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 },
3901 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
3902 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 },
3903 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3980 },
3904 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4011 },
3905 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 },
3906 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 },
3907 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4014 },
3908 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4015 },
3909 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4016 },
3910 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4017 },
3911 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4018 },
3912 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4019 },
3913 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 },
3914 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4020 },
3915 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4021 },
3916 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4022 },
3917 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3918 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4023 },
3919 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 },
3920 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4024 },
3921 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4025 },
3922 .{ .char = '4', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
3923 .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
3924 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4026 },
3925 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4027 },
3926 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3748 },
3927 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4028 },
3928 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4029 },
3929 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4030 },
3930 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4031 },
3931 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4032 },
3932 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4033 },
3933 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4035 },
3934 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4036 },
3935 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4037 },
3936 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4038 },
3937 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4041 },
3938 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 },
3939 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4042 },
3940 .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4043 },
3941 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4044 },
3942 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4045 },
3943 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4046 },
3944 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4047 },
3945 .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4049 },
3946 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4050 },
3947 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4051 },
3948 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4052 },
3949 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4054 },
3950 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
3951 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4056 },
3952 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4057 },
3953 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4054 },
3954 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4060 },
3955 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
3956 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3773 },
3957 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4062 },
3958 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 4063 },
3959 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4065 },
3960 .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 170, .child_index = 4066 },
3961 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4069 },
3962 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4070 },
3963 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4071 },
3964 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4073 },
3965 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4057 },
3966 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4074 },
3967 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4074 },
3968 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4075 },
3969 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4076 },
3970 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 },
3971 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4078 },
3972 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4079 },
3973 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4082 },
3974 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4082 },
3975 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4054 },
3976 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4083 },
3977 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4085 },
3978 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 4086 },
3979 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4088 },
3980 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4090 },
3981 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4090 },
3982 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4090 },
3983 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4090 },
3984 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4091 },
3985 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4092 },
3986 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4093 },
3987 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4096 },
3988 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4097 },
3989 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 4099 },
3990 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 27, .child_index = 4101 },
3991 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4103 },
3992 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 },
3993 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 },
3994 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 },
3995 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 4107 },
3996 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 },
3997 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 },
3998 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 4109 },
3999 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 4113 },
4000 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 4109 },
4001 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 4109 },
4002 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4107 },
4003 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 },
4004 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 4118 },
4005 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3825 },
4006 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4119 },
4007 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4120 },
4008 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4121 },
4009 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 4105 },
4010 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4122 },
4011 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4124 },
4012 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4125 },
4013 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4125 },
4014 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4126 },
4015 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3834 },
4016 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3837 },
4017 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4127 },
4018 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4129 },
4019 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4130 },
4020 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4131 },
4021 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4131 },
4022 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4132 },
4023 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3840 },
4024 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3841 },
4025 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3845 },
4026 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4086 },
4027 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4133 },
4028 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4134 },
4029 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 22, .child_index = 4135 },
4030 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4088 },
4031 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4137 },
4032 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4138 },
4033 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 },
4034 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 },
4035 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 },
4036 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 },
4037 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4140 },
4038 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4140 },
4039 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4141 },
4040 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4142 },
4041 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3877 },
4042 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3864 },
4043 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3868 },
4044 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3869 },
4045 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4143 },
4046 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4145 },
4047 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4146 },
4048 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4147 },
4049 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4148 },
4050 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3875 },
4051 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4149 },
4052 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4151 },
4053 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4152 },
4054 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4155 },
4055 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3876 },
4056 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 },
4057 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3882 },
4058 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3883 },
4059 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4156 },
4060 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4158 },
4061 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3862 },
4062 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4159 },
4063 .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2311 },
4064 .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 },
4065 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4161 },
4066 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4162 },
4067 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4164 },
4068 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4069 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4070 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 },
4071 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 },
4072 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4073 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 },
4074 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3586 },
4075 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3367 },
4076 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 4165 },
4077 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4173 },
4078 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4174 },
4079 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 4175 },
4080 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4176 },
4081 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1708 },
4082 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2622 },
4083 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4177 },
4084 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4178 },
4085 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4179 },
4086 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4180 },
4087 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4181 },
4088 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4182 },
4089 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4183 },
4090 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 },
4091 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 },
4092 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 568 },
4093 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 },
4094 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 },
4095 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4184 },
4096 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4185 },
4097 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4186 },
4098 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4188 },
4099 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2680 },
4100 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3927 },
4101 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4189 },
4102 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4190 },
4103 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4191 },
4104 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4193 },
4105 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4194 },
4106 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
4107 .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
4108 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4195 },
4109 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4196 },
4110 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4197 },
4111 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4198 },
4112 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4199 },
4113 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4200 },
4114 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4201 },
4115 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4202 },
4116 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4203 },
4117 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4204 },
4118 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4205 },
4119 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4206 },
4120 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 },
4121 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4208 },
4122 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4209 },
4123 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4210 },
4124 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4211 },
4125 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4212 },
4126 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4213 },
4127 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4214 },
4128 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4215 },
4129 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4217 },
4130 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4218 },
4131 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4220 },
4132 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4221 },
4133 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4222 },
4134 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3011 },
4135 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4223 },
4136 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 },
4137 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4224 },
4138 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4225 },
4139 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4226 },
4140 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4227 },
4141 .{ .char = 'A', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 4228 },
4142 .{ .char = 'T', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4143 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
4144 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4229 },
4145 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4230 },
4146 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 4231 },
4147 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
4148 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4233 },
4149 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1840 },
4150 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4234 },
4151 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 4235 },
4152 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4247 },
4153 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4248 },
4154 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4249 },
4155 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4250 },
4156 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
4157 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4251 },
4158 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4254 },
4159 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
4160 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3981 },
4161 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4162 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 },
4163 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 },
4164 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 },
4165 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4256 },
4166 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 },
4167 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 },
4168 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4257 },
4169 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4258 },
4170 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4260 },
4171 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2507 },
4172 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4261 },
4173 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 656 },
4174 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4262 },
4175 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3997 },
4176 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3998 },
4177 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4263 },
4178 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 },
4179 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4264 },
4180 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3997 },
4181 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4005 },
4182 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4265 },
4183 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4266 },
4184 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4267 },
4185 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4268 },
4186 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4271 },
4187 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 },
4188 .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4189 .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4190 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4191 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
4192 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 },
4193 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4272 },
4194 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4273 },
4195 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4275 },
4196 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4276 },
4197 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4277 },
4198 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3196 },
4199 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4278 },
4200 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4279 },
4201 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4280 },
4202 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4281 },
4203 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3456 },
4204 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3308 },
4205 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4284 },
4206 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4285 },
4207 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4286 },
4208 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4287 },
4209 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4288 },
4210 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4289 },
4211 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4290 },
4212 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4291 },
4213 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3676 },
4214 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4041 },
4215 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4292 },
4216 .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4217 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4292 },
4218 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4293 },
4219 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 },
4220 .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 },
4221 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 },
4222 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4294 },
4223 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4295 },
4224 .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4296 },
4225 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
4226 .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4296 },
4227 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
4228 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4297 },
4229 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4298 },
4230 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4299 },
4231 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3791 },
4232 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
4233 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4300 },
4234 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4301 },
4235 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4302 },
4236 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4303 },
4237 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4304 },
4238 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4305 },
4239 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
4240 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4306 },
4241 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
4242 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
4243 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4307 },
4244 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 84, .child_index = 4309 },
4245 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 84, .child_index = 4309 },
4246 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4306 },
4247 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
4248 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4314 },
4249 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4069 },
4250 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
4251 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 },
4252 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4315 },
4253 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4057 },
4254 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4317 },
4255 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4318 },
4256 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4146 },
4257 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4319 },
4258 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4320 },
4259 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4321 },
4260 .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 },
4261 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
4262 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3761 },
4263 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3547 },
4264 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4322 },
4265 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3547 },
4266 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 },
4267 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4324 },
4268 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4325 },
4269 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4326 },
4270 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 },
4271 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 },
4272 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 },
4273 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4327 },
4274 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 },
4275 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 },
4276 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 4329 },
4277 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4329 },
4278 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4331 },
4279 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4332 },
4280 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4331 },
4281 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4331 },
4282 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3547 },
4283 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 },
4284 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4334 },
4285 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4334 },
4286 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4335 },
4287 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 },
4288 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 },
4289 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4338 },
4290 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4341 },
4291 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4335 },
4292 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 },
4293 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 },
4294 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4338 },
4295 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4107 },
4296 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4343 },
4297 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4343 },
4298 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3858 },
4299 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3862 },
4300 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 },
4301 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4345 },
4302 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3838 },
4303 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3834 },
4304 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3841 },
4305 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3845 },
4306 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4346 },
4307 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4347 },
4308 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4127 },
4309 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3841 },
4310 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4349 },
4311 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4351 },
4312 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 4352 },
4313 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4322 },
4314 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4325 },
4315 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4325 },
4316 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4325 },
4317 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4354 },
4318 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4356 },
4319 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4357 },
4320 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3864 },
4321 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3869 },
4322 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3864 },
4323 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 },
4324 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4361 },
4325 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4362 },
4326 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4363 },
4327 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4363 },
4328 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4364 },
4329 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 },
4330 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3882 },
4331 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3883 },
4332 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4365 },
4333 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 },
4334 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3883 },
4335 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3877 },
4336 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4366 },
4337 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4366 },
4338 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4367 },
4339 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4369 },
4340 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4369 },
4341 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4370 },
4342 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4371 },
4343 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4373 },
4344 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4374 },
4345 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 4375 },
4346 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4379 },
4347 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4380 },
4348 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4381 },
4349 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4382 },
4350 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4383 },
4351 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4384 },
4352 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 4385 },
4353 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4387 },
4354 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4388 },
4355 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4389 },
4356 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4390 },
4357 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4391 },
4358 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4392 },
4359 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4394 },
4360 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4395 },
4361 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4396 },
4362 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4399 },
4363 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4400 },
4364 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4401 },
4365 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4402 },
4366 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 405 },
4367 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4403 },
4368 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4404 },
4369 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 },
4370 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4405 },
4371 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4406 },
4372 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4407 },
4373 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4409 },
4374 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4410 },
4375 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4411 },
4376 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4412 },
4377 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4413 },
4378 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4414 },
4379 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4415 },
4380 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4416 },
4381 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4418 },
4382 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2319 },
4383 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4420 },
4384 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4421 },
4385 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4422 },
4386 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4423 },
4387 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3979 },
4388 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4424 },
4389 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4425 },
4390 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4426 },
4391 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4427 },
4392 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 },
4393 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4428 },
4394 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4429 },
4395 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4430 },
4396 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4428 },
4397 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
4398 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4431 },
4399 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 },
4400 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4432 },
4401 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4434 },
4402 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3648 },
4403 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4435 },
4404 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4436 },
4405 .{ .char = 'T', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4406 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4437 },
4407 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4438 },
4408 .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3024 },
4409 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4410 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4439 },
4411 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4440 },
4412 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4441 },
4413 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4443 },
4414 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4444 },
4415 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4447 },
4416 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4448 },
4417 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4450 },
4418 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2245 },
4419 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4451 },
4420 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3609 },
4421 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4452 },
4422 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4454 },
4423 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4457 },
4424 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4458 },
4425 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4459 },
4426 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4460 },
4427 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4461 },
4428 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
4429 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 },
4430 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4431 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 },
4432 .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4433 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4462 },
4434 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4463 },
4435 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 },
4436 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3405 },
4437 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4464 },
4438 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 },
4439 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4465 },
4440 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4466 },
4441 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3405 },
4442 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4467 },
4443 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 },
4444 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4468 },
4445 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4469 },
4446 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4266 },
4447 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4470 },
4448 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4471 },
4449 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4472 },
4450 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1893 },
4451 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4473 },
4452 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4474 },
4453 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 },
4454 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4475 },
4455 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4476 },
4456 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4477 },
4457 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4478 },
4458 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2137 },
4459 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4479 },
4460 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 },
4461 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4480 },
4462 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4481 },
4463 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4482 },
4464 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4483 },
4465 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4484 },
4466 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4485 },
4467 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4486 },
4468 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4487 },
4469 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
4470 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4488 },
4471 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 },
4472 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4473 .{ .char = 'M', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4474 .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4489 },
4475 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4490 },
4476 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4491 },
4477 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4492 },
4478 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4493 },
4479 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 },
4480 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 },
4481 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 },
4482 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4494 },
4483 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4496 },
4484 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4497 },
4485 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4497 },
4486 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4498 },
4487 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4499 },
4488 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 4501 },
4489 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4504 },
4490 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 4507 },
4491 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4306 },
4492 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4493 },
4493 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4493 },
4494 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4146 },
4495 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4508 },
4496 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3870 },
4497 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3870 },
4498 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4510 },
4499 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4511 },
4500 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4511 },
4501 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4512 },
4502 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4513 },
4503 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4516 },
4504 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4091 },
4505 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4517 },
4506 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4518 },
4507 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4518 },
4508 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4519 },
4509 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4520 },
4510 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4520 },
4511 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4521 },
4512 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4522 },
4513 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4522 },
4514 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4522 },
4515 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4524 },
4516 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4522 },
4517 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4525 },
4518 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4526 },
4519 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4526 },
4520 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4527 },
4521 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4527 },
4522 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4529 },
4523 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 },
4524 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4131 },
4525 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4131 },
4526 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4530 },
4527 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4530 },
4528 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4531 },
4529 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3855 },
4530 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4533 },
4531 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4527 },
4532 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4534 },
4533 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4536 },
4534 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4508 },
4535 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4508 },
4536 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4537 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4538 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4538 },
4539 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4539 },
4540 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3875 },
4541 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4540 },
4542 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4536 },
4543 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 },
4544 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4542 },
4545 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 },
4546 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4543 },
4547 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4544 },
4548 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4545 },
4549 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4546 },
4550 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4547 },
4551 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4548 },
4552 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4549 },
4553 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4380 },
4554 .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4381 },
4555 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4382 },
4556 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4550 },
4557 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4554 },
4558 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4555 },
4559 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4556 },
4560 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4557 },
4561 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4558 },
4562 .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 4559 },
4563 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4560 },
4564 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4561 },
4565 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4562 },
4566 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4563 },
4567 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4564 },
4568 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4565 },
4569 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 },
4570 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 },
4571 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4566 },
4572 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4568 },
4573 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4569 },
4574 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4571 },
4575 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2214 },
4576 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4572 },
4577 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4573 },
4578 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3913 },
4579 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4574 },
4580 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
4581 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
4582 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4575 },
4583 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4576 },
4584 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3637 },
4585 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4577 },
4586 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4578 },
4587 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4579 },
4588 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
4589 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4580 },
4590 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4582 },
4591 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4583 },
4592 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4584 },
4593 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1389 },
4594 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 },
4595 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4420 },
4596 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4585 },
4597 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4586 },
4598 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4587 },
4599 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4588 },
4600 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4589 },
4601 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3324 },
4602 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 },
4603 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4590 },
4604 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4591 },
4605 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1940 },
4606 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4592 },
4607 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2819 },
4608 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 },
4609 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3648 },
4610 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4593 },
4611 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4594 },
4612 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4595 },
4613 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4596 },
4614 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4597 },
4615 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4598 },
4616 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
4617 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4599 },
4618 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 },
4619 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4600 },
4620 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4601 },
4621 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4602 },
4622 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 738 },
4623 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4603 },
4624 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2268 },
4625 .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4605 },
4626 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 },
4627 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4606 },
4628 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4607 },
4629 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 580 },
4630 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4608 },
4631 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 },
4632 .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 286 },
4633 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4609 },
4634 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4610 },
4635 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4611 },
4636 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4612 },
4637 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4613 },
4638 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4614 },
4639 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 },
4640 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4261 },
4641 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 561 },
4642 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4615 },
4643 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3701 },
4644 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4616 },
4645 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4617 },
4646 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4261 },
4647 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4618 },
4648 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4619 },
4649 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4620 },
4650 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2199 },
4651 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4621 },
4652 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4622 },
4653 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4623 },
4654 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4624 },
4655 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3301 },
4656 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1129 },
4657 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4627 },
4658 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4628 },
4659 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4632 },
4660 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4634 },
4661 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4635 },
4662 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4636 },
4663 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4637 },
4664 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4638 },
4665 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4639 },
4666 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4640 },
4667 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4668 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4298 },
4669 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4642 },
4670 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4642 },
4671 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4301 },
4672 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4645 },
4673 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4646 },
4674 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4648 },
4675 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4649 },
4676 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4649 },
4677 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4649 },
4678 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4649 },
4679 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 4109 },
4680 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4649 },
4681 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4651 },
4682 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4649 },
4683 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4652 },
4684 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 4109 },
4685 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4317 },
4686 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4653 },
4687 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4654 },
4688 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 },
4689 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4513 },
4690 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4691 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4516 },
4692 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4693 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4694 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 },
4695 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4327 },
4696 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4656 },
4697 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4331 },
4698 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4658 },
4699 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4660 },
4700 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4661 },
4701 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4662 },
4702 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4662 },
4703 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4295 },
4704 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4663 },
4705 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4663 },
4706 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4664 },
4707 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4667 },
4708 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4668 },
4709 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4668 },
4710 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4669 },
4711 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4670 },
4712 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4670 },
4713 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4714 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4715 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4512 },
4716 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4346 },
4717 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4513 },
4718 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4513 },
4719 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3609 },
4720 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4671 },
4721 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4673 },
4722 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4674 },
4723 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4381 },
4724 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4675 },
4725 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4676 },
4726 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4546 },
4727 .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4728 .{ .char = '1', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4729 .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4730 .{ .char = '3', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4731 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 },
4732 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4677 },
4733 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4678 },
4734 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 },
4735 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4679 },
4736 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4680 },
4737 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4681 },
4738 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4682 },
4739 .{ .char = 'C', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4683 },
4740 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4684 },
4741 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4685 },
4742 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4686 },
4743 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4687 },
4744 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4688 },
4745 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4689 },
4746 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3026 },
4747 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4690 },
4748 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4692 },
4749 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 },
4750 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 },
4751 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4693 },
4752 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 },
4753 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3470 },
4754 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4694 },
4755 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4695 },
4756 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4696 },
4757 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4697 },
4758 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4698 },
4759 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 },
4760 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4700 },
4761 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4701 },
4762 .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4702 },
4763 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4703 },
4764 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
4765 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4704 },
4766 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4705 },
4767 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4706 },
4768 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4707 },
4769 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4708 },
4770 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4709 },
4771 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4710 },
4772 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4711 },
4773 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4712 },
4774 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4713 },
4775 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4714 },
4776 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4715 },
4777 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4716 },
4778 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4717 },
4779 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4718 },
4780 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4719 },
4781 .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4782 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 },
4783 .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 4720 },
4784 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4722 },
4785 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4723 },
4786 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4716 },
4787 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1663 },
4788 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4724 },
4789 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 },
4790 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4725 },
4791 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4726 },
4792 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 561 },
4793 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4727 },
4794 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4728 },
4795 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4730 },
4796 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4731 },
4797 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4732 },
4798 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4733 },
4799 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4734 },
4800 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4735 },
4801 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4736 },
4802 .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4738 },
4803 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4739 },
4804 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4740 },
4805 .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4741 },
4806 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4742 },
4807 .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4743 },
4808 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4744 },
4809 .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4745 },
4810 .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4745 },
4811 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4746 },
4812 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4747 },
4813 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4748 },
4814 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4636 },
4815 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4751 },
4816 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4752 },
4817 .{ .char = 'a', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4818 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4819 .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4516 },
4820 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4821 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4822 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4753 },
4823 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4301 },
4824 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4315 },
4825 .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4826 .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4754 },
4827 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4755 },
4828 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4756 },
4829 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4756 },
4830 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4757 },
4831 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4642 },
4832 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4642 },
4833 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4325 },
4834 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4540 },
4835 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4091 },
4836 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4138 },
4837 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4356 },
4838 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4524 },
4839 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4660 },
4840 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4758 },
4841 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4842 .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4359 },
4843 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 },
4844 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 },
4845 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4759 },
4846 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4760 },
4847 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4762 },
4848 .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4763 },
4849 .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4764 },
4850 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4765 },
4851 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4766 },
4852 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4554 },
4853 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4767 },
4854 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4769 },
4855 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4554 },
4856 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 873 },
4857 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4560 },
4858 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 4773 },
4859 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4775 },
4860 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4776 },
4861 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4777 },
4862 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4778 },
4863 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4779 },
4864 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4780 },
4865 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4780 },
4866 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4781 },
4867 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
4868 .{ .char = '8', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4782 },
4869 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4783 },
4870 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 },
4871 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3659 },
4872 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4636 },
4873 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4784 },
4874 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 },
4875 .{ .char = '1', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 4785 },
4876 .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4785 },
4877 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4786 },
4878 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 },
4879 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 },
4880 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4787 },
4881 .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 4788 },
4882 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4789 },
4883 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4790 },
4884 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4791 },
4885 .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4792 },
4886 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4793 },
4887 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 },
4888 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4794 },
4889 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4289 },
4890 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4795 },
4891 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4796 },
4892 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4797 },
4893 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4798 },
4894 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4799 },
4895 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4800 },
4896 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2236 },
4897 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4801 },
4898 .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4899 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4802 },
4900 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4803 },
4901 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4804 },
4902 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4805 },
4903 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4806 },
4904 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4807 },
4905 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4469 },
4906 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4618 },
4907 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4469 },
4908 .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4266 },
4909 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4808 },
4910 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4809 },
4911 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4810 },
4912 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4811 },
4913 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4812 },
4914 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4812 },
4915 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4813 },
4916 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4814 },
4917 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4815 },
4918 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4816 },
4919 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4817 },
4920 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4818 },
4921 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4819 },
4922 .{ .char = 'D', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4820 },
4923 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4822 },
4924 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 },
4925 .{ .char = 'x', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4926 .{ .char = 'y', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4927 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4928 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4823 },
4929 .{ .char = '5', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4824 },
4930 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4301 },
4931 .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4825 },
4932 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4651 },
4933 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4754 },
4934 .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 },
4935 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 },
4936 .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 },
4937 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4146 },
4938 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4146 },
4939 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4826 },
4940 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 },
4941 .{ .char = '4', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 },
4942 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4828 },
4943 .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1938 },
4944 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 },
4945 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4829 },
4946 .{ .char = 'w', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4947 .{ .char = 'x', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4948 .{ .char = 'y', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
4949 .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4950 .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 },
4951 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4830 },
4952 .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 4833 },
4953 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4837 },
4954 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4838 },
4955 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4839 },
4956 .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4840 },
4957 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3886 },
4958 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4841 },
4959 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4842 },
4960 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4843 },
4961 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4844 },
4962 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4845 },
4963 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4846 },
4964 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4847 },
4965 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4416 },
4966 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4210 },
4967 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4848 },
4968 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4849 },
4969 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4850 },
4970 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4851 },
4971 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4852 },
4972 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4854 },
4973 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4855 },
4974 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4856 },
4975 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4857 },
4976 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4858 },
4977 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4859 },
4978 .{ .char = '0', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
4979 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4860 },
4980 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4861 },
4981 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4862 },
4982 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4863 },
4983 .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4864 },
4984 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4865 },
4985 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4867 },
4986 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4868 },
4987 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4869 },
4988 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4739 },
4989 .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4813 },
4990 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 },
4991 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4870 },
4992 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4871 },
4993 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4872 },
4994 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4873 },
4995 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4874 },
4996 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4873 },
4997 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4875 },
4998 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4875 },
4999 .{ .char = 'D', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4877 },
5000 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4880 },
5001 .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4881 },
5002 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4882 },
5003 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4757 },
5004 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4757 },
5005 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4884 },
5006 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4885 },
5007 .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4886 },
5008 .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 496 },
5009 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3366 },
5010 .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 },
5011 .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 },
5012 .{ .char = '8', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
5013 .{ .char = 'P', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4887 },
5014 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4888 },
5015 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4889 },
5016 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3052 },
5017 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4890 },
5018 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4891 },
5019 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2568 },
5020 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4892 },
5021 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2808 },
5022 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 },
5023 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4894 },
5024 .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 },
5025 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 },
5026 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4895 },
5027 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4896 },
5028 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3961 },
5029 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4485 },
5030 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4409 },
5031 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4897 },
5032 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4898 },
5033 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4899 },
5034 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
5035 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4900 },
5036 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4901 },
5037 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 471 },
5038 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4902 },
5039 .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4903 },
5040 .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4904 },
5041 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4905 },
5042 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 4906 },
5043 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4906 },
5044 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4907 },
5045 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2877 },
5046 .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4908 },
5047 .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4813 },
5048 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 183 },
5049 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4909 },
5050 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4910 },
5051 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4911 },
5052 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4912 },
5053 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4912 },
5054 .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4912 },
5055 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4912 },
5056 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 },
5057 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4693 },
5058 .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4914 },
5059 .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 },
5060 .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
5061 .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4916 },
5062 .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4917 },
5063 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4918 },
5064 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4919 },
5065 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4920 },
5066 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4921 },
5067 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2963 },
5068 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4925 },
5069 .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3026 },
5070 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 },
5071 .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4926 },
5072 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3366 },
5073 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 },
5074 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4927 },
5075 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4928 },
5076 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 },
5077 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4929 },
5078 .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4930 },
5079 .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 },
5080 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4931 },
5081 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4932 },
5082 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4017 },
5083 .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
5084 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4933 },
5085 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4934 },
5086 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4935 },
5087 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 },
5088 .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4936 },
5089 .{ .char = '_', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
5090 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4912 },
5091 .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
5092 .{ .char = 'u', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
5093 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4937 },
5094 .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4938 },
5095 .{ .char = 'q', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
5096 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4939 },
5097 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4940 },
5098 .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4941 },
5099 .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4587 },
5100 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 520 },
5101 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 420 },
5102 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4942 },
5103 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4943 },
5104 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4944 },
5105 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4945 },
5106 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3301 },
5107 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4946 },
5108 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4947 },
5109 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3195 },
5110 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4948 },
5111 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2460 },
5112 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4949 },
5113 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 },
5114 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4950 },
5115 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4952 },
5116 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4955 },
5117 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4956 },
5118 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4957 },
5119 .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
5120 .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4958 },
5121 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3578 },
5122 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 },
5123 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 },
5124 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4959 },
5125 .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 },
5126 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4960 },
5127 .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4961 },
5128 .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 821 },
5129 .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4918 },
5130 .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4962 },
5131 .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4962 },
5132 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4964 },
5133 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4965 },
5134 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4966 },
5135 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 },
5136 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 },
5137 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4967 },
5138 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4969 },
5139 .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 },
5140 .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 },
5141 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4970 },
5142 .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4971 },
5143 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4972 },
5144 .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4973 },
5145 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4974 },
5146 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1440 },
5147 .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4975 },
5148 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4976 },
5149 .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 },
5150 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4977 },
5151 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4978 },
5152 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 },
5153 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4979 },
5154 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4980 },
5155 .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4981 },
5156 .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1701 },
5157 .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4982 },
5158 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4983 },
5159 .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4984 },
5160 .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 },
5161 .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4985 },
5162 .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4986 },
5163 .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4987 },
5164 .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 },
5165};
5166pub const data = blk: {
5167 @setEvalBranchQuota(3986);
5168 break :blk [_]@This(){
5169 // _Block_object_assign
5170 .{ .tag = @enumFromInt(0), .properties = .{ .param_str = "vv*vC*iC", .header = .blocks, .attributes = .{ .lib_function_without_prefix = true } } },
5171 // _Block_object_dispose
5172 .{ .tag = @enumFromInt(1), .properties = .{ .param_str = "vvC*iC", .header = .blocks, .attributes = .{ .lib_function_without_prefix = true } } },
5173 // _Exit
5174 .{ .tag = @enumFromInt(2), .properties = .{ .param_str = "vi", .header = .stdlib, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } },
5175 // _InterlockedAnd
5176 .{ .tag = @enumFromInt(3), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } },
5177 // _InterlockedAnd16
5178 .{ .tag = @enumFromInt(4), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } },
5179 // _InterlockedAnd8
5180 .{ .tag = @enumFromInt(5), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } },
5181 // _InterlockedCompareExchange
5182 .{ .tag = @enumFromInt(6), .properties = .{ .param_str = "NiNiD*NiNi", .language = .all_ms_languages } },
5183 // _InterlockedCompareExchange16
5184 .{ .tag = @enumFromInt(7), .properties = .{ .param_str = "ssD*ss", .language = .all_ms_languages } },
5185 // _InterlockedCompareExchange64
5186 .{ .tag = @enumFromInt(8), .properties = .{ .param_str = "LLiLLiD*LLiLLi", .language = .all_ms_languages } },
5187 // _InterlockedCompareExchange8
5188 .{ .tag = @enumFromInt(9), .properties = .{ .param_str = "ccD*cc", .language = .all_ms_languages } },
5189 // _InterlockedCompareExchangePointer
5190 .{ .tag = @enumFromInt(10), .properties = .{ .param_str = "v*v*D*v*v*", .language = .all_ms_languages } },
5191 // _InterlockedCompareExchangePointer_nf
5192 .{ .tag = @enumFromInt(11), .properties = .{ .param_str = "v*v*D*v*v*", .language = .all_ms_languages } },
5193 // _InterlockedDecrement
5194 .{ .tag = @enumFromInt(12), .properties = .{ .param_str = "NiNiD*", .language = .all_ms_languages } },
5195 // _InterlockedDecrement16
5196 .{ .tag = @enumFromInt(13), .properties = .{ .param_str = "ssD*", .language = .all_ms_languages } },
5197 // _InterlockedExchange
5198 .{ .tag = @enumFromInt(14), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } },
5199 // _InterlockedExchange16
5200 .{ .tag = @enumFromInt(15), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } },
5201 // _InterlockedExchange8
5202 .{ .tag = @enumFromInt(16), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } },
5203 // _InterlockedExchangeAdd
5204 .{ .tag = @enumFromInt(17), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } },
5205 // _InterlockedExchangeAdd16
5206 .{ .tag = @enumFromInt(18), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } },
5207 // _InterlockedExchangeAdd8
5208 .{ .tag = @enumFromInt(19), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } },
5209 // _InterlockedExchangePointer
5210 .{ .tag = @enumFromInt(20), .properties = .{ .param_str = "v*v*D*v*", .language = .all_ms_languages } },
5211 // _InterlockedExchangeSub
5212 .{ .tag = @enumFromInt(21), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } },
5213 // _InterlockedExchangeSub16
5214 .{ .tag = @enumFromInt(22), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } },
5215 // _InterlockedExchangeSub8
5216 .{ .tag = @enumFromInt(23), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } },
5217 // _InterlockedIncrement
5218 .{ .tag = @enumFromInt(24), .properties = .{ .param_str = "NiNiD*", .language = .all_ms_languages } },
5219 // _InterlockedIncrement16
5220 .{ .tag = @enumFromInt(25), .properties = .{ .param_str = "ssD*", .language = .all_ms_languages } },
5221 // _InterlockedOr
5222 .{ .tag = @enumFromInt(26), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } },
5223 // _InterlockedOr16
5224 .{ .tag = @enumFromInt(27), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } },
5225 // _InterlockedOr8
5226 .{ .tag = @enumFromInt(28), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } },
5227 // _InterlockedXor
5228 .{ .tag = @enumFromInt(29), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } },
5229 // _InterlockedXor16
5230 .{ .tag = @enumFromInt(30), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } },
5231 // _InterlockedXor8
5232 .{ .tag = @enumFromInt(31), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } },
5233 // _MoveFromCoprocessor
5234 .{ .tag = @enumFromInt(32), .properties = .{ .param_str = "UiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } },
5235 // _MoveFromCoprocessor2
5236 .{ .tag = @enumFromInt(33), .properties = .{ .param_str = "UiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } },
5237 // _MoveToCoprocessor
5238 .{ .tag = @enumFromInt(34), .properties = .{ .param_str = "vUiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } },
5239 // _MoveToCoprocessor2
5240 .{ .tag = @enumFromInt(35), .properties = .{ .param_str = "vUiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } },
5241 // _ReturnAddress
5242 .{ .tag = @enumFromInt(36), .properties = .{ .param_str = "v*", .language = .all_ms_languages } },
5243 // __GetExceptionInfo
5244 .{ .tag = @enumFromInt(37), .properties = .{ .param_str = "v*.", .language = .all_ms_languages, .attributes = .{ .custom_typecheck = true, .eval_args = false } } },
5245 // __abnormal_termination
5246 .{ .tag = @enumFromInt(38), .properties = .{ .param_str = "i", .language = .all_ms_languages } },
5247 // __annotation
5248 .{ .tag = @enumFromInt(39), .properties = .{ .param_str = "wC*.", .language = .all_ms_languages } },
5249 // __arithmetic_fence
5250 .{ .tag = @enumFromInt(40), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } },
5251 // __assume
5252 .{ .tag = @enumFromInt(41), .properties = .{ .param_str = "vb", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
5253 // __atomic_add_fetch
5254 .{ .tag = @enumFromInt(42), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5255 // __atomic_always_lock_free
5256 .{ .tag = @enumFromInt(43), .properties = .{ .param_str = "bzvCD*", .attributes = .{ .const_evaluable = true } } },
5257 // __atomic_and_fetch
5258 .{ .tag = @enumFromInt(44), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5259 // __atomic_clear
5260 .{ .tag = @enumFromInt(45), .properties = .{ .param_str = "vvD*i" } },
5261 // __atomic_compare_exchange
5262 .{ .tag = @enumFromInt(46), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5263 // __atomic_compare_exchange_n
5264 .{ .tag = @enumFromInt(47), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5265 // __atomic_exchange
5266 .{ .tag = @enumFromInt(48), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5267 // __atomic_exchange_n
5268 .{ .tag = @enumFromInt(49), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5269 // __atomic_fetch_add
5270 .{ .tag = @enumFromInt(50), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5271 // __atomic_fetch_and
5272 .{ .tag = @enumFromInt(51), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5273 // __atomic_fetch_max
5274 .{ .tag = @enumFromInt(52), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5275 // __atomic_fetch_min
5276 .{ .tag = @enumFromInt(53), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5277 // __atomic_fetch_nand
5278 .{ .tag = @enumFromInt(54), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5279 // __atomic_fetch_or
5280 .{ .tag = @enumFromInt(55), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5281 // __atomic_fetch_sub
5282 .{ .tag = @enumFromInt(56), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5283 // __atomic_fetch_xor
5284 .{ .tag = @enumFromInt(57), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5285 // __atomic_is_lock_free
5286 .{ .tag = @enumFromInt(58), .properties = .{ .param_str = "bzvCD*", .attributes = .{ .const_evaluable = true } } },
5287 // __atomic_load
5288 .{ .tag = @enumFromInt(59), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5289 // __atomic_load_n
5290 .{ .tag = @enumFromInt(60), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5291 // __atomic_max_fetch
5292 .{ .tag = @enumFromInt(61), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5293 // __atomic_min_fetch
5294 .{ .tag = @enumFromInt(62), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5295 // __atomic_nand_fetch
5296 .{ .tag = @enumFromInt(63), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5297 // __atomic_or_fetch
5298 .{ .tag = @enumFromInt(64), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5299 // __atomic_signal_fence
5300 .{ .tag = @enumFromInt(65), .properties = .{ .param_str = "vi" } },
5301 // __atomic_store
5302 .{ .tag = @enumFromInt(66), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5303 // __atomic_store_n
5304 .{ .tag = @enumFromInt(67), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5305 // __atomic_sub_fetch
5306 .{ .tag = @enumFromInt(68), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5307 // __atomic_test_and_set
5308 .{ .tag = @enumFromInt(69), .properties = .{ .param_str = "bvD*i" } },
5309 // __atomic_thread_fence
5310 .{ .tag = @enumFromInt(70), .properties = .{ .param_str = "vi" } },
5311 // __atomic_xor_fetch
5312 .{ .tag = @enumFromInt(71), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5313 // __builtin___CFStringMakeConstantString
5314 .{ .tag = @enumFromInt(72), .properties = .{ .param_str = "FC*cC*", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5315 // __builtin___NSStringMakeConstantString
5316 .{ .tag = @enumFromInt(73), .properties = .{ .param_str = "FC*cC*", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5317 // __builtin___clear_cache
5318 .{ .tag = @enumFromInt(74), .properties = .{ .param_str = "vc*c*" } },
5319 // __builtin___fprintf_chk
5320 .{ .tag = @enumFromInt(75), .properties = .{ .param_str = "iP*RicC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 2 } } },
5321 // __builtin___get_unsafe_stack_bottom
5322 .{ .tag = @enumFromInt(76), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5323 // __builtin___get_unsafe_stack_ptr
5324 .{ .tag = @enumFromInt(77), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5325 // __builtin___get_unsafe_stack_start
5326 .{ .tag = @enumFromInt(78), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5327 // __builtin___get_unsafe_stack_top
5328 .{ .tag = @enumFromInt(79), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5329 // __builtin___memccpy_chk
5330 .{ .tag = @enumFromInt(80), .properties = .{ .param_str = "v*v*vC*izz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5331 // __builtin___memcpy_chk
5332 .{ .tag = @enumFromInt(81), .properties = .{ .param_str = "v*v*vC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5333 // __builtin___memmove_chk
5334 .{ .tag = @enumFromInt(82), .properties = .{ .param_str = "v*v*vC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5335 // __builtin___mempcpy_chk
5336 .{ .tag = @enumFromInt(83), .properties = .{ .param_str = "v*v*vC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5337 // __builtin___memset_chk
5338 .{ .tag = @enumFromInt(84), .properties = .{ .param_str = "v*v*izz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5339 // __builtin___printf_chk
5340 .{ .tag = @enumFromInt(85), .properties = .{ .param_str = "iicC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 } } },
5341 // __builtin___snprintf_chk
5342 .{ .tag = @enumFromInt(86), .properties = .{ .param_str = "ic*RzizcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 4 } } },
5343 // __builtin___sprintf_chk
5344 .{ .tag = @enumFromInt(87), .properties = .{ .param_str = "ic*RizcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 3 } } },
5345 // __builtin___stpcpy_chk
5346 .{ .tag = @enumFromInt(88), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5347 // __builtin___stpncpy_chk
5348 .{ .tag = @enumFromInt(89), .properties = .{ .param_str = "c*c*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5349 // __builtin___strcat_chk
5350 .{ .tag = @enumFromInt(90), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5351 // __builtin___strcpy_chk
5352 .{ .tag = @enumFromInt(91), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5353 // __builtin___strlcat_chk
5354 .{ .tag = @enumFromInt(92), .properties = .{ .param_str = "zc*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5355 // __builtin___strlcpy_chk
5356 .{ .tag = @enumFromInt(93), .properties = .{ .param_str = "zc*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5357 // __builtin___strncat_chk
5358 .{ .tag = @enumFromInt(94), .properties = .{ .param_str = "c*c*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5359 // __builtin___strncpy_chk
5360 .{ .tag = @enumFromInt(95), .properties = .{ .param_str = "c*c*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5361 // __builtin___vfprintf_chk
5362 .{ .tag = @enumFromInt(96), .properties = .{ .param_str = "iP*RicC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 2 } } },
5363 // __builtin___vprintf_chk
5364 .{ .tag = @enumFromInt(97), .properties = .{ .param_str = "iicC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } },
5365 // __builtin___vsnprintf_chk
5366 .{ .tag = @enumFromInt(98), .properties = .{ .param_str = "ic*RzizcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 4 } } },
5367 // __builtin___vsprintf_chk
5368 .{ .tag = @enumFromInt(99), .properties = .{ .param_str = "ic*RizcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 3 } } },
5369 // __builtin_abort
5370 .{ .tag = @enumFromInt(100), .properties = .{ .param_str = "v", .attributes = .{ .noreturn = true, .lib_function_with_builtin_prefix = true } } },
5371 // __builtin_abs
5372 .{ .tag = @enumFromInt(101), .properties = .{ .param_str = "ii", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
5373 // __builtin_acos
5374 .{ .tag = @enumFromInt(102), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5375 // __builtin_acosf
5376 .{ .tag = @enumFromInt(103), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5377 // __builtin_acosf128
5378 .{ .tag = @enumFromInt(104), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5379 // __builtin_acosh
5380 .{ .tag = @enumFromInt(105), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5381 // __builtin_acoshf
5382 .{ .tag = @enumFromInt(106), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5383 // __builtin_acoshf128
5384 .{ .tag = @enumFromInt(107), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5385 // __builtin_acoshl
5386 .{ .tag = @enumFromInt(108), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5387 // __builtin_acosl
5388 .{ .tag = @enumFromInt(109), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5389 // __builtin_add_overflow
5390 .{ .tag = @enumFromInt(110), .properties = .{ .param_str = "b.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } },
5391 // __builtin_addc
5392 .{ .tag = @enumFromInt(111), .properties = .{ .param_str = "UiUiCUiCUiCUi*" } },
5393 // __builtin_addcb
5394 .{ .tag = @enumFromInt(112), .properties = .{ .param_str = "UcUcCUcCUcCUc*" } },
5395 // __builtin_addcl
5396 .{ .tag = @enumFromInt(113), .properties = .{ .param_str = "ULiULiCULiCULiCULi*" } },
5397 // __builtin_addcll
5398 .{ .tag = @enumFromInt(114), .properties = .{ .param_str = "ULLiULLiCULLiCULLiCULLi*" } },
5399 // __builtin_addcs
5400 .{ .tag = @enumFromInt(115), .properties = .{ .param_str = "UsUsCUsCUsCUs*" } },
5401 // __builtin_align_down
5402 .{ .tag = @enumFromInt(116), .properties = .{ .param_str = "v*vC*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } },
5403 // __builtin_align_up
5404 .{ .tag = @enumFromInt(117), .properties = .{ .param_str = "v*vC*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } },
5405 // __builtin_alloca
5406 .{ .tag = @enumFromInt(118), .properties = .{ .param_str = "v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5407 // __builtin_alloca_uninitialized
5408 .{ .tag = @enumFromInt(119), .properties = .{ .param_str = "v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5409 // __builtin_alloca_with_align
5410 .{ .tag = @enumFromInt(120), .properties = .{ .param_str = "v*zIz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5411 // __builtin_alloca_with_align_uninitialized
5412 .{ .tag = @enumFromInt(121), .properties = .{ .param_str = "v*zIz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5413 // __builtin_amdgcn_alignbit
5414 .{ .tag = @enumFromInt(122), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5415 // __builtin_amdgcn_alignbyte
5416 .{ .tag = @enumFromInt(123), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5417 // __builtin_amdgcn_atomic_dec32
5418 .{ .tag = @enumFromInt(124), .properties = .{ .param_str = "UZiUZiD*UZiUicC*", .target_set = TargetSet.initOne(.amdgpu) } },
5419 // __builtin_amdgcn_atomic_dec64
5420 .{ .tag = @enumFromInt(125), .properties = .{ .param_str = "UWiUWiD*UWiUicC*", .target_set = TargetSet.initOne(.amdgpu) } },
5421 // __builtin_amdgcn_atomic_inc32
5422 .{ .tag = @enumFromInt(126), .properties = .{ .param_str = "UZiUZiD*UZiUicC*", .target_set = TargetSet.initOne(.amdgpu) } },
5423 // __builtin_amdgcn_atomic_inc64
5424 .{ .tag = @enumFromInt(127), .properties = .{ .param_str = "UWiUWiD*UWiUicC*", .target_set = TargetSet.initOne(.amdgpu) } },
5425 // __builtin_amdgcn_buffer_wbinvl1
5426 .{ .tag = @enumFromInt(128), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } },
5427 // __builtin_amdgcn_class
5428 .{ .tag = @enumFromInt(129), .properties = .{ .param_str = "bdi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5429 // __builtin_amdgcn_classf
5430 .{ .tag = @enumFromInt(130), .properties = .{ .param_str = "bfi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5431 // __builtin_amdgcn_cosf
5432 .{ .tag = @enumFromInt(131), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5433 // __builtin_amdgcn_cubeid
5434 .{ .tag = @enumFromInt(132), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5435 // __builtin_amdgcn_cubema
5436 .{ .tag = @enumFromInt(133), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5437 // __builtin_amdgcn_cubesc
5438 .{ .tag = @enumFromInt(134), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5439 // __builtin_amdgcn_cubetc
5440 .{ .tag = @enumFromInt(135), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5441 // __builtin_amdgcn_cvt_pk_i16
5442 .{ .tag = @enumFromInt(136), .properties = .{ .param_str = "E2sii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5443 // __builtin_amdgcn_cvt_pk_u16
5444 .{ .tag = @enumFromInt(137), .properties = .{ .param_str = "E2UsUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5445 // __builtin_amdgcn_cvt_pk_u8_f32
5446 .{ .tag = @enumFromInt(138), .properties = .{ .param_str = "UifUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5447 // __builtin_amdgcn_cvt_pknorm_i16
5448 .{ .tag = @enumFromInt(139), .properties = .{ .param_str = "E2sff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5449 // __builtin_amdgcn_cvt_pknorm_u16
5450 .{ .tag = @enumFromInt(140), .properties = .{ .param_str = "E2Usff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5451 // __builtin_amdgcn_cvt_pkrtz
5452 .{ .tag = @enumFromInt(141), .properties = .{ .param_str = "E2hff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5453 // __builtin_amdgcn_dispatch_ptr
5454 .{ .tag = @enumFromInt(142), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5455 // __builtin_amdgcn_div_fixup
5456 .{ .tag = @enumFromInt(143), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5457 // __builtin_amdgcn_div_fixupf
5458 .{ .tag = @enumFromInt(144), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5459 // __builtin_amdgcn_div_fmas
5460 .{ .tag = @enumFromInt(145), .properties = .{ .param_str = "ddddb", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5461 // __builtin_amdgcn_div_fmasf
5462 .{ .tag = @enumFromInt(146), .properties = .{ .param_str = "ffffb", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5463 // __builtin_amdgcn_div_scale
5464 .{ .tag = @enumFromInt(147), .properties = .{ .param_str = "dddbb*", .target_set = TargetSet.initOne(.amdgpu) } },
5465 // __builtin_amdgcn_div_scalef
5466 .{ .tag = @enumFromInt(148), .properties = .{ .param_str = "fffbb*", .target_set = TargetSet.initOne(.amdgpu) } },
5467 // __builtin_amdgcn_ds_append
5468 .{ .tag = @enumFromInt(149), .properties = .{ .param_str = "ii*3", .target_set = TargetSet.initOne(.amdgpu) } },
5469 // __builtin_amdgcn_ds_bpermute
5470 .{ .tag = @enumFromInt(150), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5471 // __builtin_amdgcn_ds_consume
5472 .{ .tag = @enumFromInt(151), .properties = .{ .param_str = "ii*3", .target_set = TargetSet.initOne(.amdgpu) } },
5473 // __builtin_amdgcn_ds_faddf
5474 .{ .tag = @enumFromInt(152), .properties = .{ .param_str = "ff*3fIiIiIb", .target_set = TargetSet.initOne(.amdgpu) } },
5475 // __builtin_amdgcn_ds_fmaxf
5476 .{ .tag = @enumFromInt(153), .properties = .{ .param_str = "ff*3fIiIiIb", .target_set = TargetSet.initOne(.amdgpu) } },
5477 // __builtin_amdgcn_ds_fminf
5478 .{ .tag = @enumFromInt(154), .properties = .{ .param_str = "ff*3fIiIiIb", .target_set = TargetSet.initOne(.amdgpu) } },
5479 // __builtin_amdgcn_ds_permute
5480 .{ .tag = @enumFromInt(155), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5481 // __builtin_amdgcn_ds_swizzle
5482 .{ .tag = @enumFromInt(156), .properties = .{ .param_str = "iiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5483 // __builtin_amdgcn_endpgm
5484 .{ .tag = @enumFromInt(157), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .noreturn = true } } },
5485 // __builtin_amdgcn_exp2f
5486 .{ .tag = @enumFromInt(158), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5487 // __builtin_amdgcn_fcmp
5488 .{ .tag = @enumFromInt(159), .properties = .{ .param_str = "WUiddIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5489 // __builtin_amdgcn_fcmpf
5490 .{ .tag = @enumFromInt(160), .properties = .{ .param_str = "WUiffIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5491 // __builtin_amdgcn_fence
5492 .{ .tag = @enumFromInt(161), .properties = .{ .param_str = "vUicC*", .target_set = TargetSet.initOne(.amdgpu) } },
5493 // __builtin_amdgcn_fmed3f
5494 .{ .tag = @enumFromInt(162), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5495 // __builtin_amdgcn_fract
5496 .{ .tag = @enumFromInt(163), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5497 // __builtin_amdgcn_fractf
5498 .{ .tag = @enumFromInt(164), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5499 // __builtin_amdgcn_frexp_exp
5500 .{ .tag = @enumFromInt(165), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5501 // __builtin_amdgcn_frexp_expf
5502 .{ .tag = @enumFromInt(166), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5503 // __builtin_amdgcn_frexp_mant
5504 .{ .tag = @enumFromInt(167), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5505 // __builtin_amdgcn_frexp_mantf
5506 .{ .tag = @enumFromInt(168), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5507 // __builtin_amdgcn_grid_size_x
5508 .{ .tag = @enumFromInt(169), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5509 // __builtin_amdgcn_grid_size_y
5510 .{ .tag = @enumFromInt(170), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5511 // __builtin_amdgcn_grid_size_z
5512 .{ .tag = @enumFromInt(171), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5513 // __builtin_amdgcn_groupstaticsize
5514 .{ .tag = @enumFromInt(172), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu) } },
5515 // __builtin_amdgcn_iglp_opt
5516 .{ .tag = @enumFromInt(173), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } },
5517 // __builtin_amdgcn_implicitarg_ptr
5518 .{ .tag = @enumFromInt(174), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5519 // __builtin_amdgcn_interp_mov
5520 .{ .tag = @enumFromInt(175), .properties = .{ .param_str = "fUiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5521 // __builtin_amdgcn_interp_p1
5522 .{ .tag = @enumFromInt(176), .properties = .{ .param_str = "ffUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5523 // __builtin_amdgcn_interp_p1_f16
5524 .{ .tag = @enumFromInt(177), .properties = .{ .param_str = "ffUiUibUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5525 // __builtin_amdgcn_interp_p2
5526 .{ .tag = @enumFromInt(178), .properties = .{ .param_str = "fffUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5527 // __builtin_amdgcn_interp_p2_f16
5528 .{ .tag = @enumFromInt(179), .properties = .{ .param_str = "hffUiUibUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5529 // __builtin_amdgcn_is_private
5530 .{ .tag = @enumFromInt(180), .properties = .{ .param_str = "bvC*0", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5531 // __builtin_amdgcn_is_shared
5532 .{ .tag = @enumFromInt(181), .properties = .{ .param_str = "bvC*0", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5533 // __builtin_amdgcn_kernarg_segment_ptr
5534 .{ .tag = @enumFromInt(182), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5535 // __builtin_amdgcn_ldexp
5536 .{ .tag = @enumFromInt(183), .properties = .{ .param_str = "ddi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5537 // __builtin_amdgcn_ldexpf
5538 .{ .tag = @enumFromInt(184), .properties = .{ .param_str = "ffi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5539 // __builtin_amdgcn_lerp
5540 .{ .tag = @enumFromInt(185), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5541 // __builtin_amdgcn_log_clampf
5542 .{ .tag = @enumFromInt(186), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5543 // __builtin_amdgcn_logf
5544 .{ .tag = @enumFromInt(187), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5545 // __builtin_amdgcn_mbcnt_hi
5546 .{ .tag = @enumFromInt(188), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5547 // __builtin_amdgcn_mbcnt_lo
5548 .{ .tag = @enumFromInt(189), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5549 // __builtin_amdgcn_mqsad_pk_u16_u8
5550 .{ .tag = @enumFromInt(190), .properties = .{ .param_str = "WUiWUiUiWUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5551 // __builtin_amdgcn_mqsad_u32_u8
5552 .{ .tag = @enumFromInt(191), .properties = .{ .param_str = "V4UiWUiUiV4Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5553 // __builtin_amdgcn_msad_u8
5554 .{ .tag = @enumFromInt(192), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5555 // __builtin_amdgcn_qsad_pk_u16_u8
5556 .{ .tag = @enumFromInt(193), .properties = .{ .param_str = "WUiWUiUiWUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5557 // __builtin_amdgcn_queue_ptr
5558 .{ .tag = @enumFromInt(194), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5559 // __builtin_amdgcn_rcp
5560 .{ .tag = @enumFromInt(195), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5561 // __builtin_amdgcn_rcpf
5562 .{ .tag = @enumFromInt(196), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5563 // __builtin_amdgcn_read_exec
5564 .{ .tag = @enumFromInt(197), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5565 // __builtin_amdgcn_read_exec_hi
5566 .{ .tag = @enumFromInt(198), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5567 // __builtin_amdgcn_read_exec_lo
5568 .{ .tag = @enumFromInt(199), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5569 // __builtin_amdgcn_readfirstlane
5570 .{ .tag = @enumFromInt(200), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5571 // __builtin_amdgcn_readlane
5572 .{ .tag = @enumFromInt(201), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5573 // __builtin_amdgcn_rsq
5574 .{ .tag = @enumFromInt(202), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5575 // __builtin_amdgcn_rsq_clamp
5576 .{ .tag = @enumFromInt(203), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5577 // __builtin_amdgcn_rsq_clampf
5578 .{ .tag = @enumFromInt(204), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5579 // __builtin_amdgcn_rsqf
5580 .{ .tag = @enumFromInt(205), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5581 // __builtin_amdgcn_s_barrier
5582 .{ .tag = @enumFromInt(206), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } },
5583 // __builtin_amdgcn_s_dcache_inv
5584 .{ .tag = @enumFromInt(207), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } },
5585 // __builtin_amdgcn_s_decperflevel
5586 .{ .tag = @enumFromInt(208), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } },
5587 // __builtin_amdgcn_s_getpc
5588 .{ .tag = @enumFromInt(209), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.amdgpu) } },
5589 // __builtin_amdgcn_s_getreg
5590 .{ .tag = @enumFromInt(210), .properties = .{ .param_str = "UiIi", .target_set = TargetSet.initOne(.amdgpu) } },
5591 // __builtin_amdgcn_s_incperflevel
5592 .{ .tag = @enumFromInt(211), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } },
5593 // __builtin_amdgcn_s_sendmsg
5594 .{ .tag = @enumFromInt(212), .properties = .{ .param_str = "vIiUi", .target_set = TargetSet.initOne(.amdgpu) } },
5595 // __builtin_amdgcn_s_sendmsghalt
5596 .{ .tag = @enumFromInt(213), .properties = .{ .param_str = "vIiUi", .target_set = TargetSet.initOne(.amdgpu) } },
5597 // __builtin_amdgcn_s_setprio
5598 .{ .tag = @enumFromInt(214), .properties = .{ .param_str = "vIs", .target_set = TargetSet.initOne(.amdgpu) } },
5599 // __builtin_amdgcn_s_setreg
5600 .{ .tag = @enumFromInt(215), .properties = .{ .param_str = "vIiUi", .target_set = TargetSet.initOne(.amdgpu) } },
5601 // __builtin_amdgcn_s_sleep
5602 .{ .tag = @enumFromInt(216), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } },
5603 // __builtin_amdgcn_s_waitcnt
5604 .{ .tag = @enumFromInt(217), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } },
5605 // __builtin_amdgcn_sad_hi_u8
5606 .{ .tag = @enumFromInt(218), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5607 // __builtin_amdgcn_sad_u16
5608 .{ .tag = @enumFromInt(219), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5609 // __builtin_amdgcn_sad_u8
5610 .{ .tag = @enumFromInt(220), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5611 // __builtin_amdgcn_sbfe
5612 .{ .tag = @enumFromInt(221), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5613 // __builtin_amdgcn_sched_barrier
5614 .{ .tag = @enumFromInt(222), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } },
5615 // __builtin_amdgcn_sched_group_barrier
5616 .{ .tag = @enumFromInt(223), .properties = .{ .param_str = "vIiIiIi", .target_set = TargetSet.initOne(.amdgpu) } },
5617 // __builtin_amdgcn_sicmp
5618 .{ .tag = @enumFromInt(224), .properties = .{ .param_str = "WUiiiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5619 // __builtin_amdgcn_sicmpl
5620 .{ .tag = @enumFromInt(225), .properties = .{ .param_str = "WUiWiWiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5621 // __builtin_amdgcn_sinf
5622 .{ .tag = @enumFromInt(226), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5623 // __builtin_amdgcn_sqrt
5624 .{ .tag = @enumFromInt(227), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5625 // __builtin_amdgcn_sqrtf
5626 .{ .tag = @enumFromInt(228), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5627 // __builtin_amdgcn_trig_preop
5628 .{ .tag = @enumFromInt(229), .properties = .{ .param_str = "ddi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5629 // __builtin_amdgcn_trig_preopf
5630 .{ .tag = @enumFromInt(230), .properties = .{ .param_str = "ffi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5631 // __builtin_amdgcn_ubfe
5632 .{ .tag = @enumFromInt(231), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5633 // __builtin_amdgcn_uicmp
5634 .{ .tag = @enumFromInt(232), .properties = .{ .param_str = "WUiUiUiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5635 // __builtin_amdgcn_uicmpl
5636 .{ .tag = @enumFromInt(233), .properties = .{ .param_str = "WUiWUiWUiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5637 // __builtin_amdgcn_wave_barrier
5638 .{ .tag = @enumFromInt(234), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } },
5639 // __builtin_amdgcn_workgroup_id_x
5640 .{ .tag = @enumFromInt(235), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5641 // __builtin_amdgcn_workgroup_id_y
5642 .{ .tag = @enumFromInt(236), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5643 // __builtin_amdgcn_workgroup_id_z
5644 .{ .tag = @enumFromInt(237), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5645 // __builtin_amdgcn_workgroup_size_x
5646 .{ .tag = @enumFromInt(238), .properties = .{ .param_str = "Us", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5647 // __builtin_amdgcn_workgroup_size_y
5648 .{ .tag = @enumFromInt(239), .properties = .{ .param_str = "Us", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5649 // __builtin_amdgcn_workgroup_size_z
5650 .{ .tag = @enumFromInt(240), .properties = .{ .param_str = "Us", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5651 // __builtin_amdgcn_workitem_id_x
5652 .{ .tag = @enumFromInt(241), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5653 // __builtin_amdgcn_workitem_id_y
5654 .{ .tag = @enumFromInt(242), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5655 // __builtin_amdgcn_workitem_id_z
5656 .{ .tag = @enumFromInt(243), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
5657 // __builtin_annotation
5658 .{ .tag = @enumFromInt(244), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
5659 // __builtin_arm_cdp
5660 .{ .tag = @enumFromInt(245), .properties = .{ .param_str = "vUIiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5661 // __builtin_arm_cdp2
5662 .{ .tag = @enumFromInt(246), .properties = .{ .param_str = "vUIiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5663 // __builtin_arm_clrex
5664 .{ .tag = @enumFromInt(247), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
5665 // __builtin_arm_cls
5666 .{ .tag = @enumFromInt(248), .properties = .{ .param_str = "UiZUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5667 // __builtin_arm_cls64
5668 .{ .tag = @enumFromInt(249), .properties = .{ .param_str = "UiWUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5669 // __builtin_arm_clz
5670 .{ .tag = @enumFromInt(250), .properties = .{ .param_str = "UiZUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5671 // __builtin_arm_clz64
5672 .{ .tag = @enumFromInt(251), .properties = .{ .param_str = "UiWUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5673 // __builtin_arm_cmse_TT
5674 .{ .tag = @enumFromInt(252), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } },
5675 // __builtin_arm_cmse_TTA
5676 .{ .tag = @enumFromInt(253), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } },
5677 // __builtin_arm_cmse_TTAT
5678 .{ .tag = @enumFromInt(254), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } },
5679 // __builtin_arm_cmse_TTT
5680 .{ .tag = @enumFromInt(255), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } },
5681 // __builtin_arm_dbg
5682 .{ .tag = @enumFromInt(256), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.arm) } },
5683 // __builtin_arm_dmb
5684 .{ .tag = @enumFromInt(257), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5685 // __builtin_arm_dsb
5686 .{ .tag = @enumFromInt(258), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5687 // __builtin_arm_get_fpscr
5688 .{ .tag = @enumFromInt(259), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5689 // __builtin_arm_isb
5690 .{ .tag = @enumFromInt(260), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5691 // __builtin_arm_ldaex
5692 .{ .tag = @enumFromInt(261), .properties = .{ .param_str = "v.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } },
5693 // __builtin_arm_ldc
5694 .{ .tag = @enumFromInt(262), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } },
5695 // __builtin_arm_ldc2
5696 .{ .tag = @enumFromInt(263), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } },
5697 // __builtin_arm_ldc2l
5698 .{ .tag = @enumFromInt(264), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } },
5699 // __builtin_arm_ldcl
5700 .{ .tag = @enumFromInt(265), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } },
5701 // __builtin_arm_ldrex
5702 .{ .tag = @enumFromInt(266), .properties = .{ .param_str = "v.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } },
5703 // __builtin_arm_ldrexd
5704 .{ .tag = @enumFromInt(267), .properties = .{ .param_str = "LLUiv*", .target_set = TargetSet.initOne(.arm) } },
5705 // __builtin_arm_mcr
5706 .{ .tag = @enumFromInt(268), .properties = .{ .param_str = "vUIiUIiUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5707 // __builtin_arm_mcr2
5708 .{ .tag = @enumFromInt(269), .properties = .{ .param_str = "vUIiUIiUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5709 // __builtin_arm_mcrr
5710 .{ .tag = @enumFromInt(270), .properties = .{ .param_str = "vUIiUIiLLUiUIi", .target_set = TargetSet.initOne(.arm) } },
5711 // __builtin_arm_mcrr2
5712 .{ .tag = @enumFromInt(271), .properties = .{ .param_str = "vUIiUIiLLUiUIi", .target_set = TargetSet.initOne(.arm) } },
5713 // __builtin_arm_mrc
5714 .{ .tag = @enumFromInt(272), .properties = .{ .param_str = "UiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5715 // __builtin_arm_mrc2
5716 .{ .tag = @enumFromInt(273), .properties = .{ .param_str = "UiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5717 // __builtin_arm_mrrc
5718 .{ .tag = @enumFromInt(274), .properties = .{ .param_str = "LLUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5719 // __builtin_arm_mrrc2
5720 .{ .tag = @enumFromInt(275), .properties = .{ .param_str = "LLUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } },
5721 // __builtin_arm_nop
5722 .{ .tag = @enumFromInt(276), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
5723 // __builtin_arm_prefetch
5724 .{ .tag = @enumFromInt(277), .properties = .{ .param_str = "!", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5725 // __builtin_arm_qadd
5726 .{ .tag = @enumFromInt(278), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5727 // __builtin_arm_qadd16
5728 .{ .tag = @enumFromInt(279), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5729 // __builtin_arm_qadd8
5730 .{ .tag = @enumFromInt(280), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5731 // __builtin_arm_qasx
5732 .{ .tag = @enumFromInt(281), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5733 // __builtin_arm_qdbl
5734 .{ .tag = @enumFromInt(282), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5735 // __builtin_arm_qsax
5736 .{ .tag = @enumFromInt(283), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5737 // __builtin_arm_qsub
5738 .{ .tag = @enumFromInt(284), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5739 // __builtin_arm_qsub16
5740 .{ .tag = @enumFromInt(285), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5741 // __builtin_arm_qsub8
5742 .{ .tag = @enumFromInt(286), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5743 // __builtin_arm_rbit
5744 .{ .tag = @enumFromInt(287), .properties = .{ .param_str = "UiUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5745 // __builtin_arm_rbit64
5746 .{ .tag = @enumFromInt(288), .properties = .{ .param_str = "WUiWUi", .target_set = TargetSet.initOne(.aarch64), .attributes = .{ .@"const" = true } } },
5747 // __builtin_arm_rsr
5748 .{ .tag = @enumFromInt(289), .properties = .{ .param_str = "UicC*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5749 // __builtin_arm_rsr64
5750 .{ .tag = @enumFromInt(290), .properties = .{ .param_str = "!", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5751 // __builtin_arm_rsrp
5752 .{ .tag = @enumFromInt(291), .properties = .{ .param_str = "v*cC*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5753 // __builtin_arm_sadd16
5754 .{ .tag = @enumFromInt(292), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5755 // __builtin_arm_sadd8
5756 .{ .tag = @enumFromInt(293), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5757 // __builtin_arm_sasx
5758 .{ .tag = @enumFromInt(294), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5759 // __builtin_arm_sel
5760 .{ .tag = @enumFromInt(295), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5761 // __builtin_arm_set_fpscr
5762 .{ .tag = @enumFromInt(296), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5763 // __builtin_arm_sev
5764 .{ .tag = @enumFromInt(297), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
5765 // __builtin_arm_sevl
5766 .{ .tag = @enumFromInt(298), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
5767 // __builtin_arm_shadd16
5768 .{ .tag = @enumFromInt(299), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5769 // __builtin_arm_shadd8
5770 .{ .tag = @enumFromInt(300), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5771 // __builtin_arm_shasx
5772 .{ .tag = @enumFromInt(301), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5773 // __builtin_arm_shsax
5774 .{ .tag = @enumFromInt(302), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5775 // __builtin_arm_shsub16
5776 .{ .tag = @enumFromInt(303), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5777 // __builtin_arm_shsub8
5778 .{ .tag = @enumFromInt(304), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5779 // __builtin_arm_smlabb
5780 .{ .tag = @enumFromInt(305), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5781 // __builtin_arm_smlabt
5782 .{ .tag = @enumFromInt(306), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5783 // __builtin_arm_smlad
5784 .{ .tag = @enumFromInt(307), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5785 // __builtin_arm_smladx
5786 .{ .tag = @enumFromInt(308), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5787 // __builtin_arm_smlald
5788 .{ .tag = @enumFromInt(309), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5789 // __builtin_arm_smlaldx
5790 .{ .tag = @enumFromInt(310), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5791 // __builtin_arm_smlatb
5792 .{ .tag = @enumFromInt(311), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5793 // __builtin_arm_smlatt
5794 .{ .tag = @enumFromInt(312), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5795 // __builtin_arm_smlawb
5796 .{ .tag = @enumFromInt(313), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5797 // __builtin_arm_smlawt
5798 .{ .tag = @enumFromInt(314), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5799 // __builtin_arm_smlsd
5800 .{ .tag = @enumFromInt(315), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5801 // __builtin_arm_smlsdx
5802 .{ .tag = @enumFromInt(316), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5803 // __builtin_arm_smlsld
5804 .{ .tag = @enumFromInt(317), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5805 // __builtin_arm_smlsldx
5806 .{ .tag = @enumFromInt(318), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5807 // __builtin_arm_smuad
5808 .{ .tag = @enumFromInt(319), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5809 // __builtin_arm_smuadx
5810 .{ .tag = @enumFromInt(320), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5811 // __builtin_arm_smulbb
5812 .{ .tag = @enumFromInt(321), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5813 // __builtin_arm_smulbt
5814 .{ .tag = @enumFromInt(322), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5815 // __builtin_arm_smultb
5816 .{ .tag = @enumFromInt(323), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5817 // __builtin_arm_smultt
5818 .{ .tag = @enumFromInt(324), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5819 // __builtin_arm_smulwb
5820 .{ .tag = @enumFromInt(325), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5821 // __builtin_arm_smulwt
5822 .{ .tag = @enumFromInt(326), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5823 // __builtin_arm_smusd
5824 .{ .tag = @enumFromInt(327), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5825 // __builtin_arm_smusdx
5826 .{ .tag = @enumFromInt(328), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5827 // __builtin_arm_ssat
5828 .{ .tag = @enumFromInt(329), .properties = .{ .param_str = "iiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5829 // __builtin_arm_ssat16
5830 .{ .tag = @enumFromInt(330), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5831 // __builtin_arm_ssax
5832 .{ .tag = @enumFromInt(331), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5833 // __builtin_arm_ssub16
5834 .{ .tag = @enumFromInt(332), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5835 // __builtin_arm_ssub8
5836 .{ .tag = @enumFromInt(333), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5837 // __builtin_arm_stc
5838 .{ .tag = @enumFromInt(334), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } },
5839 // __builtin_arm_stc2
5840 .{ .tag = @enumFromInt(335), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } },
5841 // __builtin_arm_stc2l
5842 .{ .tag = @enumFromInt(336), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } },
5843 // __builtin_arm_stcl
5844 .{ .tag = @enumFromInt(337), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } },
5845 // __builtin_arm_stlex
5846 .{ .tag = @enumFromInt(338), .properties = .{ .param_str = "i.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } },
5847 // __builtin_arm_strex
5848 .{ .tag = @enumFromInt(339), .properties = .{ .param_str = "i.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } },
5849 // __builtin_arm_strexd
5850 .{ .tag = @enumFromInt(340), .properties = .{ .param_str = "iLLUiv*", .target_set = TargetSet.initOne(.arm) } },
5851 // __builtin_arm_sxtab16
5852 .{ .tag = @enumFromInt(341), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5853 // __builtin_arm_sxtb16
5854 .{ .tag = @enumFromInt(342), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5855 // __builtin_arm_tcancel
5856 .{ .tag = @enumFromInt(343), .properties = .{ .param_str = "vWUIi", .target_set = TargetSet.initOne(.aarch64) } },
5857 // __builtin_arm_tcommit
5858 .{ .tag = @enumFromInt(344), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.aarch64) } },
5859 // __builtin_arm_tstart
5860 .{ .tag = @enumFromInt(345), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.aarch64), .attributes = .{ .returns_twice = true } } },
5861 // __builtin_arm_ttest
5862 .{ .tag = @enumFromInt(346), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.aarch64), .attributes = .{ .@"const" = true } } },
5863 // __builtin_arm_uadd16
5864 .{ .tag = @enumFromInt(347), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5865 // __builtin_arm_uadd8
5866 .{ .tag = @enumFromInt(348), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5867 // __builtin_arm_uasx
5868 .{ .tag = @enumFromInt(349), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5869 // __builtin_arm_uhadd16
5870 .{ .tag = @enumFromInt(350), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5871 // __builtin_arm_uhadd8
5872 .{ .tag = @enumFromInt(351), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5873 // __builtin_arm_uhasx
5874 .{ .tag = @enumFromInt(352), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5875 // __builtin_arm_uhsax
5876 .{ .tag = @enumFromInt(353), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5877 // __builtin_arm_uhsub16
5878 .{ .tag = @enumFromInt(354), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5879 // __builtin_arm_uhsub8
5880 .{ .tag = @enumFromInt(355), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5881 // __builtin_arm_uqadd16
5882 .{ .tag = @enumFromInt(356), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5883 // __builtin_arm_uqadd8
5884 .{ .tag = @enumFromInt(357), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5885 // __builtin_arm_uqasx
5886 .{ .tag = @enumFromInt(358), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5887 // __builtin_arm_uqsax
5888 .{ .tag = @enumFromInt(359), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5889 // __builtin_arm_uqsub16
5890 .{ .tag = @enumFromInt(360), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5891 // __builtin_arm_uqsub8
5892 .{ .tag = @enumFromInt(361), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5893 // __builtin_arm_usad8
5894 .{ .tag = @enumFromInt(362), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5895 // __builtin_arm_usada8
5896 .{ .tag = @enumFromInt(363), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5897 // __builtin_arm_usat
5898 .{ .tag = @enumFromInt(364), .properties = .{ .param_str = "UiiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5899 // __builtin_arm_usat16
5900 .{ .tag = @enumFromInt(365), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5901 // __builtin_arm_usax
5902 .{ .tag = @enumFromInt(366), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5903 // __builtin_arm_usub16
5904 .{ .tag = @enumFromInt(367), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5905 // __builtin_arm_usub8
5906 .{ .tag = @enumFromInt(368), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5907 // __builtin_arm_uxtab16
5908 .{ .tag = @enumFromInt(369), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5909 // __builtin_arm_uxtb16
5910 .{ .tag = @enumFromInt(370), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5911 // __builtin_arm_vcvtr_d
5912 .{ .tag = @enumFromInt(371), .properties = .{ .param_str = "fdi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5913 // __builtin_arm_vcvtr_f
5914 .{ .tag = @enumFromInt(372), .properties = .{ .param_str = "ffi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } },
5915 // __builtin_arm_wfe
5916 .{ .tag = @enumFromInt(373), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
5917 // __builtin_arm_wfi
5918 .{ .tag = @enumFromInt(374), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
5919 // __builtin_arm_wsr
5920 .{ .tag = @enumFromInt(375), .properties = .{ .param_str = "vcC*Ui", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5921 // __builtin_arm_wsr64
5922 .{ .tag = @enumFromInt(376), .properties = .{ .param_str = "!", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5923 // __builtin_arm_wsrp
5924 .{ .tag = @enumFromInt(377), .properties = .{ .param_str = "vcC*vC*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
5925 // __builtin_arm_yield
5926 .{ .tag = @enumFromInt(378), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
5927 // __builtin_asin
5928 .{ .tag = @enumFromInt(379), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5929 // __builtin_asinf
5930 .{ .tag = @enumFromInt(380), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5931 // __builtin_asinf128
5932 .{ .tag = @enumFromInt(381), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5933 // __builtin_asinh
5934 .{ .tag = @enumFromInt(382), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5935 // __builtin_asinhf
5936 .{ .tag = @enumFromInt(383), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5937 // __builtin_asinhf128
5938 .{ .tag = @enumFromInt(384), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5939 // __builtin_asinhl
5940 .{ .tag = @enumFromInt(385), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5941 // __builtin_asinl
5942 .{ .tag = @enumFromInt(386), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5943 // __builtin_assume
5944 .{ .tag = @enumFromInt(387), .properties = .{ .param_str = "vb", .attributes = .{ .const_evaluable = true } } },
5945 // __builtin_assume_aligned
5946 .{ .tag = @enumFromInt(388), .properties = .{ .param_str = "v*vC*z.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } },
5947 // __builtin_assume_separate_storage
5948 .{ .tag = @enumFromInt(389), .properties = .{ .param_str = "vvCD*vCD*", .attributes = .{ .const_evaluable = true } } },
5949 // __builtin_atan
5950 .{ .tag = @enumFromInt(390), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5951 // __builtin_atan2
5952 .{ .tag = @enumFromInt(391), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5953 // __builtin_atan2f
5954 .{ .tag = @enumFromInt(392), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5955 // __builtin_atan2f128
5956 .{ .tag = @enumFromInt(393), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5957 // __builtin_atan2l
5958 .{ .tag = @enumFromInt(394), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5959 // __builtin_atanf
5960 .{ .tag = @enumFromInt(395), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5961 // __builtin_atanf128
5962 .{ .tag = @enumFromInt(396), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5963 // __builtin_atanh
5964 .{ .tag = @enumFromInt(397), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5965 // __builtin_atanhf
5966 .{ .tag = @enumFromInt(398), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5967 // __builtin_atanhf128
5968 .{ .tag = @enumFromInt(399), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5969 // __builtin_atanhl
5970 .{ .tag = @enumFromInt(400), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5971 // __builtin_atanl
5972 .{ .tag = @enumFromInt(401), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5973 // __builtin_bcmp
5974 .{ .tag = @enumFromInt(402), .properties = .{ .param_str = "ivC*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
5975 // __builtin_bcopy
5976 .{ .tag = @enumFromInt(403), .properties = .{ .param_str = "vvC*v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5977 // __builtin_bitrev
5978 .{ .tag = @enumFromInt(404), .properties = .{ .param_str = "UiUi", .target_set = TargetSet.initOne(.xcore), .attributes = .{ .@"const" = true } } },
5979 // __builtin_bitreverse16
5980 .{ .tag = @enumFromInt(405), .properties = .{ .param_str = "UsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5981 // __builtin_bitreverse32
5982 .{ .tag = @enumFromInt(406), .properties = .{ .param_str = "UZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5983 // __builtin_bitreverse64
5984 .{ .tag = @enumFromInt(407), .properties = .{ .param_str = "UWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5985 // __builtin_bitreverse8
5986 .{ .tag = @enumFromInt(408), .properties = .{ .param_str = "UcUc", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5987 // __builtin_bswap16
5988 .{ .tag = @enumFromInt(409), .properties = .{ .param_str = "UsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5989 // __builtin_bswap32
5990 .{ .tag = @enumFromInt(410), .properties = .{ .param_str = "UZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5991 // __builtin_bswap64
5992 .{ .tag = @enumFromInt(411), .properties = .{ .param_str = "UWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
5993 // __builtin_bzero
5994 .{ .tag = @enumFromInt(412), .properties = .{ .param_str = "vv*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
5995 // __builtin_cabs
5996 .{ .tag = @enumFromInt(413), .properties = .{ .param_str = "dXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5997 // __builtin_cabsf
5998 .{ .tag = @enumFromInt(414), .properties = .{ .param_str = "fXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
5999 // __builtin_cabsl
6000 .{ .tag = @enumFromInt(415), .properties = .{ .param_str = "LdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6001 // __builtin_cacos
6002 .{ .tag = @enumFromInt(416), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6003 // __builtin_cacosf
6004 .{ .tag = @enumFromInt(417), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6005 // __builtin_cacosh
6006 .{ .tag = @enumFromInt(418), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6007 // __builtin_cacoshf
6008 .{ .tag = @enumFromInt(419), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6009 // __builtin_cacoshl
6010 .{ .tag = @enumFromInt(420), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6011 // __builtin_cacosl
6012 .{ .tag = @enumFromInt(421), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6013 // __builtin_call_with_static_chain
6014 .{ .tag = @enumFromInt(422), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
6015 // __builtin_calloc
6016 .{ .tag = @enumFromInt(423), .properties = .{ .param_str = "v*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6017 // __builtin_canonicalize
6018 .{ .tag = @enumFromInt(424), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true } } },
6019 // __builtin_canonicalizef
6020 .{ .tag = @enumFromInt(425), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true } } },
6021 // __builtin_canonicalizef16
6022 .{ .tag = @enumFromInt(426), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true } } },
6023 // __builtin_canonicalizel
6024 .{ .tag = @enumFromInt(427), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true } } },
6025 // __builtin_carg
6026 .{ .tag = @enumFromInt(428), .properties = .{ .param_str = "dXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6027 // __builtin_cargf
6028 .{ .tag = @enumFromInt(429), .properties = .{ .param_str = "fXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6029 // __builtin_cargl
6030 .{ .tag = @enumFromInt(430), .properties = .{ .param_str = "LdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6031 // __builtin_casin
6032 .{ .tag = @enumFromInt(431), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6033 // __builtin_casinf
6034 .{ .tag = @enumFromInt(432), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6035 // __builtin_casinh
6036 .{ .tag = @enumFromInt(433), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6037 // __builtin_casinhf
6038 .{ .tag = @enumFromInt(434), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6039 // __builtin_casinhl
6040 .{ .tag = @enumFromInt(435), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6041 // __builtin_casinl
6042 .{ .tag = @enumFromInt(436), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6043 // __builtin_catan
6044 .{ .tag = @enumFromInt(437), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6045 // __builtin_catanf
6046 .{ .tag = @enumFromInt(438), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6047 // __builtin_catanh
6048 .{ .tag = @enumFromInt(439), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6049 // __builtin_catanhf
6050 .{ .tag = @enumFromInt(440), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6051 // __builtin_catanhl
6052 .{ .tag = @enumFromInt(441), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6053 // __builtin_catanl
6054 .{ .tag = @enumFromInt(442), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6055 // __builtin_cbrt
6056 .{ .tag = @enumFromInt(443), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6057 // __builtin_cbrtf
6058 .{ .tag = @enumFromInt(444), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6059 // __builtin_cbrtf128
6060 .{ .tag = @enumFromInt(445), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6061 // __builtin_cbrtl
6062 .{ .tag = @enumFromInt(446), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6063 // __builtin_ccos
6064 .{ .tag = @enumFromInt(447), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6065 // __builtin_ccosf
6066 .{ .tag = @enumFromInt(448), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6067 // __builtin_ccosh
6068 .{ .tag = @enumFromInt(449), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6069 // __builtin_ccoshf
6070 .{ .tag = @enumFromInt(450), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6071 // __builtin_ccoshl
6072 .{ .tag = @enumFromInt(451), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6073 // __builtin_ccosl
6074 .{ .tag = @enumFromInt(452), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6075 // __builtin_ceil
6076 .{ .tag = @enumFromInt(453), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6077 // __builtin_ceilf
6078 .{ .tag = @enumFromInt(454), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6079 // __builtin_ceilf128
6080 .{ .tag = @enumFromInt(455), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6081 // __builtin_ceilf16
6082 .{ .tag = @enumFromInt(456), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6083 // __builtin_ceill
6084 .{ .tag = @enumFromInt(457), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6085 // __builtin_cexp
6086 .{ .tag = @enumFromInt(458), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6087 // __builtin_cexpf
6088 .{ .tag = @enumFromInt(459), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6089 // __builtin_cexpl
6090 .{ .tag = @enumFromInt(460), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6091 // __builtin_char_memchr
6092 .{ .tag = @enumFromInt(461), .properties = .{ .param_str = "c*cC*iz", .attributes = .{ .const_evaluable = true } } },
6093 // __builtin_cimag
6094 .{ .tag = @enumFromInt(462), .properties = .{ .param_str = "dXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6095 // __builtin_cimagf
6096 .{ .tag = @enumFromInt(463), .properties = .{ .param_str = "fXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6097 // __builtin_cimagl
6098 .{ .tag = @enumFromInt(464), .properties = .{ .param_str = "LdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6099 // __builtin_classify_type
6100 .{ .tag = @enumFromInt(465), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .eval_args = false, .const_evaluable = true } } },
6101 // __builtin_clog
6102 .{ .tag = @enumFromInt(466), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6103 // __builtin_clogf
6104 .{ .tag = @enumFromInt(467), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6105 // __builtin_clogl
6106 .{ .tag = @enumFromInt(468), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6107 // __builtin_clrsb
6108 .{ .tag = @enumFromInt(469), .properties = .{ .param_str = "ii", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6109 // __builtin_clrsbl
6110 .{ .tag = @enumFromInt(470), .properties = .{ .param_str = "iLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6111 // __builtin_clrsbll
6112 .{ .tag = @enumFromInt(471), .properties = .{ .param_str = "iLLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6113 // __builtin_clz
6114 .{ .tag = @enumFromInt(472), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6115 // __builtin_clzl
6116 .{ .tag = @enumFromInt(473), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6117 // __builtin_clzll
6118 .{ .tag = @enumFromInt(474), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6119 // __builtin_clzs
6120 .{ .tag = @enumFromInt(475), .properties = .{ .param_str = "iUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6121 // __builtin_complex
6122 .{ .tag = @enumFromInt(476), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } },
6123 // __builtin_conj
6124 .{ .tag = @enumFromInt(477), .properties = .{ .param_str = "XdXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6125 // __builtin_conjf
6126 .{ .tag = @enumFromInt(478), .properties = .{ .param_str = "XfXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6127 // __builtin_conjl
6128 .{ .tag = @enumFromInt(479), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6129 // __builtin_constant_p
6130 .{ .tag = @enumFromInt(480), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .eval_args = false, .const_evaluable = true } } },
6131 // __builtin_convertvector
6132 .{ .tag = @enumFromInt(481), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6133 // __builtin_copysign
6134 .{ .tag = @enumFromInt(482), .properties = .{ .param_str = "ddd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6135 // __builtin_copysignf
6136 .{ .tag = @enumFromInt(483), .properties = .{ .param_str = "fff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6137 // __builtin_copysignf128
6138 .{ .tag = @enumFromInt(484), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6139 // __builtin_copysignf16
6140 .{ .tag = @enumFromInt(485), .properties = .{ .param_str = "hhh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6141 // __builtin_copysignl
6142 .{ .tag = @enumFromInt(486), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6143 // __builtin_cos
6144 .{ .tag = @enumFromInt(487), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6145 // __builtin_cosf
6146 .{ .tag = @enumFromInt(488), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6147 // __builtin_cosf128
6148 .{ .tag = @enumFromInt(489), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6149 // __builtin_cosf16
6150 .{ .tag = @enumFromInt(490), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6151 // __builtin_cosh
6152 .{ .tag = @enumFromInt(491), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6153 // __builtin_coshf
6154 .{ .tag = @enumFromInt(492), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6155 // __builtin_coshf128
6156 .{ .tag = @enumFromInt(493), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6157 // __builtin_coshl
6158 .{ .tag = @enumFromInt(494), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6159 // __builtin_cosl
6160 .{ .tag = @enumFromInt(495), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6161 // __builtin_cpow
6162 .{ .tag = @enumFromInt(496), .properties = .{ .param_str = "XdXdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6163 // __builtin_cpowf
6164 .{ .tag = @enumFromInt(497), .properties = .{ .param_str = "XfXfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6165 // __builtin_cpowl
6166 .{ .tag = @enumFromInt(498), .properties = .{ .param_str = "XLdXLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6167 // __builtin_cproj
6168 .{ .tag = @enumFromInt(499), .properties = .{ .param_str = "XdXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6169 // __builtin_cprojf
6170 .{ .tag = @enumFromInt(500), .properties = .{ .param_str = "XfXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6171 // __builtin_cprojl
6172 .{ .tag = @enumFromInt(501), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6173 // __builtin_cpu_init
6174 .{ .tag = @enumFromInt(502), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.x86) } },
6175 // __builtin_cpu_is
6176 .{ .tag = @enumFromInt(503), .properties = .{ .param_str = "bcC*", .target_set = TargetSet.initOne(.x86), .attributes = .{ .@"const" = true } } },
6177 // __builtin_cpu_supports
6178 .{ .tag = @enumFromInt(504), .properties = .{ .param_str = "bcC*", .target_set = TargetSet.initOne(.x86), .attributes = .{ .@"const" = true } } },
6179 // __builtin_creal
6180 .{ .tag = @enumFromInt(505), .properties = .{ .param_str = "dXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6181 // __builtin_crealf
6182 .{ .tag = @enumFromInt(506), .properties = .{ .param_str = "fXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6183 // __builtin_creall
6184 .{ .tag = @enumFromInt(507), .properties = .{ .param_str = "LdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6185 // __builtin_csin
6186 .{ .tag = @enumFromInt(508), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6187 // __builtin_csinf
6188 .{ .tag = @enumFromInt(509), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6189 // __builtin_csinh
6190 .{ .tag = @enumFromInt(510), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6191 // __builtin_csinhf
6192 .{ .tag = @enumFromInt(511), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6193 // __builtin_csinhl
6194 .{ .tag = @enumFromInt(512), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6195 // __builtin_csinl
6196 .{ .tag = @enumFromInt(513), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6197 // __builtin_csqrt
6198 .{ .tag = @enumFromInt(514), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6199 // __builtin_csqrtf
6200 .{ .tag = @enumFromInt(515), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6201 // __builtin_csqrtl
6202 .{ .tag = @enumFromInt(516), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6203 // __builtin_ctan
6204 .{ .tag = @enumFromInt(517), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6205 // __builtin_ctanf
6206 .{ .tag = @enumFromInt(518), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6207 // __builtin_ctanh
6208 .{ .tag = @enumFromInt(519), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6209 // __builtin_ctanhf
6210 .{ .tag = @enumFromInt(520), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6211 // __builtin_ctanhl
6212 .{ .tag = @enumFromInt(521), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6213 // __builtin_ctanl
6214 .{ .tag = @enumFromInt(522), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6215 // __builtin_ctz
6216 .{ .tag = @enumFromInt(523), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6217 // __builtin_ctzl
6218 .{ .tag = @enumFromInt(524), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6219 // __builtin_ctzll
6220 .{ .tag = @enumFromInt(525), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6221 // __builtin_ctzs
6222 .{ .tag = @enumFromInt(526), .properties = .{ .param_str = "iUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6223 // __builtin_dcbf
6224 .{ .tag = @enumFromInt(527), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } },
6225 // __builtin_debugtrap
6226 .{ .tag = @enumFromInt(528), .properties = .{ .param_str = "v" } },
6227 // __builtin_dump_struct
6228 .{ .tag = @enumFromInt(529), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
6229 // __builtin_dwarf_cfa
6230 .{ .tag = @enumFromInt(530), .properties = .{ .param_str = "v*" } },
6231 // __builtin_dwarf_sp_column
6232 .{ .tag = @enumFromInt(531), .properties = .{ .param_str = "Ui" } },
6233 // __builtin_dynamic_object_size
6234 .{ .tag = @enumFromInt(532), .properties = .{ .param_str = "zvC*i", .attributes = .{ .eval_args = false, .const_evaluable = true } } },
6235 // __builtin_eh_return
6236 .{ .tag = @enumFromInt(533), .properties = .{ .param_str = "vzv*", .attributes = .{ .noreturn = true } } },
6237 // __builtin_eh_return_data_regno
6238 .{ .tag = @enumFromInt(534), .properties = .{ .param_str = "iIi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6239 // __builtin_elementwise_abs
6240 .{ .tag = @enumFromInt(535), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6241 // __builtin_elementwise_add_sat
6242 .{ .tag = @enumFromInt(536), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6243 // __builtin_elementwise_bitreverse
6244 .{ .tag = @enumFromInt(537), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6245 // __builtin_elementwise_canonicalize
6246 .{ .tag = @enumFromInt(538), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6247 // __builtin_elementwise_ceil
6248 .{ .tag = @enumFromInt(539), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6249 // __builtin_elementwise_copysign
6250 .{ .tag = @enumFromInt(540), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6251 // __builtin_elementwise_cos
6252 .{ .tag = @enumFromInt(541), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6253 // __builtin_elementwise_exp
6254 .{ .tag = @enumFromInt(542), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6255 // __builtin_elementwise_exp2
6256 .{ .tag = @enumFromInt(543), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6257 // __builtin_elementwise_floor
6258 .{ .tag = @enumFromInt(544), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6259 // __builtin_elementwise_fma
6260 .{ .tag = @enumFromInt(545), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6261 // __builtin_elementwise_log
6262 .{ .tag = @enumFromInt(546), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6263 // __builtin_elementwise_log10
6264 .{ .tag = @enumFromInt(547), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6265 // __builtin_elementwise_log2
6266 .{ .tag = @enumFromInt(548), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6267 // __builtin_elementwise_max
6268 .{ .tag = @enumFromInt(549), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6269 // __builtin_elementwise_min
6270 .{ .tag = @enumFromInt(550), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6271 // __builtin_elementwise_nearbyint
6272 .{ .tag = @enumFromInt(551), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6273 // __builtin_elementwise_pow
6274 .{ .tag = @enumFromInt(552), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6275 // __builtin_elementwise_rint
6276 .{ .tag = @enumFromInt(553), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6277 // __builtin_elementwise_round
6278 .{ .tag = @enumFromInt(554), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6279 // __builtin_elementwise_roundeven
6280 .{ .tag = @enumFromInt(555), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6281 // __builtin_elementwise_sin
6282 .{ .tag = @enumFromInt(556), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6283 // __builtin_elementwise_sqrt
6284 .{ .tag = @enumFromInt(557), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6285 // __builtin_elementwise_sub_sat
6286 .{ .tag = @enumFromInt(558), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6287 // __builtin_elementwise_trunc
6288 .{ .tag = @enumFromInt(559), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
6289 // __builtin_erf
6290 .{ .tag = @enumFromInt(560), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6291 // __builtin_erfc
6292 .{ .tag = @enumFromInt(561), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6293 // __builtin_erfcf
6294 .{ .tag = @enumFromInt(562), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6295 // __builtin_erfcf128
6296 .{ .tag = @enumFromInt(563), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6297 // __builtin_erfcl
6298 .{ .tag = @enumFromInt(564), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6299 // __builtin_erff
6300 .{ .tag = @enumFromInt(565), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6301 // __builtin_erff128
6302 .{ .tag = @enumFromInt(566), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6303 // __builtin_erfl
6304 .{ .tag = @enumFromInt(567), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6305 // __builtin_exp
6306 .{ .tag = @enumFromInt(568), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6307 // __builtin_exp10
6308 .{ .tag = @enumFromInt(569), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6309 // __builtin_exp10f
6310 .{ .tag = @enumFromInt(570), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6311 // __builtin_exp10f128
6312 .{ .tag = @enumFromInt(571), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6313 // __builtin_exp10f16
6314 .{ .tag = @enumFromInt(572), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6315 // __builtin_exp10l
6316 .{ .tag = @enumFromInt(573), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6317 // __builtin_exp2
6318 .{ .tag = @enumFromInt(574), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6319 // __builtin_exp2f
6320 .{ .tag = @enumFromInt(575), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6321 // __builtin_exp2f128
6322 .{ .tag = @enumFromInt(576), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6323 // __builtin_exp2f16
6324 .{ .tag = @enumFromInt(577), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6325 // __builtin_exp2l
6326 .{ .tag = @enumFromInt(578), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6327 // __builtin_expect
6328 .{ .tag = @enumFromInt(579), .properties = .{ .param_str = "LiLiLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6329 // __builtin_expect_with_probability
6330 .{ .tag = @enumFromInt(580), .properties = .{ .param_str = "LiLiLid", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6331 // __builtin_expf
6332 .{ .tag = @enumFromInt(581), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6333 // __builtin_expf128
6334 .{ .tag = @enumFromInt(582), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6335 // __builtin_expf16
6336 .{ .tag = @enumFromInt(583), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6337 // __builtin_expl
6338 .{ .tag = @enumFromInt(584), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6339 // __builtin_expm1
6340 .{ .tag = @enumFromInt(585), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6341 // __builtin_expm1f
6342 .{ .tag = @enumFromInt(586), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6343 // __builtin_expm1f128
6344 .{ .tag = @enumFromInt(587), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6345 // __builtin_expm1l
6346 .{ .tag = @enumFromInt(588), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6347 // __builtin_extend_pointer
6348 .{ .tag = @enumFromInt(589), .properties = .{ .param_str = "ULLiv*" } },
6349 // __builtin_extract_return_addr
6350 .{ .tag = @enumFromInt(590), .properties = .{ .param_str = "v*v*" } },
6351 // __builtin_fabs
6352 .{ .tag = @enumFromInt(591), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6353 // __builtin_fabsf
6354 .{ .tag = @enumFromInt(592), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6355 // __builtin_fabsf128
6356 .{ .tag = @enumFromInt(593), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6357 // __builtin_fabsf16
6358 .{ .tag = @enumFromInt(594), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6359 // __builtin_fabsl
6360 .{ .tag = @enumFromInt(595), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6361 // __builtin_fdim
6362 .{ .tag = @enumFromInt(596), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6363 // __builtin_fdimf
6364 .{ .tag = @enumFromInt(597), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6365 // __builtin_fdimf128
6366 .{ .tag = @enumFromInt(598), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6367 // __builtin_fdiml
6368 .{ .tag = @enumFromInt(599), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6369 // __builtin_ffs
6370 .{ .tag = @enumFromInt(600), .properties = .{ .param_str = "ii", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6371 // __builtin_ffsl
6372 .{ .tag = @enumFromInt(601), .properties = .{ .param_str = "iLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6373 // __builtin_ffsll
6374 .{ .tag = @enumFromInt(602), .properties = .{ .param_str = "iLLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6375 // __builtin_floor
6376 .{ .tag = @enumFromInt(603), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6377 // __builtin_floorf
6378 .{ .tag = @enumFromInt(604), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6379 // __builtin_floorf128
6380 .{ .tag = @enumFromInt(605), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6381 // __builtin_floorf16
6382 .{ .tag = @enumFromInt(606), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6383 // __builtin_floorl
6384 .{ .tag = @enumFromInt(607), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6385 // __builtin_flt_rounds
6386 .{ .tag = @enumFromInt(608), .properties = .{ .param_str = "i" } },
6387 // __builtin_fma
6388 .{ .tag = @enumFromInt(609), .properties = .{ .param_str = "dddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6389 // __builtin_fmaf
6390 .{ .tag = @enumFromInt(610), .properties = .{ .param_str = "ffff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6391 // __builtin_fmaf128
6392 .{ .tag = @enumFromInt(611), .properties = .{ .param_str = "LLdLLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6393 // __builtin_fmaf16
6394 .{ .tag = @enumFromInt(612), .properties = .{ .param_str = "hhhh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6395 // __builtin_fmal
6396 .{ .tag = @enumFromInt(613), .properties = .{ .param_str = "LdLdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6397 // __builtin_fmax
6398 .{ .tag = @enumFromInt(614), .properties = .{ .param_str = "ddd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6399 // __builtin_fmaxf
6400 .{ .tag = @enumFromInt(615), .properties = .{ .param_str = "fff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6401 // __builtin_fmaxf128
6402 .{ .tag = @enumFromInt(616), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6403 // __builtin_fmaxf16
6404 .{ .tag = @enumFromInt(617), .properties = .{ .param_str = "hhh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6405 // __builtin_fmaxl
6406 .{ .tag = @enumFromInt(618), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6407 // __builtin_fmin
6408 .{ .tag = @enumFromInt(619), .properties = .{ .param_str = "ddd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6409 // __builtin_fminf
6410 .{ .tag = @enumFromInt(620), .properties = .{ .param_str = "fff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6411 // __builtin_fminf128
6412 .{ .tag = @enumFromInt(621), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6413 // __builtin_fminf16
6414 .{ .tag = @enumFromInt(622), .properties = .{ .param_str = "hhh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6415 // __builtin_fminl
6416 .{ .tag = @enumFromInt(623), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6417 // __builtin_fmod
6418 .{ .tag = @enumFromInt(624), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6419 // __builtin_fmodf
6420 .{ .tag = @enumFromInt(625), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6421 // __builtin_fmodf128
6422 .{ .tag = @enumFromInt(626), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6423 // __builtin_fmodf16
6424 .{ .tag = @enumFromInt(627), .properties = .{ .param_str = "hhh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6425 // __builtin_fmodl
6426 .{ .tag = @enumFromInt(628), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6427 // __builtin_fpclassify
6428 .{ .tag = @enumFromInt(629), .properties = .{ .param_str = "iiiiii.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6429 // __builtin_fprintf
6430 .{ .tag = @enumFromInt(630), .properties = .{ .param_str = "iP*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 } } },
6431 // __builtin_frame_address
6432 .{ .tag = @enumFromInt(631), .properties = .{ .param_str = "v*IUi" } },
6433 // __builtin_free
6434 .{ .tag = @enumFromInt(632), .properties = .{ .param_str = "vv*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6435 // __builtin_frexp
6436 .{ .tag = @enumFromInt(633), .properties = .{ .param_str = "ddi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6437 // __builtin_frexpf
6438 .{ .tag = @enumFromInt(634), .properties = .{ .param_str = "ffi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6439 // __builtin_frexpf128
6440 .{ .tag = @enumFromInt(635), .properties = .{ .param_str = "LLdLLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6441 // __builtin_frexpf16
6442 .{ .tag = @enumFromInt(636), .properties = .{ .param_str = "hhi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6443 // __builtin_frexpl
6444 .{ .tag = @enumFromInt(637), .properties = .{ .param_str = "LdLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6445 // __builtin_frob_return_addr
6446 .{ .tag = @enumFromInt(638), .properties = .{ .param_str = "v*v*" } },
6447 // __builtin_fscanf
6448 .{ .tag = @enumFromInt(639), .properties = .{ .param_str = "iP*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } },
6449 // __builtin_getid
6450 .{ .tag = @enumFromInt(640), .properties = .{ .param_str = "Si", .target_set = TargetSet.initOne(.xcore), .attributes = .{ .@"const" = true } } },
6451 // __builtin_getps
6452 .{ .tag = @enumFromInt(641), .properties = .{ .param_str = "UiUi", .target_set = TargetSet.initOne(.xcore) } },
6453 // __builtin_huge_val
6454 .{ .tag = @enumFromInt(642), .properties = .{ .param_str = "d", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6455 // __builtin_huge_valf
6456 .{ .tag = @enumFromInt(643), .properties = .{ .param_str = "f", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6457 // __builtin_huge_valf128
6458 .{ .tag = @enumFromInt(644), .properties = .{ .param_str = "LLd", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6459 // __builtin_huge_valf16
6460 .{ .tag = @enumFromInt(645), .properties = .{ .param_str = "x", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6461 // __builtin_huge_vall
6462 .{ .tag = @enumFromInt(646), .properties = .{ .param_str = "Ld", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6463 // __builtin_hypot
6464 .{ .tag = @enumFromInt(647), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6465 // __builtin_hypotf
6466 .{ .tag = @enumFromInt(648), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6467 // __builtin_hypotf128
6468 .{ .tag = @enumFromInt(649), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6469 // __builtin_hypotl
6470 .{ .tag = @enumFromInt(650), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6471 // __builtin_ia32_rdpmc
6472 .{ .tag = @enumFromInt(651), .properties = .{ .param_str = "UOii", .target_set = TargetSet.initOne(.x86) } },
6473 // __builtin_ia32_rdtsc
6474 .{ .tag = @enumFromInt(652), .properties = .{ .param_str = "UOi", .target_set = TargetSet.initOne(.x86) } },
6475 // __builtin_ia32_rdtscp
6476 .{ .tag = @enumFromInt(653), .properties = .{ .param_str = "UOiUi*", .target_set = TargetSet.initOne(.x86) } },
6477 // __builtin_ilogb
6478 .{ .tag = @enumFromInt(654), .properties = .{ .param_str = "id", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6479 // __builtin_ilogbf
6480 .{ .tag = @enumFromInt(655), .properties = .{ .param_str = "if", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6481 // __builtin_ilogbf128
6482 .{ .tag = @enumFromInt(656), .properties = .{ .param_str = "iLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6483 // __builtin_ilogbl
6484 .{ .tag = @enumFromInt(657), .properties = .{ .param_str = "iLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6485 // __builtin_index
6486 .{ .tag = @enumFromInt(658), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6487 // __builtin_inf
6488 .{ .tag = @enumFromInt(659), .properties = .{ .param_str = "d", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6489 // __builtin_inff
6490 .{ .tag = @enumFromInt(660), .properties = .{ .param_str = "f", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6491 // __builtin_inff128
6492 .{ .tag = @enumFromInt(661), .properties = .{ .param_str = "LLd", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6493 // __builtin_inff16
6494 .{ .tag = @enumFromInt(662), .properties = .{ .param_str = "x", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6495 // __builtin_infl
6496 .{ .tag = @enumFromInt(663), .properties = .{ .param_str = "Ld", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
6497 // __builtin_init_dwarf_reg_size_table
6498 .{ .tag = @enumFromInt(664), .properties = .{ .param_str = "vv*" } },
6499 // __builtin_is_aligned
6500 .{ .tag = @enumFromInt(665), .properties = .{ .param_str = "bvC*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } },
6501 // __builtin_isfinite
6502 .{ .tag = @enumFromInt(666), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6503 // __builtin_isfpclass
6504 .{ .tag = @enumFromInt(667), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } },
6505 // __builtin_isgreater
6506 .{ .tag = @enumFromInt(668), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6507 // __builtin_isgreaterequal
6508 .{ .tag = @enumFromInt(669), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6509 // __builtin_isinf
6510 .{ .tag = @enumFromInt(670), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6511 // __builtin_isinf_sign
6512 .{ .tag = @enumFromInt(671), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6513 // __builtin_isless
6514 .{ .tag = @enumFromInt(672), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6515 // __builtin_islessequal
6516 .{ .tag = @enumFromInt(673), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6517 // __builtin_islessgreater
6518 .{ .tag = @enumFromInt(674), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6519 // __builtin_isnan
6520 .{ .tag = @enumFromInt(675), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6521 // __builtin_isnormal
6522 .{ .tag = @enumFromInt(676), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6523 // __builtin_isunordered
6524 .{ .tag = @enumFromInt(677), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6525 // __builtin_labs
6526 .{ .tag = @enumFromInt(678), .properties = .{ .param_str = "LiLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6527 // __builtin_launder
6528 .{ .tag = @enumFromInt(679), .properties = .{ .param_str = "v*v*", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } },
6529 // __builtin_ldexp
6530 .{ .tag = @enumFromInt(680), .properties = .{ .param_str = "ddi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6531 // __builtin_ldexpf
6532 .{ .tag = @enumFromInt(681), .properties = .{ .param_str = "ffi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6533 // __builtin_ldexpf128
6534 .{ .tag = @enumFromInt(682), .properties = .{ .param_str = "LLdLLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6535 // __builtin_ldexpf16
6536 .{ .tag = @enumFromInt(683), .properties = .{ .param_str = "hhi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6537 // __builtin_ldexpl
6538 .{ .tag = @enumFromInt(684), .properties = .{ .param_str = "LdLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6539 // __builtin_lgamma
6540 .{ .tag = @enumFromInt(685), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6541 // __builtin_lgammaf
6542 .{ .tag = @enumFromInt(686), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6543 // __builtin_lgammaf128
6544 .{ .tag = @enumFromInt(687), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6545 // __builtin_lgammal
6546 .{ .tag = @enumFromInt(688), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6547 // __builtin_llabs
6548 .{ .tag = @enumFromInt(689), .properties = .{ .param_str = "LLiLLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
6549 // __builtin_llrint
6550 .{ .tag = @enumFromInt(690), .properties = .{ .param_str = "LLid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6551 // __builtin_llrintf
6552 .{ .tag = @enumFromInt(691), .properties = .{ .param_str = "LLif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6553 // __builtin_llrintf128
6554 .{ .tag = @enumFromInt(692), .properties = .{ .param_str = "LLiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6555 // __builtin_llrintl
6556 .{ .tag = @enumFromInt(693), .properties = .{ .param_str = "LLiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6557 // __builtin_llround
6558 .{ .tag = @enumFromInt(694), .properties = .{ .param_str = "LLid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6559 // __builtin_llroundf
6560 .{ .tag = @enumFromInt(695), .properties = .{ .param_str = "LLif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6561 // __builtin_llroundf128
6562 .{ .tag = @enumFromInt(696), .properties = .{ .param_str = "LLiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6563 // __builtin_llroundl
6564 .{ .tag = @enumFromInt(697), .properties = .{ .param_str = "LLiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6565 // __builtin_log
6566 .{ .tag = @enumFromInt(698), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6567 // __builtin_log10
6568 .{ .tag = @enumFromInt(699), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6569 // __builtin_log10f
6570 .{ .tag = @enumFromInt(700), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6571 // __builtin_log10f128
6572 .{ .tag = @enumFromInt(701), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6573 // __builtin_log10f16
6574 .{ .tag = @enumFromInt(702), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6575 // __builtin_log10l
6576 .{ .tag = @enumFromInt(703), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6577 // __builtin_log1p
6578 .{ .tag = @enumFromInt(704), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6579 // __builtin_log1pf
6580 .{ .tag = @enumFromInt(705), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6581 // __builtin_log1pf128
6582 .{ .tag = @enumFromInt(706), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6583 // __builtin_log1pl
6584 .{ .tag = @enumFromInt(707), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6585 // __builtin_log2
6586 .{ .tag = @enumFromInt(708), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6587 // __builtin_log2f
6588 .{ .tag = @enumFromInt(709), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6589 // __builtin_log2f128
6590 .{ .tag = @enumFromInt(710), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6591 // __builtin_log2f16
6592 .{ .tag = @enumFromInt(711), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6593 // __builtin_log2l
6594 .{ .tag = @enumFromInt(712), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6595 // __builtin_logb
6596 .{ .tag = @enumFromInt(713), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6597 // __builtin_logbf
6598 .{ .tag = @enumFromInt(714), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6599 // __builtin_logbf128
6600 .{ .tag = @enumFromInt(715), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6601 // __builtin_logbl
6602 .{ .tag = @enumFromInt(716), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6603 // __builtin_logf
6604 .{ .tag = @enumFromInt(717), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6605 // __builtin_logf128
6606 .{ .tag = @enumFromInt(718), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6607 // __builtin_logf16
6608 .{ .tag = @enumFromInt(719), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6609 // __builtin_logl
6610 .{ .tag = @enumFromInt(720), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6611 // __builtin_longjmp
6612 .{ .tag = @enumFromInt(721), .properties = .{ .param_str = "vv**i", .attributes = .{ .noreturn = true } } },
6613 // __builtin_lrint
6614 .{ .tag = @enumFromInt(722), .properties = .{ .param_str = "Lid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6615 // __builtin_lrintf
6616 .{ .tag = @enumFromInt(723), .properties = .{ .param_str = "Lif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6617 // __builtin_lrintf128
6618 .{ .tag = @enumFromInt(724), .properties = .{ .param_str = "LiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6619 // __builtin_lrintl
6620 .{ .tag = @enumFromInt(725), .properties = .{ .param_str = "LiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6621 // __builtin_lround
6622 .{ .tag = @enumFromInt(726), .properties = .{ .param_str = "Lid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6623 // __builtin_lroundf
6624 .{ .tag = @enumFromInt(727), .properties = .{ .param_str = "Lif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6625 // __builtin_lroundf128
6626 .{ .tag = @enumFromInt(728), .properties = .{ .param_str = "LiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6627 // __builtin_lroundl
6628 .{ .tag = @enumFromInt(729), .properties = .{ .param_str = "LiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
6629 // __builtin_malloc
6630 .{ .tag = @enumFromInt(730), .properties = .{ .param_str = "v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6631 // __builtin_matrix_column_major_load
6632 .{ .tag = @enumFromInt(731), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6633 // __builtin_matrix_column_major_store
6634 .{ .tag = @enumFromInt(732), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6635 // __builtin_matrix_transpose
6636 .{ .tag = @enumFromInt(733), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
6637 // __builtin_memchr
6638 .{ .tag = @enumFromInt(734), .properties = .{ .param_str = "v*vC*iz", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6639 // __builtin_memcmp
6640 .{ .tag = @enumFromInt(735), .properties = .{ .param_str = "ivC*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6641 // __builtin_memcpy
6642 .{ .tag = @enumFromInt(736), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6643 // __builtin_memcpy_inline
6644 .{ .tag = @enumFromInt(737), .properties = .{ .param_str = "vv*vC*Iz" } },
6645 // __builtin_memmove
6646 .{ .tag = @enumFromInt(738), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
6647 // __builtin_mempcpy
6648 .{ .tag = @enumFromInt(739), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6649 // __builtin_memset
6650 .{ .tag = @enumFromInt(740), .properties = .{ .param_str = "v*v*iz", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6651 // __builtin_memset_inline
6652 .{ .tag = @enumFromInt(741), .properties = .{ .param_str = "vv*iIz" } },
6653 // __builtin_mips_absq_s_ph
6654 .{ .tag = @enumFromInt(742), .properties = .{ .param_str = "V2sV2s", .target_set = TargetSet.initOne(.mips) } },
6655 // __builtin_mips_absq_s_qb
6656 .{ .tag = @enumFromInt(743), .properties = .{ .param_str = "V4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6657 // __builtin_mips_absq_s_w
6658 .{ .tag = @enumFromInt(744), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.mips) } },
6659 // __builtin_mips_addq_ph
6660 .{ .tag = @enumFromInt(745), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6661 // __builtin_mips_addq_s_ph
6662 .{ .tag = @enumFromInt(746), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6663 // __builtin_mips_addq_s_w
6664 .{ .tag = @enumFromInt(747), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6665 // __builtin_mips_addqh_ph
6666 .{ .tag = @enumFromInt(748), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6667 // __builtin_mips_addqh_r_ph
6668 .{ .tag = @enumFromInt(749), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6669 // __builtin_mips_addqh_r_w
6670 .{ .tag = @enumFromInt(750), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6671 // __builtin_mips_addqh_w
6672 .{ .tag = @enumFromInt(751), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6673 // __builtin_mips_addsc
6674 .{ .tag = @enumFromInt(752), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6675 // __builtin_mips_addu_ph
6676 .{ .tag = @enumFromInt(753), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6677 // __builtin_mips_addu_qb
6678 .{ .tag = @enumFromInt(754), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6679 // __builtin_mips_addu_s_ph
6680 .{ .tag = @enumFromInt(755), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6681 // __builtin_mips_addu_s_qb
6682 .{ .tag = @enumFromInt(756), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6683 // __builtin_mips_adduh_qb
6684 .{ .tag = @enumFromInt(757), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6685 // __builtin_mips_adduh_r_qb
6686 .{ .tag = @enumFromInt(758), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6687 // __builtin_mips_addwc
6688 .{ .tag = @enumFromInt(759), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6689 // __builtin_mips_append
6690 .{ .tag = @enumFromInt(760), .properties = .{ .param_str = "iiiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6691 // __builtin_mips_balign
6692 .{ .tag = @enumFromInt(761), .properties = .{ .param_str = "iiiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6693 // __builtin_mips_bitrev
6694 .{ .tag = @enumFromInt(762), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6695 // __builtin_mips_bposge32
6696 .{ .tag = @enumFromInt(763), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.mips) } },
6697 // __builtin_mips_cmp_eq_ph
6698 .{ .tag = @enumFromInt(764), .properties = .{ .param_str = "vV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6699 // __builtin_mips_cmp_le_ph
6700 .{ .tag = @enumFromInt(765), .properties = .{ .param_str = "vV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6701 // __builtin_mips_cmp_lt_ph
6702 .{ .tag = @enumFromInt(766), .properties = .{ .param_str = "vV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6703 // __builtin_mips_cmpgdu_eq_qb
6704 .{ .tag = @enumFromInt(767), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6705 // __builtin_mips_cmpgdu_le_qb
6706 .{ .tag = @enumFromInt(768), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6707 // __builtin_mips_cmpgdu_lt_qb
6708 .{ .tag = @enumFromInt(769), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6709 // __builtin_mips_cmpgu_eq_qb
6710 .{ .tag = @enumFromInt(770), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6711 // __builtin_mips_cmpgu_le_qb
6712 .{ .tag = @enumFromInt(771), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6713 // __builtin_mips_cmpgu_lt_qb
6714 .{ .tag = @enumFromInt(772), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6715 // __builtin_mips_cmpu_eq_qb
6716 .{ .tag = @enumFromInt(773), .properties = .{ .param_str = "vV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6717 // __builtin_mips_cmpu_le_qb
6718 .{ .tag = @enumFromInt(774), .properties = .{ .param_str = "vV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6719 // __builtin_mips_cmpu_lt_qb
6720 .{ .tag = @enumFromInt(775), .properties = .{ .param_str = "vV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6721 // __builtin_mips_dpa_w_ph
6722 .{ .tag = @enumFromInt(776), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6723 // __builtin_mips_dpaq_s_w_ph
6724 .{ .tag = @enumFromInt(777), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6725 // __builtin_mips_dpaq_sa_l_w
6726 .{ .tag = @enumFromInt(778), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips) } },
6727 // __builtin_mips_dpaqx_s_w_ph
6728 .{ .tag = @enumFromInt(779), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6729 // __builtin_mips_dpaqx_sa_w_ph
6730 .{ .tag = @enumFromInt(780), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6731 // __builtin_mips_dpau_h_qbl
6732 .{ .tag = @enumFromInt(781), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6733 // __builtin_mips_dpau_h_qbr
6734 .{ .tag = @enumFromInt(782), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6735 // __builtin_mips_dpax_w_ph
6736 .{ .tag = @enumFromInt(783), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6737 // __builtin_mips_dps_w_ph
6738 .{ .tag = @enumFromInt(784), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6739 // __builtin_mips_dpsq_s_w_ph
6740 .{ .tag = @enumFromInt(785), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6741 // __builtin_mips_dpsq_sa_l_w
6742 .{ .tag = @enumFromInt(786), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips) } },
6743 // __builtin_mips_dpsqx_s_w_ph
6744 .{ .tag = @enumFromInt(787), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6745 // __builtin_mips_dpsqx_sa_w_ph
6746 .{ .tag = @enumFromInt(788), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6747 // __builtin_mips_dpsu_h_qbl
6748 .{ .tag = @enumFromInt(789), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6749 // __builtin_mips_dpsu_h_qbr
6750 .{ .tag = @enumFromInt(790), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6751 // __builtin_mips_dpsx_w_ph
6752 .{ .tag = @enumFromInt(791), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6753 // __builtin_mips_extp
6754 .{ .tag = @enumFromInt(792), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } },
6755 // __builtin_mips_extpdp
6756 .{ .tag = @enumFromInt(793), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } },
6757 // __builtin_mips_extr_r_w
6758 .{ .tag = @enumFromInt(794), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } },
6759 // __builtin_mips_extr_rs_w
6760 .{ .tag = @enumFromInt(795), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } },
6761 // __builtin_mips_extr_s_h
6762 .{ .tag = @enumFromInt(796), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } },
6763 // __builtin_mips_extr_w
6764 .{ .tag = @enumFromInt(797), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } },
6765 // __builtin_mips_insv
6766 .{ .tag = @enumFromInt(798), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6767 // __builtin_mips_lbux
6768 .{ .tag = @enumFromInt(799), .properties = .{ .param_str = "iv*i", .target_set = TargetSet.initOne(.mips) } },
6769 // __builtin_mips_lhx
6770 .{ .tag = @enumFromInt(800), .properties = .{ .param_str = "iv*i", .target_set = TargetSet.initOne(.mips) } },
6771 // __builtin_mips_lwx
6772 .{ .tag = @enumFromInt(801), .properties = .{ .param_str = "iv*i", .target_set = TargetSet.initOne(.mips) } },
6773 // __builtin_mips_madd
6774 .{ .tag = @enumFromInt(802), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6775 // __builtin_mips_maddu
6776 .{ .tag = @enumFromInt(803), .properties = .{ .param_str = "LLiLLiUiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6777 // __builtin_mips_maq_s_w_phl
6778 .{ .tag = @enumFromInt(804), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6779 // __builtin_mips_maq_s_w_phr
6780 .{ .tag = @enumFromInt(805), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6781 // __builtin_mips_maq_sa_w_phl
6782 .{ .tag = @enumFromInt(806), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6783 // __builtin_mips_maq_sa_w_phr
6784 .{ .tag = @enumFromInt(807), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6785 // __builtin_mips_modsub
6786 .{ .tag = @enumFromInt(808), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6787 // __builtin_mips_msub
6788 .{ .tag = @enumFromInt(809), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6789 // __builtin_mips_msubu
6790 .{ .tag = @enumFromInt(810), .properties = .{ .param_str = "LLiLLiUiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6791 // __builtin_mips_mthlip
6792 .{ .tag = @enumFromInt(811), .properties = .{ .param_str = "LLiLLii", .target_set = TargetSet.initOne(.mips) } },
6793 // __builtin_mips_mul_ph
6794 .{ .tag = @enumFromInt(812), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6795 // __builtin_mips_mul_s_ph
6796 .{ .tag = @enumFromInt(813), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6797 // __builtin_mips_muleq_s_w_phl
6798 .{ .tag = @enumFromInt(814), .properties = .{ .param_str = "iV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6799 // __builtin_mips_muleq_s_w_phr
6800 .{ .tag = @enumFromInt(815), .properties = .{ .param_str = "iV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6801 // __builtin_mips_muleu_s_ph_qbl
6802 .{ .tag = @enumFromInt(816), .properties = .{ .param_str = "V2sV4ScV2s", .target_set = TargetSet.initOne(.mips) } },
6803 // __builtin_mips_muleu_s_ph_qbr
6804 .{ .tag = @enumFromInt(817), .properties = .{ .param_str = "V2sV4ScV2s", .target_set = TargetSet.initOne(.mips) } },
6805 // __builtin_mips_mulq_rs_ph
6806 .{ .tag = @enumFromInt(818), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6807 // __builtin_mips_mulq_rs_w
6808 .{ .tag = @enumFromInt(819), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6809 // __builtin_mips_mulq_s_ph
6810 .{ .tag = @enumFromInt(820), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6811 // __builtin_mips_mulq_s_w
6812 .{ .tag = @enumFromInt(821), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6813 // __builtin_mips_mulsa_w_ph
6814 .{ .tag = @enumFromInt(822), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6815 // __builtin_mips_mulsaq_s_w_ph
6816 .{ .tag = @enumFromInt(823), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6817 // __builtin_mips_mult
6818 .{ .tag = @enumFromInt(824), .properties = .{ .param_str = "LLiii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6819 // __builtin_mips_multu
6820 .{ .tag = @enumFromInt(825), .properties = .{ .param_str = "LLiUiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6821 // __builtin_mips_packrl_ph
6822 .{ .tag = @enumFromInt(826), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6823 // __builtin_mips_pick_ph
6824 .{ .tag = @enumFromInt(827), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6825 // __builtin_mips_pick_qb
6826 .{ .tag = @enumFromInt(828), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6827 // __builtin_mips_preceq_w_phl
6828 .{ .tag = @enumFromInt(829), .properties = .{ .param_str = "iV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6829 // __builtin_mips_preceq_w_phr
6830 .{ .tag = @enumFromInt(830), .properties = .{ .param_str = "iV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6831 // __builtin_mips_precequ_ph_qbl
6832 .{ .tag = @enumFromInt(831), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6833 // __builtin_mips_precequ_ph_qbla
6834 .{ .tag = @enumFromInt(832), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6835 // __builtin_mips_precequ_ph_qbr
6836 .{ .tag = @enumFromInt(833), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6837 // __builtin_mips_precequ_ph_qbra
6838 .{ .tag = @enumFromInt(834), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6839 // __builtin_mips_preceu_ph_qbl
6840 .{ .tag = @enumFromInt(835), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6841 // __builtin_mips_preceu_ph_qbla
6842 .{ .tag = @enumFromInt(836), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6843 // __builtin_mips_preceu_ph_qbr
6844 .{ .tag = @enumFromInt(837), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6845 // __builtin_mips_preceu_ph_qbra
6846 .{ .tag = @enumFromInt(838), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6847 // __builtin_mips_precr_qb_ph
6848 .{ .tag = @enumFromInt(839), .properties = .{ .param_str = "V4ScV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6849 // __builtin_mips_precr_sra_ph_w
6850 .{ .tag = @enumFromInt(840), .properties = .{ .param_str = "V2siiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6851 // __builtin_mips_precr_sra_r_ph_w
6852 .{ .tag = @enumFromInt(841), .properties = .{ .param_str = "V2siiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6853 // __builtin_mips_precrq_ph_w
6854 .{ .tag = @enumFromInt(842), .properties = .{ .param_str = "V2sii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6855 // __builtin_mips_precrq_qb_ph
6856 .{ .tag = @enumFromInt(843), .properties = .{ .param_str = "V4ScV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6857 // __builtin_mips_precrq_rs_ph_w
6858 .{ .tag = @enumFromInt(844), .properties = .{ .param_str = "V2sii", .target_set = TargetSet.initOne(.mips) } },
6859 // __builtin_mips_precrqu_s_qb_ph
6860 .{ .tag = @enumFromInt(845), .properties = .{ .param_str = "V4ScV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6861 // __builtin_mips_prepend
6862 .{ .tag = @enumFromInt(846), .properties = .{ .param_str = "iiiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6863 // __builtin_mips_raddu_w_qb
6864 .{ .tag = @enumFromInt(847), .properties = .{ .param_str = "iV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6865 // __builtin_mips_rddsp
6866 .{ .tag = @enumFromInt(848), .properties = .{ .param_str = "iIi", .target_set = TargetSet.initOne(.mips) } },
6867 // __builtin_mips_repl_ph
6868 .{ .tag = @enumFromInt(849), .properties = .{ .param_str = "V2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6869 // __builtin_mips_repl_qb
6870 .{ .tag = @enumFromInt(850), .properties = .{ .param_str = "V4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6871 // __builtin_mips_shilo
6872 .{ .tag = @enumFromInt(851), .properties = .{ .param_str = "LLiLLii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6873 // __builtin_mips_shll_ph
6874 .{ .tag = @enumFromInt(852), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips) } },
6875 // __builtin_mips_shll_qb
6876 .{ .tag = @enumFromInt(853), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips) } },
6877 // __builtin_mips_shll_s_ph
6878 .{ .tag = @enumFromInt(854), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips) } },
6879 // __builtin_mips_shll_s_w
6880 .{ .tag = @enumFromInt(855), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6881 // __builtin_mips_shra_ph
6882 .{ .tag = @enumFromInt(856), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6883 // __builtin_mips_shra_qb
6884 .{ .tag = @enumFromInt(857), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6885 // __builtin_mips_shra_r_ph
6886 .{ .tag = @enumFromInt(858), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6887 // __builtin_mips_shra_r_qb
6888 .{ .tag = @enumFromInt(859), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6889 // __builtin_mips_shra_r_w
6890 .{ .tag = @enumFromInt(860), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6891 // __builtin_mips_shrl_ph
6892 .{ .tag = @enumFromInt(861), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6893 // __builtin_mips_shrl_qb
6894 .{ .tag = @enumFromInt(862), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6895 // __builtin_mips_subq_ph
6896 .{ .tag = @enumFromInt(863), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6897 // __builtin_mips_subq_s_ph
6898 .{ .tag = @enumFromInt(864), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6899 // __builtin_mips_subq_s_w
6900 .{ .tag = @enumFromInt(865), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } },
6901 // __builtin_mips_subqh_ph
6902 .{ .tag = @enumFromInt(866), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6903 // __builtin_mips_subqh_r_ph
6904 .{ .tag = @enumFromInt(867), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6905 // __builtin_mips_subqh_r_w
6906 .{ .tag = @enumFromInt(868), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6907 // __builtin_mips_subqh_w
6908 .{ .tag = @enumFromInt(869), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6909 // __builtin_mips_subu_ph
6910 .{ .tag = @enumFromInt(870), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6911 // __builtin_mips_subu_qb
6912 .{ .tag = @enumFromInt(871), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6913 // __builtin_mips_subu_s_ph
6914 .{ .tag = @enumFromInt(872), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } },
6915 // __builtin_mips_subu_s_qb
6916 .{ .tag = @enumFromInt(873), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } },
6917 // __builtin_mips_subuh_qb
6918 .{ .tag = @enumFromInt(874), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6919 // __builtin_mips_subuh_r_qb
6920 .{ .tag = @enumFromInt(875), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6921 // __builtin_mips_wrdsp
6922 .{ .tag = @enumFromInt(876), .properties = .{ .param_str = "viIi", .target_set = TargetSet.initOne(.mips) } },
6923 // __builtin_modf
6924 .{ .tag = @enumFromInt(877), .properties = .{ .param_str = "ddd*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6925 // __builtin_modff
6926 .{ .tag = @enumFromInt(878), .properties = .{ .param_str = "fff*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6927 // __builtin_modff128
6928 .{ .tag = @enumFromInt(879), .properties = .{ .param_str = "LLdLLdLLd*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6929 // __builtin_modfl
6930 .{ .tag = @enumFromInt(880), .properties = .{ .param_str = "LdLdLd*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
6931 // __builtin_msa_add_a_b
6932 .{ .tag = @enumFromInt(881), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6933 // __builtin_msa_add_a_d
6934 .{ .tag = @enumFromInt(882), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6935 // __builtin_msa_add_a_h
6936 .{ .tag = @enumFromInt(883), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6937 // __builtin_msa_add_a_w
6938 .{ .tag = @enumFromInt(884), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6939 // __builtin_msa_adds_a_b
6940 .{ .tag = @enumFromInt(885), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6941 // __builtin_msa_adds_a_d
6942 .{ .tag = @enumFromInt(886), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6943 // __builtin_msa_adds_a_h
6944 .{ .tag = @enumFromInt(887), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6945 // __builtin_msa_adds_a_w
6946 .{ .tag = @enumFromInt(888), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6947 // __builtin_msa_adds_s_b
6948 .{ .tag = @enumFromInt(889), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6949 // __builtin_msa_adds_s_d
6950 .{ .tag = @enumFromInt(890), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6951 // __builtin_msa_adds_s_h
6952 .{ .tag = @enumFromInt(891), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6953 // __builtin_msa_adds_s_w
6954 .{ .tag = @enumFromInt(892), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6955 // __builtin_msa_adds_u_b
6956 .{ .tag = @enumFromInt(893), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6957 // __builtin_msa_adds_u_d
6958 .{ .tag = @enumFromInt(894), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6959 // __builtin_msa_adds_u_h
6960 .{ .tag = @enumFromInt(895), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6961 // __builtin_msa_adds_u_w
6962 .{ .tag = @enumFromInt(896), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6963 // __builtin_msa_addv_b
6964 .{ .tag = @enumFromInt(897), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6965 // __builtin_msa_addv_d
6966 .{ .tag = @enumFromInt(898), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6967 // __builtin_msa_addv_h
6968 .{ .tag = @enumFromInt(899), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6969 // __builtin_msa_addv_w
6970 .{ .tag = @enumFromInt(900), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6971 // __builtin_msa_addvi_b
6972 .{ .tag = @enumFromInt(901), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6973 // __builtin_msa_addvi_d
6974 .{ .tag = @enumFromInt(902), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6975 // __builtin_msa_addvi_h
6976 .{ .tag = @enumFromInt(903), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6977 // __builtin_msa_addvi_w
6978 .{ .tag = @enumFromInt(904), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6979 // __builtin_msa_and_v
6980 .{ .tag = @enumFromInt(905), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6981 // __builtin_msa_andi_b
6982 .{ .tag = @enumFromInt(906), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6983 // __builtin_msa_asub_s_b
6984 .{ .tag = @enumFromInt(907), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6985 // __builtin_msa_asub_s_d
6986 .{ .tag = @enumFromInt(908), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6987 // __builtin_msa_asub_s_h
6988 .{ .tag = @enumFromInt(909), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6989 // __builtin_msa_asub_s_w
6990 .{ .tag = @enumFromInt(910), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6991 // __builtin_msa_asub_u_b
6992 .{ .tag = @enumFromInt(911), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6993 // __builtin_msa_asub_u_d
6994 .{ .tag = @enumFromInt(912), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6995 // __builtin_msa_asub_u_h
6996 .{ .tag = @enumFromInt(913), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6997 // __builtin_msa_asub_u_w
6998 .{ .tag = @enumFromInt(914), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
6999 // __builtin_msa_ave_s_b
7000 .{ .tag = @enumFromInt(915), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7001 // __builtin_msa_ave_s_d
7002 .{ .tag = @enumFromInt(916), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7003 // __builtin_msa_ave_s_h
7004 .{ .tag = @enumFromInt(917), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7005 // __builtin_msa_ave_s_w
7006 .{ .tag = @enumFromInt(918), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7007 // __builtin_msa_ave_u_b
7008 .{ .tag = @enumFromInt(919), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7009 // __builtin_msa_ave_u_d
7010 .{ .tag = @enumFromInt(920), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7011 // __builtin_msa_ave_u_h
7012 .{ .tag = @enumFromInt(921), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7013 // __builtin_msa_ave_u_w
7014 .{ .tag = @enumFromInt(922), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7015 // __builtin_msa_aver_s_b
7016 .{ .tag = @enumFromInt(923), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7017 // __builtin_msa_aver_s_d
7018 .{ .tag = @enumFromInt(924), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7019 // __builtin_msa_aver_s_h
7020 .{ .tag = @enumFromInt(925), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7021 // __builtin_msa_aver_s_w
7022 .{ .tag = @enumFromInt(926), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7023 // __builtin_msa_aver_u_b
7024 .{ .tag = @enumFromInt(927), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7025 // __builtin_msa_aver_u_d
7026 .{ .tag = @enumFromInt(928), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7027 // __builtin_msa_aver_u_h
7028 .{ .tag = @enumFromInt(929), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7029 // __builtin_msa_aver_u_w
7030 .{ .tag = @enumFromInt(930), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7031 // __builtin_msa_bclr_b
7032 .{ .tag = @enumFromInt(931), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7033 // __builtin_msa_bclr_d
7034 .{ .tag = @enumFromInt(932), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7035 // __builtin_msa_bclr_h
7036 .{ .tag = @enumFromInt(933), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7037 // __builtin_msa_bclr_w
7038 .{ .tag = @enumFromInt(934), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7039 // __builtin_msa_bclri_b
7040 .{ .tag = @enumFromInt(935), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7041 // __builtin_msa_bclri_d
7042 .{ .tag = @enumFromInt(936), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7043 // __builtin_msa_bclri_h
7044 .{ .tag = @enumFromInt(937), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7045 // __builtin_msa_bclri_w
7046 .{ .tag = @enumFromInt(938), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7047 // __builtin_msa_binsl_b
7048 .{ .tag = @enumFromInt(939), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7049 // __builtin_msa_binsl_d
7050 .{ .tag = @enumFromInt(940), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7051 // __builtin_msa_binsl_h
7052 .{ .tag = @enumFromInt(941), .properties = .{ .param_str = "V8UsV8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7053 // __builtin_msa_binsl_w
7054 .{ .tag = @enumFromInt(942), .properties = .{ .param_str = "V4UiV4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7055 // __builtin_msa_binsli_b
7056 .{ .tag = @enumFromInt(943), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7057 // __builtin_msa_binsli_d
7058 .{ .tag = @enumFromInt(944), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7059 // __builtin_msa_binsli_h
7060 .{ .tag = @enumFromInt(945), .properties = .{ .param_str = "V8UsV8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7061 // __builtin_msa_binsli_w
7062 .{ .tag = @enumFromInt(946), .properties = .{ .param_str = "V4UiV4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7063 // __builtin_msa_binsr_b
7064 .{ .tag = @enumFromInt(947), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7065 // __builtin_msa_binsr_d
7066 .{ .tag = @enumFromInt(948), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7067 // __builtin_msa_binsr_h
7068 .{ .tag = @enumFromInt(949), .properties = .{ .param_str = "V8UsV8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7069 // __builtin_msa_binsr_w
7070 .{ .tag = @enumFromInt(950), .properties = .{ .param_str = "V4UiV4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7071 // __builtin_msa_binsri_b
7072 .{ .tag = @enumFromInt(951), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7073 // __builtin_msa_binsri_d
7074 .{ .tag = @enumFromInt(952), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7075 // __builtin_msa_binsri_h
7076 .{ .tag = @enumFromInt(953), .properties = .{ .param_str = "V8UsV8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7077 // __builtin_msa_binsri_w
7078 .{ .tag = @enumFromInt(954), .properties = .{ .param_str = "V4UiV4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7079 // __builtin_msa_bmnz_v
7080 .{ .tag = @enumFromInt(955), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7081 // __builtin_msa_bmnzi_b
7082 .{ .tag = @enumFromInt(956), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7083 // __builtin_msa_bmz_v
7084 .{ .tag = @enumFromInt(957), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7085 // __builtin_msa_bmzi_b
7086 .{ .tag = @enumFromInt(958), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7087 // __builtin_msa_bneg_b
7088 .{ .tag = @enumFromInt(959), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7089 // __builtin_msa_bneg_d
7090 .{ .tag = @enumFromInt(960), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7091 // __builtin_msa_bneg_h
7092 .{ .tag = @enumFromInt(961), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7093 // __builtin_msa_bneg_w
7094 .{ .tag = @enumFromInt(962), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7095 // __builtin_msa_bnegi_b
7096 .{ .tag = @enumFromInt(963), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7097 // __builtin_msa_bnegi_d
7098 .{ .tag = @enumFromInt(964), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7099 // __builtin_msa_bnegi_h
7100 .{ .tag = @enumFromInt(965), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7101 // __builtin_msa_bnegi_w
7102 .{ .tag = @enumFromInt(966), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7103 // __builtin_msa_bnz_b
7104 .{ .tag = @enumFromInt(967), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7105 // __builtin_msa_bnz_d
7106 .{ .tag = @enumFromInt(968), .properties = .{ .param_str = "iV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7107 // __builtin_msa_bnz_h
7108 .{ .tag = @enumFromInt(969), .properties = .{ .param_str = "iV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7109 // __builtin_msa_bnz_v
7110 .{ .tag = @enumFromInt(970), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7111 // __builtin_msa_bnz_w
7112 .{ .tag = @enumFromInt(971), .properties = .{ .param_str = "iV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7113 // __builtin_msa_bsel_v
7114 .{ .tag = @enumFromInt(972), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7115 // __builtin_msa_bseli_b
7116 .{ .tag = @enumFromInt(973), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7117 // __builtin_msa_bset_b
7118 .{ .tag = @enumFromInt(974), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7119 // __builtin_msa_bset_d
7120 .{ .tag = @enumFromInt(975), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7121 // __builtin_msa_bset_h
7122 .{ .tag = @enumFromInt(976), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7123 // __builtin_msa_bset_w
7124 .{ .tag = @enumFromInt(977), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7125 // __builtin_msa_bseti_b
7126 .{ .tag = @enumFromInt(978), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7127 // __builtin_msa_bseti_d
7128 .{ .tag = @enumFromInt(979), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7129 // __builtin_msa_bseti_h
7130 .{ .tag = @enumFromInt(980), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7131 // __builtin_msa_bseti_w
7132 .{ .tag = @enumFromInt(981), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7133 // __builtin_msa_bz_b
7134 .{ .tag = @enumFromInt(982), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7135 // __builtin_msa_bz_d
7136 .{ .tag = @enumFromInt(983), .properties = .{ .param_str = "iV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7137 // __builtin_msa_bz_h
7138 .{ .tag = @enumFromInt(984), .properties = .{ .param_str = "iV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7139 // __builtin_msa_bz_v
7140 .{ .tag = @enumFromInt(985), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7141 // __builtin_msa_bz_w
7142 .{ .tag = @enumFromInt(986), .properties = .{ .param_str = "iV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7143 // __builtin_msa_ceq_b
7144 .{ .tag = @enumFromInt(987), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7145 // __builtin_msa_ceq_d
7146 .{ .tag = @enumFromInt(988), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7147 // __builtin_msa_ceq_h
7148 .{ .tag = @enumFromInt(989), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7149 // __builtin_msa_ceq_w
7150 .{ .tag = @enumFromInt(990), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7151 // __builtin_msa_ceqi_b
7152 .{ .tag = @enumFromInt(991), .properties = .{ .param_str = "V16ScV16ScISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7153 // __builtin_msa_ceqi_d
7154 .{ .tag = @enumFromInt(992), .properties = .{ .param_str = "V2SLLiV2SLLiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7155 // __builtin_msa_ceqi_h
7156 .{ .tag = @enumFromInt(993), .properties = .{ .param_str = "V8SsV8SsISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7157 // __builtin_msa_ceqi_w
7158 .{ .tag = @enumFromInt(994), .properties = .{ .param_str = "V4SiV4SiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7159 // __builtin_msa_cfcmsa
7160 .{ .tag = @enumFromInt(995), .properties = .{ .param_str = "iIi", .target_set = TargetSet.initOne(.mips) } },
7161 // __builtin_msa_cle_s_b
7162 .{ .tag = @enumFromInt(996), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7163 // __builtin_msa_cle_s_d
7164 .{ .tag = @enumFromInt(997), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7165 // __builtin_msa_cle_s_h
7166 .{ .tag = @enumFromInt(998), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7167 // __builtin_msa_cle_s_w
7168 .{ .tag = @enumFromInt(999), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7169 // __builtin_msa_cle_u_b
7170 .{ .tag = @enumFromInt(1000), .properties = .{ .param_str = "V16ScV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7171 // __builtin_msa_cle_u_d
7172 .{ .tag = @enumFromInt(1001), .properties = .{ .param_str = "V2SLLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7173 // __builtin_msa_cle_u_h
7174 .{ .tag = @enumFromInt(1002), .properties = .{ .param_str = "V8SsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7175 // __builtin_msa_cle_u_w
7176 .{ .tag = @enumFromInt(1003), .properties = .{ .param_str = "V4SiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7177 // __builtin_msa_clei_s_b
7178 .{ .tag = @enumFromInt(1004), .properties = .{ .param_str = "V16ScV16ScISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7179 // __builtin_msa_clei_s_d
7180 .{ .tag = @enumFromInt(1005), .properties = .{ .param_str = "V2SLLiV2SLLiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7181 // __builtin_msa_clei_s_h
7182 .{ .tag = @enumFromInt(1006), .properties = .{ .param_str = "V8SsV8SsISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7183 // __builtin_msa_clei_s_w
7184 .{ .tag = @enumFromInt(1007), .properties = .{ .param_str = "V4SiV4SiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7185 // __builtin_msa_clei_u_b
7186 .{ .tag = @enumFromInt(1008), .properties = .{ .param_str = "V16ScV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7187 // __builtin_msa_clei_u_d
7188 .{ .tag = @enumFromInt(1009), .properties = .{ .param_str = "V2SLLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7189 // __builtin_msa_clei_u_h
7190 .{ .tag = @enumFromInt(1010), .properties = .{ .param_str = "V8SsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7191 // __builtin_msa_clei_u_w
7192 .{ .tag = @enumFromInt(1011), .properties = .{ .param_str = "V4SiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7193 // __builtin_msa_clt_s_b
7194 .{ .tag = @enumFromInt(1012), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7195 // __builtin_msa_clt_s_d
7196 .{ .tag = @enumFromInt(1013), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7197 // __builtin_msa_clt_s_h
7198 .{ .tag = @enumFromInt(1014), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7199 // __builtin_msa_clt_s_w
7200 .{ .tag = @enumFromInt(1015), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7201 // __builtin_msa_clt_u_b
7202 .{ .tag = @enumFromInt(1016), .properties = .{ .param_str = "V16ScV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7203 // __builtin_msa_clt_u_d
7204 .{ .tag = @enumFromInt(1017), .properties = .{ .param_str = "V2SLLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7205 // __builtin_msa_clt_u_h
7206 .{ .tag = @enumFromInt(1018), .properties = .{ .param_str = "V8SsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7207 // __builtin_msa_clt_u_w
7208 .{ .tag = @enumFromInt(1019), .properties = .{ .param_str = "V4SiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7209 // __builtin_msa_clti_s_b
7210 .{ .tag = @enumFromInt(1020), .properties = .{ .param_str = "V16ScV16ScISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7211 // __builtin_msa_clti_s_d
7212 .{ .tag = @enumFromInt(1021), .properties = .{ .param_str = "V2SLLiV2SLLiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7213 // __builtin_msa_clti_s_h
7214 .{ .tag = @enumFromInt(1022), .properties = .{ .param_str = "V8SsV8SsISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7215 // __builtin_msa_clti_s_w
7216 .{ .tag = @enumFromInt(1023), .properties = .{ .param_str = "V4SiV4SiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7217 // __builtin_msa_clti_u_b
7218 .{ .tag = @enumFromInt(1024), .properties = .{ .param_str = "V16ScV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7219 // __builtin_msa_clti_u_d
7220 .{ .tag = @enumFromInt(1025), .properties = .{ .param_str = "V2SLLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7221 // __builtin_msa_clti_u_h
7222 .{ .tag = @enumFromInt(1026), .properties = .{ .param_str = "V8SsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7223 // __builtin_msa_clti_u_w
7224 .{ .tag = @enumFromInt(1027), .properties = .{ .param_str = "V4SiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7225 // __builtin_msa_copy_s_b
7226 .{ .tag = @enumFromInt(1028), .properties = .{ .param_str = "iV16ScIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7227 // __builtin_msa_copy_s_d
7228 .{ .tag = @enumFromInt(1029), .properties = .{ .param_str = "LLiV2SLLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7229 // __builtin_msa_copy_s_h
7230 .{ .tag = @enumFromInt(1030), .properties = .{ .param_str = "iV8SsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7231 // __builtin_msa_copy_s_w
7232 .{ .tag = @enumFromInt(1031), .properties = .{ .param_str = "iV4SiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7233 // __builtin_msa_copy_u_b
7234 .{ .tag = @enumFromInt(1032), .properties = .{ .param_str = "iV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7235 // __builtin_msa_copy_u_d
7236 .{ .tag = @enumFromInt(1033), .properties = .{ .param_str = "LLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7237 // __builtin_msa_copy_u_h
7238 .{ .tag = @enumFromInt(1034), .properties = .{ .param_str = "iV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7239 // __builtin_msa_copy_u_w
7240 .{ .tag = @enumFromInt(1035), .properties = .{ .param_str = "iV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7241 // __builtin_msa_ctcmsa
7242 .{ .tag = @enumFromInt(1036), .properties = .{ .param_str = "vIii", .target_set = TargetSet.initOne(.mips) } },
7243 // __builtin_msa_div_s_b
7244 .{ .tag = @enumFromInt(1037), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7245 // __builtin_msa_div_s_d
7246 .{ .tag = @enumFromInt(1038), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7247 // __builtin_msa_div_s_h
7248 .{ .tag = @enumFromInt(1039), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7249 // __builtin_msa_div_s_w
7250 .{ .tag = @enumFromInt(1040), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7251 // __builtin_msa_div_u_b
7252 .{ .tag = @enumFromInt(1041), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7253 // __builtin_msa_div_u_d
7254 .{ .tag = @enumFromInt(1042), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7255 // __builtin_msa_div_u_h
7256 .{ .tag = @enumFromInt(1043), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7257 // __builtin_msa_div_u_w
7258 .{ .tag = @enumFromInt(1044), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7259 // __builtin_msa_dotp_s_d
7260 .{ .tag = @enumFromInt(1045), .properties = .{ .param_str = "V2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7261 // __builtin_msa_dotp_s_h
7262 .{ .tag = @enumFromInt(1046), .properties = .{ .param_str = "V8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7263 // __builtin_msa_dotp_s_w
7264 .{ .tag = @enumFromInt(1047), .properties = .{ .param_str = "V4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7265 // __builtin_msa_dotp_u_d
7266 .{ .tag = @enumFromInt(1048), .properties = .{ .param_str = "V2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7267 // __builtin_msa_dotp_u_h
7268 .{ .tag = @enumFromInt(1049), .properties = .{ .param_str = "V8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7269 // __builtin_msa_dotp_u_w
7270 .{ .tag = @enumFromInt(1050), .properties = .{ .param_str = "V4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7271 // __builtin_msa_dpadd_s_d
7272 .{ .tag = @enumFromInt(1051), .properties = .{ .param_str = "V2SLLiV2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7273 // __builtin_msa_dpadd_s_h
7274 .{ .tag = @enumFromInt(1052), .properties = .{ .param_str = "V8SsV8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7275 // __builtin_msa_dpadd_s_w
7276 .{ .tag = @enumFromInt(1053), .properties = .{ .param_str = "V4SiV4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7277 // __builtin_msa_dpadd_u_d
7278 .{ .tag = @enumFromInt(1054), .properties = .{ .param_str = "V2ULLiV2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7279 // __builtin_msa_dpadd_u_h
7280 .{ .tag = @enumFromInt(1055), .properties = .{ .param_str = "V8UsV8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7281 // __builtin_msa_dpadd_u_w
7282 .{ .tag = @enumFromInt(1056), .properties = .{ .param_str = "V4UiV4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7283 // __builtin_msa_dpsub_s_d
7284 .{ .tag = @enumFromInt(1057), .properties = .{ .param_str = "V2SLLiV2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7285 // __builtin_msa_dpsub_s_h
7286 .{ .tag = @enumFromInt(1058), .properties = .{ .param_str = "V8SsV8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7287 // __builtin_msa_dpsub_s_w
7288 .{ .tag = @enumFromInt(1059), .properties = .{ .param_str = "V4SiV4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7289 // __builtin_msa_dpsub_u_d
7290 .{ .tag = @enumFromInt(1060), .properties = .{ .param_str = "V2ULLiV2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7291 // __builtin_msa_dpsub_u_h
7292 .{ .tag = @enumFromInt(1061), .properties = .{ .param_str = "V8UsV8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7293 // __builtin_msa_dpsub_u_w
7294 .{ .tag = @enumFromInt(1062), .properties = .{ .param_str = "V4UiV4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7295 // __builtin_msa_fadd_d
7296 .{ .tag = @enumFromInt(1063), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7297 // __builtin_msa_fadd_w
7298 .{ .tag = @enumFromInt(1064), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7299 // __builtin_msa_fcaf_d
7300 .{ .tag = @enumFromInt(1065), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7301 // __builtin_msa_fcaf_w
7302 .{ .tag = @enumFromInt(1066), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7303 // __builtin_msa_fceq_d
7304 .{ .tag = @enumFromInt(1067), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7305 // __builtin_msa_fceq_w
7306 .{ .tag = @enumFromInt(1068), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7307 // __builtin_msa_fclass_d
7308 .{ .tag = @enumFromInt(1069), .properties = .{ .param_str = "V2LLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7309 // __builtin_msa_fclass_w
7310 .{ .tag = @enumFromInt(1070), .properties = .{ .param_str = "V4iV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7311 // __builtin_msa_fcle_d
7312 .{ .tag = @enumFromInt(1071), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7313 // __builtin_msa_fcle_w
7314 .{ .tag = @enumFromInt(1072), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7315 // __builtin_msa_fclt_d
7316 .{ .tag = @enumFromInt(1073), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7317 // __builtin_msa_fclt_w
7318 .{ .tag = @enumFromInt(1074), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7319 // __builtin_msa_fcne_d
7320 .{ .tag = @enumFromInt(1075), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7321 // __builtin_msa_fcne_w
7322 .{ .tag = @enumFromInt(1076), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7323 // __builtin_msa_fcor_d
7324 .{ .tag = @enumFromInt(1077), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7325 // __builtin_msa_fcor_w
7326 .{ .tag = @enumFromInt(1078), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7327 // __builtin_msa_fcueq_d
7328 .{ .tag = @enumFromInt(1079), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7329 // __builtin_msa_fcueq_w
7330 .{ .tag = @enumFromInt(1080), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7331 // __builtin_msa_fcule_d
7332 .{ .tag = @enumFromInt(1081), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7333 // __builtin_msa_fcule_w
7334 .{ .tag = @enumFromInt(1082), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7335 // __builtin_msa_fcult_d
7336 .{ .tag = @enumFromInt(1083), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7337 // __builtin_msa_fcult_w
7338 .{ .tag = @enumFromInt(1084), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7339 // __builtin_msa_fcun_d
7340 .{ .tag = @enumFromInt(1085), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7341 // __builtin_msa_fcun_w
7342 .{ .tag = @enumFromInt(1086), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7343 // __builtin_msa_fcune_d
7344 .{ .tag = @enumFromInt(1087), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7345 // __builtin_msa_fcune_w
7346 .{ .tag = @enumFromInt(1088), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7347 // __builtin_msa_fdiv_d
7348 .{ .tag = @enumFromInt(1089), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7349 // __builtin_msa_fdiv_w
7350 .{ .tag = @enumFromInt(1090), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7351 // __builtin_msa_fexdo_h
7352 .{ .tag = @enumFromInt(1091), .properties = .{ .param_str = "V8hV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7353 // __builtin_msa_fexdo_w
7354 .{ .tag = @enumFromInt(1092), .properties = .{ .param_str = "V4fV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7355 // __builtin_msa_fexp2_d
7356 .{ .tag = @enumFromInt(1093), .properties = .{ .param_str = "V2dV2dV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7357 // __builtin_msa_fexp2_w
7358 .{ .tag = @enumFromInt(1094), .properties = .{ .param_str = "V4fV4fV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7359 // __builtin_msa_fexupl_d
7360 .{ .tag = @enumFromInt(1095), .properties = .{ .param_str = "V2dV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7361 // __builtin_msa_fexupl_w
7362 .{ .tag = @enumFromInt(1096), .properties = .{ .param_str = "V4fV8h", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7363 // __builtin_msa_fexupr_d
7364 .{ .tag = @enumFromInt(1097), .properties = .{ .param_str = "V2dV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7365 // __builtin_msa_fexupr_w
7366 .{ .tag = @enumFromInt(1098), .properties = .{ .param_str = "V4fV8h", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7367 // __builtin_msa_ffint_s_d
7368 .{ .tag = @enumFromInt(1099), .properties = .{ .param_str = "V2dV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7369 // __builtin_msa_ffint_s_w
7370 .{ .tag = @enumFromInt(1100), .properties = .{ .param_str = "V4fV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7371 // __builtin_msa_ffint_u_d
7372 .{ .tag = @enumFromInt(1101), .properties = .{ .param_str = "V2dV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7373 // __builtin_msa_ffint_u_w
7374 .{ .tag = @enumFromInt(1102), .properties = .{ .param_str = "V4fV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7375 // __builtin_msa_ffql_d
7376 .{ .tag = @enumFromInt(1103), .properties = .{ .param_str = "V2dV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7377 // __builtin_msa_ffql_w
7378 .{ .tag = @enumFromInt(1104), .properties = .{ .param_str = "V4fV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7379 // __builtin_msa_ffqr_d
7380 .{ .tag = @enumFromInt(1105), .properties = .{ .param_str = "V2dV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7381 // __builtin_msa_ffqr_w
7382 .{ .tag = @enumFromInt(1106), .properties = .{ .param_str = "V4fV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7383 // __builtin_msa_fill_b
7384 .{ .tag = @enumFromInt(1107), .properties = .{ .param_str = "V16Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7385 // __builtin_msa_fill_d
7386 .{ .tag = @enumFromInt(1108), .properties = .{ .param_str = "V2SLLiLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7387 // __builtin_msa_fill_h
7388 .{ .tag = @enumFromInt(1109), .properties = .{ .param_str = "V8Ssi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7389 // __builtin_msa_fill_w
7390 .{ .tag = @enumFromInt(1110), .properties = .{ .param_str = "V4Sii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7391 // __builtin_msa_flog2_d
7392 .{ .tag = @enumFromInt(1111), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7393 // __builtin_msa_flog2_w
7394 .{ .tag = @enumFromInt(1112), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7395 // __builtin_msa_fmadd_d
7396 .{ .tag = @enumFromInt(1113), .properties = .{ .param_str = "V2dV2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7397 // __builtin_msa_fmadd_w
7398 .{ .tag = @enumFromInt(1114), .properties = .{ .param_str = "V4fV4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7399 // __builtin_msa_fmax_a_d
7400 .{ .tag = @enumFromInt(1115), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7401 // __builtin_msa_fmax_a_w
7402 .{ .tag = @enumFromInt(1116), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7403 // __builtin_msa_fmax_d
7404 .{ .tag = @enumFromInt(1117), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7405 // __builtin_msa_fmax_w
7406 .{ .tag = @enumFromInt(1118), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7407 // __builtin_msa_fmin_a_d
7408 .{ .tag = @enumFromInt(1119), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7409 // __builtin_msa_fmin_a_w
7410 .{ .tag = @enumFromInt(1120), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7411 // __builtin_msa_fmin_d
7412 .{ .tag = @enumFromInt(1121), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7413 // __builtin_msa_fmin_w
7414 .{ .tag = @enumFromInt(1122), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7415 // __builtin_msa_fmsub_d
7416 .{ .tag = @enumFromInt(1123), .properties = .{ .param_str = "V2dV2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7417 // __builtin_msa_fmsub_w
7418 .{ .tag = @enumFromInt(1124), .properties = .{ .param_str = "V4fV4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7419 // __builtin_msa_fmul_d
7420 .{ .tag = @enumFromInt(1125), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7421 // __builtin_msa_fmul_w
7422 .{ .tag = @enumFromInt(1126), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7423 // __builtin_msa_frcp_d
7424 .{ .tag = @enumFromInt(1127), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7425 // __builtin_msa_frcp_w
7426 .{ .tag = @enumFromInt(1128), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7427 // __builtin_msa_frint_d
7428 .{ .tag = @enumFromInt(1129), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7429 // __builtin_msa_frint_w
7430 .{ .tag = @enumFromInt(1130), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7431 // __builtin_msa_frsqrt_d
7432 .{ .tag = @enumFromInt(1131), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7433 // __builtin_msa_frsqrt_w
7434 .{ .tag = @enumFromInt(1132), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7435 // __builtin_msa_fsaf_d
7436 .{ .tag = @enumFromInt(1133), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7437 // __builtin_msa_fsaf_w
7438 .{ .tag = @enumFromInt(1134), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7439 // __builtin_msa_fseq_d
7440 .{ .tag = @enumFromInt(1135), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7441 // __builtin_msa_fseq_w
7442 .{ .tag = @enumFromInt(1136), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7443 // __builtin_msa_fsle_d
7444 .{ .tag = @enumFromInt(1137), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7445 // __builtin_msa_fsle_w
7446 .{ .tag = @enumFromInt(1138), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7447 // __builtin_msa_fslt_d
7448 .{ .tag = @enumFromInt(1139), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7449 // __builtin_msa_fslt_w
7450 .{ .tag = @enumFromInt(1140), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7451 // __builtin_msa_fsne_d
7452 .{ .tag = @enumFromInt(1141), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7453 // __builtin_msa_fsne_w
7454 .{ .tag = @enumFromInt(1142), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7455 // __builtin_msa_fsor_d
7456 .{ .tag = @enumFromInt(1143), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7457 // __builtin_msa_fsor_w
7458 .{ .tag = @enumFromInt(1144), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7459 // __builtin_msa_fsqrt_d
7460 .{ .tag = @enumFromInt(1145), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7461 // __builtin_msa_fsqrt_w
7462 .{ .tag = @enumFromInt(1146), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7463 // __builtin_msa_fsub_d
7464 .{ .tag = @enumFromInt(1147), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7465 // __builtin_msa_fsub_w
7466 .{ .tag = @enumFromInt(1148), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7467 // __builtin_msa_fsueq_d
7468 .{ .tag = @enumFromInt(1149), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7469 // __builtin_msa_fsueq_w
7470 .{ .tag = @enumFromInt(1150), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7471 // __builtin_msa_fsule_d
7472 .{ .tag = @enumFromInt(1151), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7473 // __builtin_msa_fsule_w
7474 .{ .tag = @enumFromInt(1152), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7475 // __builtin_msa_fsult_d
7476 .{ .tag = @enumFromInt(1153), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7477 // __builtin_msa_fsult_w
7478 .{ .tag = @enumFromInt(1154), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7479 // __builtin_msa_fsun_d
7480 .{ .tag = @enumFromInt(1155), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7481 // __builtin_msa_fsun_w
7482 .{ .tag = @enumFromInt(1156), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7483 // __builtin_msa_fsune_d
7484 .{ .tag = @enumFromInt(1157), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7485 // __builtin_msa_fsune_w
7486 .{ .tag = @enumFromInt(1158), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7487 // __builtin_msa_ftint_s_d
7488 .{ .tag = @enumFromInt(1159), .properties = .{ .param_str = "V2SLLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7489 // __builtin_msa_ftint_s_w
7490 .{ .tag = @enumFromInt(1160), .properties = .{ .param_str = "V4SiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7491 // __builtin_msa_ftint_u_d
7492 .{ .tag = @enumFromInt(1161), .properties = .{ .param_str = "V2ULLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7493 // __builtin_msa_ftint_u_w
7494 .{ .tag = @enumFromInt(1162), .properties = .{ .param_str = "V4UiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7495 // __builtin_msa_ftq_h
7496 .{ .tag = @enumFromInt(1163), .properties = .{ .param_str = "V4UiV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7497 // __builtin_msa_ftq_w
7498 .{ .tag = @enumFromInt(1164), .properties = .{ .param_str = "V2ULLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7499 // __builtin_msa_ftrunc_s_d
7500 .{ .tag = @enumFromInt(1165), .properties = .{ .param_str = "V2SLLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7501 // __builtin_msa_ftrunc_s_w
7502 .{ .tag = @enumFromInt(1166), .properties = .{ .param_str = "V4SiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7503 // __builtin_msa_ftrunc_u_d
7504 .{ .tag = @enumFromInt(1167), .properties = .{ .param_str = "V2ULLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7505 // __builtin_msa_ftrunc_u_w
7506 .{ .tag = @enumFromInt(1168), .properties = .{ .param_str = "V4UiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7507 // __builtin_msa_hadd_s_d
7508 .{ .tag = @enumFromInt(1169), .properties = .{ .param_str = "V2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7509 // __builtin_msa_hadd_s_h
7510 .{ .tag = @enumFromInt(1170), .properties = .{ .param_str = "V8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7511 // __builtin_msa_hadd_s_w
7512 .{ .tag = @enumFromInt(1171), .properties = .{ .param_str = "V4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7513 // __builtin_msa_hadd_u_d
7514 .{ .tag = @enumFromInt(1172), .properties = .{ .param_str = "V2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7515 // __builtin_msa_hadd_u_h
7516 .{ .tag = @enumFromInt(1173), .properties = .{ .param_str = "V8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7517 // __builtin_msa_hadd_u_w
7518 .{ .tag = @enumFromInt(1174), .properties = .{ .param_str = "V4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7519 // __builtin_msa_hsub_s_d
7520 .{ .tag = @enumFromInt(1175), .properties = .{ .param_str = "V2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7521 // __builtin_msa_hsub_s_h
7522 .{ .tag = @enumFromInt(1176), .properties = .{ .param_str = "V8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7523 // __builtin_msa_hsub_s_w
7524 .{ .tag = @enumFromInt(1177), .properties = .{ .param_str = "V4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7525 // __builtin_msa_hsub_u_d
7526 .{ .tag = @enumFromInt(1178), .properties = .{ .param_str = "V2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7527 // __builtin_msa_hsub_u_h
7528 .{ .tag = @enumFromInt(1179), .properties = .{ .param_str = "V8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7529 // __builtin_msa_hsub_u_w
7530 .{ .tag = @enumFromInt(1180), .properties = .{ .param_str = "V4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7531 // __builtin_msa_ilvev_b
7532 .{ .tag = @enumFromInt(1181), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7533 // __builtin_msa_ilvev_d
7534 .{ .tag = @enumFromInt(1182), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7535 // __builtin_msa_ilvev_h
7536 .{ .tag = @enumFromInt(1183), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7537 // __builtin_msa_ilvev_w
7538 .{ .tag = @enumFromInt(1184), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7539 // __builtin_msa_ilvl_b
7540 .{ .tag = @enumFromInt(1185), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7541 // __builtin_msa_ilvl_d
7542 .{ .tag = @enumFromInt(1186), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7543 // __builtin_msa_ilvl_h
7544 .{ .tag = @enumFromInt(1187), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7545 // __builtin_msa_ilvl_w
7546 .{ .tag = @enumFromInt(1188), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7547 // __builtin_msa_ilvod_b
7548 .{ .tag = @enumFromInt(1189), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7549 // __builtin_msa_ilvod_d
7550 .{ .tag = @enumFromInt(1190), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7551 // __builtin_msa_ilvod_h
7552 .{ .tag = @enumFromInt(1191), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7553 // __builtin_msa_ilvod_w
7554 .{ .tag = @enumFromInt(1192), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7555 // __builtin_msa_ilvr_b
7556 .{ .tag = @enumFromInt(1193), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7557 // __builtin_msa_ilvr_d
7558 .{ .tag = @enumFromInt(1194), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7559 // __builtin_msa_ilvr_h
7560 .{ .tag = @enumFromInt(1195), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7561 // __builtin_msa_ilvr_w
7562 .{ .tag = @enumFromInt(1196), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7563 // __builtin_msa_insert_b
7564 .{ .tag = @enumFromInt(1197), .properties = .{ .param_str = "V16ScV16ScIUii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7565 // __builtin_msa_insert_d
7566 .{ .tag = @enumFromInt(1198), .properties = .{ .param_str = "V2SLLiV2SLLiIUiLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7567 // __builtin_msa_insert_h
7568 .{ .tag = @enumFromInt(1199), .properties = .{ .param_str = "V8SsV8SsIUii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7569 // __builtin_msa_insert_w
7570 .{ .tag = @enumFromInt(1200), .properties = .{ .param_str = "V4SiV4SiIUii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7571 // __builtin_msa_insve_b
7572 .{ .tag = @enumFromInt(1201), .properties = .{ .param_str = "V16ScV16ScIUiV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7573 // __builtin_msa_insve_d
7574 .{ .tag = @enumFromInt(1202), .properties = .{ .param_str = "V2SLLiV2SLLiIUiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7575 // __builtin_msa_insve_h
7576 .{ .tag = @enumFromInt(1203), .properties = .{ .param_str = "V8SsV8SsIUiV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7577 // __builtin_msa_insve_w
7578 .{ .tag = @enumFromInt(1204), .properties = .{ .param_str = "V4SiV4SiIUiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7579 // __builtin_msa_ld_b
7580 .{ .tag = @enumFromInt(1205), .properties = .{ .param_str = "V16Scv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7581 // __builtin_msa_ld_d
7582 .{ .tag = @enumFromInt(1206), .properties = .{ .param_str = "V2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7583 // __builtin_msa_ld_h
7584 .{ .tag = @enumFromInt(1207), .properties = .{ .param_str = "V8Ssv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7585 // __builtin_msa_ld_w
7586 .{ .tag = @enumFromInt(1208), .properties = .{ .param_str = "V4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7587 // __builtin_msa_ldi_b
7588 .{ .tag = @enumFromInt(1209), .properties = .{ .param_str = "V16cIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7589 // __builtin_msa_ldi_d
7590 .{ .tag = @enumFromInt(1210), .properties = .{ .param_str = "V2LLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7591 // __builtin_msa_ldi_h
7592 .{ .tag = @enumFromInt(1211), .properties = .{ .param_str = "V8sIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7593 // __builtin_msa_ldi_w
7594 .{ .tag = @enumFromInt(1212), .properties = .{ .param_str = "V4iIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7595 // __builtin_msa_ldr_d
7596 .{ .tag = @enumFromInt(1213), .properties = .{ .param_str = "V2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7597 // __builtin_msa_ldr_w
7598 .{ .tag = @enumFromInt(1214), .properties = .{ .param_str = "V4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7599 // __builtin_msa_madd_q_h
7600 .{ .tag = @enumFromInt(1215), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7601 // __builtin_msa_madd_q_w
7602 .{ .tag = @enumFromInt(1216), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7603 // __builtin_msa_maddr_q_h
7604 .{ .tag = @enumFromInt(1217), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7605 // __builtin_msa_maddr_q_w
7606 .{ .tag = @enumFromInt(1218), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7607 // __builtin_msa_maddv_b
7608 .{ .tag = @enumFromInt(1219), .properties = .{ .param_str = "V16ScV16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7609 // __builtin_msa_maddv_d
7610 .{ .tag = @enumFromInt(1220), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7611 // __builtin_msa_maddv_h
7612 .{ .tag = @enumFromInt(1221), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7613 // __builtin_msa_maddv_w
7614 .{ .tag = @enumFromInt(1222), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7615 // __builtin_msa_max_a_b
7616 .{ .tag = @enumFromInt(1223), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7617 // __builtin_msa_max_a_d
7618 .{ .tag = @enumFromInt(1224), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7619 // __builtin_msa_max_a_h
7620 .{ .tag = @enumFromInt(1225), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7621 // __builtin_msa_max_a_w
7622 .{ .tag = @enumFromInt(1226), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7623 // __builtin_msa_max_s_b
7624 .{ .tag = @enumFromInt(1227), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7625 // __builtin_msa_max_s_d
7626 .{ .tag = @enumFromInt(1228), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7627 // __builtin_msa_max_s_h
7628 .{ .tag = @enumFromInt(1229), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7629 // __builtin_msa_max_s_w
7630 .{ .tag = @enumFromInt(1230), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7631 // __builtin_msa_max_u_b
7632 .{ .tag = @enumFromInt(1231), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7633 // __builtin_msa_max_u_d
7634 .{ .tag = @enumFromInt(1232), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7635 // __builtin_msa_max_u_h
7636 .{ .tag = @enumFromInt(1233), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7637 // __builtin_msa_max_u_w
7638 .{ .tag = @enumFromInt(1234), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7639 // __builtin_msa_maxi_s_b
7640 .{ .tag = @enumFromInt(1235), .properties = .{ .param_str = "V16ScV16ScIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7641 // __builtin_msa_maxi_s_d
7642 .{ .tag = @enumFromInt(1236), .properties = .{ .param_str = "V2SLLiV2SLLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7643 // __builtin_msa_maxi_s_h
7644 .{ .tag = @enumFromInt(1237), .properties = .{ .param_str = "V8SsV8SsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7645 // __builtin_msa_maxi_s_w
7646 .{ .tag = @enumFromInt(1238), .properties = .{ .param_str = "V4SiV4SiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7647 // __builtin_msa_maxi_u_b
7648 .{ .tag = @enumFromInt(1239), .properties = .{ .param_str = "V16UcV16UcIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7649 // __builtin_msa_maxi_u_d
7650 .{ .tag = @enumFromInt(1240), .properties = .{ .param_str = "V2ULLiV2ULLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7651 // __builtin_msa_maxi_u_h
7652 .{ .tag = @enumFromInt(1241), .properties = .{ .param_str = "V8UsV8UsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7653 // __builtin_msa_maxi_u_w
7654 .{ .tag = @enumFromInt(1242), .properties = .{ .param_str = "V4UiV4UiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7655 // __builtin_msa_min_a_b
7656 .{ .tag = @enumFromInt(1243), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7657 // __builtin_msa_min_a_d
7658 .{ .tag = @enumFromInt(1244), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7659 // __builtin_msa_min_a_h
7660 .{ .tag = @enumFromInt(1245), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7661 // __builtin_msa_min_a_w
7662 .{ .tag = @enumFromInt(1246), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7663 // __builtin_msa_min_s_b
7664 .{ .tag = @enumFromInt(1247), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7665 // __builtin_msa_min_s_d
7666 .{ .tag = @enumFromInt(1248), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7667 // __builtin_msa_min_s_h
7668 .{ .tag = @enumFromInt(1249), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7669 // __builtin_msa_min_s_w
7670 .{ .tag = @enumFromInt(1250), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7671 // __builtin_msa_min_u_b
7672 .{ .tag = @enumFromInt(1251), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7673 // __builtin_msa_min_u_d
7674 .{ .tag = @enumFromInt(1252), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7675 // __builtin_msa_min_u_h
7676 .{ .tag = @enumFromInt(1253), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7677 // __builtin_msa_min_u_w
7678 .{ .tag = @enumFromInt(1254), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7679 // __builtin_msa_mini_s_b
7680 .{ .tag = @enumFromInt(1255), .properties = .{ .param_str = "V16ScV16ScIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7681 // __builtin_msa_mini_s_d
7682 .{ .tag = @enumFromInt(1256), .properties = .{ .param_str = "V2SLLiV2SLLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7683 // __builtin_msa_mini_s_h
7684 .{ .tag = @enumFromInt(1257), .properties = .{ .param_str = "V8SsV8SsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7685 // __builtin_msa_mini_s_w
7686 .{ .tag = @enumFromInt(1258), .properties = .{ .param_str = "V4SiV4SiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7687 // __builtin_msa_mini_u_b
7688 .{ .tag = @enumFromInt(1259), .properties = .{ .param_str = "V16UcV16UcIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7689 // __builtin_msa_mini_u_d
7690 .{ .tag = @enumFromInt(1260), .properties = .{ .param_str = "V2ULLiV2ULLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7691 // __builtin_msa_mini_u_h
7692 .{ .tag = @enumFromInt(1261), .properties = .{ .param_str = "V8UsV8UsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7693 // __builtin_msa_mini_u_w
7694 .{ .tag = @enumFromInt(1262), .properties = .{ .param_str = "V4UiV4UiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7695 // __builtin_msa_mod_s_b
7696 .{ .tag = @enumFromInt(1263), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7697 // __builtin_msa_mod_s_d
7698 .{ .tag = @enumFromInt(1264), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7699 // __builtin_msa_mod_s_h
7700 .{ .tag = @enumFromInt(1265), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7701 // __builtin_msa_mod_s_w
7702 .{ .tag = @enumFromInt(1266), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7703 // __builtin_msa_mod_u_b
7704 .{ .tag = @enumFromInt(1267), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7705 // __builtin_msa_mod_u_d
7706 .{ .tag = @enumFromInt(1268), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7707 // __builtin_msa_mod_u_h
7708 .{ .tag = @enumFromInt(1269), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7709 // __builtin_msa_mod_u_w
7710 .{ .tag = @enumFromInt(1270), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7711 // __builtin_msa_move_v
7712 .{ .tag = @enumFromInt(1271), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7713 // __builtin_msa_msub_q_h
7714 .{ .tag = @enumFromInt(1272), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7715 // __builtin_msa_msub_q_w
7716 .{ .tag = @enumFromInt(1273), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7717 // __builtin_msa_msubr_q_h
7718 .{ .tag = @enumFromInt(1274), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7719 // __builtin_msa_msubr_q_w
7720 .{ .tag = @enumFromInt(1275), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7721 // __builtin_msa_msubv_b
7722 .{ .tag = @enumFromInt(1276), .properties = .{ .param_str = "V16ScV16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7723 // __builtin_msa_msubv_d
7724 .{ .tag = @enumFromInt(1277), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7725 // __builtin_msa_msubv_h
7726 .{ .tag = @enumFromInt(1278), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7727 // __builtin_msa_msubv_w
7728 .{ .tag = @enumFromInt(1279), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7729 // __builtin_msa_mul_q_h
7730 .{ .tag = @enumFromInt(1280), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7731 // __builtin_msa_mul_q_w
7732 .{ .tag = @enumFromInt(1281), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7733 // __builtin_msa_mulr_q_h
7734 .{ .tag = @enumFromInt(1282), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7735 // __builtin_msa_mulr_q_w
7736 .{ .tag = @enumFromInt(1283), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7737 // __builtin_msa_mulv_b
7738 .{ .tag = @enumFromInt(1284), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7739 // __builtin_msa_mulv_d
7740 .{ .tag = @enumFromInt(1285), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7741 // __builtin_msa_mulv_h
7742 .{ .tag = @enumFromInt(1286), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7743 // __builtin_msa_mulv_w
7744 .{ .tag = @enumFromInt(1287), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7745 // __builtin_msa_nloc_b
7746 .{ .tag = @enumFromInt(1288), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7747 // __builtin_msa_nloc_d
7748 .{ .tag = @enumFromInt(1289), .properties = .{ .param_str = "V2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7749 // __builtin_msa_nloc_h
7750 .{ .tag = @enumFromInt(1290), .properties = .{ .param_str = "V8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7751 // __builtin_msa_nloc_w
7752 .{ .tag = @enumFromInt(1291), .properties = .{ .param_str = "V4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7753 // __builtin_msa_nlzc_b
7754 .{ .tag = @enumFromInt(1292), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7755 // __builtin_msa_nlzc_d
7756 .{ .tag = @enumFromInt(1293), .properties = .{ .param_str = "V2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7757 // __builtin_msa_nlzc_h
7758 .{ .tag = @enumFromInt(1294), .properties = .{ .param_str = "V8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7759 // __builtin_msa_nlzc_w
7760 .{ .tag = @enumFromInt(1295), .properties = .{ .param_str = "V4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7761 // __builtin_msa_nor_v
7762 .{ .tag = @enumFromInt(1296), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7763 // __builtin_msa_nori_b
7764 .{ .tag = @enumFromInt(1297), .properties = .{ .param_str = "V16UcV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7765 // __builtin_msa_or_v
7766 .{ .tag = @enumFromInt(1298), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7767 // __builtin_msa_ori_b
7768 .{ .tag = @enumFromInt(1299), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7769 // __builtin_msa_pckev_b
7770 .{ .tag = @enumFromInt(1300), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7771 // __builtin_msa_pckev_d
7772 .{ .tag = @enumFromInt(1301), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7773 // __builtin_msa_pckev_h
7774 .{ .tag = @enumFromInt(1302), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7775 // __builtin_msa_pckev_w
7776 .{ .tag = @enumFromInt(1303), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7777 // __builtin_msa_pckod_b
7778 .{ .tag = @enumFromInt(1304), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7779 // __builtin_msa_pckod_d
7780 .{ .tag = @enumFromInt(1305), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7781 // __builtin_msa_pckod_h
7782 .{ .tag = @enumFromInt(1306), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7783 // __builtin_msa_pckod_w
7784 .{ .tag = @enumFromInt(1307), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7785 // __builtin_msa_pcnt_b
7786 .{ .tag = @enumFromInt(1308), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7787 // __builtin_msa_pcnt_d
7788 .{ .tag = @enumFromInt(1309), .properties = .{ .param_str = "V2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7789 // __builtin_msa_pcnt_h
7790 .{ .tag = @enumFromInt(1310), .properties = .{ .param_str = "V8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7791 // __builtin_msa_pcnt_w
7792 .{ .tag = @enumFromInt(1311), .properties = .{ .param_str = "V4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7793 // __builtin_msa_sat_s_b
7794 .{ .tag = @enumFromInt(1312), .properties = .{ .param_str = "V16ScV16ScIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7795 // __builtin_msa_sat_s_d
7796 .{ .tag = @enumFromInt(1313), .properties = .{ .param_str = "V2SLLiV2SLLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7797 // __builtin_msa_sat_s_h
7798 .{ .tag = @enumFromInt(1314), .properties = .{ .param_str = "V8SsV8SsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7799 // __builtin_msa_sat_s_w
7800 .{ .tag = @enumFromInt(1315), .properties = .{ .param_str = "V4SiV4SiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7801 // __builtin_msa_sat_u_b
7802 .{ .tag = @enumFromInt(1316), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7803 // __builtin_msa_sat_u_d
7804 .{ .tag = @enumFromInt(1317), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7805 // __builtin_msa_sat_u_h
7806 .{ .tag = @enumFromInt(1318), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7807 // __builtin_msa_sat_u_w
7808 .{ .tag = @enumFromInt(1319), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7809 // __builtin_msa_shf_b
7810 .{ .tag = @enumFromInt(1320), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7811 // __builtin_msa_shf_h
7812 .{ .tag = @enumFromInt(1321), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7813 // __builtin_msa_shf_w
7814 .{ .tag = @enumFromInt(1322), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7815 // __builtin_msa_sld_b
7816 .{ .tag = @enumFromInt(1323), .properties = .{ .param_str = "V16cV16cV16cUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7817 // __builtin_msa_sld_d
7818 .{ .tag = @enumFromInt(1324), .properties = .{ .param_str = "V2LLiV2LLiV2LLiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7819 // __builtin_msa_sld_h
7820 .{ .tag = @enumFromInt(1325), .properties = .{ .param_str = "V8sV8sV8sUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7821 // __builtin_msa_sld_w
7822 .{ .tag = @enumFromInt(1326), .properties = .{ .param_str = "V4iV4iV4iUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7823 // __builtin_msa_sldi_b
7824 .{ .tag = @enumFromInt(1327), .properties = .{ .param_str = "V16cV16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7825 // __builtin_msa_sldi_d
7826 .{ .tag = @enumFromInt(1328), .properties = .{ .param_str = "V2LLiV2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7827 // __builtin_msa_sldi_h
7828 .{ .tag = @enumFromInt(1329), .properties = .{ .param_str = "V8sV8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7829 // __builtin_msa_sldi_w
7830 .{ .tag = @enumFromInt(1330), .properties = .{ .param_str = "V4iV4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7831 // __builtin_msa_sll_b
7832 .{ .tag = @enumFromInt(1331), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7833 // __builtin_msa_sll_d
7834 .{ .tag = @enumFromInt(1332), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7835 // __builtin_msa_sll_h
7836 .{ .tag = @enumFromInt(1333), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7837 // __builtin_msa_sll_w
7838 .{ .tag = @enumFromInt(1334), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7839 // __builtin_msa_slli_b
7840 .{ .tag = @enumFromInt(1335), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7841 // __builtin_msa_slli_d
7842 .{ .tag = @enumFromInt(1336), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7843 // __builtin_msa_slli_h
7844 .{ .tag = @enumFromInt(1337), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7845 // __builtin_msa_slli_w
7846 .{ .tag = @enumFromInt(1338), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7847 // __builtin_msa_splat_b
7848 .{ .tag = @enumFromInt(1339), .properties = .{ .param_str = "V16cV16cUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7849 // __builtin_msa_splat_d
7850 .{ .tag = @enumFromInt(1340), .properties = .{ .param_str = "V2LLiV2LLiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7851 // __builtin_msa_splat_h
7852 .{ .tag = @enumFromInt(1341), .properties = .{ .param_str = "V8sV8sUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7853 // __builtin_msa_splat_w
7854 .{ .tag = @enumFromInt(1342), .properties = .{ .param_str = "V4iV4iUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7855 // __builtin_msa_splati_b
7856 .{ .tag = @enumFromInt(1343), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7857 // __builtin_msa_splati_d
7858 .{ .tag = @enumFromInt(1344), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7859 // __builtin_msa_splati_h
7860 .{ .tag = @enumFromInt(1345), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7861 // __builtin_msa_splati_w
7862 .{ .tag = @enumFromInt(1346), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7863 // __builtin_msa_sra_b
7864 .{ .tag = @enumFromInt(1347), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7865 // __builtin_msa_sra_d
7866 .{ .tag = @enumFromInt(1348), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7867 // __builtin_msa_sra_h
7868 .{ .tag = @enumFromInt(1349), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7869 // __builtin_msa_sra_w
7870 .{ .tag = @enumFromInt(1350), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7871 // __builtin_msa_srai_b
7872 .{ .tag = @enumFromInt(1351), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7873 // __builtin_msa_srai_d
7874 .{ .tag = @enumFromInt(1352), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7875 // __builtin_msa_srai_h
7876 .{ .tag = @enumFromInt(1353), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7877 // __builtin_msa_srai_w
7878 .{ .tag = @enumFromInt(1354), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7879 // __builtin_msa_srar_b
7880 .{ .tag = @enumFromInt(1355), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7881 // __builtin_msa_srar_d
7882 .{ .tag = @enumFromInt(1356), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7883 // __builtin_msa_srar_h
7884 .{ .tag = @enumFromInt(1357), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7885 // __builtin_msa_srar_w
7886 .{ .tag = @enumFromInt(1358), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7887 // __builtin_msa_srari_b
7888 .{ .tag = @enumFromInt(1359), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7889 // __builtin_msa_srari_d
7890 .{ .tag = @enumFromInt(1360), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7891 // __builtin_msa_srari_h
7892 .{ .tag = @enumFromInt(1361), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7893 // __builtin_msa_srari_w
7894 .{ .tag = @enumFromInt(1362), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7895 // __builtin_msa_srl_b
7896 .{ .tag = @enumFromInt(1363), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7897 // __builtin_msa_srl_d
7898 .{ .tag = @enumFromInt(1364), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7899 // __builtin_msa_srl_h
7900 .{ .tag = @enumFromInt(1365), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7901 // __builtin_msa_srl_w
7902 .{ .tag = @enumFromInt(1366), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7903 // __builtin_msa_srli_b
7904 .{ .tag = @enumFromInt(1367), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7905 // __builtin_msa_srli_d
7906 .{ .tag = @enumFromInt(1368), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7907 // __builtin_msa_srli_h
7908 .{ .tag = @enumFromInt(1369), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7909 // __builtin_msa_srli_w
7910 .{ .tag = @enumFromInt(1370), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7911 // __builtin_msa_srlr_b
7912 .{ .tag = @enumFromInt(1371), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7913 // __builtin_msa_srlr_d
7914 .{ .tag = @enumFromInt(1372), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7915 // __builtin_msa_srlr_h
7916 .{ .tag = @enumFromInt(1373), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7917 // __builtin_msa_srlr_w
7918 .{ .tag = @enumFromInt(1374), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7919 // __builtin_msa_srlri_b
7920 .{ .tag = @enumFromInt(1375), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7921 // __builtin_msa_srlri_d
7922 .{ .tag = @enumFromInt(1376), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7923 // __builtin_msa_srlri_h
7924 .{ .tag = @enumFromInt(1377), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7925 // __builtin_msa_srlri_w
7926 .{ .tag = @enumFromInt(1378), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7927 // __builtin_msa_st_b
7928 .{ .tag = @enumFromInt(1379), .properties = .{ .param_str = "vV16Scv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7929 // __builtin_msa_st_d
7930 .{ .tag = @enumFromInt(1380), .properties = .{ .param_str = "vV2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7931 // __builtin_msa_st_h
7932 .{ .tag = @enumFromInt(1381), .properties = .{ .param_str = "vV8Ssv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7933 // __builtin_msa_st_w
7934 .{ .tag = @enumFromInt(1382), .properties = .{ .param_str = "vV4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7935 // __builtin_msa_str_d
7936 .{ .tag = @enumFromInt(1383), .properties = .{ .param_str = "vV2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7937 // __builtin_msa_str_w
7938 .{ .tag = @enumFromInt(1384), .properties = .{ .param_str = "vV4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7939 // __builtin_msa_subs_s_b
7940 .{ .tag = @enumFromInt(1385), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7941 // __builtin_msa_subs_s_d
7942 .{ .tag = @enumFromInt(1386), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7943 // __builtin_msa_subs_s_h
7944 .{ .tag = @enumFromInt(1387), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7945 // __builtin_msa_subs_s_w
7946 .{ .tag = @enumFromInt(1388), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7947 // __builtin_msa_subs_u_b
7948 .{ .tag = @enumFromInt(1389), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7949 // __builtin_msa_subs_u_d
7950 .{ .tag = @enumFromInt(1390), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7951 // __builtin_msa_subs_u_h
7952 .{ .tag = @enumFromInt(1391), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7953 // __builtin_msa_subs_u_w
7954 .{ .tag = @enumFromInt(1392), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7955 // __builtin_msa_subsus_u_b
7956 .{ .tag = @enumFromInt(1393), .properties = .{ .param_str = "V16UcV16UcV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7957 // __builtin_msa_subsus_u_d
7958 .{ .tag = @enumFromInt(1394), .properties = .{ .param_str = "V2ULLiV2ULLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7959 // __builtin_msa_subsus_u_h
7960 .{ .tag = @enumFromInt(1395), .properties = .{ .param_str = "V8UsV8UsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7961 // __builtin_msa_subsus_u_w
7962 .{ .tag = @enumFromInt(1396), .properties = .{ .param_str = "V4UiV4UiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7963 // __builtin_msa_subsuu_s_b
7964 .{ .tag = @enumFromInt(1397), .properties = .{ .param_str = "V16ScV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7965 // __builtin_msa_subsuu_s_d
7966 .{ .tag = @enumFromInt(1398), .properties = .{ .param_str = "V2SLLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7967 // __builtin_msa_subsuu_s_h
7968 .{ .tag = @enumFromInt(1399), .properties = .{ .param_str = "V8SsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7969 // __builtin_msa_subsuu_s_w
7970 .{ .tag = @enumFromInt(1400), .properties = .{ .param_str = "V4SiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7971 // __builtin_msa_subv_b
7972 .{ .tag = @enumFromInt(1401), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7973 // __builtin_msa_subv_d
7974 .{ .tag = @enumFromInt(1402), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7975 // __builtin_msa_subv_h
7976 .{ .tag = @enumFromInt(1403), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7977 // __builtin_msa_subv_w
7978 .{ .tag = @enumFromInt(1404), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7979 // __builtin_msa_subvi_b
7980 .{ .tag = @enumFromInt(1405), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7981 // __builtin_msa_subvi_d
7982 .{ .tag = @enumFromInt(1406), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7983 // __builtin_msa_subvi_h
7984 .{ .tag = @enumFromInt(1407), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7985 // __builtin_msa_subvi_w
7986 .{ .tag = @enumFromInt(1408), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7987 // __builtin_msa_vshf_b
7988 .{ .tag = @enumFromInt(1409), .properties = .{ .param_str = "V16cV16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7989 // __builtin_msa_vshf_d
7990 .{ .tag = @enumFromInt(1410), .properties = .{ .param_str = "V2LLiV2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7991 // __builtin_msa_vshf_h
7992 .{ .tag = @enumFromInt(1411), .properties = .{ .param_str = "V8sV8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7993 // __builtin_msa_vshf_w
7994 .{ .tag = @enumFromInt(1412), .properties = .{ .param_str = "V4iV4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7995 // __builtin_msa_xor_v
7996 .{ .tag = @enumFromInt(1413), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7997 // __builtin_msa_xori_b
7998 .{ .tag = @enumFromInt(1414), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } },
7999 // __builtin_mul_overflow
8000 .{ .tag = @enumFromInt(1415), .properties = .{ .param_str = "b.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } },
8001 // __builtin_nan
8002 .{ .tag = @enumFromInt(1416), .properties = .{ .param_str = "dcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8003 // __builtin_nanf
8004 .{ .tag = @enumFromInt(1417), .properties = .{ .param_str = "fcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8005 // __builtin_nanf128
8006 .{ .tag = @enumFromInt(1418), .properties = .{ .param_str = "LLdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8007 // __builtin_nanf16
8008 .{ .tag = @enumFromInt(1419), .properties = .{ .param_str = "xcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8009 // __builtin_nanl
8010 .{ .tag = @enumFromInt(1420), .properties = .{ .param_str = "LdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8011 // __builtin_nans
8012 .{ .tag = @enumFromInt(1421), .properties = .{ .param_str = "dcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8013 // __builtin_nansf
8014 .{ .tag = @enumFromInt(1422), .properties = .{ .param_str = "fcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8015 // __builtin_nansf128
8016 .{ .tag = @enumFromInt(1423), .properties = .{ .param_str = "LLdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8017 // __builtin_nansf16
8018 .{ .tag = @enumFromInt(1424), .properties = .{ .param_str = "xcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8019 // __builtin_nansl
8020 .{ .tag = @enumFromInt(1425), .properties = .{ .param_str = "LdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8021 // __builtin_nearbyint
8022 .{ .tag = @enumFromInt(1426), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8023 // __builtin_nearbyintf
8024 .{ .tag = @enumFromInt(1427), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8025 // __builtin_nearbyintf128
8026 .{ .tag = @enumFromInt(1428), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8027 // __builtin_nearbyintl
8028 .{ .tag = @enumFromInt(1429), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8029 // __builtin_nextafter
8030 .{ .tag = @enumFromInt(1430), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8031 // __builtin_nextafterf
8032 .{ .tag = @enumFromInt(1431), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8033 // __builtin_nextafterf128
8034 .{ .tag = @enumFromInt(1432), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8035 // __builtin_nextafterl
8036 .{ .tag = @enumFromInt(1433), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8037 // __builtin_nexttoward
8038 .{ .tag = @enumFromInt(1434), .properties = .{ .param_str = "ddLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8039 // __builtin_nexttowardf
8040 .{ .tag = @enumFromInt(1435), .properties = .{ .param_str = "ffLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8041 // __builtin_nexttowardf128
8042 .{ .tag = @enumFromInt(1436), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8043 // __builtin_nexttowardl
8044 .{ .tag = @enumFromInt(1437), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8045 // __builtin_nondeterministic_value
8046 .{ .tag = @enumFromInt(1438), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
8047 // __builtin_nontemporal_load
8048 .{ .tag = @enumFromInt(1439), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
8049 // __builtin_nontemporal_store
8050 .{ .tag = @enumFromInt(1440), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
8051 // __builtin_objc_memmove_collectable
8052 .{ .tag = @enumFromInt(1441), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8053 // __builtin_object_size
8054 .{ .tag = @enumFromInt(1442), .properties = .{ .param_str = "zvC*i", .attributes = .{ .eval_args = false, .const_evaluable = true } } },
8055 // __builtin_operator_delete
8056 .{ .tag = @enumFromInt(1443), .properties = .{ .param_str = "vv*", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } },
8057 // __builtin_operator_new
8058 .{ .tag = @enumFromInt(1444), .properties = .{ .param_str = "v*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } },
8059 // __builtin_os_log_format
8060 .{ .tag = @enumFromInt(1445), .properties = .{ .param_str = "v*v*cC*.", .attributes = .{ .custom_typecheck = true, .format_kind = .printf } } },
8061 // __builtin_os_log_format_buffer_size
8062 .{ .tag = @enumFromInt(1446), .properties = .{ .param_str = "zcC*.", .attributes = .{ .custom_typecheck = true, .format_kind = .printf, .eval_args = false, .const_evaluable = true } } },
8063 // __builtin_pack_longdouble
8064 .{ .tag = @enumFromInt(1447), .properties = .{ .param_str = "Lddd", .target_set = TargetSet.initOne(.ppc) } },
8065 // __builtin_parity
8066 .{ .tag = @enumFromInt(1448), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8067 // __builtin_parityl
8068 .{ .tag = @enumFromInt(1449), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8069 // __builtin_parityll
8070 .{ .tag = @enumFromInt(1450), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8071 // __builtin_popcount
8072 .{ .tag = @enumFromInt(1451), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8073 // __builtin_popcountl
8074 .{ .tag = @enumFromInt(1452), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8075 // __builtin_popcountll
8076 .{ .tag = @enumFromInt(1453), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8077 // __builtin_pow
8078 .{ .tag = @enumFromInt(1454), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8079 // __builtin_powf
8080 .{ .tag = @enumFromInt(1455), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8081 // __builtin_powf128
8082 .{ .tag = @enumFromInt(1456), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8083 // __builtin_powf16
8084 .{ .tag = @enumFromInt(1457), .properties = .{ .param_str = "hhh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8085 // __builtin_powi
8086 .{ .tag = @enumFromInt(1458), .properties = .{ .param_str = "ddi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8087 // __builtin_powif
8088 .{ .tag = @enumFromInt(1459), .properties = .{ .param_str = "ffi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8089 // __builtin_powil
8090 .{ .tag = @enumFromInt(1460), .properties = .{ .param_str = "LdLdi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8091 // __builtin_powl
8092 .{ .tag = @enumFromInt(1461), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8093 // __builtin_ppc_alignx
8094 .{ .tag = @enumFromInt(1462), .properties = .{ .param_str = "vIivC*", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .@"const" = true } } },
8095 // __builtin_ppc_cmpb
8096 .{ .tag = @enumFromInt(1463), .properties = .{ .param_str = "LLiLLiLLi", .target_set = TargetSet.initOne(.ppc) } },
8097 // __builtin_ppc_compare_and_swap
8098 .{ .tag = @enumFromInt(1464), .properties = .{ .param_str = "iiD*i*i", .target_set = TargetSet.initOne(.ppc) } },
8099 // __builtin_ppc_compare_and_swaplp
8100 .{ .tag = @enumFromInt(1465), .properties = .{ .param_str = "iLiD*Li*Li", .target_set = TargetSet.initOne(.ppc) } },
8101 // __builtin_ppc_dcbfl
8102 .{ .tag = @enumFromInt(1466), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } },
8103 // __builtin_ppc_dcbflp
8104 .{ .tag = @enumFromInt(1467), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } },
8105 // __builtin_ppc_dcbst
8106 .{ .tag = @enumFromInt(1468), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } },
8107 // __builtin_ppc_dcbt
8108 .{ .tag = @enumFromInt(1469), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } },
8109 // __builtin_ppc_dcbtst
8110 .{ .tag = @enumFromInt(1470), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } },
8111 // __builtin_ppc_dcbtstt
8112 .{ .tag = @enumFromInt(1471), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } },
8113 // __builtin_ppc_dcbtt
8114 .{ .tag = @enumFromInt(1472), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } },
8115 // __builtin_ppc_dcbz
8116 .{ .tag = @enumFromInt(1473), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } },
8117 // __builtin_ppc_eieio
8118 .{ .tag = @enumFromInt(1474), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } },
8119 // __builtin_ppc_fcfid
8120 .{ .tag = @enumFromInt(1475), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8121 // __builtin_ppc_fcfud
8122 .{ .tag = @enumFromInt(1476), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8123 // __builtin_ppc_fctid
8124 .{ .tag = @enumFromInt(1477), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8125 // __builtin_ppc_fctidz
8126 .{ .tag = @enumFromInt(1478), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8127 // __builtin_ppc_fctiw
8128 .{ .tag = @enumFromInt(1479), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8129 // __builtin_ppc_fctiwz
8130 .{ .tag = @enumFromInt(1480), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8131 // __builtin_ppc_fctudz
8132 .{ .tag = @enumFromInt(1481), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8133 // __builtin_ppc_fctuwz
8134 .{ .tag = @enumFromInt(1482), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8135 // __builtin_ppc_fetch_and_add
8136 .{ .tag = @enumFromInt(1483), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.ppc) } },
8137 // __builtin_ppc_fetch_and_addlp
8138 .{ .tag = @enumFromInt(1484), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.ppc) } },
8139 // __builtin_ppc_fetch_and_and
8140 .{ .tag = @enumFromInt(1485), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.ppc) } },
8141 // __builtin_ppc_fetch_and_andlp
8142 .{ .tag = @enumFromInt(1486), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.ppc) } },
8143 // __builtin_ppc_fetch_and_or
8144 .{ .tag = @enumFromInt(1487), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.ppc) } },
8145 // __builtin_ppc_fetch_and_orlp
8146 .{ .tag = @enumFromInt(1488), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.ppc) } },
8147 // __builtin_ppc_fetch_and_swap
8148 .{ .tag = @enumFromInt(1489), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.ppc) } },
8149 // __builtin_ppc_fetch_and_swaplp
8150 .{ .tag = @enumFromInt(1490), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.ppc) } },
8151 // __builtin_ppc_fmsub
8152 .{ .tag = @enumFromInt(1491), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } },
8153 // __builtin_ppc_fmsubs
8154 .{ .tag = @enumFromInt(1492), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } },
8155 // __builtin_ppc_fnabs
8156 .{ .tag = @enumFromInt(1493), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8157 // __builtin_ppc_fnabss
8158 .{ .tag = @enumFromInt(1494), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8159 // __builtin_ppc_fnmadd
8160 .{ .tag = @enumFromInt(1495), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } },
8161 // __builtin_ppc_fnmadds
8162 .{ .tag = @enumFromInt(1496), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } },
8163 // __builtin_ppc_fnmsub
8164 .{ .tag = @enumFromInt(1497), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } },
8165 // __builtin_ppc_fnmsubs
8166 .{ .tag = @enumFromInt(1498), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } },
8167 // __builtin_ppc_fre
8168 .{ .tag = @enumFromInt(1499), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8169 // __builtin_ppc_fres
8170 .{ .tag = @enumFromInt(1500), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8171 // __builtin_ppc_fric
8172 .{ .tag = @enumFromInt(1501), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8173 // __builtin_ppc_frim
8174 .{ .tag = @enumFromInt(1502), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8175 // __builtin_ppc_frims
8176 .{ .tag = @enumFromInt(1503), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8177 // __builtin_ppc_frin
8178 .{ .tag = @enumFromInt(1504), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8179 // __builtin_ppc_frins
8180 .{ .tag = @enumFromInt(1505), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8181 // __builtin_ppc_frip
8182 .{ .tag = @enumFromInt(1506), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8183 // __builtin_ppc_frips
8184 .{ .tag = @enumFromInt(1507), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8185 // __builtin_ppc_friz
8186 .{ .tag = @enumFromInt(1508), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8187 // __builtin_ppc_frizs
8188 .{ .tag = @enumFromInt(1509), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8189 // __builtin_ppc_frsqrte
8190 .{ .tag = @enumFromInt(1510), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8191 // __builtin_ppc_frsqrtes
8192 .{ .tag = @enumFromInt(1511), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8193 // __builtin_ppc_fsel
8194 .{ .tag = @enumFromInt(1512), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } },
8195 // __builtin_ppc_fsels
8196 .{ .tag = @enumFromInt(1513), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } },
8197 // __builtin_ppc_fsqrt
8198 .{ .tag = @enumFromInt(1514), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8199 // __builtin_ppc_fsqrts
8200 .{ .tag = @enumFromInt(1515), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } },
8201 // __builtin_ppc_get_timebase
8202 .{ .tag = @enumFromInt(1516), .properties = .{ .param_str = "ULLi", .target_set = TargetSet.initOne(.ppc) } },
8203 // __builtin_ppc_iospace_eieio
8204 .{ .tag = @enumFromInt(1517), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } },
8205 // __builtin_ppc_iospace_lwsync
8206 .{ .tag = @enumFromInt(1518), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } },
8207 // __builtin_ppc_iospace_sync
8208 .{ .tag = @enumFromInt(1519), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } },
8209 // __builtin_ppc_isync
8210 .{ .tag = @enumFromInt(1520), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } },
8211 // __builtin_ppc_ldarx
8212 .{ .tag = @enumFromInt(1521), .properties = .{ .param_str = "LiLiD*", .target_set = TargetSet.initOne(.ppc) } },
8213 // __builtin_ppc_load2r
8214 .{ .tag = @enumFromInt(1522), .properties = .{ .param_str = "UsUs*", .target_set = TargetSet.initOne(.ppc) } },
8215 // __builtin_ppc_load4r
8216 .{ .tag = @enumFromInt(1523), .properties = .{ .param_str = "UiUi*", .target_set = TargetSet.initOne(.ppc) } },
8217 // __builtin_ppc_lwarx
8218 .{ .tag = @enumFromInt(1524), .properties = .{ .param_str = "iiD*", .target_set = TargetSet.initOne(.ppc) } },
8219 // __builtin_ppc_lwsync
8220 .{ .tag = @enumFromInt(1525), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } },
8221 // __builtin_ppc_maxfe
8222 .{ .tag = @enumFromInt(1526), .properties = .{ .param_str = "LdLdLdLd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } },
8223 // __builtin_ppc_maxfl
8224 .{ .tag = @enumFromInt(1527), .properties = .{ .param_str = "dddd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } },
8225 // __builtin_ppc_maxfs
8226 .{ .tag = @enumFromInt(1528), .properties = .{ .param_str = "ffff.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } },
8227 // __builtin_ppc_mfmsr
8228 .{ .tag = @enumFromInt(1529), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.ppc) } },
8229 // __builtin_ppc_mfspr
8230 .{ .tag = @enumFromInt(1530), .properties = .{ .param_str = "ULiIi", .target_set = TargetSet.initOne(.ppc) } },
8231 // __builtin_ppc_mftbu
8232 .{ .tag = @enumFromInt(1531), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.ppc) } },
8233 // __builtin_ppc_minfe
8234 .{ .tag = @enumFromInt(1532), .properties = .{ .param_str = "LdLdLdLd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } },
8235 // __builtin_ppc_minfl
8236 .{ .tag = @enumFromInt(1533), .properties = .{ .param_str = "dddd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } },
8237 // __builtin_ppc_minfs
8238 .{ .tag = @enumFromInt(1534), .properties = .{ .param_str = "ffff.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } },
8239 // __builtin_ppc_mtfsb0
8240 .{ .tag = @enumFromInt(1535), .properties = .{ .param_str = "vUIi", .target_set = TargetSet.initOne(.ppc) } },
8241 // __builtin_ppc_mtfsb1
8242 .{ .tag = @enumFromInt(1536), .properties = .{ .param_str = "vUIi", .target_set = TargetSet.initOne(.ppc) } },
8243 // __builtin_ppc_mtfsf
8244 .{ .tag = @enumFromInt(1537), .properties = .{ .param_str = "vUIiUi", .target_set = TargetSet.initOne(.ppc) } },
8245 // __builtin_ppc_mtfsfi
8246 .{ .tag = @enumFromInt(1538), .properties = .{ .param_str = "vUIiUIi", .target_set = TargetSet.initOne(.ppc) } },
8247 // __builtin_ppc_mtmsr
8248 .{ .tag = @enumFromInt(1539), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.ppc) } },
8249 // __builtin_ppc_mtspr
8250 .{ .tag = @enumFromInt(1540), .properties = .{ .param_str = "vIiULi", .target_set = TargetSet.initOne(.ppc) } },
8251 // __builtin_ppc_mulhd
8252 .{ .tag = @enumFromInt(1541), .properties = .{ .param_str = "LLiLiLi", .target_set = TargetSet.initOne(.ppc) } },
8253 // __builtin_ppc_mulhdu
8254 .{ .tag = @enumFromInt(1542), .properties = .{ .param_str = "ULLiULiULi", .target_set = TargetSet.initOne(.ppc) } },
8255 // __builtin_ppc_mulhw
8256 .{ .tag = @enumFromInt(1543), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.ppc) } },
8257 // __builtin_ppc_mulhwu
8258 .{ .tag = @enumFromInt(1544), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.ppc) } },
8259 // __builtin_ppc_popcntb
8260 .{ .tag = @enumFromInt(1545), .properties = .{ .param_str = "ULiULi", .target_set = TargetSet.initOne(.ppc) } },
8261 // __builtin_ppc_poppar4
8262 .{ .tag = @enumFromInt(1546), .properties = .{ .param_str = "iUi", .target_set = TargetSet.initOne(.ppc) } },
8263 // __builtin_ppc_poppar8
8264 .{ .tag = @enumFromInt(1547), .properties = .{ .param_str = "iULLi", .target_set = TargetSet.initOne(.ppc) } },
8265 // __builtin_ppc_rdlam
8266 .{ .tag = @enumFromInt(1548), .properties = .{ .param_str = "UWiUWiUWiUWIi", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .@"const" = true } } },
8267 // __builtin_ppc_recipdivd
8268 .{ .tag = @enumFromInt(1549), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.ppc) } },
8269 // __builtin_ppc_recipdivf
8270 .{ .tag = @enumFromInt(1550), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.ppc) } },
8271 // __builtin_ppc_rldimi
8272 .{ .tag = @enumFromInt(1551), .properties = .{ .param_str = "ULLiULLiULLiIUiIULLi", .target_set = TargetSet.initOne(.ppc) } },
8273 // __builtin_ppc_rlwimi
8274 .{ .tag = @enumFromInt(1552), .properties = .{ .param_str = "UiUiUiIUiIUi", .target_set = TargetSet.initOne(.ppc) } },
8275 // __builtin_ppc_rlwnm
8276 .{ .tag = @enumFromInt(1553), .properties = .{ .param_str = "UiUiUiIUi", .target_set = TargetSet.initOne(.ppc) } },
8277 // __builtin_ppc_rsqrtd
8278 .{ .tag = @enumFromInt(1554), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.ppc) } },
8279 // __builtin_ppc_rsqrtf
8280 .{ .tag = @enumFromInt(1555), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.ppc) } },
8281 // __builtin_ppc_stdcx
8282 .{ .tag = @enumFromInt(1556), .properties = .{ .param_str = "iLiD*Li", .target_set = TargetSet.initOne(.ppc) } },
8283 // __builtin_ppc_stfiw
8284 .{ .tag = @enumFromInt(1557), .properties = .{ .param_str = "viC*d", .target_set = TargetSet.initOne(.ppc) } },
8285 // __builtin_ppc_store2r
8286 .{ .tag = @enumFromInt(1558), .properties = .{ .param_str = "vUiUs*", .target_set = TargetSet.initOne(.ppc) } },
8287 // __builtin_ppc_store4r
8288 .{ .tag = @enumFromInt(1559), .properties = .{ .param_str = "vUiUi*", .target_set = TargetSet.initOne(.ppc) } },
8289 // __builtin_ppc_stwcx
8290 .{ .tag = @enumFromInt(1560), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.ppc) } },
8291 // __builtin_ppc_swdiv
8292 .{ .tag = @enumFromInt(1561), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.ppc) } },
8293 // __builtin_ppc_swdiv_nochk
8294 .{ .tag = @enumFromInt(1562), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.ppc) } },
8295 // __builtin_ppc_swdivs
8296 .{ .tag = @enumFromInt(1563), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.ppc) } },
8297 // __builtin_ppc_swdivs_nochk
8298 .{ .tag = @enumFromInt(1564), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.ppc) } },
8299 // __builtin_ppc_sync
8300 .{ .tag = @enumFromInt(1565), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } },
8301 // __builtin_ppc_tdw
8302 .{ .tag = @enumFromInt(1566), .properties = .{ .param_str = "vLLiLLiIUi", .target_set = TargetSet.initOne(.ppc) } },
8303 // __builtin_ppc_trap
8304 .{ .tag = @enumFromInt(1567), .properties = .{ .param_str = "vi", .target_set = TargetSet.initOne(.ppc) } },
8305 // __builtin_ppc_trapd
8306 .{ .tag = @enumFromInt(1568), .properties = .{ .param_str = "vLi", .target_set = TargetSet.initOne(.ppc) } },
8307 // __builtin_ppc_tw
8308 .{ .tag = @enumFromInt(1569), .properties = .{ .param_str = "viiIUi", .target_set = TargetSet.initOne(.ppc) } },
8309 // __builtin_prefetch
8310 .{ .tag = @enumFromInt(1570), .properties = .{ .param_str = "vvC*.", .attributes = .{ .@"const" = true } } },
8311 // __builtin_preserve_access_index
8312 .{ .tag = @enumFromInt(1571), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
8313 // __builtin_printf
8314 .{ .tag = @enumFromInt(1572), .properties = .{ .param_str = "icC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf } } },
8315 // __builtin_ptx_get_image_channel_data_typei_
8316 .{ .tag = @enumFromInt(1573), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
8317 // __builtin_ptx_get_image_channel_orderi_
8318 .{ .tag = @enumFromInt(1574), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
8319 // __builtin_ptx_get_image_depthi_
8320 .{ .tag = @enumFromInt(1575), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
8321 // __builtin_ptx_get_image_heighti_
8322 .{ .tag = @enumFromInt(1576), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
8323 // __builtin_ptx_get_image_widthi_
8324 .{ .tag = @enumFromInt(1577), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
8325 // __builtin_ptx_read_image2Dff_
8326 .{ .tag = @enumFromInt(1578), .properties = .{ .param_str = "V4fiiff", .target_set = TargetSet.initOne(.nvptx) } },
8327 // __builtin_ptx_read_image2Dfi_
8328 .{ .tag = @enumFromInt(1579), .properties = .{ .param_str = "V4fiiii", .target_set = TargetSet.initOne(.nvptx) } },
8329 // __builtin_ptx_read_image2Dif_
8330 .{ .tag = @enumFromInt(1580), .properties = .{ .param_str = "V4iiiff", .target_set = TargetSet.initOne(.nvptx) } },
8331 // __builtin_ptx_read_image2Dii_
8332 .{ .tag = @enumFromInt(1581), .properties = .{ .param_str = "V4iiiii", .target_set = TargetSet.initOne(.nvptx) } },
8333 // __builtin_ptx_read_image3Dff_
8334 .{ .tag = @enumFromInt(1582), .properties = .{ .param_str = "V4fiiffff", .target_set = TargetSet.initOne(.nvptx) } },
8335 // __builtin_ptx_read_image3Dfi_
8336 .{ .tag = @enumFromInt(1583), .properties = .{ .param_str = "V4fiiiiii", .target_set = TargetSet.initOne(.nvptx) } },
8337 // __builtin_ptx_read_image3Dif_
8338 .{ .tag = @enumFromInt(1584), .properties = .{ .param_str = "V4iiiffff", .target_set = TargetSet.initOne(.nvptx) } },
8339 // __builtin_ptx_read_image3Dii_
8340 .{ .tag = @enumFromInt(1585), .properties = .{ .param_str = "V4iiiiiii", .target_set = TargetSet.initOne(.nvptx) } },
8341 // __builtin_ptx_write_image2Df_
8342 .{ .tag = @enumFromInt(1586), .properties = .{ .param_str = "viiiffff", .target_set = TargetSet.initOne(.nvptx) } },
8343 // __builtin_ptx_write_image2Di_
8344 .{ .tag = @enumFromInt(1587), .properties = .{ .param_str = "viiiiiii", .target_set = TargetSet.initOne(.nvptx) } },
8345 // __builtin_ptx_write_image2Dui_
8346 .{ .tag = @enumFromInt(1588), .properties = .{ .param_str = "viiiUiUiUiUi", .target_set = TargetSet.initOne(.nvptx) } },
8347 // __builtin_r600_implicitarg_ptr
8348 .{ .tag = @enumFromInt(1589), .properties = .{ .param_str = "Uc*7", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8349 // __builtin_r600_read_tgid_x
8350 .{ .tag = @enumFromInt(1590), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8351 // __builtin_r600_read_tgid_y
8352 .{ .tag = @enumFromInt(1591), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8353 // __builtin_r600_read_tgid_z
8354 .{ .tag = @enumFromInt(1592), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8355 // __builtin_r600_read_tidig_x
8356 .{ .tag = @enumFromInt(1593), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8357 // __builtin_r600_read_tidig_y
8358 .{ .tag = @enumFromInt(1594), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8359 // __builtin_r600_read_tidig_z
8360 .{ .tag = @enumFromInt(1595), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8361 // __builtin_r600_recipsqrt_ieee
8362 .{ .tag = @enumFromInt(1596), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8363 // __builtin_r600_recipsqrt_ieeef
8364 .{ .tag = @enumFromInt(1597), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } },
8365 // __builtin_readcyclecounter
8366 .{ .tag = @enumFromInt(1598), .properties = .{ .param_str = "ULLi" } },
8367 // __builtin_readflm
8368 .{ .tag = @enumFromInt(1599), .properties = .{ .param_str = "d", .target_set = TargetSet.initOne(.ppc) } },
8369 // __builtin_realloc
8370 .{ .tag = @enumFromInt(1600), .properties = .{ .param_str = "v*v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8371 // __builtin_reduce_add
8372 .{ .tag = @enumFromInt(1601), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8373 // __builtin_reduce_and
8374 .{ .tag = @enumFromInt(1602), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8375 // __builtin_reduce_max
8376 .{ .tag = @enumFromInt(1603), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8377 // __builtin_reduce_min
8378 .{ .tag = @enumFromInt(1604), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8379 // __builtin_reduce_mul
8380 .{ .tag = @enumFromInt(1605), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8381 // __builtin_reduce_or
8382 .{ .tag = @enumFromInt(1606), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8383 // __builtin_reduce_xor
8384 .{ .tag = @enumFromInt(1607), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8385 // __builtin_remainder
8386 .{ .tag = @enumFromInt(1608), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8387 // __builtin_remainderf
8388 .{ .tag = @enumFromInt(1609), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8389 // __builtin_remainderf128
8390 .{ .tag = @enumFromInt(1610), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8391 // __builtin_remainderl
8392 .{ .tag = @enumFromInt(1611), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8393 // __builtin_remquo
8394 .{ .tag = @enumFromInt(1612), .properties = .{ .param_str = "dddi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8395 // __builtin_remquof
8396 .{ .tag = @enumFromInt(1613), .properties = .{ .param_str = "fffi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8397 // __builtin_remquof128
8398 .{ .tag = @enumFromInt(1614), .properties = .{ .param_str = "LLdLLdLLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8399 // __builtin_remquol
8400 .{ .tag = @enumFromInt(1615), .properties = .{ .param_str = "LdLdLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8401 // __builtin_return_address
8402 .{ .tag = @enumFromInt(1616), .properties = .{ .param_str = "v*IUi" } },
8403 // __builtin_rindex
8404 .{ .tag = @enumFromInt(1617), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8405 // __builtin_rint
8406 .{ .tag = @enumFromInt(1618), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8407 // __builtin_rintf
8408 .{ .tag = @enumFromInt(1619), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8409 // __builtin_rintf128
8410 .{ .tag = @enumFromInt(1620), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8411 // __builtin_rintf16
8412 .{ .tag = @enumFromInt(1621), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8413 // __builtin_rintl
8414 .{ .tag = @enumFromInt(1622), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8415 // __builtin_rotateleft16
8416 .{ .tag = @enumFromInt(1623), .properties = .{ .param_str = "UsUsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8417 // __builtin_rotateleft32
8418 .{ .tag = @enumFromInt(1624), .properties = .{ .param_str = "UZiUZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8419 // __builtin_rotateleft64
8420 .{ .tag = @enumFromInt(1625), .properties = .{ .param_str = "UWiUWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8421 // __builtin_rotateleft8
8422 .{ .tag = @enumFromInt(1626), .properties = .{ .param_str = "UcUcUc", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8423 // __builtin_rotateright16
8424 .{ .tag = @enumFromInt(1627), .properties = .{ .param_str = "UsUsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8425 // __builtin_rotateright32
8426 .{ .tag = @enumFromInt(1628), .properties = .{ .param_str = "UZiUZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8427 // __builtin_rotateright64
8428 .{ .tag = @enumFromInt(1629), .properties = .{ .param_str = "UWiUWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8429 // __builtin_rotateright8
8430 .{ .tag = @enumFromInt(1630), .properties = .{ .param_str = "UcUcUc", .attributes = .{ .@"const" = true, .const_evaluable = true } } },
8431 // __builtin_round
8432 .{ .tag = @enumFromInt(1631), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8433 // __builtin_roundeven
8434 .{ .tag = @enumFromInt(1632), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8435 // __builtin_roundevenf
8436 .{ .tag = @enumFromInt(1633), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8437 // __builtin_roundevenf128
8438 .{ .tag = @enumFromInt(1634), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8439 // __builtin_roundevenf16
8440 .{ .tag = @enumFromInt(1635), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8441 // __builtin_roundevenl
8442 .{ .tag = @enumFromInt(1636), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8443 // __builtin_roundf
8444 .{ .tag = @enumFromInt(1637), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8445 // __builtin_roundf128
8446 .{ .tag = @enumFromInt(1638), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8447 // __builtin_roundf16
8448 .{ .tag = @enumFromInt(1639), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8449 // __builtin_roundl
8450 .{ .tag = @enumFromInt(1640), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8451 // __builtin_sadd_overflow
8452 .{ .tag = @enumFromInt(1641), .properties = .{ .param_str = "bSiCSiCSi*", .attributes = .{ .const_evaluable = true } } },
8453 // __builtin_saddl_overflow
8454 .{ .tag = @enumFromInt(1642), .properties = .{ .param_str = "bSLiCSLiCSLi*", .attributes = .{ .const_evaluable = true } } },
8455 // __builtin_saddll_overflow
8456 .{ .tag = @enumFromInt(1643), .properties = .{ .param_str = "bSLLiCSLLiCSLLi*", .attributes = .{ .const_evaluable = true } } },
8457 // __builtin_scalbln
8458 .{ .tag = @enumFromInt(1644), .properties = .{ .param_str = "ddLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8459 // __builtin_scalblnf
8460 .{ .tag = @enumFromInt(1645), .properties = .{ .param_str = "ffLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8461 // __builtin_scalblnf128
8462 .{ .tag = @enumFromInt(1646), .properties = .{ .param_str = "LLdLLdLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8463 // __builtin_scalblnl
8464 .{ .tag = @enumFromInt(1647), .properties = .{ .param_str = "LdLdLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8465 // __builtin_scalbn
8466 .{ .tag = @enumFromInt(1648), .properties = .{ .param_str = "ddi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8467 // __builtin_scalbnf
8468 .{ .tag = @enumFromInt(1649), .properties = .{ .param_str = "ffi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8469 // __builtin_scalbnf128
8470 .{ .tag = @enumFromInt(1650), .properties = .{ .param_str = "LLdLLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8471 // __builtin_scalbnl
8472 .{ .tag = @enumFromInt(1651), .properties = .{ .param_str = "LdLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8473 // __builtin_scanf
8474 .{ .tag = @enumFromInt(1652), .properties = .{ .param_str = "icC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf } } },
8475 // __builtin_set_flt_rounds
8476 .{ .tag = @enumFromInt(1653), .properties = .{ .param_str = "vi" } },
8477 // __builtin_setflm
8478 .{ .tag = @enumFromInt(1654), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } },
8479 // __builtin_setjmp
8480 .{ .tag = @enumFromInt(1655), .properties = .{ .param_str = "iv**", .attributes = .{ .returns_twice = true } } },
8481 // __builtin_setps
8482 .{ .tag = @enumFromInt(1656), .properties = .{ .param_str = "vUiUi", .target_set = TargetSet.initOne(.xcore) } },
8483 // __builtin_setrnd
8484 .{ .tag = @enumFromInt(1657), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.ppc) } },
8485 // __builtin_shufflevector
8486 .{ .tag = @enumFromInt(1658), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } },
8487 // __builtin_signbit
8488 .{ .tag = @enumFromInt(1659), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } },
8489 // __builtin_signbitf
8490 .{ .tag = @enumFromInt(1660), .properties = .{ .param_str = "if", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8491 // __builtin_signbitl
8492 .{ .tag = @enumFromInt(1661), .properties = .{ .param_str = "iLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8493 // __builtin_sin
8494 .{ .tag = @enumFromInt(1662), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8495 // __builtin_sinf
8496 .{ .tag = @enumFromInt(1663), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8497 // __builtin_sinf128
8498 .{ .tag = @enumFromInt(1664), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8499 // __builtin_sinf16
8500 .{ .tag = @enumFromInt(1665), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8501 // __builtin_sinh
8502 .{ .tag = @enumFromInt(1666), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8503 // __builtin_sinhf
8504 .{ .tag = @enumFromInt(1667), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8505 // __builtin_sinhf128
8506 .{ .tag = @enumFromInt(1668), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8507 // __builtin_sinhl
8508 .{ .tag = @enumFromInt(1669), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8509 // __builtin_sinl
8510 .{ .tag = @enumFromInt(1670), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8511 // __builtin_smul_overflow
8512 .{ .tag = @enumFromInt(1671), .properties = .{ .param_str = "bSiCSiCSi*", .attributes = .{ .const_evaluable = true } } },
8513 // __builtin_smull_overflow
8514 .{ .tag = @enumFromInt(1672), .properties = .{ .param_str = "bSLiCSLiCSLi*", .attributes = .{ .const_evaluable = true } } },
8515 // __builtin_smulll_overflow
8516 .{ .tag = @enumFromInt(1673), .properties = .{ .param_str = "bSLLiCSLLiCSLLi*", .attributes = .{ .const_evaluable = true } } },
8517 // __builtin_snprintf
8518 .{ .tag = @enumFromInt(1674), .properties = .{ .param_str = "ic*RzcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 2 } } },
8519 // __builtin_sponentry
8520 .{ .tag = @enumFromInt(1675), .properties = .{ .param_str = "v*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
8521 // __builtin_sprintf
8522 .{ .tag = @enumFromInt(1676), .properties = .{ .param_str = "ic*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 } } },
8523 // __builtin_sqrt
8524 .{ .tag = @enumFromInt(1677), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8525 // __builtin_sqrtf
8526 .{ .tag = @enumFromInt(1678), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8527 // __builtin_sqrtf128
8528 .{ .tag = @enumFromInt(1679), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8529 // __builtin_sqrtf16
8530 .{ .tag = @enumFromInt(1680), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8531 // __builtin_sqrtl
8532 .{ .tag = @enumFromInt(1681), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8533 // __builtin_sscanf
8534 .{ .tag = @enumFromInt(1682), .properties = .{ .param_str = "icC*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } },
8535 // __builtin_ssub_overflow
8536 .{ .tag = @enumFromInt(1683), .properties = .{ .param_str = "bSiCSiCSi*", .attributes = .{ .const_evaluable = true } } },
8537 // __builtin_ssubl_overflow
8538 .{ .tag = @enumFromInt(1684), .properties = .{ .param_str = "bSLiCSLiCSLi*", .attributes = .{ .const_evaluable = true } } },
8539 // __builtin_ssubll_overflow
8540 .{ .tag = @enumFromInt(1685), .properties = .{ .param_str = "bSLLiCSLLiCSLLi*", .attributes = .{ .const_evaluable = true } } },
8541 // __builtin_stdarg_start
8542 .{ .tag = @enumFromInt(1686), .properties = .{ .param_str = "vA.", .attributes = .{ .custom_typecheck = true } } },
8543 // __builtin_stpcpy
8544 .{ .tag = @enumFromInt(1687), .properties = .{ .param_str = "c*c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8545 // __builtin_stpncpy
8546 .{ .tag = @enumFromInt(1688), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8547 // __builtin_strcasecmp
8548 .{ .tag = @enumFromInt(1689), .properties = .{ .param_str = "icC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8549 // __builtin_strcat
8550 .{ .tag = @enumFromInt(1690), .properties = .{ .param_str = "c*c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8551 // __builtin_strchr
8552 .{ .tag = @enumFromInt(1691), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8553 // __builtin_strcmp
8554 .{ .tag = @enumFromInt(1692), .properties = .{ .param_str = "icC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8555 // __builtin_strcpy
8556 .{ .tag = @enumFromInt(1693), .properties = .{ .param_str = "c*c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8557 // __builtin_strcspn
8558 .{ .tag = @enumFromInt(1694), .properties = .{ .param_str = "zcC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8559 // __builtin_strdup
8560 .{ .tag = @enumFromInt(1695), .properties = .{ .param_str = "c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8561 // __builtin_strlen
8562 .{ .tag = @enumFromInt(1696), .properties = .{ .param_str = "zcC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8563 // __builtin_strncasecmp
8564 .{ .tag = @enumFromInt(1697), .properties = .{ .param_str = "icC*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8565 // __builtin_strncat
8566 .{ .tag = @enumFromInt(1698), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8567 // __builtin_strncmp
8568 .{ .tag = @enumFromInt(1699), .properties = .{ .param_str = "icC*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
8569 // __builtin_strncpy
8570 .{ .tag = @enumFromInt(1700), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8571 // __builtin_strndup
8572 .{ .tag = @enumFromInt(1701), .properties = .{ .param_str = "c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8573 // __builtin_strpbrk
8574 .{ .tag = @enumFromInt(1702), .properties = .{ .param_str = "c*cC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8575 // __builtin_strrchr
8576 .{ .tag = @enumFromInt(1703), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8577 // __builtin_strspn
8578 .{ .tag = @enumFromInt(1704), .properties = .{ .param_str = "zcC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8579 // __builtin_strstr
8580 .{ .tag = @enumFromInt(1705), .properties = .{ .param_str = "c*cC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } },
8581 // __builtin_sub_overflow
8582 .{ .tag = @enumFromInt(1706), .properties = .{ .param_str = "b.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } },
8583 // __builtin_subc
8584 .{ .tag = @enumFromInt(1707), .properties = .{ .param_str = "UiUiCUiCUiCUi*" } },
8585 // __builtin_subcb
8586 .{ .tag = @enumFromInt(1708), .properties = .{ .param_str = "UcUcCUcCUcCUc*" } },
8587 // __builtin_subcl
8588 .{ .tag = @enumFromInt(1709), .properties = .{ .param_str = "ULiULiCULiCULiCULi*" } },
8589 // __builtin_subcll
8590 .{ .tag = @enumFromInt(1710), .properties = .{ .param_str = "ULLiULLiCULLiCULLiCULLi*" } },
8591 // __builtin_subcs
8592 .{ .tag = @enumFromInt(1711), .properties = .{ .param_str = "UsUsCUsCUsCUs*" } },
8593 // __builtin_tan
8594 .{ .tag = @enumFromInt(1712), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8595 // __builtin_tanf
8596 .{ .tag = @enumFromInt(1713), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8597 // __builtin_tanf128
8598 .{ .tag = @enumFromInt(1714), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8599 // __builtin_tanh
8600 .{ .tag = @enumFromInt(1715), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8601 // __builtin_tanhf
8602 .{ .tag = @enumFromInt(1716), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8603 // __builtin_tanhf128
8604 .{ .tag = @enumFromInt(1717), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8605 // __builtin_tanhl
8606 .{ .tag = @enumFromInt(1718), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8607 // __builtin_tanl
8608 .{ .tag = @enumFromInt(1719), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8609 // __builtin_tgamma
8610 .{ .tag = @enumFromInt(1720), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8611 // __builtin_tgammaf
8612 .{ .tag = @enumFromInt(1721), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8613 // __builtin_tgammaf128
8614 .{ .tag = @enumFromInt(1722), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8615 // __builtin_tgammal
8616 .{ .tag = @enumFromInt(1723), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
8617 // __builtin_thread_pointer
8618 .{ .tag = @enumFromInt(1724), .properties = .{ .param_str = "v*", .attributes = .{ .@"const" = true } } },
8619 // __builtin_trap
8620 .{ .tag = @enumFromInt(1725), .properties = .{ .param_str = "v", .attributes = .{ .noreturn = true } } },
8621 // __builtin_trunc
8622 .{ .tag = @enumFromInt(1726), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8623 // __builtin_truncf
8624 .{ .tag = @enumFromInt(1727), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8625 // __builtin_truncf128
8626 .{ .tag = @enumFromInt(1728), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8627 // __builtin_truncf16
8628 .{ .tag = @enumFromInt(1729), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8629 // __builtin_truncl
8630 .{ .tag = @enumFromInt(1730), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } },
8631 // __builtin_uadd_overflow
8632 .{ .tag = @enumFromInt(1731), .properties = .{ .param_str = "bUiCUiCUi*", .attributes = .{ .const_evaluable = true } } },
8633 // __builtin_uaddl_overflow
8634 .{ .tag = @enumFromInt(1732), .properties = .{ .param_str = "bULiCULiCULi*", .attributes = .{ .const_evaluable = true } } },
8635 // __builtin_uaddll_overflow
8636 .{ .tag = @enumFromInt(1733), .properties = .{ .param_str = "bULLiCULLiCULLi*", .attributes = .{ .const_evaluable = true } } },
8637 // __builtin_umul_overflow
8638 .{ .tag = @enumFromInt(1734), .properties = .{ .param_str = "bUiCUiCUi*", .attributes = .{ .const_evaluable = true } } },
8639 // __builtin_umull_overflow
8640 .{ .tag = @enumFromInt(1735), .properties = .{ .param_str = "bULiCULiCULi*", .attributes = .{ .const_evaluable = true } } },
8641 // __builtin_umulll_overflow
8642 .{ .tag = @enumFromInt(1736), .properties = .{ .param_str = "bULLiCULLiCULLi*", .attributes = .{ .const_evaluable = true } } },
8643 // __builtin_unpack_longdouble
8644 .{ .tag = @enumFromInt(1737), .properties = .{ .param_str = "dLdIi", .target_set = TargetSet.initOne(.ppc) } },
8645 // __builtin_unpredictable
8646 .{ .tag = @enumFromInt(1738), .properties = .{ .param_str = "LiLi", .attributes = .{ .@"const" = true } } },
8647 // __builtin_unreachable
8648 .{ .tag = @enumFromInt(1739), .properties = .{ .param_str = "v", .attributes = .{ .noreturn = true } } },
8649 // __builtin_unwind_init
8650 .{ .tag = @enumFromInt(1740), .properties = .{ .param_str = "v" } },
8651 // __builtin_usub_overflow
8652 .{ .tag = @enumFromInt(1741), .properties = .{ .param_str = "bUiCUiCUi*", .attributes = .{ .const_evaluable = true } } },
8653 // __builtin_usubl_overflow
8654 .{ .tag = @enumFromInt(1742), .properties = .{ .param_str = "bULiCULiCULi*", .attributes = .{ .const_evaluable = true } } },
8655 // __builtin_usubll_overflow
8656 .{ .tag = @enumFromInt(1743), .properties = .{ .param_str = "bULLiCULLiCULLi*", .attributes = .{ .const_evaluable = true } } },
8657 // __builtin_va_copy
8658 .{ .tag = @enumFromInt(1744), .properties = .{ .param_str = "vAA" } },
8659 // __builtin_va_end
8660 .{ .tag = @enumFromInt(1745), .properties = .{ .param_str = "vA" } },
8661 // __builtin_va_start
8662 .{ .tag = @enumFromInt(1746), .properties = .{ .param_str = "vA.", .attributes = .{ .custom_typecheck = true } } },
8663 // __builtin_ve_vl_andm_MMM
8664 .{ .tag = @enumFromInt(1747), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } },
8665 // __builtin_ve_vl_andm_mmm
8666 .{ .tag = @enumFromInt(1748), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } },
8667 // __builtin_ve_vl_eqvm_MMM
8668 .{ .tag = @enumFromInt(1749), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } },
8669 // __builtin_ve_vl_eqvm_mmm
8670 .{ .tag = @enumFromInt(1750), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } },
8671 // __builtin_ve_vl_extract_vm512l
8672 .{ .tag = @enumFromInt(1751), .properties = .{ .param_str = "V256bV512b", .target_set = TargetSet.initOne(.ve) } },
8673 // __builtin_ve_vl_extract_vm512u
8674 .{ .tag = @enumFromInt(1752), .properties = .{ .param_str = "V256bV512b", .target_set = TargetSet.initOne(.ve) } },
8675 // __builtin_ve_vl_fencec_s
8676 .{ .tag = @enumFromInt(1753), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8677 // __builtin_ve_vl_fencei
8678 .{ .tag = @enumFromInt(1754), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.vevl_gen) } },
8679 // __builtin_ve_vl_fencem_s
8680 .{ .tag = @enumFromInt(1755), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8681 // __builtin_ve_vl_fidcr_sss
8682 .{ .tag = @enumFromInt(1756), .properties = .{ .param_str = "LUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8683 // __builtin_ve_vl_insert_vm512l
8684 .{ .tag = @enumFromInt(1757), .properties = .{ .param_str = "V512bV512bV256b", .target_set = TargetSet.initOne(.ve) } },
8685 // __builtin_ve_vl_insert_vm512u
8686 .{ .tag = @enumFromInt(1758), .properties = .{ .param_str = "V512bV512bV256b", .target_set = TargetSet.initOne(.ve) } },
8687 // __builtin_ve_vl_lcr_sss
8688 .{ .tag = @enumFromInt(1759), .properties = .{ .param_str = "LUiLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8689 // __builtin_ve_vl_lsv_vvss
8690 .{ .tag = @enumFromInt(1760), .properties = .{ .param_str = "V256dV256dUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8691 // __builtin_ve_vl_lvm_MMss
8692 .{ .tag = @enumFromInt(1761), .properties = .{ .param_str = "V512bV512bLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8693 // __builtin_ve_vl_lvm_mmss
8694 .{ .tag = @enumFromInt(1762), .properties = .{ .param_str = "V256bV256bLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8695 // __builtin_ve_vl_lvsd_svs
8696 .{ .tag = @enumFromInt(1763), .properties = .{ .param_str = "dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8697 // __builtin_ve_vl_lvsl_svs
8698 .{ .tag = @enumFromInt(1764), .properties = .{ .param_str = "LUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8699 // __builtin_ve_vl_lvss_svs
8700 .{ .tag = @enumFromInt(1765), .properties = .{ .param_str = "fV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8701 // __builtin_ve_vl_lzvm_sml
8702 .{ .tag = @enumFromInt(1766), .properties = .{ .param_str = "LUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8703 // __builtin_ve_vl_negm_MM
8704 .{ .tag = @enumFromInt(1767), .properties = .{ .param_str = "V512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } },
8705 // __builtin_ve_vl_negm_mm
8706 .{ .tag = @enumFromInt(1768), .properties = .{ .param_str = "V256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } },
8707 // __builtin_ve_vl_nndm_MMM
8708 .{ .tag = @enumFromInt(1769), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } },
8709 // __builtin_ve_vl_nndm_mmm
8710 .{ .tag = @enumFromInt(1770), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } },
8711 // __builtin_ve_vl_orm_MMM
8712 .{ .tag = @enumFromInt(1771), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } },
8713 // __builtin_ve_vl_orm_mmm
8714 .{ .tag = @enumFromInt(1772), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } },
8715 // __builtin_ve_vl_pack_f32a
8716 .{ .tag = @enumFromInt(1773), .properties = .{ .param_str = "ULifC*", .target_set = TargetSet.initOne(.ve) } },
8717 // __builtin_ve_vl_pack_f32p
8718 .{ .tag = @enumFromInt(1774), .properties = .{ .param_str = "ULifC*fC*", .target_set = TargetSet.initOne(.ve) } },
8719 // __builtin_ve_vl_pcvm_sml
8720 .{ .tag = @enumFromInt(1775), .properties = .{ .param_str = "LUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8721 // __builtin_ve_vl_pfchv_ssl
8722 .{ .tag = @enumFromInt(1776), .properties = .{ .param_str = "vLivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
8723 // __builtin_ve_vl_pfchvnc_ssl
8724 .{ .tag = @enumFromInt(1777), .properties = .{ .param_str = "vLivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
8725 // __builtin_ve_vl_pvadds_vsvMvl
8726 .{ .tag = @enumFromInt(1778), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8727 // __builtin_ve_vl_pvadds_vsvl
8728 .{ .tag = @enumFromInt(1779), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8729 // __builtin_ve_vl_pvadds_vsvvl
8730 .{ .tag = @enumFromInt(1780), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8731 // __builtin_ve_vl_pvadds_vvvMvl
8732 .{ .tag = @enumFromInt(1781), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8733 // __builtin_ve_vl_pvadds_vvvl
8734 .{ .tag = @enumFromInt(1782), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8735 // __builtin_ve_vl_pvadds_vvvvl
8736 .{ .tag = @enumFromInt(1783), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8737 // __builtin_ve_vl_pvaddu_vsvMvl
8738 .{ .tag = @enumFromInt(1784), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8739 // __builtin_ve_vl_pvaddu_vsvl
8740 .{ .tag = @enumFromInt(1785), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8741 // __builtin_ve_vl_pvaddu_vsvvl
8742 .{ .tag = @enumFromInt(1786), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8743 // __builtin_ve_vl_pvaddu_vvvMvl
8744 .{ .tag = @enumFromInt(1787), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8745 // __builtin_ve_vl_pvaddu_vvvl
8746 .{ .tag = @enumFromInt(1788), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8747 // __builtin_ve_vl_pvaddu_vvvvl
8748 .{ .tag = @enumFromInt(1789), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8749 // __builtin_ve_vl_pvand_vsvMvl
8750 .{ .tag = @enumFromInt(1790), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8751 // __builtin_ve_vl_pvand_vsvl
8752 .{ .tag = @enumFromInt(1791), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8753 // __builtin_ve_vl_pvand_vsvvl
8754 .{ .tag = @enumFromInt(1792), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8755 // __builtin_ve_vl_pvand_vvvMvl
8756 .{ .tag = @enumFromInt(1793), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8757 // __builtin_ve_vl_pvand_vvvl
8758 .{ .tag = @enumFromInt(1794), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8759 // __builtin_ve_vl_pvand_vvvvl
8760 .{ .tag = @enumFromInt(1795), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8761 // __builtin_ve_vl_pvbrd_vsMvl
8762 .{ .tag = @enumFromInt(1796), .properties = .{ .param_str = "V256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8763 // __builtin_ve_vl_pvbrd_vsl
8764 .{ .tag = @enumFromInt(1797), .properties = .{ .param_str = "V256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8765 // __builtin_ve_vl_pvbrd_vsvl
8766 .{ .tag = @enumFromInt(1798), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8767 // __builtin_ve_vl_pvbrv_vvMvl
8768 .{ .tag = @enumFromInt(1799), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8769 // __builtin_ve_vl_pvbrv_vvl
8770 .{ .tag = @enumFromInt(1800), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8771 // __builtin_ve_vl_pvbrv_vvvl
8772 .{ .tag = @enumFromInt(1801), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8773 // __builtin_ve_vl_pvbrvlo_vvl
8774 .{ .tag = @enumFromInt(1802), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8775 // __builtin_ve_vl_pvbrvlo_vvmvl
8776 .{ .tag = @enumFromInt(1803), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8777 // __builtin_ve_vl_pvbrvlo_vvvl
8778 .{ .tag = @enumFromInt(1804), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8779 // __builtin_ve_vl_pvbrvup_vvl
8780 .{ .tag = @enumFromInt(1805), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8781 // __builtin_ve_vl_pvbrvup_vvmvl
8782 .{ .tag = @enumFromInt(1806), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8783 // __builtin_ve_vl_pvbrvup_vvvl
8784 .{ .tag = @enumFromInt(1807), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8785 // __builtin_ve_vl_pvcmps_vsvMvl
8786 .{ .tag = @enumFromInt(1808), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8787 // __builtin_ve_vl_pvcmps_vsvl
8788 .{ .tag = @enumFromInt(1809), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8789 // __builtin_ve_vl_pvcmps_vsvvl
8790 .{ .tag = @enumFromInt(1810), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8791 // __builtin_ve_vl_pvcmps_vvvMvl
8792 .{ .tag = @enumFromInt(1811), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8793 // __builtin_ve_vl_pvcmps_vvvl
8794 .{ .tag = @enumFromInt(1812), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8795 // __builtin_ve_vl_pvcmps_vvvvl
8796 .{ .tag = @enumFromInt(1813), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8797 // __builtin_ve_vl_pvcmpu_vsvMvl
8798 .{ .tag = @enumFromInt(1814), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8799 // __builtin_ve_vl_pvcmpu_vsvl
8800 .{ .tag = @enumFromInt(1815), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8801 // __builtin_ve_vl_pvcmpu_vsvvl
8802 .{ .tag = @enumFromInt(1816), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8803 // __builtin_ve_vl_pvcmpu_vvvMvl
8804 .{ .tag = @enumFromInt(1817), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8805 // __builtin_ve_vl_pvcmpu_vvvl
8806 .{ .tag = @enumFromInt(1818), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8807 // __builtin_ve_vl_pvcmpu_vvvvl
8808 .{ .tag = @enumFromInt(1819), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8809 // __builtin_ve_vl_pvcvtsw_vvl
8810 .{ .tag = @enumFromInt(1820), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8811 // __builtin_ve_vl_pvcvtsw_vvvl
8812 .{ .tag = @enumFromInt(1821), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8813 // __builtin_ve_vl_pvcvtws_vvMvl
8814 .{ .tag = @enumFromInt(1822), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8815 // __builtin_ve_vl_pvcvtws_vvl
8816 .{ .tag = @enumFromInt(1823), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8817 // __builtin_ve_vl_pvcvtws_vvvl
8818 .{ .tag = @enumFromInt(1824), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8819 // __builtin_ve_vl_pvcvtwsrz_vvMvl
8820 .{ .tag = @enumFromInt(1825), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8821 // __builtin_ve_vl_pvcvtwsrz_vvl
8822 .{ .tag = @enumFromInt(1826), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8823 // __builtin_ve_vl_pvcvtwsrz_vvvl
8824 .{ .tag = @enumFromInt(1827), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8825 // __builtin_ve_vl_pveqv_vsvMvl
8826 .{ .tag = @enumFromInt(1828), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8827 // __builtin_ve_vl_pveqv_vsvl
8828 .{ .tag = @enumFromInt(1829), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8829 // __builtin_ve_vl_pveqv_vsvvl
8830 .{ .tag = @enumFromInt(1830), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8831 // __builtin_ve_vl_pveqv_vvvMvl
8832 .{ .tag = @enumFromInt(1831), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8833 // __builtin_ve_vl_pveqv_vvvl
8834 .{ .tag = @enumFromInt(1832), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8835 // __builtin_ve_vl_pveqv_vvvvl
8836 .{ .tag = @enumFromInt(1833), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8837 // __builtin_ve_vl_pvfadd_vsvMvl
8838 .{ .tag = @enumFromInt(1834), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8839 // __builtin_ve_vl_pvfadd_vsvl
8840 .{ .tag = @enumFromInt(1835), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8841 // __builtin_ve_vl_pvfadd_vsvvl
8842 .{ .tag = @enumFromInt(1836), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8843 // __builtin_ve_vl_pvfadd_vvvMvl
8844 .{ .tag = @enumFromInt(1837), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8845 // __builtin_ve_vl_pvfadd_vvvl
8846 .{ .tag = @enumFromInt(1838), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8847 // __builtin_ve_vl_pvfadd_vvvvl
8848 .{ .tag = @enumFromInt(1839), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8849 // __builtin_ve_vl_pvfcmp_vsvMvl
8850 .{ .tag = @enumFromInt(1840), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8851 // __builtin_ve_vl_pvfcmp_vsvl
8852 .{ .tag = @enumFromInt(1841), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8853 // __builtin_ve_vl_pvfcmp_vsvvl
8854 .{ .tag = @enumFromInt(1842), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8855 // __builtin_ve_vl_pvfcmp_vvvMvl
8856 .{ .tag = @enumFromInt(1843), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8857 // __builtin_ve_vl_pvfcmp_vvvl
8858 .{ .tag = @enumFromInt(1844), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8859 // __builtin_ve_vl_pvfcmp_vvvvl
8860 .{ .tag = @enumFromInt(1845), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8861 // __builtin_ve_vl_pvfmad_vsvvMvl
8862 .{ .tag = @enumFromInt(1846), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8863 // __builtin_ve_vl_pvfmad_vsvvl
8864 .{ .tag = @enumFromInt(1847), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8865 // __builtin_ve_vl_pvfmad_vsvvvl
8866 .{ .tag = @enumFromInt(1848), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8867 // __builtin_ve_vl_pvfmad_vvsvMvl
8868 .{ .tag = @enumFromInt(1849), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8869 // __builtin_ve_vl_pvfmad_vvsvl
8870 .{ .tag = @enumFromInt(1850), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8871 // __builtin_ve_vl_pvfmad_vvsvvl
8872 .{ .tag = @enumFromInt(1851), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8873 // __builtin_ve_vl_pvfmad_vvvvMvl
8874 .{ .tag = @enumFromInt(1852), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8875 // __builtin_ve_vl_pvfmad_vvvvl
8876 .{ .tag = @enumFromInt(1853), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8877 // __builtin_ve_vl_pvfmad_vvvvvl
8878 .{ .tag = @enumFromInt(1854), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8879 // __builtin_ve_vl_pvfmax_vsvMvl
8880 .{ .tag = @enumFromInt(1855), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8881 // __builtin_ve_vl_pvfmax_vsvl
8882 .{ .tag = @enumFromInt(1856), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8883 // __builtin_ve_vl_pvfmax_vsvvl
8884 .{ .tag = @enumFromInt(1857), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8885 // __builtin_ve_vl_pvfmax_vvvMvl
8886 .{ .tag = @enumFromInt(1858), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8887 // __builtin_ve_vl_pvfmax_vvvl
8888 .{ .tag = @enumFromInt(1859), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8889 // __builtin_ve_vl_pvfmax_vvvvl
8890 .{ .tag = @enumFromInt(1860), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8891 // __builtin_ve_vl_pvfmin_vsvMvl
8892 .{ .tag = @enumFromInt(1861), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8893 // __builtin_ve_vl_pvfmin_vsvl
8894 .{ .tag = @enumFromInt(1862), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8895 // __builtin_ve_vl_pvfmin_vsvvl
8896 .{ .tag = @enumFromInt(1863), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8897 // __builtin_ve_vl_pvfmin_vvvMvl
8898 .{ .tag = @enumFromInt(1864), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8899 // __builtin_ve_vl_pvfmin_vvvl
8900 .{ .tag = @enumFromInt(1865), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8901 // __builtin_ve_vl_pvfmin_vvvvl
8902 .{ .tag = @enumFromInt(1866), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8903 // __builtin_ve_vl_pvfmkaf_Ml
8904 .{ .tag = @enumFromInt(1867), .properties = .{ .param_str = "V512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8905 // __builtin_ve_vl_pvfmkat_Ml
8906 .{ .tag = @enumFromInt(1868), .properties = .{ .param_str = "V512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8907 // __builtin_ve_vl_pvfmkseq_MvMl
8908 .{ .tag = @enumFromInt(1869), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8909 // __builtin_ve_vl_pvfmkseq_Mvl
8910 .{ .tag = @enumFromInt(1870), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8911 // __builtin_ve_vl_pvfmkseqnan_MvMl
8912 .{ .tag = @enumFromInt(1871), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8913 // __builtin_ve_vl_pvfmkseqnan_Mvl
8914 .{ .tag = @enumFromInt(1872), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8915 // __builtin_ve_vl_pvfmksge_MvMl
8916 .{ .tag = @enumFromInt(1873), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8917 // __builtin_ve_vl_pvfmksge_Mvl
8918 .{ .tag = @enumFromInt(1874), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8919 // __builtin_ve_vl_pvfmksgenan_MvMl
8920 .{ .tag = @enumFromInt(1875), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8921 // __builtin_ve_vl_pvfmksgenan_Mvl
8922 .{ .tag = @enumFromInt(1876), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8923 // __builtin_ve_vl_pvfmksgt_MvMl
8924 .{ .tag = @enumFromInt(1877), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8925 // __builtin_ve_vl_pvfmksgt_Mvl
8926 .{ .tag = @enumFromInt(1878), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8927 // __builtin_ve_vl_pvfmksgtnan_MvMl
8928 .{ .tag = @enumFromInt(1879), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8929 // __builtin_ve_vl_pvfmksgtnan_Mvl
8930 .{ .tag = @enumFromInt(1880), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8931 // __builtin_ve_vl_pvfmksle_MvMl
8932 .{ .tag = @enumFromInt(1881), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8933 // __builtin_ve_vl_pvfmksle_Mvl
8934 .{ .tag = @enumFromInt(1882), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8935 // __builtin_ve_vl_pvfmkslenan_MvMl
8936 .{ .tag = @enumFromInt(1883), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8937 // __builtin_ve_vl_pvfmkslenan_Mvl
8938 .{ .tag = @enumFromInt(1884), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8939 // __builtin_ve_vl_pvfmksloeq_mvl
8940 .{ .tag = @enumFromInt(1885), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8941 // __builtin_ve_vl_pvfmksloeq_mvml
8942 .{ .tag = @enumFromInt(1886), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8943 // __builtin_ve_vl_pvfmksloeqnan_mvl
8944 .{ .tag = @enumFromInt(1887), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8945 // __builtin_ve_vl_pvfmksloeqnan_mvml
8946 .{ .tag = @enumFromInt(1888), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8947 // __builtin_ve_vl_pvfmksloge_mvl
8948 .{ .tag = @enumFromInt(1889), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8949 // __builtin_ve_vl_pvfmksloge_mvml
8950 .{ .tag = @enumFromInt(1890), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8951 // __builtin_ve_vl_pvfmkslogenan_mvl
8952 .{ .tag = @enumFromInt(1891), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8953 // __builtin_ve_vl_pvfmkslogenan_mvml
8954 .{ .tag = @enumFromInt(1892), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8955 // __builtin_ve_vl_pvfmkslogt_mvl
8956 .{ .tag = @enumFromInt(1893), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8957 // __builtin_ve_vl_pvfmkslogt_mvml
8958 .{ .tag = @enumFromInt(1894), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8959 // __builtin_ve_vl_pvfmkslogtnan_mvl
8960 .{ .tag = @enumFromInt(1895), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8961 // __builtin_ve_vl_pvfmkslogtnan_mvml
8962 .{ .tag = @enumFromInt(1896), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8963 // __builtin_ve_vl_pvfmkslole_mvl
8964 .{ .tag = @enumFromInt(1897), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8965 // __builtin_ve_vl_pvfmkslole_mvml
8966 .{ .tag = @enumFromInt(1898), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8967 // __builtin_ve_vl_pvfmkslolenan_mvl
8968 .{ .tag = @enumFromInt(1899), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8969 // __builtin_ve_vl_pvfmkslolenan_mvml
8970 .{ .tag = @enumFromInt(1900), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8971 // __builtin_ve_vl_pvfmkslolt_mvl
8972 .{ .tag = @enumFromInt(1901), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8973 // __builtin_ve_vl_pvfmkslolt_mvml
8974 .{ .tag = @enumFromInt(1902), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8975 // __builtin_ve_vl_pvfmksloltnan_mvl
8976 .{ .tag = @enumFromInt(1903), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8977 // __builtin_ve_vl_pvfmksloltnan_mvml
8978 .{ .tag = @enumFromInt(1904), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8979 // __builtin_ve_vl_pvfmkslonan_mvl
8980 .{ .tag = @enumFromInt(1905), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8981 // __builtin_ve_vl_pvfmkslonan_mvml
8982 .{ .tag = @enumFromInt(1906), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8983 // __builtin_ve_vl_pvfmkslone_mvl
8984 .{ .tag = @enumFromInt(1907), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8985 // __builtin_ve_vl_pvfmkslone_mvml
8986 .{ .tag = @enumFromInt(1908), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8987 // __builtin_ve_vl_pvfmkslonenan_mvl
8988 .{ .tag = @enumFromInt(1909), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8989 // __builtin_ve_vl_pvfmkslonenan_mvml
8990 .{ .tag = @enumFromInt(1910), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8991 // __builtin_ve_vl_pvfmkslonum_mvl
8992 .{ .tag = @enumFromInt(1911), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8993 // __builtin_ve_vl_pvfmkslonum_mvml
8994 .{ .tag = @enumFromInt(1912), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8995 // __builtin_ve_vl_pvfmkslt_MvMl
8996 .{ .tag = @enumFromInt(1913), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8997 // __builtin_ve_vl_pvfmkslt_Mvl
8998 .{ .tag = @enumFromInt(1914), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
8999 // __builtin_ve_vl_pvfmksltnan_MvMl
9000 .{ .tag = @enumFromInt(1915), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9001 // __builtin_ve_vl_pvfmksltnan_Mvl
9002 .{ .tag = @enumFromInt(1916), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9003 // __builtin_ve_vl_pvfmksnan_MvMl
9004 .{ .tag = @enumFromInt(1917), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9005 // __builtin_ve_vl_pvfmksnan_Mvl
9006 .{ .tag = @enumFromInt(1918), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9007 // __builtin_ve_vl_pvfmksne_MvMl
9008 .{ .tag = @enumFromInt(1919), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9009 // __builtin_ve_vl_pvfmksne_Mvl
9010 .{ .tag = @enumFromInt(1920), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9011 // __builtin_ve_vl_pvfmksnenan_MvMl
9012 .{ .tag = @enumFromInt(1921), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9013 // __builtin_ve_vl_pvfmksnenan_Mvl
9014 .{ .tag = @enumFromInt(1922), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9015 // __builtin_ve_vl_pvfmksnum_MvMl
9016 .{ .tag = @enumFromInt(1923), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9017 // __builtin_ve_vl_pvfmksnum_Mvl
9018 .{ .tag = @enumFromInt(1924), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9019 // __builtin_ve_vl_pvfmksupeq_mvl
9020 .{ .tag = @enumFromInt(1925), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9021 // __builtin_ve_vl_pvfmksupeq_mvml
9022 .{ .tag = @enumFromInt(1926), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9023 // __builtin_ve_vl_pvfmksupeqnan_mvl
9024 .{ .tag = @enumFromInt(1927), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9025 // __builtin_ve_vl_pvfmksupeqnan_mvml
9026 .{ .tag = @enumFromInt(1928), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9027 // __builtin_ve_vl_pvfmksupge_mvl
9028 .{ .tag = @enumFromInt(1929), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9029 // __builtin_ve_vl_pvfmksupge_mvml
9030 .{ .tag = @enumFromInt(1930), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9031 // __builtin_ve_vl_pvfmksupgenan_mvl
9032 .{ .tag = @enumFromInt(1931), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9033 // __builtin_ve_vl_pvfmksupgenan_mvml
9034 .{ .tag = @enumFromInt(1932), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9035 // __builtin_ve_vl_pvfmksupgt_mvl
9036 .{ .tag = @enumFromInt(1933), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9037 // __builtin_ve_vl_pvfmksupgt_mvml
9038 .{ .tag = @enumFromInt(1934), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9039 // __builtin_ve_vl_pvfmksupgtnan_mvl
9040 .{ .tag = @enumFromInt(1935), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9041 // __builtin_ve_vl_pvfmksupgtnan_mvml
9042 .{ .tag = @enumFromInt(1936), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9043 // __builtin_ve_vl_pvfmksuple_mvl
9044 .{ .tag = @enumFromInt(1937), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9045 // __builtin_ve_vl_pvfmksuple_mvml
9046 .{ .tag = @enumFromInt(1938), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9047 // __builtin_ve_vl_pvfmksuplenan_mvl
9048 .{ .tag = @enumFromInt(1939), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9049 // __builtin_ve_vl_pvfmksuplenan_mvml
9050 .{ .tag = @enumFromInt(1940), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9051 // __builtin_ve_vl_pvfmksuplt_mvl
9052 .{ .tag = @enumFromInt(1941), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9053 // __builtin_ve_vl_pvfmksuplt_mvml
9054 .{ .tag = @enumFromInt(1942), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9055 // __builtin_ve_vl_pvfmksupltnan_mvl
9056 .{ .tag = @enumFromInt(1943), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9057 // __builtin_ve_vl_pvfmksupltnan_mvml
9058 .{ .tag = @enumFromInt(1944), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9059 // __builtin_ve_vl_pvfmksupnan_mvl
9060 .{ .tag = @enumFromInt(1945), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9061 // __builtin_ve_vl_pvfmksupnan_mvml
9062 .{ .tag = @enumFromInt(1946), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9063 // __builtin_ve_vl_pvfmksupne_mvl
9064 .{ .tag = @enumFromInt(1947), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9065 // __builtin_ve_vl_pvfmksupne_mvml
9066 .{ .tag = @enumFromInt(1948), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9067 // __builtin_ve_vl_pvfmksupnenan_mvl
9068 .{ .tag = @enumFromInt(1949), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9069 // __builtin_ve_vl_pvfmksupnenan_mvml
9070 .{ .tag = @enumFromInt(1950), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9071 // __builtin_ve_vl_pvfmksupnum_mvl
9072 .{ .tag = @enumFromInt(1951), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9073 // __builtin_ve_vl_pvfmksupnum_mvml
9074 .{ .tag = @enumFromInt(1952), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9075 // __builtin_ve_vl_pvfmkweq_MvMl
9076 .{ .tag = @enumFromInt(1953), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9077 // __builtin_ve_vl_pvfmkweq_Mvl
9078 .{ .tag = @enumFromInt(1954), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9079 // __builtin_ve_vl_pvfmkweqnan_MvMl
9080 .{ .tag = @enumFromInt(1955), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9081 // __builtin_ve_vl_pvfmkweqnan_Mvl
9082 .{ .tag = @enumFromInt(1956), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9083 // __builtin_ve_vl_pvfmkwge_MvMl
9084 .{ .tag = @enumFromInt(1957), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9085 // __builtin_ve_vl_pvfmkwge_Mvl
9086 .{ .tag = @enumFromInt(1958), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9087 // __builtin_ve_vl_pvfmkwgenan_MvMl
9088 .{ .tag = @enumFromInt(1959), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9089 // __builtin_ve_vl_pvfmkwgenan_Mvl
9090 .{ .tag = @enumFromInt(1960), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9091 // __builtin_ve_vl_pvfmkwgt_MvMl
9092 .{ .tag = @enumFromInt(1961), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9093 // __builtin_ve_vl_pvfmkwgt_Mvl
9094 .{ .tag = @enumFromInt(1962), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9095 // __builtin_ve_vl_pvfmkwgtnan_MvMl
9096 .{ .tag = @enumFromInt(1963), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9097 // __builtin_ve_vl_pvfmkwgtnan_Mvl
9098 .{ .tag = @enumFromInt(1964), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9099 // __builtin_ve_vl_pvfmkwle_MvMl
9100 .{ .tag = @enumFromInt(1965), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9101 // __builtin_ve_vl_pvfmkwle_Mvl
9102 .{ .tag = @enumFromInt(1966), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9103 // __builtin_ve_vl_pvfmkwlenan_MvMl
9104 .{ .tag = @enumFromInt(1967), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9105 // __builtin_ve_vl_pvfmkwlenan_Mvl
9106 .{ .tag = @enumFromInt(1968), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9107 // __builtin_ve_vl_pvfmkwloeq_mvl
9108 .{ .tag = @enumFromInt(1969), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9109 // __builtin_ve_vl_pvfmkwloeq_mvml
9110 .{ .tag = @enumFromInt(1970), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9111 // __builtin_ve_vl_pvfmkwloeqnan_mvl
9112 .{ .tag = @enumFromInt(1971), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9113 // __builtin_ve_vl_pvfmkwloeqnan_mvml
9114 .{ .tag = @enumFromInt(1972), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9115 // __builtin_ve_vl_pvfmkwloge_mvl
9116 .{ .tag = @enumFromInt(1973), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9117 // __builtin_ve_vl_pvfmkwloge_mvml
9118 .{ .tag = @enumFromInt(1974), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9119 // __builtin_ve_vl_pvfmkwlogenan_mvl
9120 .{ .tag = @enumFromInt(1975), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9121 // __builtin_ve_vl_pvfmkwlogenan_mvml
9122 .{ .tag = @enumFromInt(1976), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9123 // __builtin_ve_vl_pvfmkwlogt_mvl
9124 .{ .tag = @enumFromInt(1977), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9125 // __builtin_ve_vl_pvfmkwlogt_mvml
9126 .{ .tag = @enumFromInt(1978), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9127 // __builtin_ve_vl_pvfmkwlogtnan_mvl
9128 .{ .tag = @enumFromInt(1979), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9129 // __builtin_ve_vl_pvfmkwlogtnan_mvml
9130 .{ .tag = @enumFromInt(1980), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9131 // __builtin_ve_vl_pvfmkwlole_mvl
9132 .{ .tag = @enumFromInt(1981), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9133 // __builtin_ve_vl_pvfmkwlole_mvml
9134 .{ .tag = @enumFromInt(1982), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9135 // __builtin_ve_vl_pvfmkwlolenan_mvl
9136 .{ .tag = @enumFromInt(1983), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9137 // __builtin_ve_vl_pvfmkwlolenan_mvml
9138 .{ .tag = @enumFromInt(1984), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9139 // __builtin_ve_vl_pvfmkwlolt_mvl
9140 .{ .tag = @enumFromInt(1985), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9141 // __builtin_ve_vl_pvfmkwlolt_mvml
9142 .{ .tag = @enumFromInt(1986), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9143 // __builtin_ve_vl_pvfmkwloltnan_mvl
9144 .{ .tag = @enumFromInt(1987), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9145 // __builtin_ve_vl_pvfmkwloltnan_mvml
9146 .{ .tag = @enumFromInt(1988), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9147 // __builtin_ve_vl_pvfmkwlonan_mvl
9148 .{ .tag = @enumFromInt(1989), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9149 // __builtin_ve_vl_pvfmkwlonan_mvml
9150 .{ .tag = @enumFromInt(1990), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9151 // __builtin_ve_vl_pvfmkwlone_mvl
9152 .{ .tag = @enumFromInt(1991), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9153 // __builtin_ve_vl_pvfmkwlone_mvml
9154 .{ .tag = @enumFromInt(1992), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9155 // __builtin_ve_vl_pvfmkwlonenan_mvl
9156 .{ .tag = @enumFromInt(1993), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9157 // __builtin_ve_vl_pvfmkwlonenan_mvml
9158 .{ .tag = @enumFromInt(1994), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9159 // __builtin_ve_vl_pvfmkwlonum_mvl
9160 .{ .tag = @enumFromInt(1995), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9161 // __builtin_ve_vl_pvfmkwlonum_mvml
9162 .{ .tag = @enumFromInt(1996), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9163 // __builtin_ve_vl_pvfmkwlt_MvMl
9164 .{ .tag = @enumFromInt(1997), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9165 // __builtin_ve_vl_pvfmkwlt_Mvl
9166 .{ .tag = @enumFromInt(1998), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9167 // __builtin_ve_vl_pvfmkwltnan_MvMl
9168 .{ .tag = @enumFromInt(1999), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9169 // __builtin_ve_vl_pvfmkwltnan_Mvl
9170 .{ .tag = @enumFromInt(2000), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9171 // __builtin_ve_vl_pvfmkwnan_MvMl
9172 .{ .tag = @enumFromInt(2001), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9173 // __builtin_ve_vl_pvfmkwnan_Mvl
9174 .{ .tag = @enumFromInt(2002), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9175 // __builtin_ve_vl_pvfmkwne_MvMl
9176 .{ .tag = @enumFromInt(2003), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9177 // __builtin_ve_vl_pvfmkwne_Mvl
9178 .{ .tag = @enumFromInt(2004), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9179 // __builtin_ve_vl_pvfmkwnenan_MvMl
9180 .{ .tag = @enumFromInt(2005), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9181 // __builtin_ve_vl_pvfmkwnenan_Mvl
9182 .{ .tag = @enumFromInt(2006), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9183 // __builtin_ve_vl_pvfmkwnum_MvMl
9184 .{ .tag = @enumFromInt(2007), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9185 // __builtin_ve_vl_pvfmkwnum_Mvl
9186 .{ .tag = @enumFromInt(2008), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9187 // __builtin_ve_vl_pvfmkwupeq_mvl
9188 .{ .tag = @enumFromInt(2009), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9189 // __builtin_ve_vl_pvfmkwupeq_mvml
9190 .{ .tag = @enumFromInt(2010), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9191 // __builtin_ve_vl_pvfmkwupeqnan_mvl
9192 .{ .tag = @enumFromInt(2011), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9193 // __builtin_ve_vl_pvfmkwupeqnan_mvml
9194 .{ .tag = @enumFromInt(2012), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9195 // __builtin_ve_vl_pvfmkwupge_mvl
9196 .{ .tag = @enumFromInt(2013), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9197 // __builtin_ve_vl_pvfmkwupge_mvml
9198 .{ .tag = @enumFromInt(2014), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9199 // __builtin_ve_vl_pvfmkwupgenan_mvl
9200 .{ .tag = @enumFromInt(2015), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9201 // __builtin_ve_vl_pvfmkwupgenan_mvml
9202 .{ .tag = @enumFromInt(2016), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9203 // __builtin_ve_vl_pvfmkwupgt_mvl
9204 .{ .tag = @enumFromInt(2017), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9205 // __builtin_ve_vl_pvfmkwupgt_mvml
9206 .{ .tag = @enumFromInt(2018), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9207 // __builtin_ve_vl_pvfmkwupgtnan_mvl
9208 .{ .tag = @enumFromInt(2019), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9209 // __builtin_ve_vl_pvfmkwupgtnan_mvml
9210 .{ .tag = @enumFromInt(2020), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9211 // __builtin_ve_vl_pvfmkwuple_mvl
9212 .{ .tag = @enumFromInt(2021), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9213 // __builtin_ve_vl_pvfmkwuple_mvml
9214 .{ .tag = @enumFromInt(2022), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9215 // __builtin_ve_vl_pvfmkwuplenan_mvl
9216 .{ .tag = @enumFromInt(2023), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9217 // __builtin_ve_vl_pvfmkwuplenan_mvml
9218 .{ .tag = @enumFromInt(2024), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9219 // __builtin_ve_vl_pvfmkwuplt_mvl
9220 .{ .tag = @enumFromInt(2025), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9221 // __builtin_ve_vl_pvfmkwuplt_mvml
9222 .{ .tag = @enumFromInt(2026), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9223 // __builtin_ve_vl_pvfmkwupltnan_mvl
9224 .{ .tag = @enumFromInt(2027), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9225 // __builtin_ve_vl_pvfmkwupltnan_mvml
9226 .{ .tag = @enumFromInt(2028), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9227 // __builtin_ve_vl_pvfmkwupnan_mvl
9228 .{ .tag = @enumFromInt(2029), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9229 // __builtin_ve_vl_pvfmkwupnan_mvml
9230 .{ .tag = @enumFromInt(2030), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9231 // __builtin_ve_vl_pvfmkwupne_mvl
9232 .{ .tag = @enumFromInt(2031), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9233 // __builtin_ve_vl_pvfmkwupne_mvml
9234 .{ .tag = @enumFromInt(2032), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9235 // __builtin_ve_vl_pvfmkwupnenan_mvl
9236 .{ .tag = @enumFromInt(2033), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9237 // __builtin_ve_vl_pvfmkwupnenan_mvml
9238 .{ .tag = @enumFromInt(2034), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9239 // __builtin_ve_vl_pvfmkwupnum_mvl
9240 .{ .tag = @enumFromInt(2035), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9241 // __builtin_ve_vl_pvfmkwupnum_mvml
9242 .{ .tag = @enumFromInt(2036), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9243 // __builtin_ve_vl_pvfmsb_vsvvMvl
9244 .{ .tag = @enumFromInt(2037), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9245 // __builtin_ve_vl_pvfmsb_vsvvl
9246 .{ .tag = @enumFromInt(2038), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9247 // __builtin_ve_vl_pvfmsb_vsvvvl
9248 .{ .tag = @enumFromInt(2039), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9249 // __builtin_ve_vl_pvfmsb_vvsvMvl
9250 .{ .tag = @enumFromInt(2040), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9251 // __builtin_ve_vl_pvfmsb_vvsvl
9252 .{ .tag = @enumFromInt(2041), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9253 // __builtin_ve_vl_pvfmsb_vvsvvl
9254 .{ .tag = @enumFromInt(2042), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9255 // __builtin_ve_vl_pvfmsb_vvvvMvl
9256 .{ .tag = @enumFromInt(2043), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9257 // __builtin_ve_vl_pvfmsb_vvvvl
9258 .{ .tag = @enumFromInt(2044), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9259 // __builtin_ve_vl_pvfmsb_vvvvvl
9260 .{ .tag = @enumFromInt(2045), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9261 // __builtin_ve_vl_pvfmul_vsvMvl
9262 .{ .tag = @enumFromInt(2046), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9263 // __builtin_ve_vl_pvfmul_vsvl
9264 .{ .tag = @enumFromInt(2047), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9265 // __builtin_ve_vl_pvfmul_vsvvl
9266 .{ .tag = @enumFromInt(2048), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9267 // __builtin_ve_vl_pvfmul_vvvMvl
9268 .{ .tag = @enumFromInt(2049), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9269 // __builtin_ve_vl_pvfmul_vvvl
9270 .{ .tag = @enumFromInt(2050), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9271 // __builtin_ve_vl_pvfmul_vvvvl
9272 .{ .tag = @enumFromInt(2051), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9273 // __builtin_ve_vl_pvfnmad_vsvvMvl
9274 .{ .tag = @enumFromInt(2052), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9275 // __builtin_ve_vl_pvfnmad_vsvvl
9276 .{ .tag = @enumFromInt(2053), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9277 // __builtin_ve_vl_pvfnmad_vsvvvl
9278 .{ .tag = @enumFromInt(2054), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9279 // __builtin_ve_vl_pvfnmad_vvsvMvl
9280 .{ .tag = @enumFromInt(2055), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9281 // __builtin_ve_vl_pvfnmad_vvsvl
9282 .{ .tag = @enumFromInt(2056), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9283 // __builtin_ve_vl_pvfnmad_vvsvvl
9284 .{ .tag = @enumFromInt(2057), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9285 // __builtin_ve_vl_pvfnmad_vvvvMvl
9286 .{ .tag = @enumFromInt(2058), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9287 // __builtin_ve_vl_pvfnmad_vvvvl
9288 .{ .tag = @enumFromInt(2059), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9289 // __builtin_ve_vl_pvfnmad_vvvvvl
9290 .{ .tag = @enumFromInt(2060), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9291 // __builtin_ve_vl_pvfnmsb_vsvvMvl
9292 .{ .tag = @enumFromInt(2061), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9293 // __builtin_ve_vl_pvfnmsb_vsvvl
9294 .{ .tag = @enumFromInt(2062), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9295 // __builtin_ve_vl_pvfnmsb_vsvvvl
9296 .{ .tag = @enumFromInt(2063), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9297 // __builtin_ve_vl_pvfnmsb_vvsvMvl
9298 .{ .tag = @enumFromInt(2064), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9299 // __builtin_ve_vl_pvfnmsb_vvsvl
9300 .{ .tag = @enumFromInt(2065), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9301 // __builtin_ve_vl_pvfnmsb_vvsvvl
9302 .{ .tag = @enumFromInt(2066), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9303 // __builtin_ve_vl_pvfnmsb_vvvvMvl
9304 .{ .tag = @enumFromInt(2067), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9305 // __builtin_ve_vl_pvfnmsb_vvvvl
9306 .{ .tag = @enumFromInt(2068), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9307 // __builtin_ve_vl_pvfnmsb_vvvvvl
9308 .{ .tag = @enumFromInt(2069), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9309 // __builtin_ve_vl_pvfsub_vsvMvl
9310 .{ .tag = @enumFromInt(2070), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9311 // __builtin_ve_vl_pvfsub_vsvl
9312 .{ .tag = @enumFromInt(2071), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9313 // __builtin_ve_vl_pvfsub_vsvvl
9314 .{ .tag = @enumFromInt(2072), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9315 // __builtin_ve_vl_pvfsub_vvvMvl
9316 .{ .tag = @enumFromInt(2073), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9317 // __builtin_ve_vl_pvfsub_vvvl
9318 .{ .tag = @enumFromInt(2074), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9319 // __builtin_ve_vl_pvfsub_vvvvl
9320 .{ .tag = @enumFromInt(2075), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9321 // __builtin_ve_vl_pvldz_vvMvl
9322 .{ .tag = @enumFromInt(2076), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9323 // __builtin_ve_vl_pvldz_vvl
9324 .{ .tag = @enumFromInt(2077), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9325 // __builtin_ve_vl_pvldz_vvvl
9326 .{ .tag = @enumFromInt(2078), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9327 // __builtin_ve_vl_pvldzlo_vvl
9328 .{ .tag = @enumFromInt(2079), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9329 // __builtin_ve_vl_pvldzlo_vvmvl
9330 .{ .tag = @enumFromInt(2080), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9331 // __builtin_ve_vl_pvldzlo_vvvl
9332 .{ .tag = @enumFromInt(2081), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9333 // __builtin_ve_vl_pvldzup_vvl
9334 .{ .tag = @enumFromInt(2082), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9335 // __builtin_ve_vl_pvldzup_vvmvl
9336 .{ .tag = @enumFromInt(2083), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9337 // __builtin_ve_vl_pvldzup_vvvl
9338 .{ .tag = @enumFromInt(2084), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9339 // __builtin_ve_vl_pvmaxs_vsvMvl
9340 .{ .tag = @enumFromInt(2085), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9341 // __builtin_ve_vl_pvmaxs_vsvl
9342 .{ .tag = @enumFromInt(2086), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9343 // __builtin_ve_vl_pvmaxs_vsvvl
9344 .{ .tag = @enumFromInt(2087), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9345 // __builtin_ve_vl_pvmaxs_vvvMvl
9346 .{ .tag = @enumFromInt(2088), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9347 // __builtin_ve_vl_pvmaxs_vvvl
9348 .{ .tag = @enumFromInt(2089), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9349 // __builtin_ve_vl_pvmaxs_vvvvl
9350 .{ .tag = @enumFromInt(2090), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9351 // __builtin_ve_vl_pvmins_vsvMvl
9352 .{ .tag = @enumFromInt(2091), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9353 // __builtin_ve_vl_pvmins_vsvl
9354 .{ .tag = @enumFromInt(2092), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9355 // __builtin_ve_vl_pvmins_vsvvl
9356 .{ .tag = @enumFromInt(2093), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9357 // __builtin_ve_vl_pvmins_vvvMvl
9358 .{ .tag = @enumFromInt(2094), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9359 // __builtin_ve_vl_pvmins_vvvl
9360 .{ .tag = @enumFromInt(2095), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9361 // __builtin_ve_vl_pvmins_vvvvl
9362 .{ .tag = @enumFromInt(2096), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9363 // __builtin_ve_vl_pvor_vsvMvl
9364 .{ .tag = @enumFromInt(2097), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9365 // __builtin_ve_vl_pvor_vsvl
9366 .{ .tag = @enumFromInt(2098), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9367 // __builtin_ve_vl_pvor_vsvvl
9368 .{ .tag = @enumFromInt(2099), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9369 // __builtin_ve_vl_pvor_vvvMvl
9370 .{ .tag = @enumFromInt(2100), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9371 // __builtin_ve_vl_pvor_vvvl
9372 .{ .tag = @enumFromInt(2101), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9373 // __builtin_ve_vl_pvor_vvvvl
9374 .{ .tag = @enumFromInt(2102), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9375 // __builtin_ve_vl_pvpcnt_vvMvl
9376 .{ .tag = @enumFromInt(2103), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9377 // __builtin_ve_vl_pvpcnt_vvl
9378 .{ .tag = @enumFromInt(2104), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9379 // __builtin_ve_vl_pvpcnt_vvvl
9380 .{ .tag = @enumFromInt(2105), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9381 // __builtin_ve_vl_pvpcntlo_vvl
9382 .{ .tag = @enumFromInt(2106), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9383 // __builtin_ve_vl_pvpcntlo_vvmvl
9384 .{ .tag = @enumFromInt(2107), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9385 // __builtin_ve_vl_pvpcntlo_vvvl
9386 .{ .tag = @enumFromInt(2108), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9387 // __builtin_ve_vl_pvpcntup_vvl
9388 .{ .tag = @enumFromInt(2109), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9389 // __builtin_ve_vl_pvpcntup_vvmvl
9390 .{ .tag = @enumFromInt(2110), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9391 // __builtin_ve_vl_pvpcntup_vvvl
9392 .{ .tag = @enumFromInt(2111), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9393 // __builtin_ve_vl_pvrcp_vvl
9394 .{ .tag = @enumFromInt(2112), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9395 // __builtin_ve_vl_pvrcp_vvvl
9396 .{ .tag = @enumFromInt(2113), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9397 // __builtin_ve_vl_pvrsqrt_vvl
9398 .{ .tag = @enumFromInt(2114), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9399 // __builtin_ve_vl_pvrsqrt_vvvl
9400 .{ .tag = @enumFromInt(2115), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9401 // __builtin_ve_vl_pvrsqrtnex_vvl
9402 .{ .tag = @enumFromInt(2116), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9403 // __builtin_ve_vl_pvrsqrtnex_vvvl
9404 .{ .tag = @enumFromInt(2117), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9405 // __builtin_ve_vl_pvseq_vl
9406 .{ .tag = @enumFromInt(2118), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9407 // __builtin_ve_vl_pvseq_vvl
9408 .{ .tag = @enumFromInt(2119), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9409 // __builtin_ve_vl_pvseqlo_vl
9410 .{ .tag = @enumFromInt(2120), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9411 // __builtin_ve_vl_pvseqlo_vvl
9412 .{ .tag = @enumFromInt(2121), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9413 // __builtin_ve_vl_pvsequp_vl
9414 .{ .tag = @enumFromInt(2122), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9415 // __builtin_ve_vl_pvsequp_vvl
9416 .{ .tag = @enumFromInt(2123), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9417 // __builtin_ve_vl_pvsla_vvsMvl
9418 .{ .tag = @enumFromInt(2124), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9419 // __builtin_ve_vl_pvsla_vvsl
9420 .{ .tag = @enumFromInt(2125), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9421 // __builtin_ve_vl_pvsla_vvsvl
9422 .{ .tag = @enumFromInt(2126), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9423 // __builtin_ve_vl_pvsla_vvvMvl
9424 .{ .tag = @enumFromInt(2127), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9425 // __builtin_ve_vl_pvsla_vvvl
9426 .{ .tag = @enumFromInt(2128), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9427 // __builtin_ve_vl_pvsla_vvvvl
9428 .{ .tag = @enumFromInt(2129), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9429 // __builtin_ve_vl_pvsll_vvsMvl
9430 .{ .tag = @enumFromInt(2130), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9431 // __builtin_ve_vl_pvsll_vvsl
9432 .{ .tag = @enumFromInt(2131), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9433 // __builtin_ve_vl_pvsll_vvsvl
9434 .{ .tag = @enumFromInt(2132), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9435 // __builtin_ve_vl_pvsll_vvvMvl
9436 .{ .tag = @enumFromInt(2133), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9437 // __builtin_ve_vl_pvsll_vvvl
9438 .{ .tag = @enumFromInt(2134), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9439 // __builtin_ve_vl_pvsll_vvvvl
9440 .{ .tag = @enumFromInt(2135), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9441 // __builtin_ve_vl_pvsra_vvsMvl
9442 .{ .tag = @enumFromInt(2136), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9443 // __builtin_ve_vl_pvsra_vvsl
9444 .{ .tag = @enumFromInt(2137), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9445 // __builtin_ve_vl_pvsra_vvsvl
9446 .{ .tag = @enumFromInt(2138), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9447 // __builtin_ve_vl_pvsra_vvvMvl
9448 .{ .tag = @enumFromInt(2139), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9449 // __builtin_ve_vl_pvsra_vvvl
9450 .{ .tag = @enumFromInt(2140), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9451 // __builtin_ve_vl_pvsra_vvvvl
9452 .{ .tag = @enumFromInt(2141), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9453 // __builtin_ve_vl_pvsrl_vvsMvl
9454 .{ .tag = @enumFromInt(2142), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9455 // __builtin_ve_vl_pvsrl_vvsl
9456 .{ .tag = @enumFromInt(2143), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9457 // __builtin_ve_vl_pvsrl_vvsvl
9458 .{ .tag = @enumFromInt(2144), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9459 // __builtin_ve_vl_pvsrl_vvvMvl
9460 .{ .tag = @enumFromInt(2145), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9461 // __builtin_ve_vl_pvsrl_vvvl
9462 .{ .tag = @enumFromInt(2146), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9463 // __builtin_ve_vl_pvsrl_vvvvl
9464 .{ .tag = @enumFromInt(2147), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9465 // __builtin_ve_vl_pvsubs_vsvMvl
9466 .{ .tag = @enumFromInt(2148), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9467 // __builtin_ve_vl_pvsubs_vsvl
9468 .{ .tag = @enumFromInt(2149), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9469 // __builtin_ve_vl_pvsubs_vsvvl
9470 .{ .tag = @enumFromInt(2150), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9471 // __builtin_ve_vl_pvsubs_vvvMvl
9472 .{ .tag = @enumFromInt(2151), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9473 // __builtin_ve_vl_pvsubs_vvvl
9474 .{ .tag = @enumFromInt(2152), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9475 // __builtin_ve_vl_pvsubs_vvvvl
9476 .{ .tag = @enumFromInt(2153), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9477 // __builtin_ve_vl_pvsubu_vsvMvl
9478 .{ .tag = @enumFromInt(2154), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9479 // __builtin_ve_vl_pvsubu_vsvl
9480 .{ .tag = @enumFromInt(2155), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9481 // __builtin_ve_vl_pvsubu_vsvvl
9482 .{ .tag = @enumFromInt(2156), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9483 // __builtin_ve_vl_pvsubu_vvvMvl
9484 .{ .tag = @enumFromInt(2157), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9485 // __builtin_ve_vl_pvsubu_vvvl
9486 .{ .tag = @enumFromInt(2158), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9487 // __builtin_ve_vl_pvsubu_vvvvl
9488 .{ .tag = @enumFromInt(2159), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9489 // __builtin_ve_vl_pvxor_vsvMvl
9490 .{ .tag = @enumFromInt(2160), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9491 // __builtin_ve_vl_pvxor_vsvl
9492 .{ .tag = @enumFromInt(2161), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9493 // __builtin_ve_vl_pvxor_vsvvl
9494 .{ .tag = @enumFromInt(2162), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9495 // __builtin_ve_vl_pvxor_vvvMvl
9496 .{ .tag = @enumFromInt(2163), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9497 // __builtin_ve_vl_pvxor_vvvl
9498 .{ .tag = @enumFromInt(2164), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9499 // __builtin_ve_vl_pvxor_vvvvl
9500 .{ .tag = @enumFromInt(2165), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9501 // __builtin_ve_vl_scr_sss
9502 .{ .tag = @enumFromInt(2166), .properties = .{ .param_str = "vLUiLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9503 // __builtin_ve_vl_svm_sMs
9504 .{ .tag = @enumFromInt(2167), .properties = .{ .param_str = "LUiV512bLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9505 // __builtin_ve_vl_svm_sms
9506 .{ .tag = @enumFromInt(2168), .properties = .{ .param_str = "LUiV256bLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9507 // __builtin_ve_vl_svob
9508 .{ .tag = @enumFromInt(2169), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.vevl_gen) } },
9509 // __builtin_ve_vl_tovm_sml
9510 .{ .tag = @enumFromInt(2170), .properties = .{ .param_str = "LUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9511 // __builtin_ve_vl_tscr_ssss
9512 .{ .tag = @enumFromInt(2171), .properties = .{ .param_str = "LUiLUiLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9513 // __builtin_ve_vl_vaddsl_vsvl
9514 .{ .tag = @enumFromInt(2172), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9515 // __builtin_ve_vl_vaddsl_vsvmvl
9516 .{ .tag = @enumFromInt(2173), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9517 // __builtin_ve_vl_vaddsl_vsvvl
9518 .{ .tag = @enumFromInt(2174), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9519 // __builtin_ve_vl_vaddsl_vvvl
9520 .{ .tag = @enumFromInt(2175), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9521 // __builtin_ve_vl_vaddsl_vvvmvl
9522 .{ .tag = @enumFromInt(2176), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9523 // __builtin_ve_vl_vaddsl_vvvvl
9524 .{ .tag = @enumFromInt(2177), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9525 // __builtin_ve_vl_vaddswsx_vsvl
9526 .{ .tag = @enumFromInt(2178), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9527 // __builtin_ve_vl_vaddswsx_vsvmvl
9528 .{ .tag = @enumFromInt(2179), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9529 // __builtin_ve_vl_vaddswsx_vsvvl
9530 .{ .tag = @enumFromInt(2180), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9531 // __builtin_ve_vl_vaddswsx_vvvl
9532 .{ .tag = @enumFromInt(2181), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9533 // __builtin_ve_vl_vaddswsx_vvvmvl
9534 .{ .tag = @enumFromInt(2182), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9535 // __builtin_ve_vl_vaddswsx_vvvvl
9536 .{ .tag = @enumFromInt(2183), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9537 // __builtin_ve_vl_vaddswzx_vsvl
9538 .{ .tag = @enumFromInt(2184), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9539 // __builtin_ve_vl_vaddswzx_vsvmvl
9540 .{ .tag = @enumFromInt(2185), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9541 // __builtin_ve_vl_vaddswzx_vsvvl
9542 .{ .tag = @enumFromInt(2186), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9543 // __builtin_ve_vl_vaddswzx_vvvl
9544 .{ .tag = @enumFromInt(2187), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9545 // __builtin_ve_vl_vaddswzx_vvvmvl
9546 .{ .tag = @enumFromInt(2188), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9547 // __builtin_ve_vl_vaddswzx_vvvvl
9548 .{ .tag = @enumFromInt(2189), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9549 // __builtin_ve_vl_vaddul_vsvl
9550 .{ .tag = @enumFromInt(2190), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9551 // __builtin_ve_vl_vaddul_vsvmvl
9552 .{ .tag = @enumFromInt(2191), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9553 // __builtin_ve_vl_vaddul_vsvvl
9554 .{ .tag = @enumFromInt(2192), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9555 // __builtin_ve_vl_vaddul_vvvl
9556 .{ .tag = @enumFromInt(2193), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9557 // __builtin_ve_vl_vaddul_vvvmvl
9558 .{ .tag = @enumFromInt(2194), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9559 // __builtin_ve_vl_vaddul_vvvvl
9560 .{ .tag = @enumFromInt(2195), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9561 // __builtin_ve_vl_vadduw_vsvl
9562 .{ .tag = @enumFromInt(2196), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9563 // __builtin_ve_vl_vadduw_vsvmvl
9564 .{ .tag = @enumFromInt(2197), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9565 // __builtin_ve_vl_vadduw_vsvvl
9566 .{ .tag = @enumFromInt(2198), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9567 // __builtin_ve_vl_vadduw_vvvl
9568 .{ .tag = @enumFromInt(2199), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9569 // __builtin_ve_vl_vadduw_vvvmvl
9570 .{ .tag = @enumFromInt(2200), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9571 // __builtin_ve_vl_vadduw_vvvvl
9572 .{ .tag = @enumFromInt(2201), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9573 // __builtin_ve_vl_vand_vsvl
9574 .{ .tag = @enumFromInt(2202), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9575 // __builtin_ve_vl_vand_vsvmvl
9576 .{ .tag = @enumFromInt(2203), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9577 // __builtin_ve_vl_vand_vsvvl
9578 .{ .tag = @enumFromInt(2204), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9579 // __builtin_ve_vl_vand_vvvl
9580 .{ .tag = @enumFromInt(2205), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9581 // __builtin_ve_vl_vand_vvvmvl
9582 .{ .tag = @enumFromInt(2206), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9583 // __builtin_ve_vl_vand_vvvvl
9584 .{ .tag = @enumFromInt(2207), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9585 // __builtin_ve_vl_vbrdd_vsl
9586 .{ .tag = @enumFromInt(2208), .properties = .{ .param_str = "V256ddUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9587 // __builtin_ve_vl_vbrdd_vsmvl
9588 .{ .tag = @enumFromInt(2209), .properties = .{ .param_str = "V256ddV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9589 // __builtin_ve_vl_vbrdd_vsvl
9590 .{ .tag = @enumFromInt(2210), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9591 // __builtin_ve_vl_vbrdl_vsl
9592 .{ .tag = @enumFromInt(2211), .properties = .{ .param_str = "V256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9593 // __builtin_ve_vl_vbrdl_vsmvl
9594 .{ .tag = @enumFromInt(2212), .properties = .{ .param_str = "V256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9595 // __builtin_ve_vl_vbrdl_vsvl
9596 .{ .tag = @enumFromInt(2213), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9597 // __builtin_ve_vl_vbrds_vsl
9598 .{ .tag = @enumFromInt(2214), .properties = .{ .param_str = "V256dfUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9599 // __builtin_ve_vl_vbrds_vsmvl
9600 .{ .tag = @enumFromInt(2215), .properties = .{ .param_str = "V256dfV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9601 // __builtin_ve_vl_vbrds_vsvl
9602 .{ .tag = @enumFromInt(2216), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9603 // __builtin_ve_vl_vbrdw_vsl
9604 .{ .tag = @enumFromInt(2217), .properties = .{ .param_str = "V256diUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9605 // __builtin_ve_vl_vbrdw_vsmvl
9606 .{ .tag = @enumFromInt(2218), .properties = .{ .param_str = "V256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9607 // __builtin_ve_vl_vbrdw_vsvl
9608 .{ .tag = @enumFromInt(2219), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9609 // __builtin_ve_vl_vbrv_vvl
9610 .{ .tag = @enumFromInt(2220), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9611 // __builtin_ve_vl_vbrv_vvmvl
9612 .{ .tag = @enumFromInt(2221), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9613 // __builtin_ve_vl_vbrv_vvvl
9614 .{ .tag = @enumFromInt(2222), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9615 // __builtin_ve_vl_vcmpsl_vsvl
9616 .{ .tag = @enumFromInt(2223), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9617 // __builtin_ve_vl_vcmpsl_vsvmvl
9618 .{ .tag = @enumFromInt(2224), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9619 // __builtin_ve_vl_vcmpsl_vsvvl
9620 .{ .tag = @enumFromInt(2225), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9621 // __builtin_ve_vl_vcmpsl_vvvl
9622 .{ .tag = @enumFromInt(2226), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9623 // __builtin_ve_vl_vcmpsl_vvvmvl
9624 .{ .tag = @enumFromInt(2227), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9625 // __builtin_ve_vl_vcmpsl_vvvvl
9626 .{ .tag = @enumFromInt(2228), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9627 // __builtin_ve_vl_vcmpswsx_vsvl
9628 .{ .tag = @enumFromInt(2229), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9629 // __builtin_ve_vl_vcmpswsx_vsvmvl
9630 .{ .tag = @enumFromInt(2230), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9631 // __builtin_ve_vl_vcmpswsx_vsvvl
9632 .{ .tag = @enumFromInt(2231), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9633 // __builtin_ve_vl_vcmpswsx_vvvl
9634 .{ .tag = @enumFromInt(2232), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9635 // __builtin_ve_vl_vcmpswsx_vvvmvl
9636 .{ .tag = @enumFromInt(2233), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9637 // __builtin_ve_vl_vcmpswsx_vvvvl
9638 .{ .tag = @enumFromInt(2234), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9639 // __builtin_ve_vl_vcmpswzx_vsvl
9640 .{ .tag = @enumFromInt(2235), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9641 // __builtin_ve_vl_vcmpswzx_vsvmvl
9642 .{ .tag = @enumFromInt(2236), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9643 // __builtin_ve_vl_vcmpswzx_vsvvl
9644 .{ .tag = @enumFromInt(2237), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9645 // __builtin_ve_vl_vcmpswzx_vvvl
9646 .{ .tag = @enumFromInt(2238), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9647 // __builtin_ve_vl_vcmpswzx_vvvmvl
9648 .{ .tag = @enumFromInt(2239), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9649 // __builtin_ve_vl_vcmpswzx_vvvvl
9650 .{ .tag = @enumFromInt(2240), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9651 // __builtin_ve_vl_vcmpul_vsvl
9652 .{ .tag = @enumFromInt(2241), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9653 // __builtin_ve_vl_vcmpul_vsvmvl
9654 .{ .tag = @enumFromInt(2242), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9655 // __builtin_ve_vl_vcmpul_vsvvl
9656 .{ .tag = @enumFromInt(2243), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9657 // __builtin_ve_vl_vcmpul_vvvl
9658 .{ .tag = @enumFromInt(2244), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9659 // __builtin_ve_vl_vcmpul_vvvmvl
9660 .{ .tag = @enumFromInt(2245), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9661 // __builtin_ve_vl_vcmpul_vvvvl
9662 .{ .tag = @enumFromInt(2246), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9663 // __builtin_ve_vl_vcmpuw_vsvl
9664 .{ .tag = @enumFromInt(2247), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9665 // __builtin_ve_vl_vcmpuw_vsvmvl
9666 .{ .tag = @enumFromInt(2248), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9667 // __builtin_ve_vl_vcmpuw_vsvvl
9668 .{ .tag = @enumFromInt(2249), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9669 // __builtin_ve_vl_vcmpuw_vvvl
9670 .{ .tag = @enumFromInt(2250), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9671 // __builtin_ve_vl_vcmpuw_vvvmvl
9672 .{ .tag = @enumFromInt(2251), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9673 // __builtin_ve_vl_vcmpuw_vvvvl
9674 .{ .tag = @enumFromInt(2252), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9675 // __builtin_ve_vl_vcp_vvmvl
9676 .{ .tag = @enumFromInt(2253), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9677 // __builtin_ve_vl_vcvtdl_vvl
9678 .{ .tag = @enumFromInt(2254), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9679 // __builtin_ve_vl_vcvtdl_vvvl
9680 .{ .tag = @enumFromInt(2255), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9681 // __builtin_ve_vl_vcvtds_vvl
9682 .{ .tag = @enumFromInt(2256), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9683 // __builtin_ve_vl_vcvtds_vvvl
9684 .{ .tag = @enumFromInt(2257), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9685 // __builtin_ve_vl_vcvtdw_vvl
9686 .{ .tag = @enumFromInt(2258), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9687 // __builtin_ve_vl_vcvtdw_vvvl
9688 .{ .tag = @enumFromInt(2259), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9689 // __builtin_ve_vl_vcvtld_vvl
9690 .{ .tag = @enumFromInt(2260), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9691 // __builtin_ve_vl_vcvtld_vvmvl
9692 .{ .tag = @enumFromInt(2261), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9693 // __builtin_ve_vl_vcvtld_vvvl
9694 .{ .tag = @enumFromInt(2262), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9695 // __builtin_ve_vl_vcvtldrz_vvl
9696 .{ .tag = @enumFromInt(2263), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9697 // __builtin_ve_vl_vcvtldrz_vvmvl
9698 .{ .tag = @enumFromInt(2264), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9699 // __builtin_ve_vl_vcvtldrz_vvvl
9700 .{ .tag = @enumFromInt(2265), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9701 // __builtin_ve_vl_vcvtsd_vvl
9702 .{ .tag = @enumFromInt(2266), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9703 // __builtin_ve_vl_vcvtsd_vvvl
9704 .{ .tag = @enumFromInt(2267), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9705 // __builtin_ve_vl_vcvtsw_vvl
9706 .{ .tag = @enumFromInt(2268), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9707 // __builtin_ve_vl_vcvtsw_vvvl
9708 .{ .tag = @enumFromInt(2269), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9709 // __builtin_ve_vl_vcvtwdsx_vvl
9710 .{ .tag = @enumFromInt(2270), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9711 // __builtin_ve_vl_vcvtwdsx_vvmvl
9712 .{ .tag = @enumFromInt(2271), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9713 // __builtin_ve_vl_vcvtwdsx_vvvl
9714 .{ .tag = @enumFromInt(2272), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9715 // __builtin_ve_vl_vcvtwdsxrz_vvl
9716 .{ .tag = @enumFromInt(2273), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9717 // __builtin_ve_vl_vcvtwdsxrz_vvmvl
9718 .{ .tag = @enumFromInt(2274), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9719 // __builtin_ve_vl_vcvtwdsxrz_vvvl
9720 .{ .tag = @enumFromInt(2275), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9721 // __builtin_ve_vl_vcvtwdzx_vvl
9722 .{ .tag = @enumFromInt(2276), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9723 // __builtin_ve_vl_vcvtwdzx_vvmvl
9724 .{ .tag = @enumFromInt(2277), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9725 // __builtin_ve_vl_vcvtwdzx_vvvl
9726 .{ .tag = @enumFromInt(2278), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9727 // __builtin_ve_vl_vcvtwdzxrz_vvl
9728 .{ .tag = @enumFromInt(2279), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9729 // __builtin_ve_vl_vcvtwdzxrz_vvmvl
9730 .{ .tag = @enumFromInt(2280), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9731 // __builtin_ve_vl_vcvtwdzxrz_vvvl
9732 .{ .tag = @enumFromInt(2281), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9733 // __builtin_ve_vl_vcvtwssx_vvl
9734 .{ .tag = @enumFromInt(2282), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9735 // __builtin_ve_vl_vcvtwssx_vvmvl
9736 .{ .tag = @enumFromInt(2283), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9737 // __builtin_ve_vl_vcvtwssx_vvvl
9738 .{ .tag = @enumFromInt(2284), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9739 // __builtin_ve_vl_vcvtwssxrz_vvl
9740 .{ .tag = @enumFromInt(2285), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9741 // __builtin_ve_vl_vcvtwssxrz_vvmvl
9742 .{ .tag = @enumFromInt(2286), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9743 // __builtin_ve_vl_vcvtwssxrz_vvvl
9744 .{ .tag = @enumFromInt(2287), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9745 // __builtin_ve_vl_vcvtwszx_vvl
9746 .{ .tag = @enumFromInt(2288), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9747 // __builtin_ve_vl_vcvtwszx_vvmvl
9748 .{ .tag = @enumFromInt(2289), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9749 // __builtin_ve_vl_vcvtwszx_vvvl
9750 .{ .tag = @enumFromInt(2290), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9751 // __builtin_ve_vl_vcvtwszxrz_vvl
9752 .{ .tag = @enumFromInt(2291), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9753 // __builtin_ve_vl_vcvtwszxrz_vvmvl
9754 .{ .tag = @enumFromInt(2292), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9755 // __builtin_ve_vl_vcvtwszxrz_vvvl
9756 .{ .tag = @enumFromInt(2293), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9757 // __builtin_ve_vl_vdivsl_vsvl
9758 .{ .tag = @enumFromInt(2294), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9759 // __builtin_ve_vl_vdivsl_vsvmvl
9760 .{ .tag = @enumFromInt(2295), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9761 // __builtin_ve_vl_vdivsl_vsvvl
9762 .{ .tag = @enumFromInt(2296), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9763 // __builtin_ve_vl_vdivsl_vvsl
9764 .{ .tag = @enumFromInt(2297), .properties = .{ .param_str = "V256dV256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9765 // __builtin_ve_vl_vdivsl_vvsmvl
9766 .{ .tag = @enumFromInt(2298), .properties = .{ .param_str = "V256dV256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9767 // __builtin_ve_vl_vdivsl_vvsvl
9768 .{ .tag = @enumFromInt(2299), .properties = .{ .param_str = "V256dV256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9769 // __builtin_ve_vl_vdivsl_vvvl
9770 .{ .tag = @enumFromInt(2300), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9771 // __builtin_ve_vl_vdivsl_vvvmvl
9772 .{ .tag = @enumFromInt(2301), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9773 // __builtin_ve_vl_vdivsl_vvvvl
9774 .{ .tag = @enumFromInt(2302), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9775 // __builtin_ve_vl_vdivswsx_vsvl
9776 .{ .tag = @enumFromInt(2303), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9777 // __builtin_ve_vl_vdivswsx_vsvmvl
9778 .{ .tag = @enumFromInt(2304), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9779 // __builtin_ve_vl_vdivswsx_vsvvl
9780 .{ .tag = @enumFromInt(2305), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9781 // __builtin_ve_vl_vdivswsx_vvsl
9782 .{ .tag = @enumFromInt(2306), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9783 // __builtin_ve_vl_vdivswsx_vvsmvl
9784 .{ .tag = @enumFromInt(2307), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9785 // __builtin_ve_vl_vdivswsx_vvsvl
9786 .{ .tag = @enumFromInt(2308), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9787 // __builtin_ve_vl_vdivswsx_vvvl
9788 .{ .tag = @enumFromInt(2309), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9789 // __builtin_ve_vl_vdivswsx_vvvmvl
9790 .{ .tag = @enumFromInt(2310), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9791 // __builtin_ve_vl_vdivswsx_vvvvl
9792 .{ .tag = @enumFromInt(2311), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9793 // __builtin_ve_vl_vdivswzx_vsvl
9794 .{ .tag = @enumFromInt(2312), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9795 // __builtin_ve_vl_vdivswzx_vsvmvl
9796 .{ .tag = @enumFromInt(2313), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9797 // __builtin_ve_vl_vdivswzx_vsvvl
9798 .{ .tag = @enumFromInt(2314), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9799 // __builtin_ve_vl_vdivswzx_vvsl
9800 .{ .tag = @enumFromInt(2315), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9801 // __builtin_ve_vl_vdivswzx_vvsmvl
9802 .{ .tag = @enumFromInt(2316), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9803 // __builtin_ve_vl_vdivswzx_vvsvl
9804 .{ .tag = @enumFromInt(2317), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9805 // __builtin_ve_vl_vdivswzx_vvvl
9806 .{ .tag = @enumFromInt(2318), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9807 // __builtin_ve_vl_vdivswzx_vvvmvl
9808 .{ .tag = @enumFromInt(2319), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9809 // __builtin_ve_vl_vdivswzx_vvvvl
9810 .{ .tag = @enumFromInt(2320), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9811 // __builtin_ve_vl_vdivul_vsvl
9812 .{ .tag = @enumFromInt(2321), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9813 // __builtin_ve_vl_vdivul_vsvmvl
9814 .{ .tag = @enumFromInt(2322), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9815 // __builtin_ve_vl_vdivul_vsvvl
9816 .{ .tag = @enumFromInt(2323), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9817 // __builtin_ve_vl_vdivul_vvsl
9818 .{ .tag = @enumFromInt(2324), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9819 // __builtin_ve_vl_vdivul_vvsmvl
9820 .{ .tag = @enumFromInt(2325), .properties = .{ .param_str = "V256dV256dLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9821 // __builtin_ve_vl_vdivul_vvsvl
9822 .{ .tag = @enumFromInt(2326), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9823 // __builtin_ve_vl_vdivul_vvvl
9824 .{ .tag = @enumFromInt(2327), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9825 // __builtin_ve_vl_vdivul_vvvmvl
9826 .{ .tag = @enumFromInt(2328), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9827 // __builtin_ve_vl_vdivul_vvvvl
9828 .{ .tag = @enumFromInt(2329), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9829 // __builtin_ve_vl_vdivuw_vsvl
9830 .{ .tag = @enumFromInt(2330), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9831 // __builtin_ve_vl_vdivuw_vsvmvl
9832 .{ .tag = @enumFromInt(2331), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9833 // __builtin_ve_vl_vdivuw_vsvvl
9834 .{ .tag = @enumFromInt(2332), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9835 // __builtin_ve_vl_vdivuw_vvsl
9836 .{ .tag = @enumFromInt(2333), .properties = .{ .param_str = "V256dV256dUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9837 // __builtin_ve_vl_vdivuw_vvsmvl
9838 .{ .tag = @enumFromInt(2334), .properties = .{ .param_str = "V256dV256dUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9839 // __builtin_ve_vl_vdivuw_vvsvl
9840 .{ .tag = @enumFromInt(2335), .properties = .{ .param_str = "V256dV256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9841 // __builtin_ve_vl_vdivuw_vvvl
9842 .{ .tag = @enumFromInt(2336), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9843 // __builtin_ve_vl_vdivuw_vvvmvl
9844 .{ .tag = @enumFromInt(2337), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9845 // __builtin_ve_vl_vdivuw_vvvvl
9846 .{ .tag = @enumFromInt(2338), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9847 // __builtin_ve_vl_veqv_vsvl
9848 .{ .tag = @enumFromInt(2339), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9849 // __builtin_ve_vl_veqv_vsvmvl
9850 .{ .tag = @enumFromInt(2340), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9851 // __builtin_ve_vl_veqv_vsvvl
9852 .{ .tag = @enumFromInt(2341), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9853 // __builtin_ve_vl_veqv_vvvl
9854 .{ .tag = @enumFromInt(2342), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9855 // __builtin_ve_vl_veqv_vvvmvl
9856 .{ .tag = @enumFromInt(2343), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9857 // __builtin_ve_vl_veqv_vvvvl
9858 .{ .tag = @enumFromInt(2344), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9859 // __builtin_ve_vl_vex_vvmvl
9860 .{ .tag = @enumFromInt(2345), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9861 // __builtin_ve_vl_vfaddd_vsvl
9862 .{ .tag = @enumFromInt(2346), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9863 // __builtin_ve_vl_vfaddd_vsvmvl
9864 .{ .tag = @enumFromInt(2347), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9865 // __builtin_ve_vl_vfaddd_vsvvl
9866 .{ .tag = @enumFromInt(2348), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9867 // __builtin_ve_vl_vfaddd_vvvl
9868 .{ .tag = @enumFromInt(2349), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9869 // __builtin_ve_vl_vfaddd_vvvmvl
9870 .{ .tag = @enumFromInt(2350), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9871 // __builtin_ve_vl_vfaddd_vvvvl
9872 .{ .tag = @enumFromInt(2351), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9873 // __builtin_ve_vl_vfadds_vsvl
9874 .{ .tag = @enumFromInt(2352), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9875 // __builtin_ve_vl_vfadds_vsvmvl
9876 .{ .tag = @enumFromInt(2353), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9877 // __builtin_ve_vl_vfadds_vsvvl
9878 .{ .tag = @enumFromInt(2354), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9879 // __builtin_ve_vl_vfadds_vvvl
9880 .{ .tag = @enumFromInt(2355), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9881 // __builtin_ve_vl_vfadds_vvvmvl
9882 .{ .tag = @enumFromInt(2356), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9883 // __builtin_ve_vl_vfadds_vvvvl
9884 .{ .tag = @enumFromInt(2357), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9885 // __builtin_ve_vl_vfcmpd_vsvl
9886 .{ .tag = @enumFromInt(2358), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9887 // __builtin_ve_vl_vfcmpd_vsvmvl
9888 .{ .tag = @enumFromInt(2359), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9889 // __builtin_ve_vl_vfcmpd_vsvvl
9890 .{ .tag = @enumFromInt(2360), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9891 // __builtin_ve_vl_vfcmpd_vvvl
9892 .{ .tag = @enumFromInt(2361), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9893 // __builtin_ve_vl_vfcmpd_vvvmvl
9894 .{ .tag = @enumFromInt(2362), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9895 // __builtin_ve_vl_vfcmpd_vvvvl
9896 .{ .tag = @enumFromInt(2363), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9897 // __builtin_ve_vl_vfcmps_vsvl
9898 .{ .tag = @enumFromInt(2364), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9899 // __builtin_ve_vl_vfcmps_vsvmvl
9900 .{ .tag = @enumFromInt(2365), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9901 // __builtin_ve_vl_vfcmps_vsvvl
9902 .{ .tag = @enumFromInt(2366), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9903 // __builtin_ve_vl_vfcmps_vvvl
9904 .{ .tag = @enumFromInt(2367), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9905 // __builtin_ve_vl_vfcmps_vvvmvl
9906 .{ .tag = @enumFromInt(2368), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9907 // __builtin_ve_vl_vfcmps_vvvvl
9908 .{ .tag = @enumFromInt(2369), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9909 // __builtin_ve_vl_vfdivd_vsvl
9910 .{ .tag = @enumFromInt(2370), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9911 // __builtin_ve_vl_vfdivd_vsvmvl
9912 .{ .tag = @enumFromInt(2371), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9913 // __builtin_ve_vl_vfdivd_vsvvl
9914 .{ .tag = @enumFromInt(2372), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9915 // __builtin_ve_vl_vfdivd_vvvl
9916 .{ .tag = @enumFromInt(2373), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9917 // __builtin_ve_vl_vfdivd_vvvmvl
9918 .{ .tag = @enumFromInt(2374), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9919 // __builtin_ve_vl_vfdivd_vvvvl
9920 .{ .tag = @enumFromInt(2375), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9921 // __builtin_ve_vl_vfdivs_vsvl
9922 .{ .tag = @enumFromInt(2376), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9923 // __builtin_ve_vl_vfdivs_vsvmvl
9924 .{ .tag = @enumFromInt(2377), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9925 // __builtin_ve_vl_vfdivs_vsvvl
9926 .{ .tag = @enumFromInt(2378), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9927 // __builtin_ve_vl_vfdivs_vvvl
9928 .{ .tag = @enumFromInt(2379), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9929 // __builtin_ve_vl_vfdivs_vvvmvl
9930 .{ .tag = @enumFromInt(2380), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9931 // __builtin_ve_vl_vfdivs_vvvvl
9932 .{ .tag = @enumFromInt(2381), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9933 // __builtin_ve_vl_vfmadd_vsvvl
9934 .{ .tag = @enumFromInt(2382), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9935 // __builtin_ve_vl_vfmadd_vsvvmvl
9936 .{ .tag = @enumFromInt(2383), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9937 // __builtin_ve_vl_vfmadd_vsvvvl
9938 .{ .tag = @enumFromInt(2384), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9939 // __builtin_ve_vl_vfmadd_vvsvl
9940 .{ .tag = @enumFromInt(2385), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9941 // __builtin_ve_vl_vfmadd_vvsvmvl
9942 .{ .tag = @enumFromInt(2386), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9943 // __builtin_ve_vl_vfmadd_vvsvvl
9944 .{ .tag = @enumFromInt(2387), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9945 // __builtin_ve_vl_vfmadd_vvvvl
9946 .{ .tag = @enumFromInt(2388), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9947 // __builtin_ve_vl_vfmadd_vvvvmvl
9948 .{ .tag = @enumFromInt(2389), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9949 // __builtin_ve_vl_vfmadd_vvvvvl
9950 .{ .tag = @enumFromInt(2390), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9951 // __builtin_ve_vl_vfmads_vsvvl
9952 .{ .tag = @enumFromInt(2391), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9953 // __builtin_ve_vl_vfmads_vsvvmvl
9954 .{ .tag = @enumFromInt(2392), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9955 // __builtin_ve_vl_vfmads_vsvvvl
9956 .{ .tag = @enumFromInt(2393), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9957 // __builtin_ve_vl_vfmads_vvsvl
9958 .{ .tag = @enumFromInt(2394), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9959 // __builtin_ve_vl_vfmads_vvsvmvl
9960 .{ .tag = @enumFromInt(2395), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9961 // __builtin_ve_vl_vfmads_vvsvvl
9962 .{ .tag = @enumFromInt(2396), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9963 // __builtin_ve_vl_vfmads_vvvvl
9964 .{ .tag = @enumFromInt(2397), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9965 // __builtin_ve_vl_vfmads_vvvvmvl
9966 .{ .tag = @enumFromInt(2398), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9967 // __builtin_ve_vl_vfmads_vvvvvl
9968 .{ .tag = @enumFromInt(2399), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9969 // __builtin_ve_vl_vfmaxd_vsvl
9970 .{ .tag = @enumFromInt(2400), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9971 // __builtin_ve_vl_vfmaxd_vsvmvl
9972 .{ .tag = @enumFromInt(2401), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9973 // __builtin_ve_vl_vfmaxd_vsvvl
9974 .{ .tag = @enumFromInt(2402), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9975 // __builtin_ve_vl_vfmaxd_vvvl
9976 .{ .tag = @enumFromInt(2403), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9977 // __builtin_ve_vl_vfmaxd_vvvmvl
9978 .{ .tag = @enumFromInt(2404), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9979 // __builtin_ve_vl_vfmaxd_vvvvl
9980 .{ .tag = @enumFromInt(2405), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9981 // __builtin_ve_vl_vfmaxs_vsvl
9982 .{ .tag = @enumFromInt(2406), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9983 // __builtin_ve_vl_vfmaxs_vsvmvl
9984 .{ .tag = @enumFromInt(2407), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9985 // __builtin_ve_vl_vfmaxs_vsvvl
9986 .{ .tag = @enumFromInt(2408), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9987 // __builtin_ve_vl_vfmaxs_vvvl
9988 .{ .tag = @enumFromInt(2409), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9989 // __builtin_ve_vl_vfmaxs_vvvmvl
9990 .{ .tag = @enumFromInt(2410), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9991 // __builtin_ve_vl_vfmaxs_vvvvl
9992 .{ .tag = @enumFromInt(2411), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9993 // __builtin_ve_vl_vfmind_vsvl
9994 .{ .tag = @enumFromInt(2412), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9995 // __builtin_ve_vl_vfmind_vsvmvl
9996 .{ .tag = @enumFromInt(2413), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9997 // __builtin_ve_vl_vfmind_vsvvl
9998 .{ .tag = @enumFromInt(2414), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
9999 // __builtin_ve_vl_vfmind_vvvl
10000 .{ .tag = @enumFromInt(2415), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10001 // __builtin_ve_vl_vfmind_vvvmvl
10002 .{ .tag = @enumFromInt(2416), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10003 // __builtin_ve_vl_vfmind_vvvvl
10004 .{ .tag = @enumFromInt(2417), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10005 // __builtin_ve_vl_vfmins_vsvl
10006 .{ .tag = @enumFromInt(2418), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10007 // __builtin_ve_vl_vfmins_vsvmvl
10008 .{ .tag = @enumFromInt(2419), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10009 // __builtin_ve_vl_vfmins_vsvvl
10010 .{ .tag = @enumFromInt(2420), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10011 // __builtin_ve_vl_vfmins_vvvl
10012 .{ .tag = @enumFromInt(2421), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10013 // __builtin_ve_vl_vfmins_vvvmvl
10014 .{ .tag = @enumFromInt(2422), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10015 // __builtin_ve_vl_vfmins_vvvvl
10016 .{ .tag = @enumFromInt(2423), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10017 // __builtin_ve_vl_vfmkdeq_mvl
10018 .{ .tag = @enumFromInt(2424), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10019 // __builtin_ve_vl_vfmkdeq_mvml
10020 .{ .tag = @enumFromInt(2425), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10021 // __builtin_ve_vl_vfmkdeqnan_mvl
10022 .{ .tag = @enumFromInt(2426), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10023 // __builtin_ve_vl_vfmkdeqnan_mvml
10024 .{ .tag = @enumFromInt(2427), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10025 // __builtin_ve_vl_vfmkdge_mvl
10026 .{ .tag = @enumFromInt(2428), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10027 // __builtin_ve_vl_vfmkdge_mvml
10028 .{ .tag = @enumFromInt(2429), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10029 // __builtin_ve_vl_vfmkdgenan_mvl
10030 .{ .tag = @enumFromInt(2430), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10031 // __builtin_ve_vl_vfmkdgenan_mvml
10032 .{ .tag = @enumFromInt(2431), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10033 // __builtin_ve_vl_vfmkdgt_mvl
10034 .{ .tag = @enumFromInt(2432), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10035 // __builtin_ve_vl_vfmkdgt_mvml
10036 .{ .tag = @enumFromInt(2433), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10037 // __builtin_ve_vl_vfmkdgtnan_mvl
10038 .{ .tag = @enumFromInt(2434), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10039 // __builtin_ve_vl_vfmkdgtnan_mvml
10040 .{ .tag = @enumFromInt(2435), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10041 // __builtin_ve_vl_vfmkdle_mvl
10042 .{ .tag = @enumFromInt(2436), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10043 // __builtin_ve_vl_vfmkdle_mvml
10044 .{ .tag = @enumFromInt(2437), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10045 // __builtin_ve_vl_vfmkdlenan_mvl
10046 .{ .tag = @enumFromInt(2438), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10047 // __builtin_ve_vl_vfmkdlenan_mvml
10048 .{ .tag = @enumFromInt(2439), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10049 // __builtin_ve_vl_vfmkdlt_mvl
10050 .{ .tag = @enumFromInt(2440), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10051 // __builtin_ve_vl_vfmkdlt_mvml
10052 .{ .tag = @enumFromInt(2441), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10053 // __builtin_ve_vl_vfmkdltnan_mvl
10054 .{ .tag = @enumFromInt(2442), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10055 // __builtin_ve_vl_vfmkdltnan_mvml
10056 .{ .tag = @enumFromInt(2443), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10057 // __builtin_ve_vl_vfmkdnan_mvl
10058 .{ .tag = @enumFromInt(2444), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10059 // __builtin_ve_vl_vfmkdnan_mvml
10060 .{ .tag = @enumFromInt(2445), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10061 // __builtin_ve_vl_vfmkdne_mvl
10062 .{ .tag = @enumFromInt(2446), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10063 // __builtin_ve_vl_vfmkdne_mvml
10064 .{ .tag = @enumFromInt(2447), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10065 // __builtin_ve_vl_vfmkdnenan_mvl
10066 .{ .tag = @enumFromInt(2448), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10067 // __builtin_ve_vl_vfmkdnenan_mvml
10068 .{ .tag = @enumFromInt(2449), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10069 // __builtin_ve_vl_vfmkdnum_mvl
10070 .{ .tag = @enumFromInt(2450), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10071 // __builtin_ve_vl_vfmkdnum_mvml
10072 .{ .tag = @enumFromInt(2451), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10073 // __builtin_ve_vl_vfmklaf_ml
10074 .{ .tag = @enumFromInt(2452), .properties = .{ .param_str = "V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10075 // __builtin_ve_vl_vfmklat_ml
10076 .{ .tag = @enumFromInt(2453), .properties = .{ .param_str = "V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10077 // __builtin_ve_vl_vfmkleq_mvl
10078 .{ .tag = @enumFromInt(2454), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10079 // __builtin_ve_vl_vfmkleq_mvml
10080 .{ .tag = @enumFromInt(2455), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10081 // __builtin_ve_vl_vfmkleqnan_mvl
10082 .{ .tag = @enumFromInt(2456), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10083 // __builtin_ve_vl_vfmkleqnan_mvml
10084 .{ .tag = @enumFromInt(2457), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10085 // __builtin_ve_vl_vfmklge_mvl
10086 .{ .tag = @enumFromInt(2458), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10087 // __builtin_ve_vl_vfmklge_mvml
10088 .{ .tag = @enumFromInt(2459), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10089 // __builtin_ve_vl_vfmklgenan_mvl
10090 .{ .tag = @enumFromInt(2460), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10091 // __builtin_ve_vl_vfmklgenan_mvml
10092 .{ .tag = @enumFromInt(2461), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10093 // __builtin_ve_vl_vfmklgt_mvl
10094 .{ .tag = @enumFromInt(2462), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10095 // __builtin_ve_vl_vfmklgt_mvml
10096 .{ .tag = @enumFromInt(2463), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10097 // __builtin_ve_vl_vfmklgtnan_mvl
10098 .{ .tag = @enumFromInt(2464), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10099 // __builtin_ve_vl_vfmklgtnan_mvml
10100 .{ .tag = @enumFromInt(2465), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10101 // __builtin_ve_vl_vfmklle_mvl
10102 .{ .tag = @enumFromInt(2466), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10103 // __builtin_ve_vl_vfmklle_mvml
10104 .{ .tag = @enumFromInt(2467), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10105 // __builtin_ve_vl_vfmkllenan_mvl
10106 .{ .tag = @enumFromInt(2468), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10107 // __builtin_ve_vl_vfmkllenan_mvml
10108 .{ .tag = @enumFromInt(2469), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10109 // __builtin_ve_vl_vfmkllt_mvl
10110 .{ .tag = @enumFromInt(2470), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10111 // __builtin_ve_vl_vfmkllt_mvml
10112 .{ .tag = @enumFromInt(2471), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10113 // __builtin_ve_vl_vfmklltnan_mvl
10114 .{ .tag = @enumFromInt(2472), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10115 // __builtin_ve_vl_vfmklltnan_mvml
10116 .{ .tag = @enumFromInt(2473), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10117 // __builtin_ve_vl_vfmklnan_mvl
10118 .{ .tag = @enumFromInt(2474), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10119 // __builtin_ve_vl_vfmklnan_mvml
10120 .{ .tag = @enumFromInt(2475), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10121 // __builtin_ve_vl_vfmklne_mvl
10122 .{ .tag = @enumFromInt(2476), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10123 // __builtin_ve_vl_vfmklne_mvml
10124 .{ .tag = @enumFromInt(2477), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10125 // __builtin_ve_vl_vfmklnenan_mvl
10126 .{ .tag = @enumFromInt(2478), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10127 // __builtin_ve_vl_vfmklnenan_mvml
10128 .{ .tag = @enumFromInt(2479), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10129 // __builtin_ve_vl_vfmklnum_mvl
10130 .{ .tag = @enumFromInt(2480), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10131 // __builtin_ve_vl_vfmklnum_mvml
10132 .{ .tag = @enumFromInt(2481), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10133 // __builtin_ve_vl_vfmkseq_mvl
10134 .{ .tag = @enumFromInt(2482), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10135 // __builtin_ve_vl_vfmkseq_mvml
10136 .{ .tag = @enumFromInt(2483), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10137 // __builtin_ve_vl_vfmkseqnan_mvl
10138 .{ .tag = @enumFromInt(2484), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10139 // __builtin_ve_vl_vfmkseqnan_mvml
10140 .{ .tag = @enumFromInt(2485), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10141 // __builtin_ve_vl_vfmksge_mvl
10142 .{ .tag = @enumFromInt(2486), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10143 // __builtin_ve_vl_vfmksge_mvml
10144 .{ .tag = @enumFromInt(2487), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10145 // __builtin_ve_vl_vfmksgenan_mvl
10146 .{ .tag = @enumFromInt(2488), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10147 // __builtin_ve_vl_vfmksgenan_mvml
10148 .{ .tag = @enumFromInt(2489), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10149 // __builtin_ve_vl_vfmksgt_mvl
10150 .{ .tag = @enumFromInt(2490), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10151 // __builtin_ve_vl_vfmksgt_mvml
10152 .{ .tag = @enumFromInt(2491), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10153 // __builtin_ve_vl_vfmksgtnan_mvl
10154 .{ .tag = @enumFromInt(2492), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10155 // __builtin_ve_vl_vfmksgtnan_mvml
10156 .{ .tag = @enumFromInt(2493), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10157 // __builtin_ve_vl_vfmksle_mvl
10158 .{ .tag = @enumFromInt(2494), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10159 // __builtin_ve_vl_vfmksle_mvml
10160 .{ .tag = @enumFromInt(2495), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10161 // __builtin_ve_vl_vfmkslenan_mvl
10162 .{ .tag = @enumFromInt(2496), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10163 // __builtin_ve_vl_vfmkslenan_mvml
10164 .{ .tag = @enumFromInt(2497), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10165 // __builtin_ve_vl_vfmkslt_mvl
10166 .{ .tag = @enumFromInt(2498), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10167 // __builtin_ve_vl_vfmkslt_mvml
10168 .{ .tag = @enumFromInt(2499), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10169 // __builtin_ve_vl_vfmksltnan_mvl
10170 .{ .tag = @enumFromInt(2500), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10171 // __builtin_ve_vl_vfmksltnan_mvml
10172 .{ .tag = @enumFromInt(2501), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10173 // __builtin_ve_vl_vfmksnan_mvl
10174 .{ .tag = @enumFromInt(2502), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10175 // __builtin_ve_vl_vfmksnan_mvml
10176 .{ .tag = @enumFromInt(2503), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10177 // __builtin_ve_vl_vfmksne_mvl
10178 .{ .tag = @enumFromInt(2504), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10179 // __builtin_ve_vl_vfmksne_mvml
10180 .{ .tag = @enumFromInt(2505), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10181 // __builtin_ve_vl_vfmksnenan_mvl
10182 .{ .tag = @enumFromInt(2506), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10183 // __builtin_ve_vl_vfmksnenan_mvml
10184 .{ .tag = @enumFromInt(2507), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10185 // __builtin_ve_vl_vfmksnum_mvl
10186 .{ .tag = @enumFromInt(2508), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10187 // __builtin_ve_vl_vfmksnum_mvml
10188 .{ .tag = @enumFromInt(2509), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10189 // __builtin_ve_vl_vfmkweq_mvl
10190 .{ .tag = @enumFromInt(2510), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10191 // __builtin_ve_vl_vfmkweq_mvml
10192 .{ .tag = @enumFromInt(2511), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10193 // __builtin_ve_vl_vfmkweqnan_mvl
10194 .{ .tag = @enumFromInt(2512), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10195 // __builtin_ve_vl_vfmkweqnan_mvml
10196 .{ .tag = @enumFromInt(2513), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10197 // __builtin_ve_vl_vfmkwge_mvl
10198 .{ .tag = @enumFromInt(2514), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10199 // __builtin_ve_vl_vfmkwge_mvml
10200 .{ .tag = @enumFromInt(2515), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10201 // __builtin_ve_vl_vfmkwgenan_mvl
10202 .{ .tag = @enumFromInt(2516), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10203 // __builtin_ve_vl_vfmkwgenan_mvml
10204 .{ .tag = @enumFromInt(2517), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10205 // __builtin_ve_vl_vfmkwgt_mvl
10206 .{ .tag = @enumFromInt(2518), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10207 // __builtin_ve_vl_vfmkwgt_mvml
10208 .{ .tag = @enumFromInt(2519), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10209 // __builtin_ve_vl_vfmkwgtnan_mvl
10210 .{ .tag = @enumFromInt(2520), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10211 // __builtin_ve_vl_vfmkwgtnan_mvml
10212 .{ .tag = @enumFromInt(2521), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10213 // __builtin_ve_vl_vfmkwle_mvl
10214 .{ .tag = @enumFromInt(2522), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10215 // __builtin_ve_vl_vfmkwle_mvml
10216 .{ .tag = @enumFromInt(2523), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10217 // __builtin_ve_vl_vfmkwlenan_mvl
10218 .{ .tag = @enumFromInt(2524), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10219 // __builtin_ve_vl_vfmkwlenan_mvml
10220 .{ .tag = @enumFromInt(2525), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10221 // __builtin_ve_vl_vfmkwlt_mvl
10222 .{ .tag = @enumFromInt(2526), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10223 // __builtin_ve_vl_vfmkwlt_mvml
10224 .{ .tag = @enumFromInt(2527), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10225 // __builtin_ve_vl_vfmkwltnan_mvl
10226 .{ .tag = @enumFromInt(2528), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10227 // __builtin_ve_vl_vfmkwltnan_mvml
10228 .{ .tag = @enumFromInt(2529), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10229 // __builtin_ve_vl_vfmkwnan_mvl
10230 .{ .tag = @enumFromInt(2530), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10231 // __builtin_ve_vl_vfmkwnan_mvml
10232 .{ .tag = @enumFromInt(2531), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10233 // __builtin_ve_vl_vfmkwne_mvl
10234 .{ .tag = @enumFromInt(2532), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10235 // __builtin_ve_vl_vfmkwne_mvml
10236 .{ .tag = @enumFromInt(2533), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10237 // __builtin_ve_vl_vfmkwnenan_mvl
10238 .{ .tag = @enumFromInt(2534), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10239 // __builtin_ve_vl_vfmkwnenan_mvml
10240 .{ .tag = @enumFromInt(2535), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10241 // __builtin_ve_vl_vfmkwnum_mvl
10242 .{ .tag = @enumFromInt(2536), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10243 // __builtin_ve_vl_vfmkwnum_mvml
10244 .{ .tag = @enumFromInt(2537), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10245 // __builtin_ve_vl_vfmsbd_vsvvl
10246 .{ .tag = @enumFromInt(2538), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10247 // __builtin_ve_vl_vfmsbd_vsvvmvl
10248 .{ .tag = @enumFromInt(2539), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10249 // __builtin_ve_vl_vfmsbd_vsvvvl
10250 .{ .tag = @enumFromInt(2540), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10251 // __builtin_ve_vl_vfmsbd_vvsvl
10252 .{ .tag = @enumFromInt(2541), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10253 // __builtin_ve_vl_vfmsbd_vvsvmvl
10254 .{ .tag = @enumFromInt(2542), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10255 // __builtin_ve_vl_vfmsbd_vvsvvl
10256 .{ .tag = @enumFromInt(2543), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10257 // __builtin_ve_vl_vfmsbd_vvvvl
10258 .{ .tag = @enumFromInt(2544), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10259 // __builtin_ve_vl_vfmsbd_vvvvmvl
10260 .{ .tag = @enumFromInt(2545), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10261 // __builtin_ve_vl_vfmsbd_vvvvvl
10262 .{ .tag = @enumFromInt(2546), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10263 // __builtin_ve_vl_vfmsbs_vsvvl
10264 .{ .tag = @enumFromInt(2547), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10265 // __builtin_ve_vl_vfmsbs_vsvvmvl
10266 .{ .tag = @enumFromInt(2548), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10267 // __builtin_ve_vl_vfmsbs_vsvvvl
10268 .{ .tag = @enumFromInt(2549), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10269 // __builtin_ve_vl_vfmsbs_vvsvl
10270 .{ .tag = @enumFromInt(2550), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10271 // __builtin_ve_vl_vfmsbs_vvsvmvl
10272 .{ .tag = @enumFromInt(2551), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10273 // __builtin_ve_vl_vfmsbs_vvsvvl
10274 .{ .tag = @enumFromInt(2552), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10275 // __builtin_ve_vl_vfmsbs_vvvvl
10276 .{ .tag = @enumFromInt(2553), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10277 // __builtin_ve_vl_vfmsbs_vvvvmvl
10278 .{ .tag = @enumFromInt(2554), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10279 // __builtin_ve_vl_vfmsbs_vvvvvl
10280 .{ .tag = @enumFromInt(2555), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10281 // __builtin_ve_vl_vfmuld_vsvl
10282 .{ .tag = @enumFromInt(2556), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10283 // __builtin_ve_vl_vfmuld_vsvmvl
10284 .{ .tag = @enumFromInt(2557), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10285 // __builtin_ve_vl_vfmuld_vsvvl
10286 .{ .tag = @enumFromInt(2558), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10287 // __builtin_ve_vl_vfmuld_vvvl
10288 .{ .tag = @enumFromInt(2559), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10289 // __builtin_ve_vl_vfmuld_vvvmvl
10290 .{ .tag = @enumFromInt(2560), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10291 // __builtin_ve_vl_vfmuld_vvvvl
10292 .{ .tag = @enumFromInt(2561), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10293 // __builtin_ve_vl_vfmuls_vsvl
10294 .{ .tag = @enumFromInt(2562), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10295 // __builtin_ve_vl_vfmuls_vsvmvl
10296 .{ .tag = @enumFromInt(2563), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10297 // __builtin_ve_vl_vfmuls_vsvvl
10298 .{ .tag = @enumFromInt(2564), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10299 // __builtin_ve_vl_vfmuls_vvvl
10300 .{ .tag = @enumFromInt(2565), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10301 // __builtin_ve_vl_vfmuls_vvvmvl
10302 .{ .tag = @enumFromInt(2566), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10303 // __builtin_ve_vl_vfmuls_vvvvl
10304 .{ .tag = @enumFromInt(2567), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10305 // __builtin_ve_vl_vfnmadd_vsvvl
10306 .{ .tag = @enumFromInt(2568), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10307 // __builtin_ve_vl_vfnmadd_vsvvmvl
10308 .{ .tag = @enumFromInt(2569), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10309 // __builtin_ve_vl_vfnmadd_vsvvvl
10310 .{ .tag = @enumFromInt(2570), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10311 // __builtin_ve_vl_vfnmadd_vvsvl
10312 .{ .tag = @enumFromInt(2571), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10313 // __builtin_ve_vl_vfnmadd_vvsvmvl
10314 .{ .tag = @enumFromInt(2572), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10315 // __builtin_ve_vl_vfnmadd_vvsvvl
10316 .{ .tag = @enumFromInt(2573), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10317 // __builtin_ve_vl_vfnmadd_vvvvl
10318 .{ .tag = @enumFromInt(2574), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10319 // __builtin_ve_vl_vfnmadd_vvvvmvl
10320 .{ .tag = @enumFromInt(2575), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10321 // __builtin_ve_vl_vfnmadd_vvvvvl
10322 .{ .tag = @enumFromInt(2576), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10323 // __builtin_ve_vl_vfnmads_vsvvl
10324 .{ .tag = @enumFromInt(2577), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10325 // __builtin_ve_vl_vfnmads_vsvvmvl
10326 .{ .tag = @enumFromInt(2578), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10327 // __builtin_ve_vl_vfnmads_vsvvvl
10328 .{ .tag = @enumFromInt(2579), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10329 // __builtin_ve_vl_vfnmads_vvsvl
10330 .{ .tag = @enumFromInt(2580), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10331 // __builtin_ve_vl_vfnmads_vvsvmvl
10332 .{ .tag = @enumFromInt(2581), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10333 // __builtin_ve_vl_vfnmads_vvsvvl
10334 .{ .tag = @enumFromInt(2582), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10335 // __builtin_ve_vl_vfnmads_vvvvl
10336 .{ .tag = @enumFromInt(2583), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10337 // __builtin_ve_vl_vfnmads_vvvvmvl
10338 .{ .tag = @enumFromInt(2584), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10339 // __builtin_ve_vl_vfnmads_vvvvvl
10340 .{ .tag = @enumFromInt(2585), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10341 // __builtin_ve_vl_vfnmsbd_vsvvl
10342 .{ .tag = @enumFromInt(2586), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10343 // __builtin_ve_vl_vfnmsbd_vsvvmvl
10344 .{ .tag = @enumFromInt(2587), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10345 // __builtin_ve_vl_vfnmsbd_vsvvvl
10346 .{ .tag = @enumFromInt(2588), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10347 // __builtin_ve_vl_vfnmsbd_vvsvl
10348 .{ .tag = @enumFromInt(2589), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10349 // __builtin_ve_vl_vfnmsbd_vvsvmvl
10350 .{ .tag = @enumFromInt(2590), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10351 // __builtin_ve_vl_vfnmsbd_vvsvvl
10352 .{ .tag = @enumFromInt(2591), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10353 // __builtin_ve_vl_vfnmsbd_vvvvl
10354 .{ .tag = @enumFromInt(2592), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10355 // __builtin_ve_vl_vfnmsbd_vvvvmvl
10356 .{ .tag = @enumFromInt(2593), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10357 // __builtin_ve_vl_vfnmsbd_vvvvvl
10358 .{ .tag = @enumFromInt(2594), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10359 // __builtin_ve_vl_vfnmsbs_vsvvl
10360 .{ .tag = @enumFromInt(2595), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10361 // __builtin_ve_vl_vfnmsbs_vsvvmvl
10362 .{ .tag = @enumFromInt(2596), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10363 // __builtin_ve_vl_vfnmsbs_vsvvvl
10364 .{ .tag = @enumFromInt(2597), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10365 // __builtin_ve_vl_vfnmsbs_vvsvl
10366 .{ .tag = @enumFromInt(2598), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10367 // __builtin_ve_vl_vfnmsbs_vvsvmvl
10368 .{ .tag = @enumFromInt(2599), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10369 // __builtin_ve_vl_vfnmsbs_vvsvvl
10370 .{ .tag = @enumFromInt(2600), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10371 // __builtin_ve_vl_vfnmsbs_vvvvl
10372 .{ .tag = @enumFromInt(2601), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10373 // __builtin_ve_vl_vfnmsbs_vvvvmvl
10374 .{ .tag = @enumFromInt(2602), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10375 // __builtin_ve_vl_vfnmsbs_vvvvvl
10376 .{ .tag = @enumFromInt(2603), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10377 // __builtin_ve_vl_vfrmaxdfst_vvl
10378 .{ .tag = @enumFromInt(2604), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10379 // __builtin_ve_vl_vfrmaxdfst_vvvl
10380 .{ .tag = @enumFromInt(2605), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10381 // __builtin_ve_vl_vfrmaxdlst_vvl
10382 .{ .tag = @enumFromInt(2606), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10383 // __builtin_ve_vl_vfrmaxdlst_vvvl
10384 .{ .tag = @enumFromInt(2607), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10385 // __builtin_ve_vl_vfrmaxsfst_vvl
10386 .{ .tag = @enumFromInt(2608), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10387 // __builtin_ve_vl_vfrmaxsfst_vvvl
10388 .{ .tag = @enumFromInt(2609), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10389 // __builtin_ve_vl_vfrmaxslst_vvl
10390 .{ .tag = @enumFromInt(2610), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10391 // __builtin_ve_vl_vfrmaxslst_vvvl
10392 .{ .tag = @enumFromInt(2611), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10393 // __builtin_ve_vl_vfrmindfst_vvl
10394 .{ .tag = @enumFromInt(2612), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10395 // __builtin_ve_vl_vfrmindfst_vvvl
10396 .{ .tag = @enumFromInt(2613), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10397 // __builtin_ve_vl_vfrmindlst_vvl
10398 .{ .tag = @enumFromInt(2614), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10399 // __builtin_ve_vl_vfrmindlst_vvvl
10400 .{ .tag = @enumFromInt(2615), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10401 // __builtin_ve_vl_vfrminsfst_vvl
10402 .{ .tag = @enumFromInt(2616), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10403 // __builtin_ve_vl_vfrminsfst_vvvl
10404 .{ .tag = @enumFromInt(2617), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10405 // __builtin_ve_vl_vfrminslst_vvl
10406 .{ .tag = @enumFromInt(2618), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10407 // __builtin_ve_vl_vfrminslst_vvvl
10408 .{ .tag = @enumFromInt(2619), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10409 // __builtin_ve_vl_vfsqrtd_vvl
10410 .{ .tag = @enumFromInt(2620), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10411 // __builtin_ve_vl_vfsqrtd_vvvl
10412 .{ .tag = @enumFromInt(2621), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10413 // __builtin_ve_vl_vfsqrts_vvl
10414 .{ .tag = @enumFromInt(2622), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10415 // __builtin_ve_vl_vfsqrts_vvvl
10416 .{ .tag = @enumFromInt(2623), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10417 // __builtin_ve_vl_vfsubd_vsvl
10418 .{ .tag = @enumFromInt(2624), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10419 // __builtin_ve_vl_vfsubd_vsvmvl
10420 .{ .tag = @enumFromInt(2625), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10421 // __builtin_ve_vl_vfsubd_vsvvl
10422 .{ .tag = @enumFromInt(2626), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10423 // __builtin_ve_vl_vfsubd_vvvl
10424 .{ .tag = @enumFromInt(2627), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10425 // __builtin_ve_vl_vfsubd_vvvmvl
10426 .{ .tag = @enumFromInt(2628), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10427 // __builtin_ve_vl_vfsubd_vvvvl
10428 .{ .tag = @enumFromInt(2629), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10429 // __builtin_ve_vl_vfsubs_vsvl
10430 .{ .tag = @enumFromInt(2630), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10431 // __builtin_ve_vl_vfsubs_vsvmvl
10432 .{ .tag = @enumFromInt(2631), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10433 // __builtin_ve_vl_vfsubs_vsvvl
10434 .{ .tag = @enumFromInt(2632), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10435 // __builtin_ve_vl_vfsubs_vvvl
10436 .{ .tag = @enumFromInt(2633), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10437 // __builtin_ve_vl_vfsubs_vvvmvl
10438 .{ .tag = @enumFromInt(2634), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10439 // __builtin_ve_vl_vfsubs_vvvvl
10440 .{ .tag = @enumFromInt(2635), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10441 // __builtin_ve_vl_vfsumd_vvl
10442 .{ .tag = @enumFromInt(2636), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10443 // __builtin_ve_vl_vfsumd_vvml
10444 .{ .tag = @enumFromInt(2637), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10445 // __builtin_ve_vl_vfsums_vvl
10446 .{ .tag = @enumFromInt(2638), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10447 // __builtin_ve_vl_vfsums_vvml
10448 .{ .tag = @enumFromInt(2639), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10449 // __builtin_ve_vl_vgt_vvssl
10450 .{ .tag = @enumFromInt(2640), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10451 // __builtin_ve_vl_vgt_vvssml
10452 .{ .tag = @enumFromInt(2641), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10453 // __builtin_ve_vl_vgt_vvssmvl
10454 .{ .tag = @enumFromInt(2642), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10455 // __builtin_ve_vl_vgt_vvssvl
10456 .{ .tag = @enumFromInt(2643), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10457 // __builtin_ve_vl_vgtlsx_vvssl
10458 .{ .tag = @enumFromInt(2644), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10459 // __builtin_ve_vl_vgtlsx_vvssml
10460 .{ .tag = @enumFromInt(2645), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10461 // __builtin_ve_vl_vgtlsx_vvssmvl
10462 .{ .tag = @enumFromInt(2646), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10463 // __builtin_ve_vl_vgtlsx_vvssvl
10464 .{ .tag = @enumFromInt(2647), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10465 // __builtin_ve_vl_vgtlsxnc_vvssl
10466 .{ .tag = @enumFromInt(2648), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10467 // __builtin_ve_vl_vgtlsxnc_vvssml
10468 .{ .tag = @enumFromInt(2649), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10469 // __builtin_ve_vl_vgtlsxnc_vvssmvl
10470 .{ .tag = @enumFromInt(2650), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10471 // __builtin_ve_vl_vgtlsxnc_vvssvl
10472 .{ .tag = @enumFromInt(2651), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10473 // __builtin_ve_vl_vgtlzx_vvssl
10474 .{ .tag = @enumFromInt(2652), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10475 // __builtin_ve_vl_vgtlzx_vvssml
10476 .{ .tag = @enumFromInt(2653), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10477 // __builtin_ve_vl_vgtlzx_vvssmvl
10478 .{ .tag = @enumFromInt(2654), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10479 // __builtin_ve_vl_vgtlzx_vvssvl
10480 .{ .tag = @enumFromInt(2655), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10481 // __builtin_ve_vl_vgtlzxnc_vvssl
10482 .{ .tag = @enumFromInt(2656), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10483 // __builtin_ve_vl_vgtlzxnc_vvssml
10484 .{ .tag = @enumFromInt(2657), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10485 // __builtin_ve_vl_vgtlzxnc_vvssmvl
10486 .{ .tag = @enumFromInt(2658), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10487 // __builtin_ve_vl_vgtlzxnc_vvssvl
10488 .{ .tag = @enumFromInt(2659), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10489 // __builtin_ve_vl_vgtnc_vvssl
10490 .{ .tag = @enumFromInt(2660), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10491 // __builtin_ve_vl_vgtnc_vvssml
10492 .{ .tag = @enumFromInt(2661), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10493 // __builtin_ve_vl_vgtnc_vvssmvl
10494 .{ .tag = @enumFromInt(2662), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10495 // __builtin_ve_vl_vgtnc_vvssvl
10496 .{ .tag = @enumFromInt(2663), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10497 // __builtin_ve_vl_vgtu_vvssl
10498 .{ .tag = @enumFromInt(2664), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10499 // __builtin_ve_vl_vgtu_vvssml
10500 .{ .tag = @enumFromInt(2665), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10501 // __builtin_ve_vl_vgtu_vvssmvl
10502 .{ .tag = @enumFromInt(2666), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10503 // __builtin_ve_vl_vgtu_vvssvl
10504 .{ .tag = @enumFromInt(2667), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10505 // __builtin_ve_vl_vgtunc_vvssl
10506 .{ .tag = @enumFromInt(2668), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10507 // __builtin_ve_vl_vgtunc_vvssml
10508 .{ .tag = @enumFromInt(2669), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10509 // __builtin_ve_vl_vgtunc_vvssmvl
10510 .{ .tag = @enumFromInt(2670), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10511 // __builtin_ve_vl_vgtunc_vvssvl
10512 .{ .tag = @enumFromInt(2671), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10513 // __builtin_ve_vl_vld2d_vssl
10514 .{ .tag = @enumFromInt(2672), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10515 // __builtin_ve_vl_vld2d_vssvl
10516 .{ .tag = @enumFromInt(2673), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10517 // __builtin_ve_vl_vld2dnc_vssl
10518 .{ .tag = @enumFromInt(2674), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10519 // __builtin_ve_vl_vld2dnc_vssvl
10520 .{ .tag = @enumFromInt(2675), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10521 // __builtin_ve_vl_vld_vssl
10522 .{ .tag = @enumFromInt(2676), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10523 // __builtin_ve_vl_vld_vssvl
10524 .{ .tag = @enumFromInt(2677), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10525 // __builtin_ve_vl_vldl2dsx_vssl
10526 .{ .tag = @enumFromInt(2678), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10527 // __builtin_ve_vl_vldl2dsx_vssvl
10528 .{ .tag = @enumFromInt(2679), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10529 // __builtin_ve_vl_vldl2dsxnc_vssl
10530 .{ .tag = @enumFromInt(2680), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10531 // __builtin_ve_vl_vldl2dsxnc_vssvl
10532 .{ .tag = @enumFromInt(2681), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10533 // __builtin_ve_vl_vldl2dzx_vssl
10534 .{ .tag = @enumFromInt(2682), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10535 // __builtin_ve_vl_vldl2dzx_vssvl
10536 .{ .tag = @enumFromInt(2683), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10537 // __builtin_ve_vl_vldl2dzxnc_vssl
10538 .{ .tag = @enumFromInt(2684), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10539 // __builtin_ve_vl_vldl2dzxnc_vssvl
10540 .{ .tag = @enumFromInt(2685), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10541 // __builtin_ve_vl_vldlsx_vssl
10542 .{ .tag = @enumFromInt(2686), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10543 // __builtin_ve_vl_vldlsx_vssvl
10544 .{ .tag = @enumFromInt(2687), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10545 // __builtin_ve_vl_vldlsxnc_vssl
10546 .{ .tag = @enumFromInt(2688), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10547 // __builtin_ve_vl_vldlsxnc_vssvl
10548 .{ .tag = @enumFromInt(2689), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10549 // __builtin_ve_vl_vldlzx_vssl
10550 .{ .tag = @enumFromInt(2690), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10551 // __builtin_ve_vl_vldlzx_vssvl
10552 .{ .tag = @enumFromInt(2691), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10553 // __builtin_ve_vl_vldlzxnc_vssl
10554 .{ .tag = @enumFromInt(2692), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10555 // __builtin_ve_vl_vldlzxnc_vssvl
10556 .{ .tag = @enumFromInt(2693), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10557 // __builtin_ve_vl_vldnc_vssl
10558 .{ .tag = @enumFromInt(2694), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10559 // __builtin_ve_vl_vldnc_vssvl
10560 .{ .tag = @enumFromInt(2695), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10561 // __builtin_ve_vl_vldu2d_vssl
10562 .{ .tag = @enumFromInt(2696), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10563 // __builtin_ve_vl_vldu2d_vssvl
10564 .{ .tag = @enumFromInt(2697), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10565 // __builtin_ve_vl_vldu2dnc_vssl
10566 .{ .tag = @enumFromInt(2698), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10567 // __builtin_ve_vl_vldu2dnc_vssvl
10568 .{ .tag = @enumFromInt(2699), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10569 // __builtin_ve_vl_vldu_vssl
10570 .{ .tag = @enumFromInt(2700), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10571 // __builtin_ve_vl_vldu_vssvl
10572 .{ .tag = @enumFromInt(2701), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10573 // __builtin_ve_vl_vldunc_vssl
10574 .{ .tag = @enumFromInt(2702), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
10575 // __builtin_ve_vl_vldunc_vssvl
10576 .{ .tag = @enumFromInt(2703), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10577 // __builtin_ve_vl_vldz_vvl
10578 .{ .tag = @enumFromInt(2704), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10579 // __builtin_ve_vl_vldz_vvmvl
10580 .{ .tag = @enumFromInt(2705), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10581 // __builtin_ve_vl_vldz_vvvl
10582 .{ .tag = @enumFromInt(2706), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10583 // __builtin_ve_vl_vmaxsl_vsvl
10584 .{ .tag = @enumFromInt(2707), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10585 // __builtin_ve_vl_vmaxsl_vsvmvl
10586 .{ .tag = @enumFromInt(2708), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10587 // __builtin_ve_vl_vmaxsl_vsvvl
10588 .{ .tag = @enumFromInt(2709), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10589 // __builtin_ve_vl_vmaxsl_vvvl
10590 .{ .tag = @enumFromInt(2710), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10591 // __builtin_ve_vl_vmaxsl_vvvmvl
10592 .{ .tag = @enumFromInt(2711), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10593 // __builtin_ve_vl_vmaxsl_vvvvl
10594 .{ .tag = @enumFromInt(2712), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10595 // __builtin_ve_vl_vmaxswsx_vsvl
10596 .{ .tag = @enumFromInt(2713), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10597 // __builtin_ve_vl_vmaxswsx_vsvmvl
10598 .{ .tag = @enumFromInt(2714), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10599 // __builtin_ve_vl_vmaxswsx_vsvvl
10600 .{ .tag = @enumFromInt(2715), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10601 // __builtin_ve_vl_vmaxswsx_vvvl
10602 .{ .tag = @enumFromInt(2716), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10603 // __builtin_ve_vl_vmaxswsx_vvvmvl
10604 .{ .tag = @enumFromInt(2717), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10605 // __builtin_ve_vl_vmaxswsx_vvvvl
10606 .{ .tag = @enumFromInt(2718), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10607 // __builtin_ve_vl_vmaxswzx_vsvl
10608 .{ .tag = @enumFromInt(2719), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10609 // __builtin_ve_vl_vmaxswzx_vsvmvl
10610 .{ .tag = @enumFromInt(2720), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10611 // __builtin_ve_vl_vmaxswzx_vsvvl
10612 .{ .tag = @enumFromInt(2721), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10613 // __builtin_ve_vl_vmaxswzx_vvvl
10614 .{ .tag = @enumFromInt(2722), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10615 // __builtin_ve_vl_vmaxswzx_vvvmvl
10616 .{ .tag = @enumFromInt(2723), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10617 // __builtin_ve_vl_vmaxswzx_vvvvl
10618 .{ .tag = @enumFromInt(2724), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10619 // __builtin_ve_vl_vminsl_vsvl
10620 .{ .tag = @enumFromInt(2725), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10621 // __builtin_ve_vl_vminsl_vsvmvl
10622 .{ .tag = @enumFromInt(2726), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10623 // __builtin_ve_vl_vminsl_vsvvl
10624 .{ .tag = @enumFromInt(2727), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10625 // __builtin_ve_vl_vminsl_vvvl
10626 .{ .tag = @enumFromInt(2728), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10627 // __builtin_ve_vl_vminsl_vvvmvl
10628 .{ .tag = @enumFromInt(2729), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10629 // __builtin_ve_vl_vminsl_vvvvl
10630 .{ .tag = @enumFromInt(2730), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10631 // __builtin_ve_vl_vminswsx_vsvl
10632 .{ .tag = @enumFromInt(2731), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10633 // __builtin_ve_vl_vminswsx_vsvmvl
10634 .{ .tag = @enumFromInt(2732), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10635 // __builtin_ve_vl_vminswsx_vsvvl
10636 .{ .tag = @enumFromInt(2733), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10637 // __builtin_ve_vl_vminswsx_vvvl
10638 .{ .tag = @enumFromInt(2734), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10639 // __builtin_ve_vl_vminswsx_vvvmvl
10640 .{ .tag = @enumFromInt(2735), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10641 // __builtin_ve_vl_vminswsx_vvvvl
10642 .{ .tag = @enumFromInt(2736), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10643 // __builtin_ve_vl_vminswzx_vsvl
10644 .{ .tag = @enumFromInt(2737), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10645 // __builtin_ve_vl_vminswzx_vsvmvl
10646 .{ .tag = @enumFromInt(2738), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10647 // __builtin_ve_vl_vminswzx_vsvvl
10648 .{ .tag = @enumFromInt(2739), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10649 // __builtin_ve_vl_vminswzx_vvvl
10650 .{ .tag = @enumFromInt(2740), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10651 // __builtin_ve_vl_vminswzx_vvvmvl
10652 .{ .tag = @enumFromInt(2741), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10653 // __builtin_ve_vl_vminswzx_vvvvl
10654 .{ .tag = @enumFromInt(2742), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10655 // __builtin_ve_vl_vmrg_vsvml
10656 .{ .tag = @enumFromInt(2743), .properties = .{ .param_str = "V256dLUiV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10657 // __builtin_ve_vl_vmrg_vsvmvl
10658 .{ .tag = @enumFromInt(2744), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10659 // __builtin_ve_vl_vmrg_vvvml
10660 .{ .tag = @enumFromInt(2745), .properties = .{ .param_str = "V256dV256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10661 // __builtin_ve_vl_vmrg_vvvmvl
10662 .{ .tag = @enumFromInt(2746), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10663 // __builtin_ve_vl_vmrgw_vsvMl
10664 .{ .tag = @enumFromInt(2747), .properties = .{ .param_str = "V256dUiV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10665 // __builtin_ve_vl_vmrgw_vsvMvl
10666 .{ .tag = @enumFromInt(2748), .properties = .{ .param_str = "V256dUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10667 // __builtin_ve_vl_vmrgw_vvvMl
10668 .{ .tag = @enumFromInt(2749), .properties = .{ .param_str = "V256dV256dV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10669 // __builtin_ve_vl_vmrgw_vvvMvl
10670 .{ .tag = @enumFromInt(2750), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10671 // __builtin_ve_vl_vmulsl_vsvl
10672 .{ .tag = @enumFromInt(2751), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10673 // __builtin_ve_vl_vmulsl_vsvmvl
10674 .{ .tag = @enumFromInt(2752), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10675 // __builtin_ve_vl_vmulsl_vsvvl
10676 .{ .tag = @enumFromInt(2753), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10677 // __builtin_ve_vl_vmulsl_vvvl
10678 .{ .tag = @enumFromInt(2754), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10679 // __builtin_ve_vl_vmulsl_vvvmvl
10680 .{ .tag = @enumFromInt(2755), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10681 // __builtin_ve_vl_vmulsl_vvvvl
10682 .{ .tag = @enumFromInt(2756), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10683 // __builtin_ve_vl_vmulslw_vsvl
10684 .{ .tag = @enumFromInt(2757), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10685 // __builtin_ve_vl_vmulslw_vsvvl
10686 .{ .tag = @enumFromInt(2758), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10687 // __builtin_ve_vl_vmulslw_vvvl
10688 .{ .tag = @enumFromInt(2759), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10689 // __builtin_ve_vl_vmulslw_vvvvl
10690 .{ .tag = @enumFromInt(2760), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10691 // __builtin_ve_vl_vmulswsx_vsvl
10692 .{ .tag = @enumFromInt(2761), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10693 // __builtin_ve_vl_vmulswsx_vsvmvl
10694 .{ .tag = @enumFromInt(2762), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10695 // __builtin_ve_vl_vmulswsx_vsvvl
10696 .{ .tag = @enumFromInt(2763), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10697 // __builtin_ve_vl_vmulswsx_vvvl
10698 .{ .tag = @enumFromInt(2764), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10699 // __builtin_ve_vl_vmulswsx_vvvmvl
10700 .{ .tag = @enumFromInt(2765), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10701 // __builtin_ve_vl_vmulswsx_vvvvl
10702 .{ .tag = @enumFromInt(2766), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10703 // __builtin_ve_vl_vmulswzx_vsvl
10704 .{ .tag = @enumFromInt(2767), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10705 // __builtin_ve_vl_vmulswzx_vsvmvl
10706 .{ .tag = @enumFromInt(2768), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10707 // __builtin_ve_vl_vmulswzx_vsvvl
10708 .{ .tag = @enumFromInt(2769), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10709 // __builtin_ve_vl_vmulswzx_vvvl
10710 .{ .tag = @enumFromInt(2770), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10711 // __builtin_ve_vl_vmulswzx_vvvmvl
10712 .{ .tag = @enumFromInt(2771), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10713 // __builtin_ve_vl_vmulswzx_vvvvl
10714 .{ .tag = @enumFromInt(2772), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10715 // __builtin_ve_vl_vmulul_vsvl
10716 .{ .tag = @enumFromInt(2773), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10717 // __builtin_ve_vl_vmulul_vsvmvl
10718 .{ .tag = @enumFromInt(2774), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10719 // __builtin_ve_vl_vmulul_vsvvl
10720 .{ .tag = @enumFromInt(2775), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10721 // __builtin_ve_vl_vmulul_vvvl
10722 .{ .tag = @enumFromInt(2776), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10723 // __builtin_ve_vl_vmulul_vvvmvl
10724 .{ .tag = @enumFromInt(2777), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10725 // __builtin_ve_vl_vmulul_vvvvl
10726 .{ .tag = @enumFromInt(2778), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10727 // __builtin_ve_vl_vmuluw_vsvl
10728 .{ .tag = @enumFromInt(2779), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10729 // __builtin_ve_vl_vmuluw_vsvmvl
10730 .{ .tag = @enumFromInt(2780), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10731 // __builtin_ve_vl_vmuluw_vsvvl
10732 .{ .tag = @enumFromInt(2781), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10733 // __builtin_ve_vl_vmuluw_vvvl
10734 .{ .tag = @enumFromInt(2782), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10735 // __builtin_ve_vl_vmuluw_vvvmvl
10736 .{ .tag = @enumFromInt(2783), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10737 // __builtin_ve_vl_vmuluw_vvvvl
10738 .{ .tag = @enumFromInt(2784), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10739 // __builtin_ve_vl_vmv_vsvl
10740 .{ .tag = @enumFromInt(2785), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10741 // __builtin_ve_vl_vmv_vsvmvl
10742 .{ .tag = @enumFromInt(2786), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10743 // __builtin_ve_vl_vmv_vsvvl
10744 .{ .tag = @enumFromInt(2787), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10745 // __builtin_ve_vl_vor_vsvl
10746 .{ .tag = @enumFromInt(2788), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10747 // __builtin_ve_vl_vor_vsvmvl
10748 .{ .tag = @enumFromInt(2789), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10749 // __builtin_ve_vl_vor_vsvvl
10750 .{ .tag = @enumFromInt(2790), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10751 // __builtin_ve_vl_vor_vvvl
10752 .{ .tag = @enumFromInt(2791), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10753 // __builtin_ve_vl_vor_vvvmvl
10754 .{ .tag = @enumFromInt(2792), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10755 // __builtin_ve_vl_vor_vvvvl
10756 .{ .tag = @enumFromInt(2793), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10757 // __builtin_ve_vl_vpcnt_vvl
10758 .{ .tag = @enumFromInt(2794), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10759 // __builtin_ve_vl_vpcnt_vvmvl
10760 .{ .tag = @enumFromInt(2795), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10761 // __builtin_ve_vl_vpcnt_vvvl
10762 .{ .tag = @enumFromInt(2796), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10763 // __builtin_ve_vl_vrand_vvl
10764 .{ .tag = @enumFromInt(2797), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10765 // __builtin_ve_vl_vrand_vvml
10766 .{ .tag = @enumFromInt(2798), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10767 // __builtin_ve_vl_vrcpd_vvl
10768 .{ .tag = @enumFromInt(2799), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10769 // __builtin_ve_vl_vrcpd_vvvl
10770 .{ .tag = @enumFromInt(2800), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10771 // __builtin_ve_vl_vrcps_vvl
10772 .{ .tag = @enumFromInt(2801), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10773 // __builtin_ve_vl_vrcps_vvvl
10774 .{ .tag = @enumFromInt(2802), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10775 // __builtin_ve_vl_vrmaxslfst_vvl
10776 .{ .tag = @enumFromInt(2803), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10777 // __builtin_ve_vl_vrmaxslfst_vvvl
10778 .{ .tag = @enumFromInt(2804), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10779 // __builtin_ve_vl_vrmaxsllst_vvl
10780 .{ .tag = @enumFromInt(2805), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10781 // __builtin_ve_vl_vrmaxsllst_vvvl
10782 .{ .tag = @enumFromInt(2806), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10783 // __builtin_ve_vl_vrmaxswfstsx_vvl
10784 .{ .tag = @enumFromInt(2807), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10785 // __builtin_ve_vl_vrmaxswfstsx_vvvl
10786 .{ .tag = @enumFromInt(2808), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10787 // __builtin_ve_vl_vrmaxswfstzx_vvl
10788 .{ .tag = @enumFromInt(2809), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10789 // __builtin_ve_vl_vrmaxswfstzx_vvvl
10790 .{ .tag = @enumFromInt(2810), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10791 // __builtin_ve_vl_vrmaxswlstsx_vvl
10792 .{ .tag = @enumFromInt(2811), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10793 // __builtin_ve_vl_vrmaxswlstsx_vvvl
10794 .{ .tag = @enumFromInt(2812), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10795 // __builtin_ve_vl_vrmaxswlstzx_vvl
10796 .{ .tag = @enumFromInt(2813), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10797 // __builtin_ve_vl_vrmaxswlstzx_vvvl
10798 .{ .tag = @enumFromInt(2814), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10799 // __builtin_ve_vl_vrminslfst_vvl
10800 .{ .tag = @enumFromInt(2815), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10801 // __builtin_ve_vl_vrminslfst_vvvl
10802 .{ .tag = @enumFromInt(2816), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10803 // __builtin_ve_vl_vrminsllst_vvl
10804 .{ .tag = @enumFromInt(2817), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10805 // __builtin_ve_vl_vrminsllst_vvvl
10806 .{ .tag = @enumFromInt(2818), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10807 // __builtin_ve_vl_vrminswfstsx_vvl
10808 .{ .tag = @enumFromInt(2819), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10809 // __builtin_ve_vl_vrminswfstsx_vvvl
10810 .{ .tag = @enumFromInt(2820), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10811 // __builtin_ve_vl_vrminswfstzx_vvl
10812 .{ .tag = @enumFromInt(2821), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10813 // __builtin_ve_vl_vrminswfstzx_vvvl
10814 .{ .tag = @enumFromInt(2822), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10815 // __builtin_ve_vl_vrminswlstsx_vvl
10816 .{ .tag = @enumFromInt(2823), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10817 // __builtin_ve_vl_vrminswlstsx_vvvl
10818 .{ .tag = @enumFromInt(2824), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10819 // __builtin_ve_vl_vrminswlstzx_vvl
10820 .{ .tag = @enumFromInt(2825), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10821 // __builtin_ve_vl_vrminswlstzx_vvvl
10822 .{ .tag = @enumFromInt(2826), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10823 // __builtin_ve_vl_vror_vvl
10824 .{ .tag = @enumFromInt(2827), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10825 // __builtin_ve_vl_vror_vvml
10826 .{ .tag = @enumFromInt(2828), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10827 // __builtin_ve_vl_vrsqrtd_vvl
10828 .{ .tag = @enumFromInt(2829), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10829 // __builtin_ve_vl_vrsqrtd_vvvl
10830 .{ .tag = @enumFromInt(2830), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10831 // __builtin_ve_vl_vrsqrtdnex_vvl
10832 .{ .tag = @enumFromInt(2831), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10833 // __builtin_ve_vl_vrsqrtdnex_vvvl
10834 .{ .tag = @enumFromInt(2832), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10835 // __builtin_ve_vl_vrsqrts_vvl
10836 .{ .tag = @enumFromInt(2833), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10837 // __builtin_ve_vl_vrsqrts_vvvl
10838 .{ .tag = @enumFromInt(2834), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10839 // __builtin_ve_vl_vrsqrtsnex_vvl
10840 .{ .tag = @enumFromInt(2835), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10841 // __builtin_ve_vl_vrsqrtsnex_vvvl
10842 .{ .tag = @enumFromInt(2836), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10843 // __builtin_ve_vl_vrxor_vvl
10844 .{ .tag = @enumFromInt(2837), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10845 // __builtin_ve_vl_vrxor_vvml
10846 .{ .tag = @enumFromInt(2838), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10847 // __builtin_ve_vl_vsc_vvssl
10848 .{ .tag = @enumFromInt(2839), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10849 // __builtin_ve_vl_vsc_vvssml
10850 .{ .tag = @enumFromInt(2840), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10851 // __builtin_ve_vl_vscl_vvssl
10852 .{ .tag = @enumFromInt(2841), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10853 // __builtin_ve_vl_vscl_vvssml
10854 .{ .tag = @enumFromInt(2842), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10855 // __builtin_ve_vl_vsclnc_vvssl
10856 .{ .tag = @enumFromInt(2843), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10857 // __builtin_ve_vl_vsclnc_vvssml
10858 .{ .tag = @enumFromInt(2844), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10859 // __builtin_ve_vl_vsclncot_vvssl
10860 .{ .tag = @enumFromInt(2845), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10861 // __builtin_ve_vl_vsclncot_vvssml
10862 .{ .tag = @enumFromInt(2846), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10863 // __builtin_ve_vl_vsclot_vvssl
10864 .{ .tag = @enumFromInt(2847), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10865 // __builtin_ve_vl_vsclot_vvssml
10866 .{ .tag = @enumFromInt(2848), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10867 // __builtin_ve_vl_vscnc_vvssl
10868 .{ .tag = @enumFromInt(2849), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10869 // __builtin_ve_vl_vscnc_vvssml
10870 .{ .tag = @enumFromInt(2850), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10871 // __builtin_ve_vl_vscncot_vvssl
10872 .{ .tag = @enumFromInt(2851), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10873 // __builtin_ve_vl_vscncot_vvssml
10874 .{ .tag = @enumFromInt(2852), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10875 // __builtin_ve_vl_vscot_vvssl
10876 .{ .tag = @enumFromInt(2853), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10877 // __builtin_ve_vl_vscot_vvssml
10878 .{ .tag = @enumFromInt(2854), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10879 // __builtin_ve_vl_vscu_vvssl
10880 .{ .tag = @enumFromInt(2855), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10881 // __builtin_ve_vl_vscu_vvssml
10882 .{ .tag = @enumFromInt(2856), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10883 // __builtin_ve_vl_vscunc_vvssl
10884 .{ .tag = @enumFromInt(2857), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10885 // __builtin_ve_vl_vscunc_vvssml
10886 .{ .tag = @enumFromInt(2858), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10887 // __builtin_ve_vl_vscuncot_vvssl
10888 .{ .tag = @enumFromInt(2859), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10889 // __builtin_ve_vl_vscuncot_vvssml
10890 .{ .tag = @enumFromInt(2860), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10891 // __builtin_ve_vl_vscuot_vvssl
10892 .{ .tag = @enumFromInt(2861), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10893 // __builtin_ve_vl_vscuot_vvssml
10894 .{ .tag = @enumFromInt(2862), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10895 // __builtin_ve_vl_vseq_vl
10896 .{ .tag = @enumFromInt(2863), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10897 // __builtin_ve_vl_vseq_vvl
10898 .{ .tag = @enumFromInt(2864), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10899 // __builtin_ve_vl_vsfa_vvssl
10900 .{ .tag = @enumFromInt(2865), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10901 // __builtin_ve_vl_vsfa_vvssmvl
10902 .{ .tag = @enumFromInt(2866), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10903 // __builtin_ve_vl_vsfa_vvssvl
10904 .{ .tag = @enumFromInt(2867), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10905 // __builtin_ve_vl_vshf_vvvsl
10906 .{ .tag = @enumFromInt(2868), .properties = .{ .param_str = "V256dV256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10907 // __builtin_ve_vl_vshf_vvvsvl
10908 .{ .tag = @enumFromInt(2869), .properties = .{ .param_str = "V256dV256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10909 // __builtin_ve_vl_vslal_vvsl
10910 .{ .tag = @enumFromInt(2870), .properties = .{ .param_str = "V256dV256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10911 // __builtin_ve_vl_vslal_vvsmvl
10912 .{ .tag = @enumFromInt(2871), .properties = .{ .param_str = "V256dV256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10913 // __builtin_ve_vl_vslal_vvsvl
10914 .{ .tag = @enumFromInt(2872), .properties = .{ .param_str = "V256dV256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10915 // __builtin_ve_vl_vslal_vvvl
10916 .{ .tag = @enumFromInt(2873), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10917 // __builtin_ve_vl_vslal_vvvmvl
10918 .{ .tag = @enumFromInt(2874), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10919 // __builtin_ve_vl_vslal_vvvvl
10920 .{ .tag = @enumFromInt(2875), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10921 // __builtin_ve_vl_vslawsx_vvsl
10922 .{ .tag = @enumFromInt(2876), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10923 // __builtin_ve_vl_vslawsx_vvsmvl
10924 .{ .tag = @enumFromInt(2877), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10925 // __builtin_ve_vl_vslawsx_vvsvl
10926 .{ .tag = @enumFromInt(2878), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10927 // __builtin_ve_vl_vslawsx_vvvl
10928 .{ .tag = @enumFromInt(2879), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10929 // __builtin_ve_vl_vslawsx_vvvmvl
10930 .{ .tag = @enumFromInt(2880), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10931 // __builtin_ve_vl_vslawsx_vvvvl
10932 .{ .tag = @enumFromInt(2881), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10933 // __builtin_ve_vl_vslawzx_vvsl
10934 .{ .tag = @enumFromInt(2882), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10935 // __builtin_ve_vl_vslawzx_vvsmvl
10936 .{ .tag = @enumFromInt(2883), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10937 // __builtin_ve_vl_vslawzx_vvsvl
10938 .{ .tag = @enumFromInt(2884), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10939 // __builtin_ve_vl_vslawzx_vvvl
10940 .{ .tag = @enumFromInt(2885), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10941 // __builtin_ve_vl_vslawzx_vvvmvl
10942 .{ .tag = @enumFromInt(2886), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10943 // __builtin_ve_vl_vslawzx_vvvvl
10944 .{ .tag = @enumFromInt(2887), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10945 // __builtin_ve_vl_vsll_vvsl
10946 .{ .tag = @enumFromInt(2888), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10947 // __builtin_ve_vl_vsll_vvsmvl
10948 .{ .tag = @enumFromInt(2889), .properties = .{ .param_str = "V256dV256dLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10949 // __builtin_ve_vl_vsll_vvsvl
10950 .{ .tag = @enumFromInt(2890), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10951 // __builtin_ve_vl_vsll_vvvl
10952 .{ .tag = @enumFromInt(2891), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10953 // __builtin_ve_vl_vsll_vvvmvl
10954 .{ .tag = @enumFromInt(2892), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10955 // __builtin_ve_vl_vsll_vvvvl
10956 .{ .tag = @enumFromInt(2893), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10957 // __builtin_ve_vl_vsral_vvsl
10958 .{ .tag = @enumFromInt(2894), .properties = .{ .param_str = "V256dV256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10959 // __builtin_ve_vl_vsral_vvsmvl
10960 .{ .tag = @enumFromInt(2895), .properties = .{ .param_str = "V256dV256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10961 // __builtin_ve_vl_vsral_vvsvl
10962 .{ .tag = @enumFromInt(2896), .properties = .{ .param_str = "V256dV256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10963 // __builtin_ve_vl_vsral_vvvl
10964 .{ .tag = @enumFromInt(2897), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10965 // __builtin_ve_vl_vsral_vvvmvl
10966 .{ .tag = @enumFromInt(2898), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10967 // __builtin_ve_vl_vsral_vvvvl
10968 .{ .tag = @enumFromInt(2899), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10969 // __builtin_ve_vl_vsrawsx_vvsl
10970 .{ .tag = @enumFromInt(2900), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10971 // __builtin_ve_vl_vsrawsx_vvsmvl
10972 .{ .tag = @enumFromInt(2901), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10973 // __builtin_ve_vl_vsrawsx_vvsvl
10974 .{ .tag = @enumFromInt(2902), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10975 // __builtin_ve_vl_vsrawsx_vvvl
10976 .{ .tag = @enumFromInt(2903), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10977 // __builtin_ve_vl_vsrawsx_vvvmvl
10978 .{ .tag = @enumFromInt(2904), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10979 // __builtin_ve_vl_vsrawsx_vvvvl
10980 .{ .tag = @enumFromInt(2905), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10981 // __builtin_ve_vl_vsrawzx_vvsl
10982 .{ .tag = @enumFromInt(2906), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10983 // __builtin_ve_vl_vsrawzx_vvsmvl
10984 .{ .tag = @enumFromInt(2907), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10985 // __builtin_ve_vl_vsrawzx_vvsvl
10986 .{ .tag = @enumFromInt(2908), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10987 // __builtin_ve_vl_vsrawzx_vvvl
10988 .{ .tag = @enumFromInt(2909), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10989 // __builtin_ve_vl_vsrawzx_vvvmvl
10990 .{ .tag = @enumFromInt(2910), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10991 // __builtin_ve_vl_vsrawzx_vvvvl
10992 .{ .tag = @enumFromInt(2911), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10993 // __builtin_ve_vl_vsrl_vvsl
10994 .{ .tag = @enumFromInt(2912), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10995 // __builtin_ve_vl_vsrl_vvsmvl
10996 .{ .tag = @enumFromInt(2913), .properties = .{ .param_str = "V256dV256dLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10997 // __builtin_ve_vl_vsrl_vvsvl
10998 .{ .tag = @enumFromInt(2914), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
10999 // __builtin_ve_vl_vsrl_vvvl
11000 .{ .tag = @enumFromInt(2915), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11001 // __builtin_ve_vl_vsrl_vvvmvl
11002 .{ .tag = @enumFromInt(2916), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11003 // __builtin_ve_vl_vsrl_vvvvl
11004 .{ .tag = @enumFromInt(2917), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11005 // __builtin_ve_vl_vst2d_vssl
11006 .{ .tag = @enumFromInt(2918), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11007 // __builtin_ve_vl_vst2d_vssml
11008 .{ .tag = @enumFromInt(2919), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11009 // __builtin_ve_vl_vst2dnc_vssl
11010 .{ .tag = @enumFromInt(2920), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11011 // __builtin_ve_vl_vst2dnc_vssml
11012 .{ .tag = @enumFromInt(2921), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11013 // __builtin_ve_vl_vst2dncot_vssl
11014 .{ .tag = @enumFromInt(2922), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11015 // __builtin_ve_vl_vst2dncot_vssml
11016 .{ .tag = @enumFromInt(2923), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11017 // __builtin_ve_vl_vst2dot_vssl
11018 .{ .tag = @enumFromInt(2924), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11019 // __builtin_ve_vl_vst2dot_vssml
11020 .{ .tag = @enumFromInt(2925), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11021 // __builtin_ve_vl_vst_vssl
11022 .{ .tag = @enumFromInt(2926), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11023 // __builtin_ve_vl_vst_vssml
11024 .{ .tag = @enumFromInt(2927), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11025 // __builtin_ve_vl_vstl2d_vssl
11026 .{ .tag = @enumFromInt(2928), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11027 // __builtin_ve_vl_vstl2d_vssml
11028 .{ .tag = @enumFromInt(2929), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11029 // __builtin_ve_vl_vstl2dnc_vssl
11030 .{ .tag = @enumFromInt(2930), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11031 // __builtin_ve_vl_vstl2dnc_vssml
11032 .{ .tag = @enumFromInt(2931), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11033 // __builtin_ve_vl_vstl2dncot_vssl
11034 .{ .tag = @enumFromInt(2932), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11035 // __builtin_ve_vl_vstl2dncot_vssml
11036 .{ .tag = @enumFromInt(2933), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11037 // __builtin_ve_vl_vstl2dot_vssl
11038 .{ .tag = @enumFromInt(2934), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11039 // __builtin_ve_vl_vstl2dot_vssml
11040 .{ .tag = @enumFromInt(2935), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11041 // __builtin_ve_vl_vstl_vssl
11042 .{ .tag = @enumFromInt(2936), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11043 // __builtin_ve_vl_vstl_vssml
11044 .{ .tag = @enumFromInt(2937), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11045 // __builtin_ve_vl_vstlnc_vssl
11046 .{ .tag = @enumFromInt(2938), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11047 // __builtin_ve_vl_vstlnc_vssml
11048 .{ .tag = @enumFromInt(2939), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11049 // __builtin_ve_vl_vstlncot_vssl
11050 .{ .tag = @enumFromInt(2940), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11051 // __builtin_ve_vl_vstlncot_vssml
11052 .{ .tag = @enumFromInt(2941), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11053 // __builtin_ve_vl_vstlot_vssl
11054 .{ .tag = @enumFromInt(2942), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11055 // __builtin_ve_vl_vstlot_vssml
11056 .{ .tag = @enumFromInt(2943), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11057 // __builtin_ve_vl_vstnc_vssl
11058 .{ .tag = @enumFromInt(2944), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11059 // __builtin_ve_vl_vstnc_vssml
11060 .{ .tag = @enumFromInt(2945), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11061 // __builtin_ve_vl_vstncot_vssl
11062 .{ .tag = @enumFromInt(2946), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11063 // __builtin_ve_vl_vstncot_vssml
11064 .{ .tag = @enumFromInt(2947), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11065 // __builtin_ve_vl_vstot_vssl
11066 .{ .tag = @enumFromInt(2948), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11067 // __builtin_ve_vl_vstot_vssml
11068 .{ .tag = @enumFromInt(2949), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11069 // __builtin_ve_vl_vstu2d_vssl
11070 .{ .tag = @enumFromInt(2950), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11071 // __builtin_ve_vl_vstu2d_vssml
11072 .{ .tag = @enumFromInt(2951), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11073 // __builtin_ve_vl_vstu2dnc_vssl
11074 .{ .tag = @enumFromInt(2952), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11075 // __builtin_ve_vl_vstu2dnc_vssml
11076 .{ .tag = @enumFromInt(2953), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11077 // __builtin_ve_vl_vstu2dncot_vssl
11078 .{ .tag = @enumFromInt(2954), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11079 // __builtin_ve_vl_vstu2dncot_vssml
11080 .{ .tag = @enumFromInt(2955), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11081 // __builtin_ve_vl_vstu2dot_vssl
11082 .{ .tag = @enumFromInt(2956), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11083 // __builtin_ve_vl_vstu2dot_vssml
11084 .{ .tag = @enumFromInt(2957), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11085 // __builtin_ve_vl_vstu_vssl
11086 .{ .tag = @enumFromInt(2958), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11087 // __builtin_ve_vl_vstu_vssml
11088 .{ .tag = @enumFromInt(2959), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11089 // __builtin_ve_vl_vstunc_vssl
11090 .{ .tag = @enumFromInt(2960), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11091 // __builtin_ve_vl_vstunc_vssml
11092 .{ .tag = @enumFromInt(2961), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11093 // __builtin_ve_vl_vstuncot_vssl
11094 .{ .tag = @enumFromInt(2962), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11095 // __builtin_ve_vl_vstuncot_vssml
11096 .{ .tag = @enumFromInt(2963), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11097 // __builtin_ve_vl_vstuot_vssl
11098 .{ .tag = @enumFromInt(2964), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } },
11099 // __builtin_ve_vl_vstuot_vssml
11100 .{ .tag = @enumFromInt(2965), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11101 // __builtin_ve_vl_vsubsl_vsvl
11102 .{ .tag = @enumFromInt(2966), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11103 // __builtin_ve_vl_vsubsl_vsvmvl
11104 .{ .tag = @enumFromInt(2967), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11105 // __builtin_ve_vl_vsubsl_vsvvl
11106 .{ .tag = @enumFromInt(2968), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11107 // __builtin_ve_vl_vsubsl_vvvl
11108 .{ .tag = @enumFromInt(2969), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11109 // __builtin_ve_vl_vsubsl_vvvmvl
11110 .{ .tag = @enumFromInt(2970), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11111 // __builtin_ve_vl_vsubsl_vvvvl
11112 .{ .tag = @enumFromInt(2971), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11113 // __builtin_ve_vl_vsubswsx_vsvl
11114 .{ .tag = @enumFromInt(2972), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11115 // __builtin_ve_vl_vsubswsx_vsvmvl
11116 .{ .tag = @enumFromInt(2973), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11117 // __builtin_ve_vl_vsubswsx_vsvvl
11118 .{ .tag = @enumFromInt(2974), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11119 // __builtin_ve_vl_vsubswsx_vvvl
11120 .{ .tag = @enumFromInt(2975), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11121 // __builtin_ve_vl_vsubswsx_vvvmvl
11122 .{ .tag = @enumFromInt(2976), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11123 // __builtin_ve_vl_vsubswsx_vvvvl
11124 .{ .tag = @enumFromInt(2977), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11125 // __builtin_ve_vl_vsubswzx_vsvl
11126 .{ .tag = @enumFromInt(2978), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11127 // __builtin_ve_vl_vsubswzx_vsvmvl
11128 .{ .tag = @enumFromInt(2979), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11129 // __builtin_ve_vl_vsubswzx_vsvvl
11130 .{ .tag = @enumFromInt(2980), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11131 // __builtin_ve_vl_vsubswzx_vvvl
11132 .{ .tag = @enumFromInt(2981), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11133 // __builtin_ve_vl_vsubswzx_vvvmvl
11134 .{ .tag = @enumFromInt(2982), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11135 // __builtin_ve_vl_vsubswzx_vvvvl
11136 .{ .tag = @enumFromInt(2983), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11137 // __builtin_ve_vl_vsubul_vsvl
11138 .{ .tag = @enumFromInt(2984), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11139 // __builtin_ve_vl_vsubul_vsvmvl
11140 .{ .tag = @enumFromInt(2985), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11141 // __builtin_ve_vl_vsubul_vsvvl
11142 .{ .tag = @enumFromInt(2986), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11143 // __builtin_ve_vl_vsubul_vvvl
11144 .{ .tag = @enumFromInt(2987), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11145 // __builtin_ve_vl_vsubul_vvvmvl
11146 .{ .tag = @enumFromInt(2988), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11147 // __builtin_ve_vl_vsubul_vvvvl
11148 .{ .tag = @enumFromInt(2989), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11149 // __builtin_ve_vl_vsubuw_vsvl
11150 .{ .tag = @enumFromInt(2990), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11151 // __builtin_ve_vl_vsubuw_vsvmvl
11152 .{ .tag = @enumFromInt(2991), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11153 // __builtin_ve_vl_vsubuw_vsvvl
11154 .{ .tag = @enumFromInt(2992), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11155 // __builtin_ve_vl_vsubuw_vvvl
11156 .{ .tag = @enumFromInt(2993), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11157 // __builtin_ve_vl_vsubuw_vvvmvl
11158 .{ .tag = @enumFromInt(2994), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11159 // __builtin_ve_vl_vsubuw_vvvvl
11160 .{ .tag = @enumFromInt(2995), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11161 // __builtin_ve_vl_vsuml_vvl
11162 .{ .tag = @enumFromInt(2996), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11163 // __builtin_ve_vl_vsuml_vvml
11164 .{ .tag = @enumFromInt(2997), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11165 // __builtin_ve_vl_vsumwsx_vvl
11166 .{ .tag = @enumFromInt(2998), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11167 // __builtin_ve_vl_vsumwsx_vvml
11168 .{ .tag = @enumFromInt(2999), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11169 // __builtin_ve_vl_vsumwzx_vvl
11170 .{ .tag = @enumFromInt(3000), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11171 // __builtin_ve_vl_vsumwzx_vvml
11172 .{ .tag = @enumFromInt(3001), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11173 // __builtin_ve_vl_vxor_vsvl
11174 .{ .tag = @enumFromInt(3002), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11175 // __builtin_ve_vl_vxor_vsvmvl
11176 .{ .tag = @enumFromInt(3003), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11177 // __builtin_ve_vl_vxor_vsvvl
11178 .{ .tag = @enumFromInt(3004), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11179 // __builtin_ve_vl_vxor_vvvl
11180 .{ .tag = @enumFromInt(3005), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11181 // __builtin_ve_vl_vxor_vvvmvl
11182 .{ .tag = @enumFromInt(3006), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11183 // __builtin_ve_vl_vxor_vvvvl
11184 .{ .tag = @enumFromInt(3007), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } },
11185 // __builtin_ve_vl_xorm_MMM
11186 .{ .tag = @enumFromInt(3008), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } },
11187 // __builtin_ve_vl_xorm_mmm
11188 .{ .tag = @enumFromInt(3009), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } },
11189 // __builtin_vfprintf
11190 .{ .tag = @enumFromInt(3010), .properties = .{ .param_str = "iP*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } },
11191 // __builtin_vfscanf
11192 .{ .tag = @enumFromInt(3011), .properties = .{ .param_str = "iP*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } },
11193 // __builtin_vprintf
11194 .{ .tag = @enumFromInt(3012), .properties = .{ .param_str = "icC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf } } },
11195 // __builtin_vscanf
11196 .{ .tag = @enumFromInt(3013), .properties = .{ .param_str = "icC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf } } },
11197 // __builtin_vsnprintf
11198 .{ .tag = @enumFromInt(3014), .properties = .{ .param_str = "ic*RzcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 2 } } },
11199 // __builtin_vsprintf
11200 .{ .tag = @enumFromInt(3015), .properties = .{ .param_str = "ic*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } },
11201 // __builtin_vsscanf
11202 .{ .tag = @enumFromInt(3016), .properties = .{ .param_str = "icC*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } },
11203 // __builtin_wasm_max_f32
11204 .{ .tag = @enumFromInt(3017), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11205 // __builtin_wasm_max_f64
11206 .{ .tag = @enumFromInt(3018), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11207 // __builtin_wasm_memory_grow
11208 .{ .tag = @enumFromInt(3019), .properties = .{ .param_str = "zIiz", .target_set = TargetSet.initOne(.webassembly) } },
11209 // __builtin_wasm_memory_size
11210 .{ .tag = @enumFromInt(3020), .properties = .{ .param_str = "zIi", .target_set = TargetSet.initOne(.webassembly) } },
11211 // __builtin_wasm_min_f32
11212 .{ .tag = @enumFromInt(3021), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11213 // __builtin_wasm_min_f64
11214 .{ .tag = @enumFromInt(3022), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11215 // __builtin_wasm_trunc_s_i32_f32
11216 .{ .tag = @enumFromInt(3023), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11217 // __builtin_wasm_trunc_s_i32_f64
11218 .{ .tag = @enumFromInt(3024), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11219 // __builtin_wasm_trunc_s_i64_f32
11220 .{ .tag = @enumFromInt(3025), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11221 // __builtin_wasm_trunc_s_i64_f64
11222 .{ .tag = @enumFromInt(3026), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11223 // __builtin_wasm_trunc_u_i32_f32
11224 .{ .tag = @enumFromInt(3027), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11225 // __builtin_wasm_trunc_u_i32_f64
11226 .{ .tag = @enumFromInt(3028), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11227 // __builtin_wasm_trunc_u_i64_f32
11228 .{ .tag = @enumFromInt(3029), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11229 // __builtin_wasm_trunc_u_i64_f64
11230 .{ .tag = @enumFromInt(3030), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } },
11231 // __builtin_wcschr
11232 .{ .tag = @enumFromInt(3031), .properties = .{ .param_str = "w*wC*w", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11233 // __builtin_wcscmp
11234 .{ .tag = @enumFromInt(3032), .properties = .{ .param_str = "iwC*wC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11235 // __builtin_wcslen
11236 .{ .tag = @enumFromInt(3033), .properties = .{ .param_str = "zwC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11237 // __builtin_wcsncmp
11238 .{ .tag = @enumFromInt(3034), .properties = .{ .param_str = "iwC*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11239 // __builtin_wmemchr
11240 .{ .tag = @enumFromInt(3035), .properties = .{ .param_str = "w*wC*wz", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11241 // __builtin_wmemcmp
11242 .{ .tag = @enumFromInt(3036), .properties = .{ .param_str = "iwC*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11243 // __builtin_wmemcpy
11244 .{ .tag = @enumFromInt(3037), .properties = .{ .param_str = "w*w*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11245 // __builtin_wmemmove
11246 .{ .tag = @enumFromInt(3038), .properties = .{ .param_str = "w*w*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } },
11247 // __c11_atomic_compare_exchange_strong
11248 .{ .tag = @enumFromInt(3039), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11249 // __c11_atomic_compare_exchange_weak
11250 .{ .tag = @enumFromInt(3040), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11251 // __c11_atomic_exchange
11252 .{ .tag = @enumFromInt(3041), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11253 // __c11_atomic_fetch_add
11254 .{ .tag = @enumFromInt(3042), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11255 // __c11_atomic_fetch_and
11256 .{ .tag = @enumFromInt(3043), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11257 // __c11_atomic_fetch_max
11258 .{ .tag = @enumFromInt(3044), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11259 // __c11_atomic_fetch_min
11260 .{ .tag = @enumFromInt(3045), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11261 // __c11_atomic_fetch_nand
11262 .{ .tag = @enumFromInt(3046), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11263 // __c11_atomic_fetch_or
11264 .{ .tag = @enumFromInt(3047), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11265 // __c11_atomic_fetch_sub
11266 .{ .tag = @enumFromInt(3048), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11267 // __c11_atomic_fetch_xor
11268 .{ .tag = @enumFromInt(3049), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11269 // __c11_atomic_init
11270 .{ .tag = @enumFromInt(3050), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11271 // __c11_atomic_is_lock_free
11272 .{ .tag = @enumFromInt(3051), .properties = .{ .param_str = "bz", .attributes = .{ .const_evaluable = true } } },
11273 // __c11_atomic_load
11274 .{ .tag = @enumFromInt(3052), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11275 // __c11_atomic_signal_fence
11276 .{ .tag = @enumFromInt(3053), .properties = .{ .param_str = "vi" } },
11277 // __c11_atomic_store
11278 .{ .tag = @enumFromInt(3054), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
11279 // __c11_atomic_thread_fence
11280 .{ .tag = @enumFromInt(3055), .properties = .{ .param_str = "vi" } },
11281 // __clear_cache
11282 .{ .tag = @enumFromInt(3056), .properties = .{ .param_str = "vv*v*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
11283 // __cospi
11284 .{ .tag = @enumFromInt(3057), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
11285 // __cospif
11286 .{ .tag = @enumFromInt(3058), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
11287 // __debugbreak
11288 .{ .tag = @enumFromInt(3059), .properties = .{ .param_str = "v", .language = .all_ms_languages } },
11289 // __dmb
11290 .{ .tag = @enumFromInt(3060), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
11291 // __dsb
11292 .{ .tag = @enumFromInt(3061), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
11293 // __emit
11294 .{ .tag = @enumFromInt(3062), .properties = .{ .param_str = "vIUiC", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } },
11295 // __exception_code
11296 .{ .tag = @enumFromInt(3063), .properties = .{ .param_str = "UNi", .language = .all_ms_languages } },
11297 // __exception_info
11298 .{ .tag = @enumFromInt(3064), .properties = .{ .param_str = "v*", .language = .all_ms_languages } },
11299 // __exp10
11300 .{ .tag = @enumFromInt(3065), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
11301 // __exp10f
11302 .{ .tag = @enumFromInt(3066), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
11303 // __fastfail
11304 .{ .tag = @enumFromInt(3067), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .attributes = .{ .noreturn = true } } },
11305 // __finite
11306 .{ .tag = @enumFromInt(3068), .properties = .{ .param_str = "id", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
11307 // __finitef
11308 .{ .tag = @enumFromInt(3069), .properties = .{ .param_str = "if", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
11309 // __finitel
11310 .{ .tag = @enumFromInt(3070), .properties = .{ .param_str = "iLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
11311 // __isb
11312 .{ .tag = @enumFromInt(3071), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } },
11313 // __iso_volatile_load16
11314 .{ .tag = @enumFromInt(3072), .properties = .{ .param_str = "ssCD*", .language = .all_ms_languages } },
11315 // __iso_volatile_load32
11316 .{ .tag = @enumFromInt(3073), .properties = .{ .param_str = "iiCD*", .language = .all_ms_languages } },
11317 // __iso_volatile_load64
11318 .{ .tag = @enumFromInt(3074), .properties = .{ .param_str = "LLiLLiCD*", .language = .all_ms_languages } },
11319 // __iso_volatile_load8
11320 .{ .tag = @enumFromInt(3075), .properties = .{ .param_str = "ccCD*", .language = .all_ms_languages } },
11321 // __iso_volatile_store16
11322 .{ .tag = @enumFromInt(3076), .properties = .{ .param_str = "vsD*s", .language = .all_ms_languages } },
11323 // __iso_volatile_store32
11324 .{ .tag = @enumFromInt(3077), .properties = .{ .param_str = "viD*i", .language = .all_ms_languages } },
11325 // __iso_volatile_store64
11326 .{ .tag = @enumFromInt(3078), .properties = .{ .param_str = "vLLiD*LLi", .language = .all_ms_languages } },
11327 // __iso_volatile_store8
11328 .{ .tag = @enumFromInt(3079), .properties = .{ .param_str = "vcD*c", .language = .all_ms_languages } },
11329 // __ldrexd
11330 .{ .tag = @enumFromInt(3080), .properties = .{ .param_str = "WiWiCD*", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } },
11331 // __lzcnt
11332 .{ .tag = @enumFromInt(3081), .properties = .{ .param_str = "UiUi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } },
11333 // __lzcnt16
11334 .{ .tag = @enumFromInt(3082), .properties = .{ .param_str = "UsUs", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } },
11335 // __lzcnt64
11336 .{ .tag = @enumFromInt(3083), .properties = .{ .param_str = "UWiUWi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } },
11337 // __noop
11338 .{ .tag = @enumFromInt(3084), .properties = .{ .param_str = "i.", .language = .all_ms_languages } },
11339 // __nvvm_add_rm_d
11340 .{ .tag = @enumFromInt(3085), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11341 // __nvvm_add_rm_f
11342 .{ .tag = @enumFromInt(3086), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11343 // __nvvm_add_rm_ftz_f
11344 .{ .tag = @enumFromInt(3087), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11345 // __nvvm_add_rn_d
11346 .{ .tag = @enumFromInt(3088), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11347 // __nvvm_add_rn_f
11348 .{ .tag = @enumFromInt(3089), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11349 // __nvvm_add_rn_ftz_f
11350 .{ .tag = @enumFromInt(3090), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11351 // __nvvm_add_rp_d
11352 .{ .tag = @enumFromInt(3091), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11353 // __nvvm_add_rp_f
11354 .{ .tag = @enumFromInt(3092), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11355 // __nvvm_add_rp_ftz_f
11356 .{ .tag = @enumFromInt(3093), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11357 // __nvvm_add_rz_d
11358 .{ .tag = @enumFromInt(3094), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11359 // __nvvm_add_rz_f
11360 .{ .tag = @enumFromInt(3095), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11361 // __nvvm_add_rz_ftz_f
11362 .{ .tag = @enumFromInt(3096), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11363 // __nvvm_atom_add_gen_f
11364 .{ .tag = @enumFromInt(3097), .properties = .{ .param_str = "ffD*f", .target_set = TargetSet.initOne(.nvptx) } },
11365 // __nvvm_atom_add_gen_i
11366 .{ .tag = @enumFromInt(3098), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11367 // __nvvm_atom_add_gen_l
11368 .{ .tag = @enumFromInt(3099), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11369 // __nvvm_atom_add_gen_ll
11370 .{ .tag = @enumFromInt(3100), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11371 // __nvvm_atom_and_gen_i
11372 .{ .tag = @enumFromInt(3101), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11373 // __nvvm_atom_and_gen_l
11374 .{ .tag = @enumFromInt(3102), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11375 // __nvvm_atom_and_gen_ll
11376 .{ .tag = @enumFromInt(3103), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11377 // __nvvm_atom_cas_gen_i
11378 .{ .tag = @enumFromInt(3104), .properties = .{ .param_str = "iiD*ii", .target_set = TargetSet.initOne(.nvptx) } },
11379 // __nvvm_atom_cas_gen_l
11380 .{ .tag = @enumFromInt(3105), .properties = .{ .param_str = "LiLiD*LiLi", .target_set = TargetSet.initOne(.nvptx) } },
11381 // __nvvm_atom_cas_gen_ll
11382 .{ .tag = @enumFromInt(3106), .properties = .{ .param_str = "LLiLLiD*LLiLLi", .target_set = TargetSet.initOne(.nvptx) } },
11383 // __nvvm_atom_dec_gen_ui
11384 .{ .tag = @enumFromInt(3107), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } },
11385 // __nvvm_atom_inc_gen_ui
11386 .{ .tag = @enumFromInt(3108), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } },
11387 // __nvvm_atom_max_gen_i
11388 .{ .tag = @enumFromInt(3109), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11389 // __nvvm_atom_max_gen_l
11390 .{ .tag = @enumFromInt(3110), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11391 // __nvvm_atom_max_gen_ll
11392 .{ .tag = @enumFromInt(3111), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11393 // __nvvm_atom_max_gen_ui
11394 .{ .tag = @enumFromInt(3112), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } },
11395 // __nvvm_atom_max_gen_ul
11396 .{ .tag = @enumFromInt(3113), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.nvptx) } },
11397 // __nvvm_atom_max_gen_ull
11398 .{ .tag = @enumFromInt(3114), .properties = .{ .param_str = "ULLiULLiD*ULLi", .target_set = TargetSet.initOne(.nvptx) } },
11399 // __nvvm_atom_min_gen_i
11400 .{ .tag = @enumFromInt(3115), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11401 // __nvvm_atom_min_gen_l
11402 .{ .tag = @enumFromInt(3116), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11403 // __nvvm_atom_min_gen_ll
11404 .{ .tag = @enumFromInt(3117), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11405 // __nvvm_atom_min_gen_ui
11406 .{ .tag = @enumFromInt(3118), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } },
11407 // __nvvm_atom_min_gen_ul
11408 .{ .tag = @enumFromInt(3119), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.nvptx) } },
11409 // __nvvm_atom_min_gen_ull
11410 .{ .tag = @enumFromInt(3120), .properties = .{ .param_str = "ULLiULLiD*ULLi", .target_set = TargetSet.initOne(.nvptx) } },
11411 // __nvvm_atom_or_gen_i
11412 .{ .tag = @enumFromInt(3121), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11413 // __nvvm_atom_or_gen_l
11414 .{ .tag = @enumFromInt(3122), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11415 // __nvvm_atom_or_gen_ll
11416 .{ .tag = @enumFromInt(3123), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11417 // __nvvm_atom_sub_gen_i
11418 .{ .tag = @enumFromInt(3124), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11419 // __nvvm_atom_sub_gen_l
11420 .{ .tag = @enumFromInt(3125), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11421 // __nvvm_atom_sub_gen_ll
11422 .{ .tag = @enumFromInt(3126), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11423 // __nvvm_atom_xchg_gen_i
11424 .{ .tag = @enumFromInt(3127), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11425 // __nvvm_atom_xchg_gen_l
11426 .{ .tag = @enumFromInt(3128), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11427 // __nvvm_atom_xchg_gen_ll
11428 .{ .tag = @enumFromInt(3129), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11429 // __nvvm_atom_xor_gen_i
11430 .{ .tag = @enumFromInt(3130), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } },
11431 // __nvvm_atom_xor_gen_l
11432 .{ .tag = @enumFromInt(3131), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } },
11433 // __nvvm_atom_xor_gen_ll
11434 .{ .tag = @enumFromInt(3132), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } },
11435 // __nvvm_bar0_and
11436 .{ .tag = @enumFromInt(3133), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
11437 // __nvvm_bar0_or
11438 .{ .tag = @enumFromInt(3134), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
11439 // __nvvm_bar0_popc
11440 .{ .tag = @enumFromInt(3135), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } },
11441 // __nvvm_bar_sync
11442 .{ .tag = @enumFromInt(3136), .properties = .{ .param_str = "vi", .target_set = TargetSet.initOne(.nvptx) } },
11443 // __nvvm_bitcast_d2ll
11444 .{ .tag = @enumFromInt(3137), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } },
11445 // __nvvm_bitcast_f2i
11446 .{ .tag = @enumFromInt(3138), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11447 // __nvvm_bitcast_i2f
11448 .{ .tag = @enumFromInt(3139), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } },
11449 // __nvvm_bitcast_ll2d
11450 .{ .tag = @enumFromInt(3140), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } },
11451 // __nvvm_ceil_d
11452 .{ .tag = @enumFromInt(3141), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11453 // __nvvm_ceil_f
11454 .{ .tag = @enumFromInt(3142), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11455 // __nvvm_ceil_ftz_f
11456 .{ .tag = @enumFromInt(3143), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11457 // __nvvm_compiler_error
11458 .{ .tag = @enumFromInt(3144), .properties = .{ .param_str = "vcC*4", .target_set = TargetSet.initOne(.nvptx) } },
11459 // __nvvm_compiler_warn
11460 .{ .tag = @enumFromInt(3145), .properties = .{ .param_str = "vcC*4", .target_set = TargetSet.initOne(.nvptx) } },
11461 // __nvvm_cos_approx_f
11462 .{ .tag = @enumFromInt(3146), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11463 // __nvvm_cos_approx_ftz_f
11464 .{ .tag = @enumFromInt(3147), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11465 // __nvvm_d2f_rm
11466 .{ .tag = @enumFromInt(3148), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11467 // __nvvm_d2f_rm_ftz
11468 .{ .tag = @enumFromInt(3149), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11469 // __nvvm_d2f_rn
11470 .{ .tag = @enumFromInt(3150), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11471 // __nvvm_d2f_rn_ftz
11472 .{ .tag = @enumFromInt(3151), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11473 // __nvvm_d2f_rp
11474 .{ .tag = @enumFromInt(3152), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11475 // __nvvm_d2f_rp_ftz
11476 .{ .tag = @enumFromInt(3153), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11477 // __nvvm_d2f_rz
11478 .{ .tag = @enumFromInt(3154), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11479 // __nvvm_d2f_rz_ftz
11480 .{ .tag = @enumFromInt(3155), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } },
11481 // __nvvm_d2i_hi
11482 .{ .tag = @enumFromInt(3156), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } },
11483 // __nvvm_d2i_lo
11484 .{ .tag = @enumFromInt(3157), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } },
11485 // __nvvm_d2i_rm
11486 .{ .tag = @enumFromInt(3158), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } },
11487 // __nvvm_d2i_rn
11488 .{ .tag = @enumFromInt(3159), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } },
11489 // __nvvm_d2i_rp
11490 .{ .tag = @enumFromInt(3160), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } },
11491 // __nvvm_d2i_rz
11492 .{ .tag = @enumFromInt(3161), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } },
11493 // __nvvm_d2ll_rm
11494 .{ .tag = @enumFromInt(3162), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } },
11495 // __nvvm_d2ll_rn
11496 .{ .tag = @enumFromInt(3163), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } },
11497 // __nvvm_d2ll_rp
11498 .{ .tag = @enumFromInt(3164), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } },
11499 // __nvvm_d2ll_rz
11500 .{ .tag = @enumFromInt(3165), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } },
11501 // __nvvm_d2ui_rm
11502 .{ .tag = @enumFromInt(3166), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } },
11503 // __nvvm_d2ui_rn
11504 .{ .tag = @enumFromInt(3167), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } },
11505 // __nvvm_d2ui_rp
11506 .{ .tag = @enumFromInt(3168), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } },
11507 // __nvvm_d2ui_rz
11508 .{ .tag = @enumFromInt(3169), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } },
11509 // __nvvm_d2ull_rm
11510 .{ .tag = @enumFromInt(3170), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } },
11511 // __nvvm_d2ull_rn
11512 .{ .tag = @enumFromInt(3171), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } },
11513 // __nvvm_d2ull_rp
11514 .{ .tag = @enumFromInt(3172), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } },
11515 // __nvvm_d2ull_rz
11516 .{ .tag = @enumFromInt(3173), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } },
11517 // __nvvm_div_approx_f
11518 .{ .tag = @enumFromInt(3174), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11519 // __nvvm_div_approx_ftz_f
11520 .{ .tag = @enumFromInt(3175), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11521 // __nvvm_div_rm_d
11522 .{ .tag = @enumFromInt(3176), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11523 // __nvvm_div_rm_f
11524 .{ .tag = @enumFromInt(3177), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11525 // __nvvm_div_rm_ftz_f
11526 .{ .tag = @enumFromInt(3178), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11527 // __nvvm_div_rn_d
11528 .{ .tag = @enumFromInt(3179), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11529 // __nvvm_div_rn_f
11530 .{ .tag = @enumFromInt(3180), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11531 // __nvvm_div_rn_ftz_f
11532 .{ .tag = @enumFromInt(3181), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11533 // __nvvm_div_rp_d
11534 .{ .tag = @enumFromInt(3182), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11535 // __nvvm_div_rp_f
11536 .{ .tag = @enumFromInt(3183), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11537 // __nvvm_div_rp_ftz_f
11538 .{ .tag = @enumFromInt(3184), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11539 // __nvvm_div_rz_d
11540 .{ .tag = @enumFromInt(3185), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11541 // __nvvm_div_rz_f
11542 .{ .tag = @enumFromInt(3186), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11543 // __nvvm_div_rz_ftz_f
11544 .{ .tag = @enumFromInt(3187), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11545 // __nvvm_ex2_approx_d
11546 .{ .tag = @enumFromInt(3188), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11547 // __nvvm_ex2_approx_f
11548 .{ .tag = @enumFromInt(3189), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11549 // __nvvm_ex2_approx_ftz_f
11550 .{ .tag = @enumFromInt(3190), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11551 // __nvvm_f2h_rn
11552 .{ .tag = @enumFromInt(3191), .properties = .{ .param_str = "Usf", .target_set = TargetSet.initOne(.nvptx) } },
11553 // __nvvm_f2h_rn_ftz
11554 .{ .tag = @enumFromInt(3192), .properties = .{ .param_str = "Usf", .target_set = TargetSet.initOne(.nvptx) } },
11555 // __nvvm_f2i_rm
11556 .{ .tag = @enumFromInt(3193), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11557 // __nvvm_f2i_rm_ftz
11558 .{ .tag = @enumFromInt(3194), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11559 // __nvvm_f2i_rn
11560 .{ .tag = @enumFromInt(3195), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11561 // __nvvm_f2i_rn_ftz
11562 .{ .tag = @enumFromInt(3196), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11563 // __nvvm_f2i_rp
11564 .{ .tag = @enumFromInt(3197), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11565 // __nvvm_f2i_rp_ftz
11566 .{ .tag = @enumFromInt(3198), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11567 // __nvvm_f2i_rz
11568 .{ .tag = @enumFromInt(3199), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11569 // __nvvm_f2i_rz_ftz
11570 .{ .tag = @enumFromInt(3200), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } },
11571 // __nvvm_f2ll_rm
11572 .{ .tag = @enumFromInt(3201), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11573 // __nvvm_f2ll_rm_ftz
11574 .{ .tag = @enumFromInt(3202), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11575 // __nvvm_f2ll_rn
11576 .{ .tag = @enumFromInt(3203), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11577 // __nvvm_f2ll_rn_ftz
11578 .{ .tag = @enumFromInt(3204), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11579 // __nvvm_f2ll_rp
11580 .{ .tag = @enumFromInt(3205), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11581 // __nvvm_f2ll_rp_ftz
11582 .{ .tag = @enumFromInt(3206), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11583 // __nvvm_f2ll_rz
11584 .{ .tag = @enumFromInt(3207), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11585 // __nvvm_f2ll_rz_ftz
11586 .{ .tag = @enumFromInt(3208), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } },
11587 // __nvvm_f2ui_rm
11588 .{ .tag = @enumFromInt(3209), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11589 // __nvvm_f2ui_rm_ftz
11590 .{ .tag = @enumFromInt(3210), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11591 // __nvvm_f2ui_rn
11592 .{ .tag = @enumFromInt(3211), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11593 // __nvvm_f2ui_rn_ftz
11594 .{ .tag = @enumFromInt(3212), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11595 // __nvvm_f2ui_rp
11596 .{ .tag = @enumFromInt(3213), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11597 // __nvvm_f2ui_rp_ftz
11598 .{ .tag = @enumFromInt(3214), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11599 // __nvvm_f2ui_rz
11600 .{ .tag = @enumFromInt(3215), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11601 // __nvvm_f2ui_rz_ftz
11602 .{ .tag = @enumFromInt(3216), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } },
11603 // __nvvm_f2ull_rm
11604 .{ .tag = @enumFromInt(3217), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11605 // __nvvm_f2ull_rm_ftz
11606 .{ .tag = @enumFromInt(3218), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11607 // __nvvm_f2ull_rn
11608 .{ .tag = @enumFromInt(3219), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11609 // __nvvm_f2ull_rn_ftz
11610 .{ .tag = @enumFromInt(3220), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11611 // __nvvm_f2ull_rp
11612 .{ .tag = @enumFromInt(3221), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11613 // __nvvm_f2ull_rp_ftz
11614 .{ .tag = @enumFromInt(3222), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11615 // __nvvm_f2ull_rz
11616 .{ .tag = @enumFromInt(3223), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11617 // __nvvm_f2ull_rz_ftz
11618 .{ .tag = @enumFromInt(3224), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } },
11619 // __nvvm_fabs_d
11620 .{ .tag = @enumFromInt(3225), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11621 // __nvvm_fabs_f
11622 .{ .tag = @enumFromInt(3226), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11623 // __nvvm_fabs_ftz_f
11624 .{ .tag = @enumFromInt(3227), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11625 // __nvvm_floor_d
11626 .{ .tag = @enumFromInt(3228), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11627 // __nvvm_floor_f
11628 .{ .tag = @enumFromInt(3229), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11629 // __nvvm_floor_ftz_f
11630 .{ .tag = @enumFromInt(3230), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11631 // __nvvm_fma_rm_d
11632 .{ .tag = @enumFromInt(3231), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } },
11633 // __nvvm_fma_rm_f
11634 .{ .tag = @enumFromInt(3232), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11635 // __nvvm_fma_rm_ftz_f
11636 .{ .tag = @enumFromInt(3233), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11637 // __nvvm_fma_rn_d
11638 .{ .tag = @enumFromInt(3234), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } },
11639 // __nvvm_fma_rn_f
11640 .{ .tag = @enumFromInt(3235), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11641 // __nvvm_fma_rn_ftz_f
11642 .{ .tag = @enumFromInt(3236), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11643 // __nvvm_fma_rp_d
11644 .{ .tag = @enumFromInt(3237), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } },
11645 // __nvvm_fma_rp_f
11646 .{ .tag = @enumFromInt(3238), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11647 // __nvvm_fma_rp_ftz_f
11648 .{ .tag = @enumFromInt(3239), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11649 // __nvvm_fma_rz_d
11650 .{ .tag = @enumFromInt(3240), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } },
11651 // __nvvm_fma_rz_f
11652 .{ .tag = @enumFromInt(3241), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11653 // __nvvm_fma_rz_ftz_f
11654 .{ .tag = @enumFromInt(3242), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } },
11655 // __nvvm_fmax_d
11656 .{ .tag = @enumFromInt(3243), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11657 // __nvvm_fmax_f
11658 .{ .tag = @enumFromInt(3244), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11659 // __nvvm_fmax_ftz_f
11660 .{ .tag = @enumFromInt(3245), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11661 // __nvvm_fmin_d
11662 .{ .tag = @enumFromInt(3246), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11663 // __nvvm_fmin_f
11664 .{ .tag = @enumFromInt(3247), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11665 // __nvvm_fmin_ftz_f
11666 .{ .tag = @enumFromInt(3248), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11667 // __nvvm_i2d_rm
11668 .{ .tag = @enumFromInt(3249), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } },
11669 // __nvvm_i2d_rn
11670 .{ .tag = @enumFromInt(3250), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } },
11671 // __nvvm_i2d_rp
11672 .{ .tag = @enumFromInt(3251), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } },
11673 // __nvvm_i2d_rz
11674 .{ .tag = @enumFromInt(3252), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } },
11675 // __nvvm_i2f_rm
11676 .{ .tag = @enumFromInt(3253), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } },
11677 // __nvvm_i2f_rn
11678 .{ .tag = @enumFromInt(3254), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } },
11679 // __nvvm_i2f_rp
11680 .{ .tag = @enumFromInt(3255), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } },
11681 // __nvvm_i2f_rz
11682 .{ .tag = @enumFromInt(3256), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } },
11683 // __nvvm_isspacep_const
11684 .{ .tag = @enumFromInt(3257), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11685 // __nvvm_isspacep_global
11686 .{ .tag = @enumFromInt(3258), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11687 // __nvvm_isspacep_local
11688 .{ .tag = @enumFromInt(3259), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11689 // __nvvm_isspacep_shared
11690 .{ .tag = @enumFromInt(3260), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11691 // __nvvm_ldg_c
11692 .{ .tag = @enumFromInt(3261), .properties = .{ .param_str = "ccC*", .target_set = TargetSet.initOne(.nvptx) } },
11693 // __nvvm_ldg_c2
11694 .{ .tag = @enumFromInt(3262), .properties = .{ .param_str = "E2cE2cC*", .target_set = TargetSet.initOne(.nvptx) } },
11695 // __nvvm_ldg_c4
11696 .{ .tag = @enumFromInt(3263), .properties = .{ .param_str = "E4cE4cC*", .target_set = TargetSet.initOne(.nvptx) } },
11697 // __nvvm_ldg_d
11698 .{ .tag = @enumFromInt(3264), .properties = .{ .param_str = "ddC*", .target_set = TargetSet.initOne(.nvptx) } },
11699 // __nvvm_ldg_d2
11700 .{ .tag = @enumFromInt(3265), .properties = .{ .param_str = "E2dE2dC*", .target_set = TargetSet.initOne(.nvptx) } },
11701 // __nvvm_ldg_f
11702 .{ .tag = @enumFromInt(3266), .properties = .{ .param_str = "ffC*", .target_set = TargetSet.initOne(.nvptx) } },
11703 // __nvvm_ldg_f2
11704 .{ .tag = @enumFromInt(3267), .properties = .{ .param_str = "E2fE2fC*", .target_set = TargetSet.initOne(.nvptx) } },
11705 // __nvvm_ldg_f4
11706 .{ .tag = @enumFromInt(3268), .properties = .{ .param_str = "E4fE4fC*", .target_set = TargetSet.initOne(.nvptx) } },
11707 // __nvvm_ldg_h
11708 .{ .tag = @enumFromInt(3269), .properties = .{ .param_str = "hhC*", .target_set = TargetSet.initOne(.nvptx) } },
11709 // __nvvm_ldg_h2
11710 .{ .tag = @enumFromInt(3270), .properties = .{ .param_str = "E2hE2hC*", .target_set = TargetSet.initOne(.nvptx) } },
11711 // __nvvm_ldg_i
11712 .{ .tag = @enumFromInt(3271), .properties = .{ .param_str = "iiC*", .target_set = TargetSet.initOne(.nvptx) } },
11713 // __nvvm_ldg_i2
11714 .{ .tag = @enumFromInt(3272), .properties = .{ .param_str = "E2iE2iC*", .target_set = TargetSet.initOne(.nvptx) } },
11715 // __nvvm_ldg_i4
11716 .{ .tag = @enumFromInt(3273), .properties = .{ .param_str = "E4iE4iC*", .target_set = TargetSet.initOne(.nvptx) } },
11717 // __nvvm_ldg_l
11718 .{ .tag = @enumFromInt(3274), .properties = .{ .param_str = "LiLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11719 // __nvvm_ldg_l2
11720 .{ .tag = @enumFromInt(3275), .properties = .{ .param_str = "E2LiE2LiC*", .target_set = TargetSet.initOne(.nvptx) } },
11721 // __nvvm_ldg_ll
11722 .{ .tag = @enumFromInt(3276), .properties = .{ .param_str = "LLiLLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11723 // __nvvm_ldg_ll2
11724 .{ .tag = @enumFromInt(3277), .properties = .{ .param_str = "E2LLiE2LLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11725 // __nvvm_ldg_s
11726 .{ .tag = @enumFromInt(3278), .properties = .{ .param_str = "ssC*", .target_set = TargetSet.initOne(.nvptx) } },
11727 // __nvvm_ldg_s2
11728 .{ .tag = @enumFromInt(3279), .properties = .{ .param_str = "E2sE2sC*", .target_set = TargetSet.initOne(.nvptx) } },
11729 // __nvvm_ldg_s4
11730 .{ .tag = @enumFromInt(3280), .properties = .{ .param_str = "E4sE4sC*", .target_set = TargetSet.initOne(.nvptx) } },
11731 // __nvvm_ldg_sc
11732 .{ .tag = @enumFromInt(3281), .properties = .{ .param_str = "ScScC*", .target_set = TargetSet.initOne(.nvptx) } },
11733 // __nvvm_ldg_sc2
11734 .{ .tag = @enumFromInt(3282), .properties = .{ .param_str = "E2ScE2ScC*", .target_set = TargetSet.initOne(.nvptx) } },
11735 // __nvvm_ldg_sc4
11736 .{ .tag = @enumFromInt(3283), .properties = .{ .param_str = "E4ScE4ScC*", .target_set = TargetSet.initOne(.nvptx) } },
11737 // __nvvm_ldg_uc
11738 .{ .tag = @enumFromInt(3284), .properties = .{ .param_str = "UcUcC*", .target_set = TargetSet.initOne(.nvptx) } },
11739 // __nvvm_ldg_uc2
11740 .{ .tag = @enumFromInt(3285), .properties = .{ .param_str = "E2UcE2UcC*", .target_set = TargetSet.initOne(.nvptx) } },
11741 // __nvvm_ldg_uc4
11742 .{ .tag = @enumFromInt(3286), .properties = .{ .param_str = "E4UcE4UcC*", .target_set = TargetSet.initOne(.nvptx) } },
11743 // __nvvm_ldg_ui
11744 .{ .tag = @enumFromInt(3287), .properties = .{ .param_str = "UiUiC*", .target_set = TargetSet.initOne(.nvptx) } },
11745 // __nvvm_ldg_ui2
11746 .{ .tag = @enumFromInt(3288), .properties = .{ .param_str = "E2UiE2UiC*", .target_set = TargetSet.initOne(.nvptx) } },
11747 // __nvvm_ldg_ui4
11748 .{ .tag = @enumFromInt(3289), .properties = .{ .param_str = "E4UiE4UiC*", .target_set = TargetSet.initOne(.nvptx) } },
11749 // __nvvm_ldg_ul
11750 .{ .tag = @enumFromInt(3290), .properties = .{ .param_str = "ULiULiC*", .target_set = TargetSet.initOne(.nvptx) } },
11751 // __nvvm_ldg_ul2
11752 .{ .tag = @enumFromInt(3291), .properties = .{ .param_str = "E2ULiE2ULiC*", .target_set = TargetSet.initOne(.nvptx) } },
11753 // __nvvm_ldg_ull
11754 .{ .tag = @enumFromInt(3292), .properties = .{ .param_str = "ULLiULLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11755 // __nvvm_ldg_ull2
11756 .{ .tag = @enumFromInt(3293), .properties = .{ .param_str = "E2ULLiE2ULLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11757 // __nvvm_ldg_us
11758 .{ .tag = @enumFromInt(3294), .properties = .{ .param_str = "UsUsC*", .target_set = TargetSet.initOne(.nvptx) } },
11759 // __nvvm_ldg_us2
11760 .{ .tag = @enumFromInt(3295), .properties = .{ .param_str = "E2UsE2UsC*", .target_set = TargetSet.initOne(.nvptx) } },
11761 // __nvvm_ldg_us4
11762 .{ .tag = @enumFromInt(3296), .properties = .{ .param_str = "E4UsE4UsC*", .target_set = TargetSet.initOne(.nvptx) } },
11763 // __nvvm_ldu_c
11764 .{ .tag = @enumFromInt(3297), .properties = .{ .param_str = "ccC*", .target_set = TargetSet.initOne(.nvptx) } },
11765 // __nvvm_ldu_c2
11766 .{ .tag = @enumFromInt(3298), .properties = .{ .param_str = "E2cE2cC*", .target_set = TargetSet.initOne(.nvptx) } },
11767 // __nvvm_ldu_c4
11768 .{ .tag = @enumFromInt(3299), .properties = .{ .param_str = "E4cE4cC*", .target_set = TargetSet.initOne(.nvptx) } },
11769 // __nvvm_ldu_d
11770 .{ .tag = @enumFromInt(3300), .properties = .{ .param_str = "ddC*", .target_set = TargetSet.initOne(.nvptx) } },
11771 // __nvvm_ldu_d2
11772 .{ .tag = @enumFromInt(3301), .properties = .{ .param_str = "E2dE2dC*", .target_set = TargetSet.initOne(.nvptx) } },
11773 // __nvvm_ldu_f
11774 .{ .tag = @enumFromInt(3302), .properties = .{ .param_str = "ffC*", .target_set = TargetSet.initOne(.nvptx) } },
11775 // __nvvm_ldu_f2
11776 .{ .tag = @enumFromInt(3303), .properties = .{ .param_str = "E2fE2fC*", .target_set = TargetSet.initOne(.nvptx) } },
11777 // __nvvm_ldu_f4
11778 .{ .tag = @enumFromInt(3304), .properties = .{ .param_str = "E4fE4fC*", .target_set = TargetSet.initOne(.nvptx) } },
11779 // __nvvm_ldu_h
11780 .{ .tag = @enumFromInt(3305), .properties = .{ .param_str = "hhC*", .target_set = TargetSet.initOne(.nvptx) } },
11781 // __nvvm_ldu_h2
11782 .{ .tag = @enumFromInt(3306), .properties = .{ .param_str = "E2hE2hC*", .target_set = TargetSet.initOne(.nvptx) } },
11783 // __nvvm_ldu_i
11784 .{ .tag = @enumFromInt(3307), .properties = .{ .param_str = "iiC*", .target_set = TargetSet.initOne(.nvptx) } },
11785 // __nvvm_ldu_i2
11786 .{ .tag = @enumFromInt(3308), .properties = .{ .param_str = "E2iE2iC*", .target_set = TargetSet.initOne(.nvptx) } },
11787 // __nvvm_ldu_i4
11788 .{ .tag = @enumFromInt(3309), .properties = .{ .param_str = "E4iE4iC*", .target_set = TargetSet.initOne(.nvptx) } },
11789 // __nvvm_ldu_l
11790 .{ .tag = @enumFromInt(3310), .properties = .{ .param_str = "LiLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11791 // __nvvm_ldu_l2
11792 .{ .tag = @enumFromInt(3311), .properties = .{ .param_str = "E2LiE2LiC*", .target_set = TargetSet.initOne(.nvptx) } },
11793 // __nvvm_ldu_ll
11794 .{ .tag = @enumFromInt(3312), .properties = .{ .param_str = "LLiLLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11795 // __nvvm_ldu_ll2
11796 .{ .tag = @enumFromInt(3313), .properties = .{ .param_str = "E2LLiE2LLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11797 // __nvvm_ldu_s
11798 .{ .tag = @enumFromInt(3314), .properties = .{ .param_str = "ssC*", .target_set = TargetSet.initOne(.nvptx) } },
11799 // __nvvm_ldu_s2
11800 .{ .tag = @enumFromInt(3315), .properties = .{ .param_str = "E2sE2sC*", .target_set = TargetSet.initOne(.nvptx) } },
11801 // __nvvm_ldu_s4
11802 .{ .tag = @enumFromInt(3316), .properties = .{ .param_str = "E4sE4sC*", .target_set = TargetSet.initOne(.nvptx) } },
11803 // __nvvm_ldu_sc
11804 .{ .tag = @enumFromInt(3317), .properties = .{ .param_str = "ScScC*", .target_set = TargetSet.initOne(.nvptx) } },
11805 // __nvvm_ldu_sc2
11806 .{ .tag = @enumFromInt(3318), .properties = .{ .param_str = "E2ScE2ScC*", .target_set = TargetSet.initOne(.nvptx) } },
11807 // __nvvm_ldu_sc4
11808 .{ .tag = @enumFromInt(3319), .properties = .{ .param_str = "E4ScE4ScC*", .target_set = TargetSet.initOne(.nvptx) } },
11809 // __nvvm_ldu_uc
11810 .{ .tag = @enumFromInt(3320), .properties = .{ .param_str = "UcUcC*", .target_set = TargetSet.initOne(.nvptx) } },
11811 // __nvvm_ldu_uc2
11812 .{ .tag = @enumFromInt(3321), .properties = .{ .param_str = "E2UcE2UcC*", .target_set = TargetSet.initOne(.nvptx) } },
11813 // __nvvm_ldu_uc4
11814 .{ .tag = @enumFromInt(3322), .properties = .{ .param_str = "E4UcE4UcC*", .target_set = TargetSet.initOne(.nvptx) } },
11815 // __nvvm_ldu_ui
11816 .{ .tag = @enumFromInt(3323), .properties = .{ .param_str = "UiUiC*", .target_set = TargetSet.initOne(.nvptx) } },
11817 // __nvvm_ldu_ui2
11818 .{ .tag = @enumFromInt(3324), .properties = .{ .param_str = "E2UiE2UiC*", .target_set = TargetSet.initOne(.nvptx) } },
11819 // __nvvm_ldu_ui4
11820 .{ .tag = @enumFromInt(3325), .properties = .{ .param_str = "E4UiE4UiC*", .target_set = TargetSet.initOne(.nvptx) } },
11821 // __nvvm_ldu_ul
11822 .{ .tag = @enumFromInt(3326), .properties = .{ .param_str = "ULiULiC*", .target_set = TargetSet.initOne(.nvptx) } },
11823 // __nvvm_ldu_ul2
11824 .{ .tag = @enumFromInt(3327), .properties = .{ .param_str = "E2ULiE2ULiC*", .target_set = TargetSet.initOne(.nvptx) } },
11825 // __nvvm_ldu_ull
11826 .{ .tag = @enumFromInt(3328), .properties = .{ .param_str = "ULLiULLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11827 // __nvvm_ldu_ull2
11828 .{ .tag = @enumFromInt(3329), .properties = .{ .param_str = "E2ULLiE2ULLiC*", .target_set = TargetSet.initOne(.nvptx) } },
11829 // __nvvm_ldu_us
11830 .{ .tag = @enumFromInt(3330), .properties = .{ .param_str = "UsUsC*", .target_set = TargetSet.initOne(.nvptx) } },
11831 // __nvvm_ldu_us2
11832 .{ .tag = @enumFromInt(3331), .properties = .{ .param_str = "E2UsE2UsC*", .target_set = TargetSet.initOne(.nvptx) } },
11833 // __nvvm_ldu_us4
11834 .{ .tag = @enumFromInt(3332), .properties = .{ .param_str = "E4UsE4UsC*", .target_set = TargetSet.initOne(.nvptx) } },
11835 // __nvvm_lg2_approx_d
11836 .{ .tag = @enumFromInt(3333), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11837 // __nvvm_lg2_approx_f
11838 .{ .tag = @enumFromInt(3334), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11839 // __nvvm_lg2_approx_ftz_f
11840 .{ .tag = @enumFromInt(3335), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11841 // __nvvm_ll2d_rm
11842 .{ .tag = @enumFromInt(3336), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } },
11843 // __nvvm_ll2d_rn
11844 .{ .tag = @enumFromInt(3337), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } },
11845 // __nvvm_ll2d_rp
11846 .{ .tag = @enumFromInt(3338), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } },
11847 // __nvvm_ll2d_rz
11848 .{ .tag = @enumFromInt(3339), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } },
11849 // __nvvm_ll2f_rm
11850 .{ .tag = @enumFromInt(3340), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } },
11851 // __nvvm_ll2f_rn
11852 .{ .tag = @enumFromInt(3341), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } },
11853 // __nvvm_ll2f_rp
11854 .{ .tag = @enumFromInt(3342), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } },
11855 // __nvvm_ll2f_rz
11856 .{ .tag = @enumFromInt(3343), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } },
11857 // __nvvm_lohi_i2d
11858 .{ .tag = @enumFromInt(3344), .properties = .{ .param_str = "dii", .target_set = TargetSet.initOne(.nvptx) } },
11859 // __nvvm_membar_cta
11860 .{ .tag = @enumFromInt(3345), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } },
11861 // __nvvm_membar_gl
11862 .{ .tag = @enumFromInt(3346), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } },
11863 // __nvvm_membar_sys
11864 .{ .tag = @enumFromInt(3347), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } },
11865 // __nvvm_memcpy
11866 .{ .tag = @enumFromInt(3348), .properties = .{ .param_str = "vUc*Uc*zi", .target_set = TargetSet.initOne(.nvptx) } },
11867 // __nvvm_memset
11868 .{ .tag = @enumFromInt(3349), .properties = .{ .param_str = "vUc*Uczi", .target_set = TargetSet.initOne(.nvptx) } },
11869 // __nvvm_mul24_i
11870 .{ .tag = @enumFromInt(3350), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.nvptx) } },
11871 // __nvvm_mul24_ui
11872 .{ .tag = @enumFromInt(3351), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.nvptx) } },
11873 // __nvvm_mul_rm_d
11874 .{ .tag = @enumFromInt(3352), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11875 // __nvvm_mul_rm_f
11876 .{ .tag = @enumFromInt(3353), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11877 // __nvvm_mul_rm_ftz_f
11878 .{ .tag = @enumFromInt(3354), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11879 // __nvvm_mul_rn_d
11880 .{ .tag = @enumFromInt(3355), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11881 // __nvvm_mul_rn_f
11882 .{ .tag = @enumFromInt(3356), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11883 // __nvvm_mul_rn_ftz_f
11884 .{ .tag = @enumFromInt(3357), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11885 // __nvvm_mul_rp_d
11886 .{ .tag = @enumFromInt(3358), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11887 // __nvvm_mul_rp_f
11888 .{ .tag = @enumFromInt(3359), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11889 // __nvvm_mul_rp_ftz_f
11890 .{ .tag = @enumFromInt(3360), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11891 // __nvvm_mul_rz_d
11892 .{ .tag = @enumFromInt(3361), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } },
11893 // __nvvm_mul_rz_f
11894 .{ .tag = @enumFromInt(3362), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11895 // __nvvm_mul_rz_ftz_f
11896 .{ .tag = @enumFromInt(3363), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } },
11897 // __nvvm_mulhi_i
11898 .{ .tag = @enumFromInt(3364), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.nvptx) } },
11899 // __nvvm_mulhi_ll
11900 .{ .tag = @enumFromInt(3365), .properties = .{ .param_str = "LLiLLiLLi", .target_set = TargetSet.initOne(.nvptx) } },
11901 // __nvvm_mulhi_ui
11902 .{ .tag = @enumFromInt(3366), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.nvptx) } },
11903 // __nvvm_mulhi_ull
11904 .{ .tag = @enumFromInt(3367), .properties = .{ .param_str = "ULLiULLiULLi", .target_set = TargetSet.initOne(.nvptx) } },
11905 // __nvvm_prmt
11906 .{ .tag = @enumFromInt(3368), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.nvptx) } },
11907 // __nvvm_rcp_approx_ftz_d
11908 .{ .tag = @enumFromInt(3369), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11909 // __nvvm_rcp_approx_ftz_f
11910 .{ .tag = @enumFromInt(3370), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11911 // __nvvm_rcp_rm_d
11912 .{ .tag = @enumFromInt(3371), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11913 // __nvvm_rcp_rm_f
11914 .{ .tag = @enumFromInt(3372), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11915 // __nvvm_rcp_rm_ftz_f
11916 .{ .tag = @enumFromInt(3373), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11917 // __nvvm_rcp_rn_d
11918 .{ .tag = @enumFromInt(3374), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11919 // __nvvm_rcp_rn_f
11920 .{ .tag = @enumFromInt(3375), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11921 // __nvvm_rcp_rn_ftz_f
11922 .{ .tag = @enumFromInt(3376), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11923 // __nvvm_rcp_rp_d
11924 .{ .tag = @enumFromInt(3377), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11925 // __nvvm_rcp_rp_f
11926 .{ .tag = @enumFromInt(3378), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11927 // __nvvm_rcp_rp_ftz_f
11928 .{ .tag = @enumFromInt(3379), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11929 // __nvvm_rcp_rz_d
11930 .{ .tag = @enumFromInt(3380), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
11931 // __nvvm_rcp_rz_f
11932 .{ .tag = @enumFromInt(3381), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11933 // __nvvm_rcp_rz_ftz_f
11934 .{ .tag = @enumFromInt(3382), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
11935 // __nvvm_read_ptx_sreg_clock
11936 .{ .tag = @enumFromInt(3383), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } },
11937 // __nvvm_read_ptx_sreg_clock64
11938 .{ .tag = @enumFromInt(3384), .properties = .{ .param_str = "LLi", .target_set = TargetSet.initOne(.nvptx) } },
11939 // __nvvm_read_ptx_sreg_ctaid_w
11940 .{ .tag = @enumFromInt(3385), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11941 // __nvvm_read_ptx_sreg_ctaid_x
11942 .{ .tag = @enumFromInt(3386), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11943 // __nvvm_read_ptx_sreg_ctaid_y
11944 .{ .tag = @enumFromInt(3387), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11945 // __nvvm_read_ptx_sreg_ctaid_z
11946 .{ .tag = @enumFromInt(3388), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11947 // __nvvm_read_ptx_sreg_gridid
11948 .{ .tag = @enumFromInt(3389), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11949 // __nvvm_read_ptx_sreg_laneid
11950 .{ .tag = @enumFromInt(3390), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11951 // __nvvm_read_ptx_sreg_lanemask_eq
11952 .{ .tag = @enumFromInt(3391), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11953 // __nvvm_read_ptx_sreg_lanemask_ge
11954 .{ .tag = @enumFromInt(3392), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11955 // __nvvm_read_ptx_sreg_lanemask_gt
11956 .{ .tag = @enumFromInt(3393), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11957 // __nvvm_read_ptx_sreg_lanemask_le
11958 .{ .tag = @enumFromInt(3394), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11959 // __nvvm_read_ptx_sreg_lanemask_lt
11960 .{ .tag = @enumFromInt(3395), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11961 // __nvvm_read_ptx_sreg_nctaid_w
11962 .{ .tag = @enumFromInt(3396), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11963 // __nvvm_read_ptx_sreg_nctaid_x
11964 .{ .tag = @enumFromInt(3397), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11965 // __nvvm_read_ptx_sreg_nctaid_y
11966 .{ .tag = @enumFromInt(3398), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11967 // __nvvm_read_ptx_sreg_nctaid_z
11968 .{ .tag = @enumFromInt(3399), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11969 // __nvvm_read_ptx_sreg_nsmid
11970 .{ .tag = @enumFromInt(3400), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11971 // __nvvm_read_ptx_sreg_ntid_w
11972 .{ .tag = @enumFromInt(3401), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11973 // __nvvm_read_ptx_sreg_ntid_x
11974 .{ .tag = @enumFromInt(3402), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11975 // __nvvm_read_ptx_sreg_ntid_y
11976 .{ .tag = @enumFromInt(3403), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11977 // __nvvm_read_ptx_sreg_ntid_z
11978 .{ .tag = @enumFromInt(3404), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11979 // __nvvm_read_ptx_sreg_nwarpid
11980 .{ .tag = @enumFromInt(3405), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11981 // __nvvm_read_ptx_sreg_pm0
11982 .{ .tag = @enumFromInt(3406), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } },
11983 // __nvvm_read_ptx_sreg_pm1
11984 .{ .tag = @enumFromInt(3407), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } },
11985 // __nvvm_read_ptx_sreg_pm2
11986 .{ .tag = @enumFromInt(3408), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } },
11987 // __nvvm_read_ptx_sreg_pm3
11988 .{ .tag = @enumFromInt(3409), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } },
11989 // __nvvm_read_ptx_sreg_smid
11990 .{ .tag = @enumFromInt(3410), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11991 // __nvvm_read_ptx_sreg_tid_w
11992 .{ .tag = @enumFromInt(3411), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11993 // __nvvm_read_ptx_sreg_tid_x
11994 .{ .tag = @enumFromInt(3412), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11995 // __nvvm_read_ptx_sreg_tid_y
11996 .{ .tag = @enumFromInt(3413), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11997 // __nvvm_read_ptx_sreg_tid_z
11998 .{ .tag = @enumFromInt(3414), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
11999 // __nvvm_read_ptx_sreg_warpid
12000 .{ .tag = @enumFromInt(3415), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } },
12001 // __nvvm_round_d
12002 .{ .tag = @enumFromInt(3416), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12003 // __nvvm_round_f
12004 .{ .tag = @enumFromInt(3417), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12005 // __nvvm_round_ftz_f
12006 .{ .tag = @enumFromInt(3418), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12007 // __nvvm_rsqrt_approx_d
12008 .{ .tag = @enumFromInt(3419), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12009 // __nvvm_rsqrt_approx_f
12010 .{ .tag = @enumFromInt(3420), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12011 // __nvvm_rsqrt_approx_ftz_f
12012 .{ .tag = @enumFromInt(3421), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12013 // __nvvm_sad_i
12014 .{ .tag = @enumFromInt(3422), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } },
12015 // __nvvm_sad_ui
12016 .{ .tag = @enumFromInt(3423), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.nvptx) } },
12017 // __nvvm_saturate_d
12018 .{ .tag = @enumFromInt(3424), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12019 // __nvvm_saturate_f
12020 .{ .tag = @enumFromInt(3425), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12021 // __nvvm_saturate_ftz_f
12022 .{ .tag = @enumFromInt(3426), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12023 // __nvvm_shfl_bfly_f32
12024 .{ .tag = @enumFromInt(3427), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } },
12025 // __nvvm_shfl_bfly_i32
12026 .{ .tag = @enumFromInt(3428), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } },
12027 // __nvvm_shfl_down_f32
12028 .{ .tag = @enumFromInt(3429), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } },
12029 // __nvvm_shfl_down_i32
12030 .{ .tag = @enumFromInt(3430), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } },
12031 // __nvvm_shfl_idx_f32
12032 .{ .tag = @enumFromInt(3431), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } },
12033 // __nvvm_shfl_idx_i32
12034 .{ .tag = @enumFromInt(3432), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } },
12035 // __nvvm_shfl_up_f32
12036 .{ .tag = @enumFromInt(3433), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } },
12037 // __nvvm_shfl_up_i32
12038 .{ .tag = @enumFromInt(3434), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } },
12039 // __nvvm_sin_approx_f
12040 .{ .tag = @enumFromInt(3435), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12041 // __nvvm_sin_approx_ftz_f
12042 .{ .tag = @enumFromInt(3436), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12043 // __nvvm_sqrt_approx_f
12044 .{ .tag = @enumFromInt(3437), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12045 // __nvvm_sqrt_approx_ftz_f
12046 .{ .tag = @enumFromInt(3438), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12047 // __nvvm_sqrt_rm_d
12048 .{ .tag = @enumFromInt(3439), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12049 // __nvvm_sqrt_rm_f
12050 .{ .tag = @enumFromInt(3440), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12051 // __nvvm_sqrt_rm_ftz_f
12052 .{ .tag = @enumFromInt(3441), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12053 // __nvvm_sqrt_rn_d
12054 .{ .tag = @enumFromInt(3442), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12055 // __nvvm_sqrt_rn_f
12056 .{ .tag = @enumFromInt(3443), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12057 // __nvvm_sqrt_rn_ftz_f
12058 .{ .tag = @enumFromInt(3444), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12059 // __nvvm_sqrt_rp_d
12060 .{ .tag = @enumFromInt(3445), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12061 // __nvvm_sqrt_rp_f
12062 .{ .tag = @enumFromInt(3446), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12063 // __nvvm_sqrt_rp_ftz_f
12064 .{ .tag = @enumFromInt(3447), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12065 // __nvvm_sqrt_rz_d
12066 .{ .tag = @enumFromInt(3448), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12067 // __nvvm_sqrt_rz_f
12068 .{ .tag = @enumFromInt(3449), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12069 // __nvvm_sqrt_rz_ftz_f
12070 .{ .tag = @enumFromInt(3450), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12071 // __nvvm_trunc_d
12072 .{ .tag = @enumFromInt(3451), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } },
12073 // __nvvm_trunc_f
12074 .{ .tag = @enumFromInt(3452), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12075 // __nvvm_trunc_ftz_f
12076 .{ .tag = @enumFromInt(3453), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } },
12077 // __nvvm_ui2d_rm
12078 .{ .tag = @enumFromInt(3454), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } },
12079 // __nvvm_ui2d_rn
12080 .{ .tag = @enumFromInt(3455), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } },
12081 // __nvvm_ui2d_rp
12082 .{ .tag = @enumFromInt(3456), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } },
12083 // __nvvm_ui2d_rz
12084 .{ .tag = @enumFromInt(3457), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } },
12085 // __nvvm_ui2f_rm
12086 .{ .tag = @enumFromInt(3458), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } },
12087 // __nvvm_ui2f_rn
12088 .{ .tag = @enumFromInt(3459), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } },
12089 // __nvvm_ui2f_rp
12090 .{ .tag = @enumFromInt(3460), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } },
12091 // __nvvm_ui2f_rz
12092 .{ .tag = @enumFromInt(3461), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } },
12093 // __nvvm_ull2d_rm
12094 .{ .tag = @enumFromInt(3462), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } },
12095 // __nvvm_ull2d_rn
12096 .{ .tag = @enumFromInt(3463), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } },
12097 // __nvvm_ull2d_rp
12098 .{ .tag = @enumFromInt(3464), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } },
12099 // __nvvm_ull2d_rz
12100 .{ .tag = @enumFromInt(3465), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } },
12101 // __nvvm_ull2f_rm
12102 .{ .tag = @enumFromInt(3466), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } },
12103 // __nvvm_ull2f_rn
12104 .{ .tag = @enumFromInt(3467), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } },
12105 // __nvvm_ull2f_rp
12106 .{ .tag = @enumFromInt(3468), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } },
12107 // __nvvm_ull2f_rz
12108 .{ .tag = @enumFromInt(3469), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } },
12109 // __nvvm_vote_all
12110 .{ .tag = @enumFromInt(3470), .properties = .{ .param_str = "bb", .target_set = TargetSet.initOne(.nvptx) } },
12111 // __nvvm_vote_any
12112 .{ .tag = @enumFromInt(3471), .properties = .{ .param_str = "bb", .target_set = TargetSet.initOne(.nvptx) } },
12113 // __nvvm_vote_ballot
12114 .{ .tag = @enumFromInt(3472), .properties = .{ .param_str = "Uib", .target_set = TargetSet.initOne(.nvptx) } },
12115 // __nvvm_vote_uni
12116 .{ .tag = @enumFromInt(3473), .properties = .{ .param_str = "bb", .target_set = TargetSet.initOne(.nvptx) } },
12117 // __popcnt
12118 .{ .tag = @enumFromInt(3474), .properties = .{ .param_str = "UiUi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } },
12119 // __popcnt16
12120 .{ .tag = @enumFromInt(3475), .properties = .{ .param_str = "UsUs", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } },
12121 // __popcnt64
12122 .{ .tag = @enumFromInt(3476), .properties = .{ .param_str = "UWiUWi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } },
12123 // __rdtsc
12124 .{ .tag = @enumFromInt(3477), .properties = .{ .param_str = "UOi", .target_set = TargetSet.initOne(.x86) } },
12125 // __sev
12126 .{ .tag = @enumFromInt(3478), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
12127 // __sevl
12128 .{ .tag = @enumFromInt(3479), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
12129 // __sigsetjmp
12130 .{ .tag = @enumFromInt(3480), .properties = .{ .param_str = "iSJi", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
12131 // __sinpi
12132 .{ .tag = @enumFromInt(3481), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12133 // __sinpif
12134 .{ .tag = @enumFromInt(3482), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12135 // __sync_add_and_fetch
12136 .{ .tag = @enumFromInt(3483), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12137 // __sync_add_and_fetch_1
12138 .{ .tag = @enumFromInt(3484), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12139 // __sync_add_and_fetch_16
12140 .{ .tag = @enumFromInt(3485), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12141 // __sync_add_and_fetch_2
12142 .{ .tag = @enumFromInt(3486), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12143 // __sync_add_and_fetch_4
12144 .{ .tag = @enumFromInt(3487), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12145 // __sync_add_and_fetch_8
12146 .{ .tag = @enumFromInt(3488), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12147 // __sync_and_and_fetch
12148 .{ .tag = @enumFromInt(3489), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12149 // __sync_and_and_fetch_1
12150 .{ .tag = @enumFromInt(3490), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12151 // __sync_and_and_fetch_16
12152 .{ .tag = @enumFromInt(3491), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12153 // __sync_and_and_fetch_2
12154 .{ .tag = @enumFromInt(3492), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12155 // __sync_and_and_fetch_4
12156 .{ .tag = @enumFromInt(3493), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12157 // __sync_and_and_fetch_8
12158 .{ .tag = @enumFromInt(3494), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12159 // __sync_bool_compare_and_swap
12160 .{ .tag = @enumFromInt(3495), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12161 // __sync_bool_compare_and_swap_1
12162 .{ .tag = @enumFromInt(3496), .properties = .{ .param_str = "bcD*cc.", .attributes = .{ .custom_typecheck = true } } },
12163 // __sync_bool_compare_and_swap_16
12164 .{ .tag = @enumFromInt(3497), .properties = .{ .param_str = "bLLLiD*LLLiLLLi.", .attributes = .{ .custom_typecheck = true } } },
12165 // __sync_bool_compare_and_swap_2
12166 .{ .tag = @enumFromInt(3498), .properties = .{ .param_str = "bsD*ss.", .attributes = .{ .custom_typecheck = true } } },
12167 // __sync_bool_compare_and_swap_4
12168 .{ .tag = @enumFromInt(3499), .properties = .{ .param_str = "biD*ii.", .attributes = .{ .custom_typecheck = true } } },
12169 // __sync_bool_compare_and_swap_8
12170 .{ .tag = @enumFromInt(3500), .properties = .{ .param_str = "bLLiD*LLiLLi.", .attributes = .{ .custom_typecheck = true } } },
12171 // __sync_fetch_and_add
12172 .{ .tag = @enumFromInt(3501), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12173 // __sync_fetch_and_add_1
12174 .{ .tag = @enumFromInt(3502), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12175 // __sync_fetch_and_add_16
12176 .{ .tag = @enumFromInt(3503), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12177 // __sync_fetch_and_add_2
12178 .{ .tag = @enumFromInt(3504), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12179 // __sync_fetch_and_add_4
12180 .{ .tag = @enumFromInt(3505), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12181 // __sync_fetch_and_add_8
12182 .{ .tag = @enumFromInt(3506), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12183 // __sync_fetch_and_and
12184 .{ .tag = @enumFromInt(3507), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12185 // __sync_fetch_and_and_1
12186 .{ .tag = @enumFromInt(3508), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12187 // __sync_fetch_and_and_16
12188 .{ .tag = @enumFromInt(3509), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12189 // __sync_fetch_and_and_2
12190 .{ .tag = @enumFromInt(3510), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12191 // __sync_fetch_and_and_4
12192 .{ .tag = @enumFromInt(3511), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12193 // __sync_fetch_and_and_8
12194 .{ .tag = @enumFromInt(3512), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12195 // __sync_fetch_and_max
12196 .{ .tag = @enumFromInt(3513), .properties = .{ .param_str = "iiD*i" } },
12197 // __sync_fetch_and_min
12198 .{ .tag = @enumFromInt(3514), .properties = .{ .param_str = "iiD*i" } },
12199 // __sync_fetch_and_nand
12200 .{ .tag = @enumFromInt(3515), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12201 // __sync_fetch_and_nand_1
12202 .{ .tag = @enumFromInt(3516), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12203 // __sync_fetch_and_nand_16
12204 .{ .tag = @enumFromInt(3517), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12205 // __sync_fetch_and_nand_2
12206 .{ .tag = @enumFromInt(3518), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12207 // __sync_fetch_and_nand_4
12208 .{ .tag = @enumFromInt(3519), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12209 // __sync_fetch_and_nand_8
12210 .{ .tag = @enumFromInt(3520), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12211 // __sync_fetch_and_or
12212 .{ .tag = @enumFromInt(3521), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12213 // __sync_fetch_and_or_1
12214 .{ .tag = @enumFromInt(3522), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12215 // __sync_fetch_and_or_16
12216 .{ .tag = @enumFromInt(3523), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12217 // __sync_fetch_and_or_2
12218 .{ .tag = @enumFromInt(3524), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12219 // __sync_fetch_and_or_4
12220 .{ .tag = @enumFromInt(3525), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12221 // __sync_fetch_and_or_8
12222 .{ .tag = @enumFromInt(3526), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12223 // __sync_fetch_and_sub
12224 .{ .tag = @enumFromInt(3527), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12225 // __sync_fetch_and_sub_1
12226 .{ .tag = @enumFromInt(3528), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12227 // __sync_fetch_and_sub_16
12228 .{ .tag = @enumFromInt(3529), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12229 // __sync_fetch_and_sub_2
12230 .{ .tag = @enumFromInt(3530), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12231 // __sync_fetch_and_sub_4
12232 .{ .tag = @enumFromInt(3531), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12233 // __sync_fetch_and_sub_8
12234 .{ .tag = @enumFromInt(3532), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12235 // __sync_fetch_and_umax
12236 .{ .tag = @enumFromInt(3533), .properties = .{ .param_str = "UiUiD*Ui" } },
12237 // __sync_fetch_and_umin
12238 .{ .tag = @enumFromInt(3534), .properties = .{ .param_str = "UiUiD*Ui" } },
12239 // __sync_fetch_and_xor
12240 .{ .tag = @enumFromInt(3535), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12241 // __sync_fetch_and_xor_1
12242 .{ .tag = @enumFromInt(3536), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12243 // __sync_fetch_and_xor_16
12244 .{ .tag = @enumFromInt(3537), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12245 // __sync_fetch_and_xor_2
12246 .{ .tag = @enumFromInt(3538), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12247 // __sync_fetch_and_xor_4
12248 .{ .tag = @enumFromInt(3539), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12249 // __sync_fetch_and_xor_8
12250 .{ .tag = @enumFromInt(3540), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12251 // __sync_lock_release
12252 .{ .tag = @enumFromInt(3541), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12253 // __sync_lock_release_1
12254 .{ .tag = @enumFromInt(3542), .properties = .{ .param_str = "vcD*.", .attributes = .{ .custom_typecheck = true } } },
12255 // __sync_lock_release_16
12256 .{ .tag = @enumFromInt(3543), .properties = .{ .param_str = "vLLLiD*.", .attributes = .{ .custom_typecheck = true } } },
12257 // __sync_lock_release_2
12258 .{ .tag = @enumFromInt(3544), .properties = .{ .param_str = "vsD*.", .attributes = .{ .custom_typecheck = true } } },
12259 // __sync_lock_release_4
12260 .{ .tag = @enumFromInt(3545), .properties = .{ .param_str = "viD*.", .attributes = .{ .custom_typecheck = true } } },
12261 // __sync_lock_release_8
12262 .{ .tag = @enumFromInt(3546), .properties = .{ .param_str = "vLLiD*.", .attributes = .{ .custom_typecheck = true } } },
12263 // __sync_lock_test_and_set
12264 .{ .tag = @enumFromInt(3547), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12265 // __sync_lock_test_and_set_1
12266 .{ .tag = @enumFromInt(3548), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12267 // __sync_lock_test_and_set_16
12268 .{ .tag = @enumFromInt(3549), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12269 // __sync_lock_test_and_set_2
12270 .{ .tag = @enumFromInt(3550), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12271 // __sync_lock_test_and_set_4
12272 .{ .tag = @enumFromInt(3551), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12273 // __sync_lock_test_and_set_8
12274 .{ .tag = @enumFromInt(3552), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12275 // __sync_nand_and_fetch
12276 .{ .tag = @enumFromInt(3553), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12277 // __sync_nand_and_fetch_1
12278 .{ .tag = @enumFromInt(3554), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12279 // __sync_nand_and_fetch_16
12280 .{ .tag = @enumFromInt(3555), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12281 // __sync_nand_and_fetch_2
12282 .{ .tag = @enumFromInt(3556), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12283 // __sync_nand_and_fetch_4
12284 .{ .tag = @enumFromInt(3557), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12285 // __sync_nand_and_fetch_8
12286 .{ .tag = @enumFromInt(3558), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12287 // __sync_or_and_fetch
12288 .{ .tag = @enumFromInt(3559), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12289 // __sync_or_and_fetch_1
12290 .{ .tag = @enumFromInt(3560), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12291 // __sync_or_and_fetch_16
12292 .{ .tag = @enumFromInt(3561), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12293 // __sync_or_and_fetch_2
12294 .{ .tag = @enumFromInt(3562), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12295 // __sync_or_and_fetch_4
12296 .{ .tag = @enumFromInt(3563), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12297 // __sync_or_and_fetch_8
12298 .{ .tag = @enumFromInt(3564), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12299 // __sync_sub_and_fetch
12300 .{ .tag = @enumFromInt(3565), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12301 // __sync_sub_and_fetch_1
12302 .{ .tag = @enumFromInt(3566), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12303 // __sync_sub_and_fetch_16
12304 .{ .tag = @enumFromInt(3567), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12305 // __sync_sub_and_fetch_2
12306 .{ .tag = @enumFromInt(3568), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12307 // __sync_sub_and_fetch_4
12308 .{ .tag = @enumFromInt(3569), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12309 // __sync_sub_and_fetch_8
12310 .{ .tag = @enumFromInt(3570), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12311 // __sync_swap
12312 .{ .tag = @enumFromInt(3571), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12313 // __sync_swap_1
12314 .{ .tag = @enumFromInt(3572), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12315 // __sync_swap_16
12316 .{ .tag = @enumFromInt(3573), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12317 // __sync_swap_2
12318 .{ .tag = @enumFromInt(3574), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12319 // __sync_swap_4
12320 .{ .tag = @enumFromInt(3575), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12321 // __sync_swap_8
12322 .{ .tag = @enumFromInt(3576), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12323 // __sync_synchronize
12324 .{ .tag = @enumFromInt(3577), .properties = .{ .param_str = "v" } },
12325 // __sync_val_compare_and_swap
12326 .{ .tag = @enumFromInt(3578), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12327 // __sync_val_compare_and_swap_1
12328 .{ .tag = @enumFromInt(3579), .properties = .{ .param_str = "ccD*cc.", .attributes = .{ .custom_typecheck = true } } },
12329 // __sync_val_compare_and_swap_16
12330 .{ .tag = @enumFromInt(3580), .properties = .{ .param_str = "LLLiLLLiD*LLLiLLLi.", .attributes = .{ .custom_typecheck = true } } },
12331 // __sync_val_compare_and_swap_2
12332 .{ .tag = @enumFromInt(3581), .properties = .{ .param_str = "ssD*ss.", .attributes = .{ .custom_typecheck = true } } },
12333 // __sync_val_compare_and_swap_4
12334 .{ .tag = @enumFromInt(3582), .properties = .{ .param_str = "iiD*ii.", .attributes = .{ .custom_typecheck = true } } },
12335 // __sync_val_compare_and_swap_8
12336 .{ .tag = @enumFromInt(3583), .properties = .{ .param_str = "LLiLLiD*LLiLLi.", .attributes = .{ .custom_typecheck = true } } },
12337 // __sync_xor_and_fetch
12338 .{ .tag = @enumFromInt(3584), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } },
12339 // __sync_xor_and_fetch_1
12340 .{ .tag = @enumFromInt(3585), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } },
12341 // __sync_xor_and_fetch_16
12342 .{ .tag = @enumFromInt(3586), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } },
12343 // __sync_xor_and_fetch_2
12344 .{ .tag = @enumFromInt(3587), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } },
12345 // __sync_xor_and_fetch_4
12346 .{ .tag = @enumFromInt(3588), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } },
12347 // __sync_xor_and_fetch_8
12348 .{ .tag = @enumFromInt(3589), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } },
12349 // __syncthreads
12350 .{ .tag = @enumFromInt(3590), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } },
12351 // __tanpi
12352 .{ .tag = @enumFromInt(3591), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12353 // __tanpif
12354 .{ .tag = @enumFromInt(3592), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12355 // __va_start
12356 .{ .tag = @enumFromInt(3593), .properties = .{ .param_str = "vc**.", .language = .all_ms_languages, .attributes = .{ .custom_typecheck = true } } },
12357 // __warn_memset_zero_len
12358 .{ .tag = @enumFromInt(3594), .properties = .{ .param_str = "v", .attributes = .{ .pure = true } } },
12359 // __wfe
12360 .{ .tag = @enumFromInt(3595), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
12361 // __wfi
12362 .{ .tag = @enumFromInt(3596), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
12363 // __xray_customevent
12364 .{ .tag = @enumFromInt(3597), .properties = .{ .param_str = "vcC*z" } },
12365 // __xray_typedevent
12366 .{ .tag = @enumFromInt(3598), .properties = .{ .param_str = "vzcC*z" } },
12367 // __yield
12368 .{ .tag = @enumFromInt(3599), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } },
12369 // _abnormal_termination
12370 .{ .tag = @enumFromInt(3600), .properties = .{ .param_str = "i", .language = .all_ms_languages } },
12371 // _alloca
12372 .{ .tag = @enumFromInt(3601), .properties = .{ .param_str = "v*z", .language = .all_ms_languages } },
12373 // _bittest
12374 .{ .tag = @enumFromInt(3602), .properties = .{ .param_str = "UcNiC*Ni", .language = .all_ms_languages } },
12375 // _bittest64
12376 .{ .tag = @enumFromInt(3603), .properties = .{ .param_str = "UcWiC*Wi", .language = .all_ms_languages } },
12377 // _bittestandcomplement
12378 .{ .tag = @enumFromInt(3604), .properties = .{ .param_str = "UcNi*Ni", .language = .all_ms_languages } },
12379 // _bittestandcomplement64
12380 .{ .tag = @enumFromInt(3605), .properties = .{ .param_str = "UcWi*Wi", .language = .all_ms_languages } },
12381 // _bittestandreset
12382 .{ .tag = @enumFromInt(3606), .properties = .{ .param_str = "UcNi*Ni", .language = .all_ms_languages } },
12383 // _bittestandreset64
12384 .{ .tag = @enumFromInt(3607), .properties = .{ .param_str = "UcWi*Wi", .language = .all_ms_languages } },
12385 // _bittestandset
12386 .{ .tag = @enumFromInt(3608), .properties = .{ .param_str = "UcNi*Ni", .language = .all_ms_languages } },
12387 // _bittestandset64
12388 .{ .tag = @enumFromInt(3609), .properties = .{ .param_str = "UcWi*Wi", .language = .all_ms_languages } },
12389 // _byteswap_uint64
12390 .{ .tag = @enumFromInt(3610), .properties = .{ .param_str = "ULLiULLi", .header = .stdlib, .language = .all_ms_languages, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12391 // _byteswap_ulong
12392 .{ .tag = @enumFromInt(3611), .properties = .{ .param_str = "UNiUNi", .header = .stdlib, .language = .all_ms_languages, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12393 // _byteswap_ushort
12394 .{ .tag = @enumFromInt(3612), .properties = .{ .param_str = "UsUs", .header = .stdlib, .language = .all_ms_languages, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12395 // _exception_code
12396 .{ .tag = @enumFromInt(3613), .properties = .{ .param_str = "UNi", .language = .all_ms_languages } },
12397 // _exception_info
12398 .{ .tag = @enumFromInt(3614), .properties = .{ .param_str = "v*", .language = .all_ms_languages } },
12399 // _exit
12400 .{ .tag = @enumFromInt(3615), .properties = .{ .param_str = "vi", .header = .unistd, .language = .all_gnu_languages, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } },
12401 // _interlockedbittestandreset
12402 .{ .tag = @enumFromInt(3616), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12403 // _interlockedbittestandreset64
12404 .{ .tag = @enumFromInt(3617), .properties = .{ .param_str = "UcWiD*Wi", .language = .all_ms_languages } },
12405 // _interlockedbittestandreset_acq
12406 .{ .tag = @enumFromInt(3618), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12407 // _interlockedbittestandreset_nf
12408 .{ .tag = @enumFromInt(3619), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12409 // _interlockedbittestandreset_rel
12410 .{ .tag = @enumFromInt(3620), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12411 // _interlockedbittestandset
12412 .{ .tag = @enumFromInt(3621), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12413 // _interlockedbittestandset64
12414 .{ .tag = @enumFromInt(3622), .properties = .{ .param_str = "UcWiD*Wi", .language = .all_ms_languages } },
12415 // _interlockedbittestandset_acq
12416 .{ .tag = @enumFromInt(3623), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12417 // _interlockedbittestandset_nf
12418 .{ .tag = @enumFromInt(3624), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12419 // _interlockedbittestandset_rel
12420 .{ .tag = @enumFromInt(3625), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } },
12421 // _longjmp
12422 .{ .tag = @enumFromInt(3626), .properties = .{ .param_str = "vJi", .header = .setjmp, .language = .all_gnu_languages, .attributes = .{ .noreturn = true, .allow_type_mismatch = true, .lib_function_without_prefix = true } } },
12423 // _lrotl
12424 .{ .tag = @enumFromInt(3627), .properties = .{ .param_str = "ULiULii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12425 // _lrotr
12426 .{ .tag = @enumFromInt(3628), .properties = .{ .param_str = "ULiULii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12427 // _rotl
12428 .{ .tag = @enumFromInt(3629), .properties = .{ .param_str = "UiUii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12429 // _rotl16
12430 .{ .tag = @enumFromInt(3630), .properties = .{ .param_str = "UsUsUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12431 // _rotl64
12432 .{ .tag = @enumFromInt(3631), .properties = .{ .param_str = "UWiUWii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12433 // _rotl8
12434 .{ .tag = @enumFromInt(3632), .properties = .{ .param_str = "UcUcUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12435 // _rotr
12436 .{ .tag = @enumFromInt(3633), .properties = .{ .param_str = "UiUii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12437 // _rotr16
12438 .{ .tag = @enumFromInt(3634), .properties = .{ .param_str = "UsUsUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12439 // _rotr64
12440 .{ .tag = @enumFromInt(3635), .properties = .{ .param_str = "UWiUWii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12441 // _rotr8
12442 .{ .tag = @enumFromInt(3636), .properties = .{ .param_str = "UcUcUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } },
12443 // _setjmp
12444 .{ .tag = @enumFromInt(3637), .properties = .{ .param_str = "iJ", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
12445 // _setjmpex
12446 .{ .tag = @enumFromInt(3638), .properties = .{ .param_str = "iJ", .header = .setjmpex, .language = .all_ms_languages, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
12447 // abort
12448 .{ .tag = @enumFromInt(3639), .properties = .{ .param_str = "v", .header = .stdlib, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } },
12449 // abs
12450 .{ .tag = @enumFromInt(3640), .properties = .{ .param_str = "ii", .header = .stdlib, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12451 // acos
12452 .{ .tag = @enumFromInt(3641), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12453 // acosf
12454 .{ .tag = @enumFromInt(3642), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12455 // acosh
12456 .{ .tag = @enumFromInt(3643), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12457 // acoshf
12458 .{ .tag = @enumFromInt(3644), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12459 // acoshl
12460 .{ .tag = @enumFromInt(3645), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12461 // acosl
12462 .{ .tag = @enumFromInt(3646), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12463 // aligned_alloc
12464 .{ .tag = @enumFromInt(3647), .properties = .{ .param_str = "v*zz", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
12465 // alloca
12466 .{ .tag = @enumFromInt(3648), .properties = .{ .param_str = "v*z", .header = .stdlib, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12467 // asin
12468 .{ .tag = @enumFromInt(3649), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12469 // asinf
12470 .{ .tag = @enumFromInt(3650), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12471 // asinh
12472 .{ .tag = @enumFromInt(3651), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12473 // asinhf
12474 .{ .tag = @enumFromInt(3652), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12475 // asinhl
12476 .{ .tag = @enumFromInt(3653), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12477 // asinl
12478 .{ .tag = @enumFromInt(3654), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12479 // atan
12480 .{ .tag = @enumFromInt(3655), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12481 // atan2
12482 .{ .tag = @enumFromInt(3656), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12483 // atan2f
12484 .{ .tag = @enumFromInt(3657), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12485 // atan2l
12486 .{ .tag = @enumFromInt(3658), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12487 // atanf
12488 .{ .tag = @enumFromInt(3659), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12489 // atanh
12490 .{ .tag = @enumFromInt(3660), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12491 // atanhf
12492 .{ .tag = @enumFromInt(3661), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12493 // atanhl
12494 .{ .tag = @enumFromInt(3662), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12495 // atanl
12496 .{ .tag = @enumFromInt(3663), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12497 // bcmp
12498 .{ .tag = @enumFromInt(3664), .properties = .{ .param_str = "ivC*vC*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
12499 // bcopy
12500 .{ .tag = @enumFromInt(3665), .properties = .{ .param_str = "vvC*v*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12501 // bzero
12502 .{ .tag = @enumFromInt(3666), .properties = .{ .param_str = "vv*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12503 // cabs
12504 .{ .tag = @enumFromInt(3667), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12505 // cabsf
12506 .{ .tag = @enumFromInt(3668), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12507 // cabsl
12508 .{ .tag = @enumFromInt(3669), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12509 // cacos
12510 .{ .tag = @enumFromInt(3670), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12511 // cacosf
12512 .{ .tag = @enumFromInt(3671), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12513 // cacosh
12514 .{ .tag = @enumFromInt(3672), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12515 // cacoshf
12516 .{ .tag = @enumFromInt(3673), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12517 // cacoshl
12518 .{ .tag = @enumFromInt(3674), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12519 // cacosl
12520 .{ .tag = @enumFromInt(3675), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12521 // calloc
12522 .{ .tag = @enumFromInt(3676), .properties = .{ .param_str = "v*zz", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
12523 // carg
12524 .{ .tag = @enumFromInt(3677), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12525 // cargf
12526 .{ .tag = @enumFromInt(3678), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12527 // cargl
12528 .{ .tag = @enumFromInt(3679), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12529 // casin
12530 .{ .tag = @enumFromInt(3680), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12531 // casinf
12532 .{ .tag = @enumFromInt(3681), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12533 // casinh
12534 .{ .tag = @enumFromInt(3682), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12535 // casinhf
12536 .{ .tag = @enumFromInt(3683), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12537 // casinhl
12538 .{ .tag = @enumFromInt(3684), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12539 // casinl
12540 .{ .tag = @enumFromInt(3685), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12541 // catan
12542 .{ .tag = @enumFromInt(3686), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12543 // catanf
12544 .{ .tag = @enumFromInt(3687), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12545 // catanh
12546 .{ .tag = @enumFromInt(3688), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12547 // catanhf
12548 .{ .tag = @enumFromInt(3689), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12549 // catanhl
12550 .{ .tag = @enumFromInt(3690), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12551 // catanl
12552 .{ .tag = @enumFromInt(3691), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12553 // cbrt
12554 .{ .tag = @enumFromInt(3692), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12555 // cbrtf
12556 .{ .tag = @enumFromInt(3693), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12557 // cbrtl
12558 .{ .tag = @enumFromInt(3694), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12559 // ccos
12560 .{ .tag = @enumFromInt(3695), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12561 // ccosf
12562 .{ .tag = @enumFromInt(3696), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12563 // ccosh
12564 .{ .tag = @enumFromInt(3697), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12565 // ccoshf
12566 .{ .tag = @enumFromInt(3698), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12567 // ccoshl
12568 .{ .tag = @enumFromInt(3699), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12569 // ccosl
12570 .{ .tag = @enumFromInt(3700), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12571 // ceil
12572 .{ .tag = @enumFromInt(3701), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12573 // ceilf
12574 .{ .tag = @enumFromInt(3702), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12575 // ceill
12576 .{ .tag = @enumFromInt(3703), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12577 // cexp
12578 .{ .tag = @enumFromInt(3704), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12579 // cexpf
12580 .{ .tag = @enumFromInt(3705), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12581 // cexpl
12582 .{ .tag = @enumFromInt(3706), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12583 // cimag
12584 .{ .tag = @enumFromInt(3707), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12585 // cimagf
12586 .{ .tag = @enumFromInt(3708), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12587 // cimagl
12588 .{ .tag = @enumFromInt(3709), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12589 // clog
12590 .{ .tag = @enumFromInt(3710), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12591 // clogf
12592 .{ .tag = @enumFromInt(3711), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12593 // clogl
12594 .{ .tag = @enumFromInt(3712), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12595 // conj
12596 .{ .tag = @enumFromInt(3713), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12597 // conjf
12598 .{ .tag = @enumFromInt(3714), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12599 // conjl
12600 .{ .tag = @enumFromInt(3715), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12601 // copysign
12602 .{ .tag = @enumFromInt(3716), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12603 // copysignf
12604 .{ .tag = @enumFromInt(3717), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12605 // copysignl
12606 .{ .tag = @enumFromInt(3718), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12607 // cos
12608 .{ .tag = @enumFromInt(3719), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12609 // cosf
12610 .{ .tag = @enumFromInt(3720), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12611 // cosh
12612 .{ .tag = @enumFromInt(3721), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12613 // coshf
12614 .{ .tag = @enumFromInt(3722), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12615 // coshl
12616 .{ .tag = @enumFromInt(3723), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12617 // cosl
12618 .{ .tag = @enumFromInt(3724), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12619 // cpow
12620 .{ .tag = @enumFromInt(3725), .properties = .{ .param_str = "XdXdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12621 // cpowf
12622 .{ .tag = @enumFromInt(3726), .properties = .{ .param_str = "XfXfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12623 // cpowl
12624 .{ .tag = @enumFromInt(3727), .properties = .{ .param_str = "XLdXLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12625 // cproj
12626 .{ .tag = @enumFromInt(3728), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12627 // cprojf
12628 .{ .tag = @enumFromInt(3729), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12629 // cprojl
12630 .{ .tag = @enumFromInt(3730), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12631 // creal
12632 .{ .tag = @enumFromInt(3731), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12633 // crealf
12634 .{ .tag = @enumFromInt(3732), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12635 // creall
12636 .{ .tag = @enumFromInt(3733), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12637 // csin
12638 .{ .tag = @enumFromInt(3734), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12639 // csinf
12640 .{ .tag = @enumFromInt(3735), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12641 // csinh
12642 .{ .tag = @enumFromInt(3736), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12643 // csinhf
12644 .{ .tag = @enumFromInt(3737), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12645 // csinhl
12646 .{ .tag = @enumFromInt(3738), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12647 // csinl
12648 .{ .tag = @enumFromInt(3739), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12649 // csqrt
12650 .{ .tag = @enumFromInt(3740), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12651 // csqrtf
12652 .{ .tag = @enumFromInt(3741), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12653 // csqrtl
12654 .{ .tag = @enumFromInt(3742), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12655 // ctan
12656 .{ .tag = @enumFromInt(3743), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12657 // ctanf
12658 .{ .tag = @enumFromInt(3744), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12659 // ctanh
12660 .{ .tag = @enumFromInt(3745), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12661 // ctanhf
12662 .{ .tag = @enumFromInt(3746), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12663 // ctanhl
12664 .{ .tag = @enumFromInt(3747), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12665 // ctanl
12666 .{ .tag = @enumFromInt(3748), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12667 // erf
12668 .{ .tag = @enumFromInt(3749), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12669 // erfc
12670 .{ .tag = @enumFromInt(3750), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12671 // erfcf
12672 .{ .tag = @enumFromInt(3751), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12673 // erfcl
12674 .{ .tag = @enumFromInt(3752), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12675 // erff
12676 .{ .tag = @enumFromInt(3753), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12677 // erfl
12678 .{ .tag = @enumFromInt(3754), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12679 // exit
12680 .{ .tag = @enumFromInt(3755), .properties = .{ .param_str = "vi", .header = .stdlib, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } },
12681 // exp
12682 .{ .tag = @enumFromInt(3756), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12683 // exp2
12684 .{ .tag = @enumFromInt(3757), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12685 // exp2f
12686 .{ .tag = @enumFromInt(3758), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12687 // exp2l
12688 .{ .tag = @enumFromInt(3759), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12689 // expf
12690 .{ .tag = @enumFromInt(3760), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12691 // expl
12692 .{ .tag = @enumFromInt(3761), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12693 // expm1
12694 .{ .tag = @enumFromInt(3762), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12695 // expm1f
12696 .{ .tag = @enumFromInt(3763), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12697 // expm1l
12698 .{ .tag = @enumFromInt(3764), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12699 // fabs
12700 .{ .tag = @enumFromInt(3765), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12701 // fabsf
12702 .{ .tag = @enumFromInt(3766), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12703 // fabsl
12704 .{ .tag = @enumFromInt(3767), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12705 // fdim
12706 .{ .tag = @enumFromInt(3768), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12707 // fdimf
12708 .{ .tag = @enumFromInt(3769), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12709 // fdiml
12710 .{ .tag = @enumFromInt(3770), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12711 // finite
12712 .{ .tag = @enumFromInt(3771), .properties = .{ .param_str = "id", .header = .math, .language = .gnu_lang, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12713 // finitef
12714 .{ .tag = @enumFromInt(3772), .properties = .{ .param_str = "if", .header = .math, .language = .gnu_lang, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12715 // finitel
12716 .{ .tag = @enumFromInt(3773), .properties = .{ .param_str = "iLd", .header = .math, .language = .gnu_lang, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12717 // floor
12718 .{ .tag = @enumFromInt(3774), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12719 // floorf
12720 .{ .tag = @enumFromInt(3775), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12721 // floorl
12722 .{ .tag = @enumFromInt(3776), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12723 // fma
12724 .{ .tag = @enumFromInt(3777), .properties = .{ .param_str = "dddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12725 // fmaf
12726 .{ .tag = @enumFromInt(3778), .properties = .{ .param_str = "ffff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12727 // fmal
12728 .{ .tag = @enumFromInt(3779), .properties = .{ .param_str = "LdLdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12729 // fmax
12730 .{ .tag = @enumFromInt(3780), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12731 // fmaxf
12732 .{ .tag = @enumFromInt(3781), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12733 // fmaxl
12734 .{ .tag = @enumFromInt(3782), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12735 // fmin
12736 .{ .tag = @enumFromInt(3783), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12737 // fminf
12738 .{ .tag = @enumFromInt(3784), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12739 // fminl
12740 .{ .tag = @enumFromInt(3785), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12741 // fmod
12742 .{ .tag = @enumFromInt(3786), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12743 // fmodf
12744 .{ .tag = @enumFromInt(3787), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12745 // fmodl
12746 .{ .tag = @enumFromInt(3788), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12747 // fopen
12748 .{ .tag = @enumFromInt(3789), .properties = .{ .param_str = "P*cC*cC*", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true } } },
12749 // fprintf
12750 .{ .tag = @enumFromInt(3790), .properties = .{ .param_str = "iP*cC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 1 } } },
12751 // fread
12752 .{ .tag = @enumFromInt(3791), .properties = .{ .param_str = "zv*zzP*", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true } } },
12753 // free
12754 .{ .tag = @enumFromInt(3792), .properties = .{ .param_str = "vv*", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
12755 // frexp
12756 .{ .tag = @enumFromInt(3793), .properties = .{ .param_str = "ddi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12757 // frexpf
12758 .{ .tag = @enumFromInt(3794), .properties = .{ .param_str = "ffi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12759 // frexpl
12760 .{ .tag = @enumFromInt(3795), .properties = .{ .param_str = "LdLdi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12761 // fscanf
12762 .{ .tag = @enumFromInt(3796), .properties = .{ .param_str = "iP*RcC*R.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } },
12763 // fwrite
12764 .{ .tag = @enumFromInt(3797), .properties = .{ .param_str = "zvC*zzP*", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true } } },
12765 // getcontext
12766 .{ .tag = @enumFromInt(3798), .properties = .{ .param_str = "iK*", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
12767 // hypot
12768 .{ .tag = @enumFromInt(3799), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12769 // hypotf
12770 .{ .tag = @enumFromInt(3800), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12771 // hypotl
12772 .{ .tag = @enumFromInt(3801), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12773 // ilogb
12774 .{ .tag = @enumFromInt(3802), .properties = .{ .param_str = "id", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12775 // ilogbf
12776 .{ .tag = @enumFromInt(3803), .properties = .{ .param_str = "if", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12777 // ilogbl
12778 .{ .tag = @enumFromInt(3804), .properties = .{ .param_str = "iLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12779 // index
12780 .{ .tag = @enumFromInt(3805), .properties = .{ .param_str = "c*cC*i", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12781 // isalnum
12782 .{ .tag = @enumFromInt(3806), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12783 // isalpha
12784 .{ .tag = @enumFromInt(3807), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12785 // isblank
12786 .{ .tag = @enumFromInt(3808), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12787 // iscntrl
12788 .{ .tag = @enumFromInt(3809), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12789 // isdigit
12790 .{ .tag = @enumFromInt(3810), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12791 // isgraph
12792 .{ .tag = @enumFromInt(3811), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12793 // islower
12794 .{ .tag = @enumFromInt(3812), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12795 // isprint
12796 .{ .tag = @enumFromInt(3813), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12797 // ispunct
12798 .{ .tag = @enumFromInt(3814), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12799 // isspace
12800 .{ .tag = @enumFromInt(3815), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12801 // isupper
12802 .{ .tag = @enumFromInt(3816), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12803 // isxdigit
12804 .{ .tag = @enumFromInt(3817), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12805 // labs
12806 .{ .tag = @enumFromInt(3818), .properties = .{ .param_str = "LiLi", .header = .stdlib, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12807 // ldexp
12808 .{ .tag = @enumFromInt(3819), .properties = .{ .param_str = "ddi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12809 // ldexpf
12810 .{ .tag = @enumFromInt(3820), .properties = .{ .param_str = "ffi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12811 // ldexpl
12812 .{ .tag = @enumFromInt(3821), .properties = .{ .param_str = "LdLdi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12813 // lgamma
12814 .{ .tag = @enumFromInt(3822), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12815 // lgammaf
12816 .{ .tag = @enumFromInt(3823), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12817 // lgammal
12818 .{ .tag = @enumFromInt(3824), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12819 // llabs
12820 .{ .tag = @enumFromInt(3825), .properties = .{ .param_str = "LLiLLi", .header = .stdlib, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12821 // llrint
12822 .{ .tag = @enumFromInt(3826), .properties = .{ .param_str = "LLid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12823 // llrintf
12824 .{ .tag = @enumFromInt(3827), .properties = .{ .param_str = "LLif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12825 // llrintl
12826 .{ .tag = @enumFromInt(3828), .properties = .{ .param_str = "LLiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12827 // llround
12828 .{ .tag = @enumFromInt(3829), .properties = .{ .param_str = "LLid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12829 // llroundf
12830 .{ .tag = @enumFromInt(3830), .properties = .{ .param_str = "LLif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12831 // llroundl
12832 .{ .tag = @enumFromInt(3831), .properties = .{ .param_str = "LLiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12833 // log
12834 .{ .tag = @enumFromInt(3832), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12835 // log10
12836 .{ .tag = @enumFromInt(3833), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12837 // log10f
12838 .{ .tag = @enumFromInt(3834), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12839 // log10l
12840 .{ .tag = @enumFromInt(3835), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12841 // log1p
12842 .{ .tag = @enumFromInt(3836), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12843 // log1pf
12844 .{ .tag = @enumFromInt(3837), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12845 // log1pl
12846 .{ .tag = @enumFromInt(3838), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12847 // log2
12848 .{ .tag = @enumFromInt(3839), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12849 // log2f
12850 .{ .tag = @enumFromInt(3840), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12851 // log2l
12852 .{ .tag = @enumFromInt(3841), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12853 // logb
12854 .{ .tag = @enumFromInt(3842), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12855 // logbf
12856 .{ .tag = @enumFromInt(3843), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12857 // logbl
12858 .{ .tag = @enumFromInt(3844), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12859 // logf
12860 .{ .tag = @enumFromInt(3845), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12861 // logl
12862 .{ .tag = @enumFromInt(3846), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12863 // longjmp
12864 .{ .tag = @enumFromInt(3847), .properties = .{ .param_str = "vJi", .header = .setjmp, .attributes = .{ .noreturn = true, .allow_type_mismatch = true, .lib_function_without_prefix = true } } },
12865 // lrint
12866 .{ .tag = @enumFromInt(3848), .properties = .{ .param_str = "Lid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12867 // lrintf
12868 .{ .tag = @enumFromInt(3849), .properties = .{ .param_str = "Lif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12869 // lrintl
12870 .{ .tag = @enumFromInt(3850), .properties = .{ .param_str = "LiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12871 // lround
12872 .{ .tag = @enumFromInt(3851), .properties = .{ .param_str = "Lid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12873 // lroundf
12874 .{ .tag = @enumFromInt(3852), .properties = .{ .param_str = "Lif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12875 // lroundl
12876 .{ .tag = @enumFromInt(3853), .properties = .{ .param_str = "LiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12877 // malloc
12878 .{ .tag = @enumFromInt(3854), .properties = .{ .param_str = "v*z", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
12879 // memalign
12880 .{ .tag = @enumFromInt(3855), .properties = .{ .param_str = "v*zz", .header = .malloc, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12881 // memccpy
12882 .{ .tag = @enumFromInt(3856), .properties = .{ .param_str = "v*v*vC*iz", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12883 // memchr
12884 .{ .tag = @enumFromInt(3857), .properties = .{ .param_str = "v*vC*iz", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
12885 // memcmp
12886 .{ .tag = @enumFromInt(3858), .properties = .{ .param_str = "ivC*vC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
12887 // memcpy
12888 .{ .tag = @enumFromInt(3859), .properties = .{ .param_str = "v*v*vC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
12889 // memmove
12890 .{ .tag = @enumFromInt(3860), .properties = .{ .param_str = "v*v*vC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
12891 // mempcpy
12892 .{ .tag = @enumFromInt(3861), .properties = .{ .param_str = "v*v*vC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12893 // memset
12894 .{ .tag = @enumFromInt(3862), .properties = .{ .param_str = "v*v*iz", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
12895 // modf
12896 .{ .tag = @enumFromInt(3863), .properties = .{ .param_str = "ddd*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12897 // modff
12898 .{ .tag = @enumFromInt(3864), .properties = .{ .param_str = "fff*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12899 // modfl
12900 .{ .tag = @enumFromInt(3865), .properties = .{ .param_str = "LdLdLd*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12901 // nan
12902 .{ .tag = @enumFromInt(3866), .properties = .{ .param_str = "dcC*", .header = .math, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12903 // nanf
12904 .{ .tag = @enumFromInt(3867), .properties = .{ .param_str = "fcC*", .header = .math, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12905 // nanl
12906 .{ .tag = @enumFromInt(3868), .properties = .{ .param_str = "LdcC*", .header = .math, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
12907 // nearbyint
12908 .{ .tag = @enumFromInt(3869), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12909 // nearbyintf
12910 .{ .tag = @enumFromInt(3870), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12911 // nearbyintl
12912 .{ .tag = @enumFromInt(3871), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12913 // nextafter
12914 .{ .tag = @enumFromInt(3872), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12915 // nextafterf
12916 .{ .tag = @enumFromInt(3873), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12917 // nextafterl
12918 .{ .tag = @enumFromInt(3874), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12919 // nexttoward
12920 .{ .tag = @enumFromInt(3875), .properties = .{ .param_str = "ddLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12921 // nexttowardf
12922 .{ .tag = @enumFromInt(3876), .properties = .{ .param_str = "ffLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12923 // nexttowardl
12924 .{ .tag = @enumFromInt(3877), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12925 // pow
12926 .{ .tag = @enumFromInt(3878), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12927 // powf
12928 .{ .tag = @enumFromInt(3879), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12929 // powl
12930 .{ .tag = @enumFromInt(3880), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12931 // printf
12932 .{ .tag = @enumFromInt(3881), .properties = .{ .param_str = "icC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf } } },
12933 // realloc
12934 .{ .tag = @enumFromInt(3882), .properties = .{ .param_str = "v*v*z", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
12935 // remainder
12936 .{ .tag = @enumFromInt(3883), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12937 // remainderf
12938 .{ .tag = @enumFromInt(3884), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12939 // remainderl
12940 .{ .tag = @enumFromInt(3885), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12941 // remquo
12942 .{ .tag = @enumFromInt(3886), .properties = .{ .param_str = "dddi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12943 // remquof
12944 .{ .tag = @enumFromInt(3887), .properties = .{ .param_str = "fffi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12945 // remquol
12946 .{ .tag = @enumFromInt(3888), .properties = .{ .param_str = "LdLdLdi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } },
12947 // rindex
12948 .{ .tag = @enumFromInt(3889), .properties = .{ .param_str = "c*cC*i", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
12949 // rint
12950 .{ .tag = @enumFromInt(3890), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true } } },
12951 // rintf
12952 .{ .tag = @enumFromInt(3891), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true } } },
12953 // rintl
12954 .{ .tag = @enumFromInt(3892), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true } } },
12955 // round
12956 .{ .tag = @enumFromInt(3893), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12957 // roundeven
12958 .{ .tag = @enumFromInt(3894), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12959 // roundevenf
12960 .{ .tag = @enumFromInt(3895), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12961 // roundevenl
12962 .{ .tag = @enumFromInt(3896), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12963 // roundf
12964 .{ .tag = @enumFromInt(3897), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12965 // roundl
12966 .{ .tag = @enumFromInt(3898), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
12967 // savectx
12968 .{ .tag = @enumFromInt(3899), .properties = .{ .param_str = "iJ", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
12969 // scalbln
12970 .{ .tag = @enumFromInt(3900), .properties = .{ .param_str = "ddLi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12971 // scalblnf
12972 .{ .tag = @enumFromInt(3901), .properties = .{ .param_str = "ffLi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12973 // scalblnl
12974 .{ .tag = @enumFromInt(3902), .properties = .{ .param_str = "LdLdLi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12975 // scalbn
12976 .{ .tag = @enumFromInt(3903), .properties = .{ .param_str = "ddi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12977 // scalbnf
12978 .{ .tag = @enumFromInt(3904), .properties = .{ .param_str = "ffi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12979 // scalbnl
12980 .{ .tag = @enumFromInt(3905), .properties = .{ .param_str = "LdLdi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12981 // scanf
12982 .{ .tag = @enumFromInt(3906), .properties = .{ .param_str = "icC*R.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf } } },
12983 // setjmp
12984 .{ .tag = @enumFromInt(3907), .properties = .{ .param_str = "iJ", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
12985 // siglongjmp
12986 .{ .tag = @enumFromInt(3908), .properties = .{ .param_str = "vSJi", .header = .setjmp, .language = .all_gnu_languages, .attributes = .{ .noreturn = true, .allow_type_mismatch = true, .lib_function_without_prefix = true } } },
12987 // sigsetjmp
12988 .{ .tag = @enumFromInt(3909), .properties = .{ .param_str = "iSJi", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
12989 // sin
12990 .{ .tag = @enumFromInt(3910), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12991 // sinf
12992 .{ .tag = @enumFromInt(3911), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12993 // sinh
12994 .{ .tag = @enumFromInt(3912), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12995 // sinhf
12996 .{ .tag = @enumFromInt(3913), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12997 // sinhl
12998 .{ .tag = @enumFromInt(3914), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
12999 // sinl
13000 .{ .tag = @enumFromInt(3915), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13001 // snprintf
13002 .{ .tag = @enumFromInt(3916), .properties = .{ .param_str = "ic*zcC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 2 } } },
13003 // sprintf
13004 .{ .tag = @enumFromInt(3917), .properties = .{ .param_str = "ic*cC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 1 } } },
13005 // sqrt
13006 .{ .tag = @enumFromInt(3918), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13007 // sqrtf
13008 .{ .tag = @enumFromInt(3919), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13009 // sqrtl
13010 .{ .tag = @enumFromInt(3920), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13011 // sscanf
13012 .{ .tag = @enumFromInt(3921), .properties = .{ .param_str = "icC*RcC*R.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } },
13013 // stpcpy
13014 .{ .tag = @enumFromInt(3922), .properties = .{ .param_str = "c*c*cC*", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13015 // stpncpy
13016 .{ .tag = @enumFromInt(3923), .properties = .{ .param_str = "c*c*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13017 // strcasecmp
13018 .{ .tag = @enumFromInt(3924), .properties = .{ .param_str = "icC*cC*", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13019 // strcat
13020 .{ .tag = @enumFromInt(3925), .properties = .{ .param_str = "c*c*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13021 // strchr
13022 .{ .tag = @enumFromInt(3926), .properties = .{ .param_str = "c*cC*i", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13023 // strcmp
13024 .{ .tag = @enumFromInt(3927), .properties = .{ .param_str = "icC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13025 // strcpy
13026 .{ .tag = @enumFromInt(3928), .properties = .{ .param_str = "c*c*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13027 // strcspn
13028 .{ .tag = @enumFromInt(3929), .properties = .{ .param_str = "zcC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13029 // strdup
13030 .{ .tag = @enumFromInt(3930), .properties = .{ .param_str = "c*cC*", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13031 // strerror
13032 .{ .tag = @enumFromInt(3931), .properties = .{ .param_str = "c*i", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13033 // strlcat
13034 .{ .tag = @enumFromInt(3932), .properties = .{ .param_str = "zc*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13035 // strlcpy
13036 .{ .tag = @enumFromInt(3933), .properties = .{ .param_str = "zc*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13037 // strlen
13038 .{ .tag = @enumFromInt(3934), .properties = .{ .param_str = "zcC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13039 // strncasecmp
13040 .{ .tag = @enumFromInt(3935), .properties = .{ .param_str = "icC*cC*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13041 // strncat
13042 .{ .tag = @enumFromInt(3936), .properties = .{ .param_str = "c*c*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13043 // strncmp
13044 .{ .tag = @enumFromInt(3937), .properties = .{ .param_str = "icC*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13045 // strncpy
13046 .{ .tag = @enumFromInt(3938), .properties = .{ .param_str = "c*c*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13047 // strndup
13048 .{ .tag = @enumFromInt(3939), .properties = .{ .param_str = "c*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } },
13049 // strpbrk
13050 .{ .tag = @enumFromInt(3940), .properties = .{ .param_str = "c*cC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13051 // strrchr
13052 .{ .tag = @enumFromInt(3941), .properties = .{ .param_str = "c*cC*i", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13053 // strspn
13054 .{ .tag = @enumFromInt(3942), .properties = .{ .param_str = "zcC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13055 // strstr
13056 .{ .tag = @enumFromInt(3943), .properties = .{ .param_str = "c*cC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13057 // strtod
13058 .{ .tag = @enumFromInt(3944), .properties = .{ .param_str = "dcC*c**", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
13059 // strtof
13060 .{ .tag = @enumFromInt(3945), .properties = .{ .param_str = "fcC*c**", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
13061 // strtok
13062 .{ .tag = @enumFromInt(3946), .properties = .{ .param_str = "c*c*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13063 // strtol
13064 .{ .tag = @enumFromInt(3947), .properties = .{ .param_str = "LicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
13065 // strtold
13066 .{ .tag = @enumFromInt(3948), .properties = .{ .param_str = "LdcC*c**", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
13067 // strtoll
13068 .{ .tag = @enumFromInt(3949), .properties = .{ .param_str = "LLicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
13069 // strtoul
13070 .{ .tag = @enumFromInt(3950), .properties = .{ .param_str = "ULicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
13071 // strtoull
13072 .{ .tag = @enumFromInt(3951), .properties = .{ .param_str = "ULLicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } },
13073 // strxfrm
13074 .{ .tag = @enumFromInt(3952), .properties = .{ .param_str = "zc*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } },
13075 // tan
13076 .{ .tag = @enumFromInt(3953), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13077 // tanf
13078 .{ .tag = @enumFromInt(3954), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13079 // tanh
13080 .{ .tag = @enumFromInt(3955), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13081 // tanhf
13082 .{ .tag = @enumFromInt(3956), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13083 // tanhl
13084 .{ .tag = @enumFromInt(3957), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13085 // tanl
13086 .{ .tag = @enumFromInt(3958), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13087 // tgamma
13088 .{ .tag = @enumFromInt(3959), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13089 // tgammaf
13090 .{ .tag = @enumFromInt(3960), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13091 // tgammal
13092 .{ .tag = @enumFromInt(3961), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } },
13093 // tolower
13094 .{ .tag = @enumFromInt(3962), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
13095 // toupper
13096 .{ .tag = @enumFromInt(3963), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } },
13097 // trunc
13098 .{ .tag = @enumFromInt(3964), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
13099 // truncf
13100 .{ .tag = @enumFromInt(3965), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
13101 // truncl
13102 .{ .tag = @enumFromInt(3966), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } },
13103 // va_copy
13104 .{ .tag = @enumFromInt(3967), .properties = .{ .param_str = "vAA", .header = .stdarg, .attributes = .{ .lib_function_without_prefix = true } } },
13105 // va_end
13106 .{ .tag = @enumFromInt(3968), .properties = .{ .param_str = "vA", .header = .stdarg, .attributes = .{ .lib_function_without_prefix = true } } },
13107 // va_start
13108 .{ .tag = @enumFromInt(3969), .properties = .{ .param_str = "vA.", .header = .stdarg, .attributes = .{ .lib_function_without_prefix = true } } },
13109 // vfork
13110 .{ .tag = @enumFromInt(3970), .properties = .{ .param_str = "p", .header = .unistd, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } },
13111 // vfprintf
13112 .{ .tag = @enumFromInt(3971), .properties = .{ .param_str = "iP*cC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } },
13113 // vfscanf
13114 .{ .tag = @enumFromInt(3972), .properties = .{ .param_str = "iP*RcC*Ra", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } },
13115 // vprintf
13116 .{ .tag = @enumFromInt(3973), .properties = .{ .param_str = "icC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf } } },
13117 // vscanf
13118 .{ .tag = @enumFromInt(3974), .properties = .{ .param_str = "icC*Ra", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf } } },
13119 // vsnprintf
13120 .{ .tag = @enumFromInt(3975), .properties = .{ .param_str = "ic*zcC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 2 } } },
13121 // vsprintf
13122 .{ .tag = @enumFromInt(3976), .properties = .{ .param_str = "ic*cC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } },
13123 // vsscanf
13124 .{ .tag = @enumFromInt(3977), .properties = .{ .param_str = "icC*RcC*Ra", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } },
13125 // wcschr
13126 .{ .tag = @enumFromInt(3978), .properties = .{ .param_str = "w*wC*w", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13127 // wcscmp
13128 .{ .tag = @enumFromInt(3979), .properties = .{ .param_str = "iwC*wC*", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13129 // wcslen
13130 .{ .tag = @enumFromInt(3980), .properties = .{ .param_str = "zwC*", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13131 // wcsncmp
13132 .{ .tag = @enumFromInt(3981), .properties = .{ .param_str = "iwC*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13133 // wmemchr
13134 .{ .tag = @enumFromInt(3982), .properties = .{ .param_str = "w*wC*wz", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13135 // wmemcmp
13136 .{ .tag = @enumFromInt(3983), .properties = .{ .param_str = "iwC*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13137 // wmemcpy
13138 .{ .tag = @enumFromInt(3984), .properties = .{ .param_str = "w*w*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13139 // wmemmove
13140 .{ .tag = @enumFromInt(3985), .properties = .{ .param_str = "w*w*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } },
13141 };
13142};
13143};
13144}
lib/compiler/aro/aro/Builtins/Properties.zig created+143
......@@ -0,0 +1,143 @@
1const std = @import("std");
2
3const Properties = @This();
4
5param_str: []const u8,
6language: Language = .all_languages,
7attributes: Attributes = Attributes{},
8header: Header = .none,
9target_set: TargetSet = TargetSet.initOne(.basic),
10
11/// Header which must be included for a builtin to be available
12pub const Header = enum {
13 none,
14 /// stdio.h
15 stdio,
16 /// stdlib.h
17 stdlib,
18 /// setjmpex.h
19 setjmpex,
20 /// stdarg.h
21 stdarg,
22 /// string.h
23 string,
24 /// ctype.h
25 ctype,
26 /// wchar.h
27 wchar,
28 /// setjmp.h
29 setjmp,
30 /// malloc.h
31 malloc,
32 /// strings.h
33 strings,
34 /// unistd.h
35 unistd,
36 /// pthread.h
37 pthread,
38 /// math.h
39 math,
40 /// complex.h
41 complex,
42 /// Blocks.h
43 blocks,
44};
45
46/// Languages in which a builtin is available
47pub const Language = enum {
48 all_languages,
49 all_ms_languages,
50 all_gnu_languages,
51 gnu_lang,
52};
53
54pub const Attributes = packed struct {
55 /// Function does not return
56 noreturn: bool = false,
57
58 /// Function has no side effects
59 pure: bool = false,
60
61 /// Function has no side effects and does not read memory
62 @"const": bool = false,
63
64 /// Signature is meaningless; use custom typecheck
65 custom_typecheck: bool = false,
66
67 /// A declaration of this builtin should be recognized even if the type doesn't match the specified signature.
68 allow_type_mismatch: bool = false,
69
70 /// this is a libc/libm function with a '__builtin_' prefix added.
71 lib_function_with_builtin_prefix: bool = false,
72
73 /// this is a libc/libm function without a '__builtin_' prefix. This builtin is disableable by '-fno-builtin-foo'
74 lib_function_without_prefix: bool = false,
75
76 /// Function returns twice (e.g. setjmp)
77 returns_twice: bool = false,
78
79 /// Nature of the format string passed to this function
80 format_kind: enum(u3) {
81 /// Does not take a format string
82 none,
83 /// this is a printf-like function whose Nth argument is the format string
84 printf,
85 /// function is like vprintf in that it accepts its arguments as a va_list rather than through an ellipsis
86 vprintf,
87 /// this is a scanf-like function whose Nth argument is the format string
88 scanf,
89 /// the function is like vscanf in that it accepts its arguments as a va_list rather than through an ellipsis
90 vscanf,
91 } = .none,
92
93 /// Position of format string argument. Only meaningful if format_kind is not .none
94 format_string_position: u5 = 0,
95
96 /// if false, arguments are not evaluated
97 eval_args: bool = true,
98
99 /// no side effects and does not read memory, but only when -fno-math-errno and FP exceptions are ignored
100 const_without_errno_and_fp_exceptions: bool = false,
101
102 /// no side effects and does not read memory, but only when FP exceptions are ignored
103 const_without_fp_exceptions: bool = false,
104
105 /// this function can be constant evaluated by the frontend
106 const_evaluable: bool = false,
107};
108
109pub const Target = enum {
110 /// Supported on all targets
111 basic,
112 aarch64,
113 aarch64_neon_sve_bridge,
114 aarch64_neon_sve_bridge_cg,
115 amdgpu,
116 arm,
117 bpf,
118 hexagon,
119 hexagon_dep,
120 hexagon_map_custom_dep,
121 loong_arch,
122 mips,
123 neon,
124 nvptx,
125 ppc,
126 riscv,
127 riscv_vector,
128 sve,
129 systemz,
130 ve,
131 vevl_gen,
132 webassembly,
133 x86,
134 x86_64,
135 xcore,
136};
137
138/// Targets for which a builtin is enabled
139pub const TargetSet = std.enums.EnumSet(Target);
140
141pub fn isVarArgs(properties: Properties) bool {
142 return properties.param_str[properties.param_str.len - 1] == '.';
143}
lib/compiler/aro/aro/Builtins/TypeDescription.zig created+286
......@@ -0,0 +1,286 @@
1const std = @import("std");
2
3const TypeDescription = @This();
4
5prefix: []const Prefix,
6spec: Spec,
7suffix: []const Suffix,
8
9pub const Component = union(enum) {
10 prefix: Prefix,
11 spec: Spec,
12 suffix: Suffix,
13};
14
15pub const ComponentIterator = struct {
16 str: []const u8,
17 idx: usize,
18
19 pub fn init(str: []const u8) ComponentIterator {
20 return .{
21 .str = str,
22 .idx = 0,
23 };
24 }
25
26 pub fn peek(self: *ComponentIterator) ?Component {
27 const idx = self.idx;
28 defer self.idx = idx;
29 return self.next();
30 }
31
32 pub fn next(self: *ComponentIterator) ?Component {
33 if (self.idx == self.str.len) return null;
34 const c = self.str[self.idx];
35 self.idx += 1;
36 switch (c) {
37 'L' => {
38 if (self.str[self.idx] != 'L') return .{ .prefix = .L };
39 self.idx += 1;
40 if (self.str[self.idx] != 'L') return .{ .prefix = .LL };
41 self.idx += 1;
42 return .{ .prefix = .LLL };
43 },
44 'Z' => return .{ .prefix = .Z },
45 'W' => return .{ .prefix = .W },
46 'N' => return .{ .prefix = .N },
47 'O' => return .{ .prefix = .O },
48 'S' => {
49 if (self.str[self.idx] == 'J') {
50 self.idx += 1;
51 return .{ .spec = .SJ };
52 }
53 return .{ .prefix = .S };
54 },
55 'U' => return .{ .prefix = .U },
56 'I' => return .{ .prefix = .I },
57
58 'v' => return .{ .spec = .v },
59 'b' => return .{ .spec = .b },
60 'c' => return .{ .spec = .c },
61 's' => return .{ .spec = .s },
62 'i' => return .{ .spec = .i },
63 'h' => return .{ .spec = .h },
64 'x' => return .{ .spec = .x },
65 'y' => return .{ .spec = .y },
66 'f' => return .{ .spec = .f },
67 'd' => return .{ .spec = .d },
68 'z' => return .{ .spec = .z },
69 'w' => return .{ .spec = .w },
70 'F' => return .{ .spec = .F },
71 'G' => return .{ .spec = .G },
72 'H' => return .{ .spec = .H },
73 'M' => return .{ .spec = .M },
74 'a' => return .{ .spec = .a },
75 'A' => return .{ .spec = .A },
76 'V', 'q', 'E' => {
77 const start = self.idx;
78 while (std.ascii.isDigit(self.str[self.idx])) : (self.idx += 1) {}
79 const count = std.fmt.parseUnsigned(u32, self.str[start..self.idx], 10) catch unreachable;
80 return switch (c) {
81 'V' => .{ .spec = .{ .V = count } },
82 'q' => .{ .spec = .{ .q = count } },
83 'E' => .{ .spec = .{ .E = count } },
84 else => unreachable,
85 };
86 },
87 'X' => {
88 defer self.idx += 1;
89 switch (self.str[self.idx]) {
90 'f' => return .{ .spec = .{ .X = .float } },
91 'd' => return .{ .spec = .{ .X = .double } },
92 'L' => {
93 self.idx += 1;
94 return .{ .spec = .{ .X = .longdouble } };
95 },
96 else => unreachable,
97 }
98 },
99 'Y' => return .{ .spec = .Y },
100 'P' => return .{ .spec = .P },
101 'J' => return .{ .spec = .J },
102 'K' => return .{ .spec = .K },
103 'p' => return .{ .spec = .p },
104 '.' => {
105 // can only appear at end of param string; indicates varargs function
106 std.debug.assert(self.idx == self.str.len);
107 return null;
108 },
109 '!' => {
110 std.debug.assert(self.str.len == 1);
111 return .{ .spec = .@"!" };
112 },
113
114 '*' => {
115 if (self.idx < self.str.len and std.ascii.isDigit(self.str[self.idx])) {
116 defer self.idx += 1;
117 const addr_space = self.str[self.idx] - '0';
118 return .{ .suffix = .{ .@"*" = addr_space } };
119 } else {
120 return .{ .suffix = .{ .@"*" = null } };
121 }
122 },
123 'C' => return .{ .suffix = .C },
124 'D' => return .{ .suffix = .D },
125 'R' => return .{ .suffix = .R },
126 else => unreachable,
127 }
128 return null;
129 }
130};
131
132pub const TypeIterator = struct {
133 param_str: []const u8,
134 prefix: [4]Prefix,
135 spec: Spec,
136 suffix: [4]Suffix,
137 idx: usize,
138
139 pub fn init(param_str: []const u8) TypeIterator {
140 return .{
141 .param_str = param_str,
142 .prefix = undefined,
143 .spec = undefined,
144 .suffix = undefined,
145 .idx = 0,
146 };
147 }
148
149 /// Returned `TypeDescription` contains fields which are slices into the underlying `TypeIterator`
150 /// The returned value is invalidated when `.next()` is called again or the TypeIterator goes out
151 // of scope.
152 pub fn next(self: *TypeIterator) ?TypeDescription {
153 var it = ComponentIterator.init(self.param_str[self.idx..]);
154 defer self.idx += it.idx;
155
156 var prefix_count: usize = 0;
157 var maybe_spec: ?Spec = null;
158 var suffix_count: usize = 0;
159 while (it.peek()) |component| {
160 switch (component) {
161 .prefix => |prefix| {
162 if (maybe_spec != null) break;
163 self.prefix[prefix_count] = prefix;
164 prefix_count += 1;
165 },
166 .spec => |spec| {
167 if (maybe_spec != null) break;
168 maybe_spec = spec;
169 },
170 .suffix => |suffix| {
171 std.debug.assert(maybe_spec != null);
172 self.suffix[suffix_count] = suffix;
173 suffix_count += 1;
174 },
175 }
176 _ = it.next();
177 }
178 if (maybe_spec) |spec| {
179 return TypeDescription{
180 .prefix = self.prefix[0..prefix_count],
181 .spec = spec,
182 .suffix = self.suffix[0..suffix_count],
183 };
184 }
185 return null;
186 }
187};
188
189const Prefix = enum {
190 /// long (e.g. Li for 'long int', Ld for 'long double')
191 L,
192 /// long long (e.g. LLi for 'long long int', LLd for __float128)
193 LL,
194 /// __int128_t (e.g. LLLi)
195 LLL,
196 /// int32_t (require a native 32-bit integer type on the target)
197 Z,
198 /// int64_t (require a native 64-bit integer type on the target)
199 W,
200 /// 'int' size if target is LP64, 'L' otherwise.
201 N,
202 /// long for OpenCL targets, long long otherwise.
203 O,
204 /// signed
205 S,
206 /// unsigned
207 U,
208 /// Required to constant fold to an integer constant expression.
209 I,
210};
211
212const Spec = union(enum) {
213 /// void
214 v,
215 /// boolean
216 b,
217 /// char
218 c,
219 /// short
220 s,
221 /// int
222 i,
223 /// half (__fp16, OpenCL)
224 h,
225 /// half (_Float16)
226 x,
227 /// half (__bf16)
228 y,
229 /// float
230 f,
231 /// double
232 d,
233 /// size_t
234 z,
235 /// wchar_t
236 w,
237 /// constant CFString
238 F,
239 /// id
240 G,
241 /// SEL
242 H,
243 /// struct objc_super
244 M,
245 /// __builtin_va_list
246 a,
247 /// "reference" to __builtin_va_list
248 A,
249 /// Vector, followed by the number of elements and the base type.
250 V: u32,
251 /// Scalable vector, followed by the number of elements and the base type.
252 q: u32,
253 /// ext_vector, followed by the number of elements and the base type.
254 E: u32,
255 /// _Complex, followed by the base type.
256 X: enum {
257 float,
258 double,
259 longdouble,
260 },
261 /// ptrdiff_t
262 Y,
263 /// FILE
264 P,
265 /// jmp_buf
266 J,
267 /// sigjmp_buf
268 SJ,
269 /// ucontext_t
270 K,
271 /// pid_t
272 p,
273 /// Used to indicate a builtin with target-dependent param types. Must appear by itself
274 @"!",
275};
276
277const Suffix = union(enum) {
278 /// pointer (optionally followed by an address space number,if no address space is specified than any address space will be accepted)
279 @"*": ?u8,
280 /// const
281 C,
282 /// volatile
283 D,
284 /// restrict
285 R,
286};
lib/compiler/aro/aro/CodeGen.zig created+1295
......@@ -0,0 +1,1295 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const backend = @import("../backend.zig");
5const Interner = backend.Interner;
6const Ir = backend.Ir;
7const Builtins = @import("Builtins.zig");
8const Builtin = Builtins.Builtin;
9const Compilation = @import("Compilation.zig");
10const Builder = Ir.Builder;
11const StrInt = @import("StringInterner.zig");
12const StringId = StrInt.StringId;
13const Tree = @import("Tree.zig");
14const NodeIndex = Tree.NodeIndex;
15const Type = @import("Type.zig");
16const Value = @import("Value.zig");
17
18const WipSwitch = struct {
19 cases: Cases = .{},
20 default: ?Ir.Ref = null,
21 size: u64,
22
23 const Cases = std.MultiArrayList(struct {
24 val: Interner.Ref,
25 label: Ir.Ref,
26 });
27};
28
29const Symbol = struct {
30 name: StringId,
31 val: Ir.Ref,
32};
33
34const Error = Compilation.Error;
35
36const CodeGen = @This();
37
38tree: Tree,
39comp: *Compilation,
40builder: Builder,
41node_tag: []const Tree.Tag,
42node_data: []const Tree.Node.Data,
43node_ty: []const Type,
44wip_switch: *WipSwitch = undefined,
45symbols: std.ArrayListUnmanaged(Symbol) = .{},
46ret_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
47phi_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
48record_elem_buf: std.ArrayListUnmanaged(Interner.Ref) = .{},
49record_cache: std.AutoHashMapUnmanaged(*Type.Record, Interner.Ref) = .{},
50cond_dummy_ty: ?Interner.Ref = null,
51bool_invert: bool = false,
52bool_end_label: Ir.Ref = .none,
53cond_dummy_ref: Ir.Ref = undefined,
54continue_label: Ir.Ref = undefined,
55break_label: Ir.Ref = undefined,
56return_label: Ir.Ref = undefined,
57
58fn fail(c: *CodeGen, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {
59 try c.comp.diagnostics.list.append(c.comp.gpa, .{
60 .tag = .cli_error,
61 .kind = .@"fatal error",
62 .extra = .{ .str = try std.fmt.allocPrint(c.comp.diagnostics.arena.allocator(), fmt, args) },
63 });
64 return error.FatalError;
65}
66
67pub fn genIr(tree: Tree) Compilation.Error!Ir {
68 const gpa = tree.comp.gpa;
69 var c = CodeGen{
70 .builder = .{
71 .gpa = tree.comp.gpa,
72 .interner = &tree.comp.interner,
73 .arena = std.heap.ArenaAllocator.init(gpa),
74 },
75 .tree = tree,
76 .comp = tree.comp,
77 .node_tag = tree.nodes.items(.tag),
78 .node_data = tree.nodes.items(.data),
79 .node_ty = tree.nodes.items(.ty),
80 };
81 defer c.symbols.deinit(gpa);
82 defer c.ret_nodes.deinit(gpa);
83 defer c.phi_nodes.deinit(gpa);
84 defer c.record_elem_buf.deinit(gpa);
85 defer c.record_cache.deinit(gpa);
86 defer c.builder.deinit();
87
88 const node_tags = tree.nodes.items(.tag);
89 for (tree.root_decls) |decl| {
90 c.builder.arena.deinit();
91 c.builder.arena = std.heap.ArenaAllocator.init(gpa);
92
93 switch (node_tags[@intFromEnum(decl)]) {
94 .static_assert,
95 .typedef,
96 .struct_decl_two,
97 .union_decl_two,
98 .enum_decl_two,
99 .struct_decl,
100 .union_decl,
101 .enum_decl,
102 => {},
103
104 .fn_proto,
105 .static_fn_proto,
106 .inline_fn_proto,
107 .inline_static_fn_proto,
108 .extern_var,
109 .threadlocal_extern_var,
110 => {},
111
112 .fn_def,
113 .static_fn_def,
114 .inline_fn_def,
115 .inline_static_fn_def,
116 => c.genFn(decl) catch |err| switch (err) {
117 error.FatalError => return error.FatalError,
118 error.OutOfMemory => return error.OutOfMemory,
119 },
120
121 .@"var",
122 .static_var,
123 .threadlocal_var,
124 .threadlocal_static_var,
125 => c.genVar(decl) catch |err| switch (err) {
126 error.FatalError => return error.FatalError,
127 error.OutOfMemory => return error.OutOfMemory,
128 },
129 else => unreachable,
130 }
131 }
132 return c.builder.finish();
133}
134
135fn genType(c: *CodeGen, base_ty: Type) !Interner.Ref {
136 var key: Interner.Key = undefined;
137 const ty = base_ty.canonicalize(.standard);
138 switch (ty.specifier) {
139 .void => return .void,
140 .bool => return .i1,
141 .@"struct" => {
142 if (c.record_cache.get(ty.data.record)) |some| return some;
143
144 const elem_buf_top = c.record_elem_buf.items.len;
145 defer c.record_elem_buf.items.len = elem_buf_top;
146
147 for (ty.data.record.fields) |field| {
148 if (!field.isRegularField()) {
149 return c.fail("TODO lower struct bitfields", .{});
150 }
151 // TODO handle padding bits
152 const field_ref = try c.genType(field.ty);
153 try c.record_elem_buf.append(c.builder.gpa, field_ref);
154 }
155
156 return c.builder.interner.put(c.builder.gpa, .{
157 .record_ty = c.record_elem_buf.items[elem_buf_top..],
158 });
159 },
160 .@"union" => {
161 return c.fail("TODO lower union types", .{});
162 },
163 else => {},
164 }
165 if (ty.isPtr()) return .ptr;
166 if (ty.isFunc()) return .func;
167 if (!ty.isReal()) return c.fail("TODO lower complex types", .{});
168 if (ty.isInt()) {
169 const bits = ty.bitSizeof(c.comp).?;
170 key = .{ .int_ty = @intCast(bits) };
171 } else if (ty.isFloat()) {
172 const bits = ty.bitSizeof(c.comp).?;
173 key = .{ .float_ty = @intCast(bits) };
174 } else if (ty.isArray()) {
175 const elem = try c.genType(ty.elemType());
176 key = .{ .array_ty = .{ .child = elem, .len = ty.arrayLen().? } };
177 } else if (ty.specifier == .vector) {
178 const elem = try c.genType(ty.elemType());
179 key = .{ .vector_ty = .{ .child = elem, .len = @intCast(ty.data.array.len) } };
180 } else if (ty.is(.nullptr_t)) {
181 return c.fail("TODO lower nullptr_t", .{});
182 }
183 return c.builder.interner.put(c.builder.gpa, key);
184}
185
186fn genFn(c: *CodeGen, decl: NodeIndex) Error!void {
187 const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name);
188 const func_ty = c.node_ty[@intFromEnum(decl)].canonicalize(.standard);
189 c.ret_nodes.items.len = 0;
190
191 try c.builder.startFn();
192
193 for (func_ty.data.func.params) |param| {
194 // TODO handle calling convention here
195 const arg = try c.builder.addArg(try c.genType(param.ty));
196
197 const size: u32 = @intCast(param.ty.sizeof(c.comp).?); // TODO add error in parser
198 const @"align" = param.ty.alignof(c.comp);
199 const alloc = try c.builder.addAlloc(size, @"align");
200 try c.builder.addStore(alloc, arg);
201 try c.symbols.append(c.comp.gpa, .{ .name = param.name, .val = alloc });
202 }
203
204 // Generate body
205 c.return_label = try c.builder.makeLabel("return");
206 try c.genStmt(c.node_data[@intFromEnum(decl)].decl.node);
207
208 // Relocate returns
209 if (c.ret_nodes.items.len == 0) {
210 _ = try c.builder.addInst(.ret, .{ .un = .none }, .noreturn);
211 } else if (c.ret_nodes.items.len == 1) {
212 c.builder.body.items.len -= 1;
213 _ = try c.builder.addInst(.ret, .{ .un = c.ret_nodes.items[0].value }, .noreturn);
214 } else {
215 try c.builder.startBlock(c.return_label);
216 const phi = try c.builder.addPhi(c.ret_nodes.items, try c.genType(func_ty.returnType()));
217 _ = try c.builder.addInst(.ret, .{ .un = phi }, .noreturn);
218 }
219
220 try c.builder.finishFn(name);
221}
222
223fn addUn(c: *CodeGen, tag: Ir.Inst.Tag, operand: Ir.Ref, ty: Type) !Ir.Ref {
224 return c.builder.addInst(tag, .{ .un = operand }, try c.genType(ty));
225}
226
227fn addBin(c: *CodeGen, tag: Ir.Inst.Tag, lhs: Ir.Ref, rhs: Ir.Ref, ty: Type) !Ir.Ref {
228 return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, try c.genType(ty));
229}
230
231fn addBranch(c: *CodeGen, cond: Ir.Ref, true_label: Ir.Ref, false_label: Ir.Ref) !void {
232 if (true_label == c.bool_end_label) {
233 if (false_label == c.bool_end_label) {
234 try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = cond });
235 return;
236 }
237 try c.addBoolPhi(!c.bool_invert);
238 }
239 if (false_label == c.bool_end_label) {
240 try c.addBoolPhi(c.bool_invert);
241 }
242 return c.builder.addBranch(cond, true_label, false_label);
243}
244
245fn addBoolPhi(c: *CodeGen, value: bool) !void {
246 const val = try c.builder.addConstant((try Value.int(@intFromBool(value), c.comp)).ref(), .i1);
247 try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = val });
248}
249
250fn genStmt(c: *CodeGen, node: NodeIndex) Error!void {
251 _ = try c.genExpr(node);
252}
253
254fn genExpr(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
255 std.debug.assert(node != .none);
256 const ty = c.node_ty[@intFromEnum(node)];
257 if (c.tree.value_map.get(node)) |val| {
258 return c.builder.addConstant(val.ref(), try c.genType(ty));
259 }
260 const data = c.node_data[@intFromEnum(node)];
261 switch (c.node_tag[@intFromEnum(node)]) {
262 .enumeration_ref,
263 .bool_literal,
264 .int_literal,
265 .char_literal,
266 .float_literal,
267 .imaginary_literal,
268 .string_literal_expr,
269 .alignof_expr,
270 => unreachable, // These should have an entry in value_map.
271 .fn_def,
272 .static_fn_def,
273 .inline_fn_def,
274 .inline_static_fn_def,
275 .invalid,
276 .threadlocal_var,
277 => unreachable,
278 .static_assert,
279 .fn_proto,
280 .static_fn_proto,
281 .inline_fn_proto,
282 .inline_static_fn_proto,
283 .extern_var,
284 .threadlocal_extern_var,
285 .typedef,
286 .struct_decl_two,
287 .union_decl_two,
288 .enum_decl_two,
289 .struct_decl,
290 .union_decl,
291 .enum_decl,
292 .enum_field_decl,
293 .record_field_decl,
294 .indirect_record_field_decl,
295 .struct_forward_decl,
296 .union_forward_decl,
297 .enum_forward_decl,
298 .null_stmt,
299 => {},
300 .static_var,
301 .implicit_static_var,
302 .threadlocal_static_var,
303 => try c.genVar(node), // TODO
304 .@"var" => {
305 const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
306 const @"align" = ty.alignof(c.comp);
307 const alloc = try c.builder.addAlloc(size, @"align");
308 const name = try StrInt.intern(c.comp, c.tree.tokSlice(data.decl.name));
309 try c.symbols.append(c.comp.gpa, .{ .name = name, .val = alloc });
310 if (data.decl.node != .none) {
311 try c.genInitializer(alloc, ty, data.decl.node);
312 }
313 },
314 .labeled_stmt => {
315 const label = try c.builder.makeLabel("label");
316 try c.builder.startBlock(label);
317 try c.genStmt(data.decl.node);
318 },
319 .compound_stmt_two => {
320 const old_sym_len = c.symbols.items.len;
321 c.symbols.items.len = old_sym_len;
322
323 if (data.bin.lhs != .none) try c.genStmt(data.bin.lhs);
324 if (data.bin.rhs != .none) try c.genStmt(data.bin.rhs);
325 },
326 .compound_stmt => {
327 const old_sym_len = c.symbols.items.len;
328 c.symbols.items.len = old_sym_len;
329
330 for (c.tree.data[data.range.start..data.range.end]) |stmt| try c.genStmt(stmt);
331 },
332 .if_then_else_stmt => {
333 const then_label = try c.builder.makeLabel("if.then");
334 const else_label = try c.builder.makeLabel("if.else");
335 const end_label = try c.builder.makeLabel("if.end");
336
337 try c.genBoolExpr(data.if3.cond, then_label, else_label);
338
339 try c.builder.startBlock(then_label);
340 try c.genStmt(c.tree.data[data.if3.body]); // then
341 try c.builder.addJump(end_label);
342
343 try c.builder.startBlock(else_label);
344 try c.genStmt(c.tree.data[data.if3.body + 1]); // else
345
346 try c.builder.startBlock(end_label);
347 },
348 .if_then_stmt => {
349 const then_label = try c.builder.makeLabel("if.then");
350 const end_label = try c.builder.makeLabel("if.end");
351
352 try c.genBoolExpr(data.bin.lhs, then_label, end_label);
353
354 try c.builder.startBlock(then_label);
355 try c.genStmt(data.bin.rhs); // then
356 try c.builder.startBlock(end_label);
357 },
358 .switch_stmt => {
359 var wip_switch = WipSwitch{
360 .size = c.node_ty[@intFromEnum(data.bin.lhs)].sizeof(c.comp).?,
361 };
362 defer wip_switch.cases.deinit(c.builder.gpa);
363
364 const old_wip_switch = c.wip_switch;
365 defer c.wip_switch = old_wip_switch;
366 c.wip_switch = &wip_switch;
367
368 const old_break_label = c.break_label;
369 defer c.break_label = old_break_label;
370 const end_ref = try c.builder.makeLabel("switch.end");
371 c.break_label = end_ref;
372
373 const cond = try c.genExpr(data.bin.lhs);
374 const switch_index = c.builder.instructions.len;
375 _ = try c.builder.addInst(.@"switch", undefined, .noreturn);
376
377 try c.genStmt(data.bin.rhs); // body
378
379 const default_ref = wip_switch.default orelse end_ref;
380 try c.builder.startBlock(end_ref);
381
382 const a = c.builder.arena.allocator();
383 const switch_data = try a.create(Ir.Inst.Switch);
384 switch_data.* = .{
385 .target = cond,
386 .cases_len = @intCast(wip_switch.cases.len),
387 .case_vals = (try a.dupe(Interner.Ref, wip_switch.cases.items(.val))).ptr,
388 .case_labels = (try a.dupe(Ir.Ref, wip_switch.cases.items(.label))).ptr,
389 .default = default_ref,
390 };
391 c.builder.instructions.items(.data)[switch_index] = .{ .@"switch" = switch_data };
392 },
393 .case_stmt => {
394 const val = c.tree.value_map.get(data.bin.lhs).?;
395 const label = try c.builder.makeLabel("case");
396 try c.builder.startBlock(label);
397 try c.wip_switch.cases.append(c.builder.gpa, .{
398 .val = val.ref(),
399 .label = label,
400 });
401 try c.genStmt(data.bin.rhs);
402 },
403 .default_stmt => {
404 const default = try c.builder.makeLabel("default");
405 try c.builder.startBlock(default);
406 c.wip_switch.default = default;
407 try c.genStmt(data.un);
408 },
409 .while_stmt => {
410 const old_break_label = c.break_label;
411 defer c.break_label = old_break_label;
412
413 const old_continue_label = c.continue_label;
414 defer c.continue_label = old_continue_label;
415
416 const cond_label = try c.builder.makeLabel("while.cond");
417 const then_label = try c.builder.makeLabel("while.then");
418 const end_label = try c.builder.makeLabel("while.end");
419
420 c.continue_label = cond_label;
421 c.break_label = end_label;
422
423 try c.builder.startBlock(cond_label);
424 try c.genBoolExpr(data.bin.lhs, then_label, end_label);
425
426 try c.builder.startBlock(then_label);
427 try c.genStmt(data.bin.rhs);
428 try c.builder.addJump(cond_label);
429 try c.builder.startBlock(end_label);
430 },
431 .do_while_stmt => {
432 const old_break_label = c.break_label;
433 defer c.break_label = old_break_label;
434
435 const old_continue_label = c.continue_label;
436 defer c.continue_label = old_continue_label;
437
438 const then_label = try c.builder.makeLabel("do.then");
439 const cond_label = try c.builder.makeLabel("do.cond");
440 const end_label = try c.builder.makeLabel("do.end");
441
442 c.continue_label = cond_label;
443 c.break_label = end_label;
444
445 try c.builder.startBlock(then_label);
446 try c.genStmt(data.bin.rhs);
447
448 try c.builder.startBlock(cond_label);
449 try c.genBoolExpr(data.bin.lhs, then_label, end_label);
450
451 try c.builder.startBlock(end_label);
452 },
453 .for_decl_stmt => {
454 const old_break_label = c.break_label;
455 defer c.break_label = old_break_label;
456
457 const old_continue_label = c.continue_label;
458 defer c.continue_label = old_continue_label;
459
460 const for_decl = data.forDecl(&c.tree);
461 for (for_decl.decls) |decl| try c.genStmt(decl);
462
463 const then_label = try c.builder.makeLabel("for.then");
464 var cond_label = then_label;
465 const cont_label = try c.builder.makeLabel("for.cont");
466 const end_label = try c.builder.makeLabel("for.end");
467
468 c.continue_label = cont_label;
469 c.break_label = end_label;
470
471 if (for_decl.cond != .none) {
472 cond_label = try c.builder.makeLabel("for.cond");
473 try c.builder.startBlock(cond_label);
474 try c.genBoolExpr(for_decl.cond, then_label, end_label);
475 }
476 try c.builder.startBlock(then_label);
477 try c.genStmt(for_decl.body);
478 if (for_decl.incr != .none) {
479 _ = try c.genExpr(for_decl.incr);
480 }
481 try c.builder.addJump(cond_label);
482 try c.builder.startBlock(end_label);
483 },
484 .forever_stmt => {
485 const old_break_label = c.break_label;
486 defer c.break_label = old_break_label;
487
488 const old_continue_label = c.continue_label;
489 defer c.continue_label = old_continue_label;
490
491 const then_label = try c.builder.makeLabel("for.then");
492 const end_label = try c.builder.makeLabel("for.end");
493
494 c.continue_label = then_label;
495 c.break_label = end_label;
496
497 try c.builder.startBlock(then_label);
498 try c.genStmt(data.un);
499 try c.builder.startBlock(end_label);
500 },
501 .for_stmt => {
502 const old_break_label = c.break_label;
503 defer c.break_label = old_break_label;
504
505 const old_continue_label = c.continue_label;
506 defer c.continue_label = old_continue_label;
507
508 const for_stmt = data.forStmt(&c.tree);
509 if (for_stmt.init != .none) _ = try c.genExpr(for_stmt.init);
510
511 const then_label = try c.builder.makeLabel("for.then");
512 var cond_label = then_label;
513 const cont_label = try c.builder.makeLabel("for.cont");
514 const end_label = try c.builder.makeLabel("for.end");
515
516 c.continue_label = cont_label;
517 c.break_label = end_label;
518
519 if (for_stmt.cond != .none) {
520 cond_label = try c.builder.makeLabel("for.cond");
521 try c.builder.startBlock(cond_label);
522 try c.genBoolExpr(for_stmt.cond, then_label, end_label);
523 }
524 try c.builder.startBlock(then_label);
525 try c.genStmt(for_stmt.body);
526 if (for_stmt.incr != .none) {
527 _ = try c.genExpr(for_stmt.incr);
528 }
529 try c.builder.addJump(cond_label);
530 try c.builder.startBlock(end_label);
531 },
532 .continue_stmt => try c.builder.addJump(c.continue_label),
533 .break_stmt => try c.builder.addJump(c.break_label),
534 .return_stmt => {
535 if (data.un != .none) {
536 const operand = try c.genExpr(data.un);
537 try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
538 }
539 try c.builder.addJump(c.return_label);
540 },
541 .implicit_return => {
542 if (data.return_zero) {
543 const operand = try c.builder.addConstant(.zero, try c.genType(ty));
544 try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label });
545 }
546 // No need to emit a jump since implicit_return is always the last instruction.
547 },
548 .case_range_stmt,
549 .goto_stmt,
550 .computed_goto_stmt,
551 .nullptr_literal,
552 => return c.fail("TODO CodeGen.genStmt {}\n", .{c.node_tag[@intFromEnum(node)]}),
553 .comma_expr => {
554 _ = try c.genExpr(data.bin.lhs);
555 return c.genExpr(data.bin.rhs);
556 },
557 .assign_expr => {
558 const rhs = try c.genExpr(data.bin.rhs);
559 const lhs = try c.genLval(data.bin.lhs);
560 try c.builder.addStore(lhs, rhs);
561 return rhs;
562 },
563 .mul_assign_expr => return c.genCompoundAssign(node, .mul),
564 .div_assign_expr => return c.genCompoundAssign(node, .div),
565 .mod_assign_expr => return c.genCompoundAssign(node, .mod),
566 .add_assign_expr => return c.genCompoundAssign(node, .add),
567 .sub_assign_expr => return c.genCompoundAssign(node, .sub),
568 .shl_assign_expr => return c.genCompoundAssign(node, .bit_shl),
569 .shr_assign_expr => return c.genCompoundAssign(node, .bit_shr),
570 .bit_and_assign_expr => return c.genCompoundAssign(node, .bit_and),
571 .bit_xor_assign_expr => return c.genCompoundAssign(node, .bit_xor),
572 .bit_or_assign_expr => return c.genCompoundAssign(node, .bit_or),
573 .bit_or_expr => return c.genBinOp(node, .bit_or),
574 .bit_xor_expr => return c.genBinOp(node, .bit_xor),
575 .bit_and_expr => return c.genBinOp(node, .bit_and),
576 .equal_expr => {
577 const cmp = try c.genComparison(node, .cmp_eq);
578 return c.addUn(.zext, cmp, ty);
579 },
580 .not_equal_expr => {
581 const cmp = try c.genComparison(node, .cmp_ne);
582 return c.addUn(.zext, cmp, ty);
583 },
584 .less_than_expr => {
585 const cmp = try c.genComparison(node, .cmp_lt);
586 return c.addUn(.zext, cmp, ty);
587 },
588 .less_than_equal_expr => {
589 const cmp = try c.genComparison(node, .cmp_lte);
590 return c.addUn(.zext, cmp, ty);
591 },
592 .greater_than_expr => {
593 const cmp = try c.genComparison(node, .cmp_gt);
594 return c.addUn(.zext, cmp, ty);
595 },
596 .greater_than_equal_expr => {
597 const cmp = try c.genComparison(node, .cmp_gte);
598 return c.addUn(.zext, cmp, ty);
599 },
600 .shl_expr => return c.genBinOp(node, .bit_shl),
601 .shr_expr => return c.genBinOp(node, .bit_shr),
602 .add_expr => {
603 if (ty.isPtr()) {
604 const lhs_ty = c.node_ty[@intFromEnum(data.bin.lhs)];
605 if (lhs_ty.isPtr()) {
606 const ptr = try c.genExpr(data.bin.lhs);
607 const offset = try c.genExpr(data.bin.rhs);
608 const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
609 return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
610 } else {
611 const offset = try c.genExpr(data.bin.lhs);
612 const ptr = try c.genExpr(data.bin.rhs);
613 const offset_ty = lhs_ty;
614 return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
615 }
616 }
617 return c.genBinOp(node, .add);
618 },
619 .sub_expr => {
620 if (ty.isPtr()) {
621 const ptr = try c.genExpr(data.bin.lhs);
622 const offset = try c.genExpr(data.bin.rhs);
623 const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)];
624 return c.genPtrArithmetic(ptr, offset, offset_ty, ty);
625 }
626 return c.genBinOp(node, .sub);
627 },
628 .mul_expr => return c.genBinOp(node, .mul),
629 .div_expr => return c.genBinOp(node, .div),
630 .mod_expr => return c.genBinOp(node, .mod),
631 .addr_of_expr => return try c.genLval(data.un),
632 .deref_expr => {
633 const un_data = c.node_data[@intFromEnum(data.un)];
634 if (c.node_tag[@intFromEnum(data.un)] == .implicit_cast and un_data.cast.kind == .function_to_pointer) {
635 return c.genExpr(data.un);
636 }
637 const operand = try c.genLval(data.un);
638 return c.addUn(.load, operand, ty);
639 },
640 .plus_expr => return c.genExpr(data.un),
641 .negate_expr => {
642 const zero = try c.builder.addConstant(.zero, try c.genType(ty));
643 const operand = try c.genExpr(data.un);
644 return c.addBin(.sub, zero, operand, ty);
645 },
646 .bit_not_expr => {
647 const operand = try c.genExpr(data.un);
648 return c.addUn(.bit_not, operand, ty);
649 },
650 .bool_not_expr => {
651 const zero = try c.builder.addConstant(.zero, try c.genType(ty));
652 const operand = try c.genExpr(data.un);
653 return c.addBin(.cmp_ne, zero, operand, ty);
654 },
655 .pre_inc_expr => {
656 const operand = try c.genLval(data.un);
657 const val = try c.addUn(.load, operand, ty);
658 const one = try c.builder.addConstant(.one, try c.genType(ty));
659 const plus_one = try c.addBin(.add, val, one, ty);
660 try c.builder.addStore(operand, plus_one);
661 return plus_one;
662 },
663 .pre_dec_expr => {
664 const operand = try c.genLval(data.un);
665 const val = try c.addUn(.load, operand, ty);
666 const one = try c.builder.addConstant(.one, try c.genType(ty));
667 const plus_one = try c.addBin(.sub, val, one, ty);
668 try c.builder.addStore(operand, plus_one);
669 return plus_one;
670 },
671 .post_inc_expr => {
672 const operand = try c.genLval(data.un);
673 const val = try c.addUn(.load, operand, ty);
674 const one = try c.builder.addConstant(.one, try c.genType(ty));
675 const plus_one = try c.addBin(.add, val, one, ty);
676 try c.builder.addStore(operand, plus_one);
677 return val;
678 },
679 .post_dec_expr => {
680 const operand = try c.genLval(data.un);
681 const val = try c.addUn(.load, operand, ty);
682 const one = try c.builder.addConstant(.one, try c.genType(ty));
683 const plus_one = try c.addBin(.sub, val, one, ty);
684 try c.builder.addStore(operand, plus_one);
685 return val;
686 },
687 .paren_expr => return c.genExpr(data.un),
688 .decl_ref_expr => unreachable, // Lval expression.
689 .explicit_cast, .implicit_cast => switch (data.cast.kind) {
690 .no_op => return c.genExpr(data.cast.operand),
691 .to_void => {
692 _ = try c.genExpr(data.cast.operand);
693 return .none;
694 },
695 .lval_to_rval => {
696 const operand = try c.genLval(data.cast.operand);
697 return c.addUn(.load, operand, ty);
698 },
699 .function_to_pointer, .array_to_pointer => {
700 return c.genLval(data.cast.operand);
701 },
702 .int_cast => {
703 const operand = try c.genExpr(data.cast.operand);
704 const src_ty = c.node_ty[@intFromEnum(data.cast.operand)];
705 const src_bits = src_ty.bitSizeof(c.comp).?;
706 const dest_bits = ty.bitSizeof(c.comp).?;
707 if (src_bits == dest_bits) {
708 return operand;
709 } else if (src_bits < dest_bits) {
710 if (src_ty.isUnsignedInt(c.comp))
711 return c.addUn(.zext, operand, ty)
712 else
713 return c.addUn(.sext, operand, ty);
714 } else {
715 return c.addUn(.trunc, operand, ty);
716 }
717 },
718 .bool_to_int => {
719 const operand = try c.genExpr(data.cast.operand);
720 return c.addUn(.zext, operand, ty);
721 },
722 .pointer_to_bool, .int_to_bool, .float_to_bool => {
723 const lhs = try c.genExpr(data.cast.operand);
724 const rhs = try c.builder.addConstant(.zero, try c.genType(c.node_ty[@intFromEnum(node)]));
725 return c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
726 },
727 .bitcast,
728 .pointer_to_int,
729 .bool_to_float,
730 .bool_to_pointer,
731 .int_to_float,
732 .complex_int_to_complex_float,
733 .int_to_pointer,
734 .float_to_int,
735 .complex_float_to_complex_int,
736 .complex_int_cast,
737 .complex_int_to_real,
738 .real_to_complex_int,
739 .float_cast,
740 .complex_float_cast,
741 .complex_float_to_real,
742 .real_to_complex_float,
743 .null_to_pointer,
744 .union_cast,
745 .vector_splat,
746 => return c.fail("TODO CodeGen gen CastKind {}\n", .{data.cast.kind}),
747 },
748 .binary_cond_expr => {
749 if (c.tree.value_map.get(data.if3.cond)) |cond| {
750 if (cond.toBool(c.comp)) {
751 c.cond_dummy_ref = try c.genExpr(data.if3.cond);
752 return c.genExpr(c.tree.data[data.if3.body]); // then
753 } else {
754 return c.genExpr(c.tree.data[data.if3.body + 1]); // else
755 }
756 }
757
758 const then_label = try c.builder.makeLabel("ternary.then");
759 const else_label = try c.builder.makeLabel("ternary.else");
760 const end_label = try c.builder.makeLabel("ternary.end");
761 const cond_ty = c.node_ty[@intFromEnum(data.if3.cond)];
762 {
763 const old_cond_dummy_ty = c.cond_dummy_ty;
764 defer c.cond_dummy_ty = old_cond_dummy_ty;
765 c.cond_dummy_ty = try c.genType(cond_ty);
766
767 try c.genBoolExpr(data.if3.cond, then_label, else_label);
768 }
769
770 try c.builder.startBlock(then_label);
771 if (c.builder.instructions.items(.ty)[@intFromEnum(c.cond_dummy_ref)] == .i1) {
772 c.cond_dummy_ref = try c.addUn(.zext, c.cond_dummy_ref, cond_ty);
773 }
774 const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
775 try c.builder.addJump(end_label);
776 const then_exit = c.builder.current_label;
777
778 try c.builder.startBlock(else_label);
779 const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
780 const else_exit = c.builder.current_label;
781
782 try c.builder.startBlock(end_label);
783
784 var phi_buf: [2]Ir.Inst.Phi.Input = .{
785 .{ .value = then_val, .label = then_exit },
786 .{ .value = else_val, .label = else_exit },
787 };
788 return c.builder.addPhi(&phi_buf, try c.genType(ty));
789 },
790 .cond_dummy_expr => return c.cond_dummy_ref,
791 .cond_expr => {
792 if (c.tree.value_map.get(data.if3.cond)) |cond| {
793 if (cond.toBool(c.comp)) {
794 return c.genExpr(c.tree.data[data.if3.body]); // then
795 } else {
796 return c.genExpr(c.tree.data[data.if3.body + 1]); // else
797 }
798 }
799
800 const then_label = try c.builder.makeLabel("ternary.then");
801 const else_label = try c.builder.makeLabel("ternary.else");
802 const end_label = try c.builder.makeLabel("ternary.end");
803
804 try c.genBoolExpr(data.if3.cond, then_label, else_label);
805
806 try c.builder.startBlock(then_label);
807 const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then
808 try c.builder.addJump(end_label);
809 const then_exit = c.builder.current_label;
810
811 try c.builder.startBlock(else_label);
812 const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else
813 const else_exit = c.builder.current_label;
814
815 try c.builder.startBlock(end_label);
816
817 var phi_buf: [2]Ir.Inst.Phi.Input = .{
818 .{ .value = then_val, .label = then_exit },
819 .{ .value = else_val, .label = else_exit },
820 };
821 return c.builder.addPhi(&phi_buf, try c.genType(ty));
822 },
823 .call_expr_one => if (data.bin.rhs == .none) {
824 return c.genCall(data.bin.lhs, &.{}, ty);
825 } else {
826 return c.genCall(data.bin.lhs, &.{data.bin.rhs}, ty);
827 },
828 .call_expr => {
829 return c.genCall(c.tree.data[data.range.start], c.tree.data[data.range.start + 1 .. data.range.end], ty);
830 },
831 .bool_or_expr => {
832 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
833 if (!lhs.toBool(c.comp)) {
834 return c.builder.addConstant(.one, try c.genType(ty));
835 }
836 return c.genExpr(data.bin.rhs);
837 }
838
839 const false_label = try c.builder.makeLabel("bool_false");
840 const exit_label = try c.builder.makeLabel("bool_exit");
841
842 const old_bool_end_label = c.bool_end_label;
843 defer c.bool_end_label = old_bool_end_label;
844 c.bool_end_label = exit_label;
845
846 const phi_nodes_top = c.phi_nodes.items.len;
847 defer c.phi_nodes.items.len = phi_nodes_top;
848
849 try c.genBoolExpr(data.bin.lhs, exit_label, false_label);
850
851 try c.builder.startBlock(false_label);
852 try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
853
854 try c.builder.startBlock(exit_label);
855
856 const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
857 return c.addUn(.zext, phi, ty);
858 },
859 .bool_and_expr => {
860 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
861 if (!lhs.toBool(c.comp)) {
862 return c.builder.addConstant(.zero, try c.genType(ty));
863 }
864 return c.genExpr(data.bin.rhs);
865 }
866
867 const true_label = try c.builder.makeLabel("bool_true");
868 const exit_label = try c.builder.makeLabel("bool_exit");
869
870 const old_bool_end_label = c.bool_end_label;
871 defer c.bool_end_label = old_bool_end_label;
872 c.bool_end_label = exit_label;
873
874 const phi_nodes_top = c.phi_nodes.items.len;
875 defer c.phi_nodes.items.len = phi_nodes_top;
876
877 try c.genBoolExpr(data.bin.lhs, true_label, exit_label);
878
879 try c.builder.startBlock(true_label);
880 try c.genBoolExpr(data.bin.rhs, exit_label, exit_label);
881
882 try c.builder.startBlock(exit_label);
883
884 const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1);
885 return c.addUn(.zext, phi, ty);
886 },
887 .builtin_choose_expr => {
888 const cond = c.tree.value_map.get(data.if3.cond).?;
889 if (cond.toBool(c.comp)) {
890 return c.genExpr(c.tree.data[data.if3.body]);
891 } else {
892 return c.genExpr(c.tree.data[data.if3.body + 1]);
893 }
894 },
895 .generic_expr_one => {
896 const index = @intFromEnum(data.bin.rhs);
897 switch (c.node_tag[index]) {
898 .generic_association_expr, .generic_default_expr => {
899 return c.genExpr(c.node_data[index].un);
900 },
901 else => unreachable,
902 }
903 },
904 .generic_expr => {
905 const index = @intFromEnum(c.tree.data[data.range.start + 1]);
906 switch (c.node_tag[index]) {
907 .generic_association_expr, .generic_default_expr => {
908 return c.genExpr(c.node_data[index].un);
909 },
910 else => unreachable,
911 }
912 },
913 .generic_association_expr, .generic_default_expr => unreachable,
914 .stmt_expr => switch (c.node_tag[@intFromEnum(data.un)]) {
915 .compound_stmt_two => {
916 const old_sym_len = c.symbols.items.len;
917 c.symbols.items.len = old_sym_len;
918
919 const stmt_data = c.node_data[@intFromEnum(data.un)];
920 if (stmt_data.bin.rhs == .none) return c.genExpr(stmt_data.bin.lhs);
921 try c.genStmt(stmt_data.bin.lhs);
922 return c.genExpr(stmt_data.bin.rhs);
923 },
924 .compound_stmt => {
925 const old_sym_len = c.symbols.items.len;
926 c.symbols.items.len = old_sym_len;
927
928 const stmt_data = c.node_data[@intFromEnum(data.un)];
929 for (c.tree.data[stmt_data.range.start .. stmt_data.range.end - 1]) |stmt| try c.genStmt(stmt);
930 return c.genExpr(c.tree.data[stmt_data.range.end]);
931 },
932 else => unreachable,
933 },
934 .builtin_call_expr_one => {
935 const name = c.tree.tokSlice(data.decl.name);
936 const builtin = c.comp.builtins.lookup(name).builtin;
937 if (data.decl.node == .none) {
938 return c.genBuiltinCall(builtin, &.{}, ty);
939 } else {
940 return c.genBuiltinCall(builtin, &.{data.decl.node}, ty);
941 }
942 },
943 .builtin_call_expr => {
944 const name_node_idx = c.tree.data[data.range.start];
945 const name = c.tree.tokSlice(@intFromEnum(name_node_idx));
946 const builtin = c.comp.builtins.lookup(name).builtin;
947 return c.genBuiltinCall(builtin, c.tree.data[data.range.start + 1 .. data.range.end], ty);
948 },
949 .addr_of_label,
950 .imag_expr,
951 .real_expr,
952 .sizeof_expr,
953 .special_builtin_call_one,
954 => return c.fail("TODO CodeGen.genExpr {}\n", .{c.node_tag[@intFromEnum(node)]}),
955 else => unreachable, // Not an expression.
956 }
957 return .none;
958}
959
960fn genLval(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
961 std.debug.assert(node != .none);
962 assert(c.tree.isLval(node));
963 const data = c.node_data[@intFromEnum(node)];
964 switch (c.node_tag[@intFromEnum(node)]) {
965 .string_literal_expr => {
966 const val = c.tree.value_map.get(node).?;
967 return c.builder.addConstant(val.ref(), .ptr);
968 },
969 .paren_expr => return c.genLval(data.un),
970 .decl_ref_expr => {
971 const slice = c.tree.tokSlice(data.decl_ref);
972 const name = try StrInt.intern(c.comp, slice);
973 var i = c.symbols.items.len;
974 while (i > 0) {
975 i -= 1;
976 if (c.symbols.items[i].name == name) {
977 return c.symbols.items[i].val;
978 }
979 }
980
981 const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
982 const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
983 try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
984 return ref;
985 },
986 .deref_expr => return c.genExpr(data.un),
987 .compound_literal_expr => {
988 const ty = c.node_ty[@intFromEnum(node)];
989 const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser
990 const @"align" = ty.alignof(c.comp);
991 const alloc = try c.builder.addAlloc(size, @"align");
992 try c.genInitializer(alloc, ty, data.un);
993 return alloc;
994 },
995 .builtin_choose_expr => {
996 const cond = c.tree.value_map.get(data.if3.cond).?;
997 if (cond.toBool(c.comp)) {
998 return c.genLval(c.tree.data[data.if3.body]);
999 } else {
1000 return c.genLval(c.tree.data[data.if3.body + 1]);
1001 }
1002 },
1003 .member_access_expr,
1004 .member_access_ptr_expr,
1005 .array_access_expr,
1006 .static_compound_literal_expr,
1007 .thread_local_compound_literal_expr,
1008 .static_thread_local_compound_literal_expr,
1009 => return c.fail("TODO CodeGen.genLval {}\n", .{c.node_tag[@intFromEnum(node)]}),
1010 else => unreachable, // Not an lval expression.
1011 }
1012}
1013
1014fn genBoolExpr(c: *CodeGen, base: NodeIndex, true_label: Ir.Ref, false_label: Ir.Ref) Error!void {
1015 var node = base;
1016 while (true) switch (c.node_tag[@intFromEnum(node)]) {
1017 .paren_expr => {
1018 node = c.node_data[@intFromEnum(node)].un;
1019 },
1020 else => break,
1021 };
1022
1023 const data = c.node_data[@intFromEnum(node)];
1024 switch (c.node_tag[@intFromEnum(node)]) {
1025 .bool_or_expr => {
1026 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
1027 if (lhs.toBool(c.comp)) {
1028 if (true_label == c.bool_end_label) {
1029 return c.addBoolPhi(!c.bool_invert);
1030 }
1031 return c.builder.addJump(true_label);
1032 }
1033 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1034 }
1035
1036 const new_false_label = try c.builder.makeLabel("bool_false");
1037 try c.genBoolExpr(data.bin.lhs, true_label, new_false_label);
1038 try c.builder.startBlock(new_false_label);
1039
1040 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1041 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1042 },
1043 .bool_and_expr => {
1044 if (c.tree.value_map.get(data.bin.lhs)) |lhs| {
1045 if (!lhs.toBool(c.comp)) {
1046 if (false_label == c.bool_end_label) {
1047 return c.addBoolPhi(c.bool_invert);
1048 }
1049 return c.builder.addJump(false_label);
1050 }
1051 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1052 }
1053
1054 const new_true_label = try c.builder.makeLabel("bool_true");
1055 try c.genBoolExpr(data.bin.lhs, new_true_label, false_label);
1056 try c.builder.startBlock(new_true_label);
1057
1058 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1059 return c.genBoolExpr(data.bin.rhs, true_label, false_label);
1060 },
1061 .bool_not_expr => {
1062 c.bool_invert = !c.bool_invert;
1063 defer c.bool_invert = !c.bool_invert;
1064
1065 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.zero, ty);
1066 return c.genBoolExpr(data.un, false_label, true_label);
1067 },
1068 .equal_expr => {
1069 const cmp = try c.genComparison(node, .cmp_eq);
1070 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1071 return c.addBranch(cmp, true_label, false_label);
1072 },
1073 .not_equal_expr => {
1074 const cmp = try c.genComparison(node, .cmp_ne);
1075 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1076 return c.addBranch(cmp, true_label, false_label);
1077 },
1078 .less_than_expr => {
1079 const cmp = try c.genComparison(node, .cmp_lt);
1080 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1081 return c.addBranch(cmp, true_label, false_label);
1082 },
1083 .less_than_equal_expr => {
1084 const cmp = try c.genComparison(node, .cmp_lte);
1085 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1086 return c.addBranch(cmp, true_label, false_label);
1087 },
1088 .greater_than_expr => {
1089 const cmp = try c.genComparison(node, .cmp_gt);
1090 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1091 return c.addBranch(cmp, true_label, false_label);
1092 },
1093 .greater_than_equal_expr => {
1094 const cmp = try c.genComparison(node, .cmp_gte);
1095 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1096 return c.addBranch(cmp, true_label, false_label);
1097 },
1098 .explicit_cast, .implicit_cast => switch (data.cast.kind) {
1099 .bool_to_int => {
1100 const operand = try c.genExpr(data.cast.operand);
1101 if (c.cond_dummy_ty != null) c.cond_dummy_ref = operand;
1102 return c.addBranch(operand, true_label, false_label);
1103 },
1104 else => {},
1105 },
1106 .binary_cond_expr => {
1107 if (c.tree.value_map.get(data.if3.cond)) |cond| {
1108 if (cond.toBool(c.comp)) {
1109 return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
1110 } else {
1111 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1112 }
1113 }
1114
1115 const new_false_label = try c.builder.makeLabel("ternary.else");
1116 try c.genBoolExpr(data.if3.cond, true_label, new_false_label);
1117
1118 try c.builder.startBlock(new_false_label);
1119 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1120 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1121 },
1122 .cond_expr => {
1123 if (c.tree.value_map.get(data.if3.cond)) |cond| {
1124 if (cond.toBool(c.comp)) {
1125 return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
1126 } else {
1127 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1128 }
1129 }
1130
1131 const new_true_label = try c.builder.makeLabel("ternary.then");
1132 const new_false_label = try c.builder.makeLabel("ternary.else");
1133 try c.genBoolExpr(data.if3.cond, new_true_label, new_false_label);
1134
1135 try c.builder.startBlock(new_true_label);
1136 try c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then
1137 try c.builder.startBlock(new_false_label);
1138 if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty);
1139 return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else
1140 },
1141 else => {},
1142 }
1143
1144 if (c.tree.value_map.get(node)) |value| {
1145 if (value.toBool(c.comp)) {
1146 if (true_label == c.bool_end_label) {
1147 return c.addBoolPhi(!c.bool_invert);
1148 }
1149 return c.builder.addJump(true_label);
1150 } else {
1151 if (false_label == c.bool_end_label) {
1152 return c.addBoolPhi(c.bool_invert);
1153 }
1154 return c.builder.addJump(false_label);
1155 }
1156 }
1157
1158 // Assume int operand.
1159 const lhs = try c.genExpr(node);
1160 const rhs = try c.builder.addConstant(.zero, try c.genType(c.node_ty[@intFromEnum(node)]));
1161 const cmp = try c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
1162 if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp;
1163 try c.addBranch(cmp, true_label, false_label);
1164}
1165
1166fn genBuiltinCall(c: *CodeGen, builtin: Builtin, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
1167 _ = arg_nodes;
1168 _ = ty;
1169 return c.fail("TODO CodeGen.genBuiltinCall {s}\n", .{Builtin.nameFromTag(builtin.tag).span()});
1170}
1171
1172fn genCall(c: *CodeGen, fn_node: NodeIndex, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref {
1173 // Detect direct calls.
1174 const fn_ref = blk: {
1175 const data = c.node_data[@intFromEnum(fn_node)];
1176 if (c.node_tag[@intFromEnum(fn_node)] != .implicit_cast or data.cast.kind != .function_to_pointer) {
1177 break :blk try c.genExpr(fn_node);
1178 }
1179
1180 var cur = @intFromEnum(data.cast.operand);
1181 while (true) switch (c.node_tag[cur]) {
1182 .paren_expr, .addr_of_expr, .deref_expr => {
1183 cur = @intFromEnum(c.node_data[cur].un);
1184 },
1185 .implicit_cast => {
1186 const cast = c.node_data[cur].cast;
1187 if (cast.kind != .function_to_pointer) {
1188 break :blk try c.genExpr(fn_node);
1189 }
1190 cur = @intFromEnum(cast.operand);
1191 },
1192 .decl_ref_expr => {
1193 const slice = c.tree.tokSlice(c.node_data[cur].decl_ref);
1194 const name = try StrInt.intern(c.comp, slice);
1195 var i = c.symbols.items.len;
1196 while (i > 0) {
1197 i -= 1;
1198 if (c.symbols.items[i].name == name) {
1199 break :blk try c.genExpr(fn_node);
1200 }
1201 }
1202
1203 const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice);
1204 const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len);
1205 try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr });
1206 break :blk ref;
1207 },
1208 else => break :blk try c.genExpr(fn_node),
1209 };
1210 };
1211
1212 const args = try c.builder.arena.allocator().alloc(Ir.Ref, arg_nodes.len);
1213 for (arg_nodes, args) |node, *arg| {
1214 // TODO handle calling convention here
1215 arg.* = try c.genExpr(node);
1216 }
1217 // TODO handle variadic call
1218 const call = try c.builder.arena.allocator().create(Ir.Inst.Call);
1219 call.* = .{
1220 .func = fn_ref,
1221 .args_len = @intCast(args.len),
1222 .args_ptr = args.ptr,
1223 };
1224 return c.builder.addInst(.call, .{ .call = call }, try c.genType(ty));
1225}
1226
1227fn genCompoundAssign(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
1228 const bin = c.node_data[@intFromEnum(node)].bin;
1229 const ty = c.node_ty[@intFromEnum(node)];
1230 const rhs = try c.genExpr(bin.rhs);
1231 const lhs = try c.genLval(bin.lhs);
1232 const res = try c.addBin(tag, lhs, rhs, ty);
1233 try c.builder.addStore(lhs, res);
1234 return res;
1235}
1236
1237fn genBinOp(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
1238 const bin = c.node_data[@intFromEnum(node)].bin;
1239 const ty = c.node_ty[@intFromEnum(node)];
1240 const lhs = try c.genExpr(bin.lhs);
1241 const rhs = try c.genExpr(bin.rhs);
1242 return c.addBin(tag, lhs, rhs, ty);
1243}
1244
1245fn genComparison(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref {
1246 const bin = c.node_data[@intFromEnum(node)].bin;
1247 const lhs = try c.genExpr(bin.lhs);
1248 const rhs = try c.genExpr(bin.rhs);
1249
1250 return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1);
1251}
1252
1253fn genPtrArithmetic(c: *CodeGen, ptr: Ir.Ref, offset: Ir.Ref, offset_ty: Type, ty: Type) Error!Ir.Ref {
1254 // TODO consider adding a getelemptr instruction
1255 const size = ty.elemType().sizeof(c.comp).?;
1256 if (size == 1) {
1257 return c.builder.addInst(.add, .{ .bin = .{ .lhs = ptr, .rhs = offset } }, try c.genType(ty));
1258 }
1259
1260 const size_inst = try c.builder.addConstant((try Value.int(size, c.comp)).ref(), try c.genType(offset_ty));
1261 const offset_inst = try c.addBin(.mul, offset, size_inst, offset_ty);
1262 return c.addBin(.add, ptr, offset_inst, offset_ty);
1263}
1264
1265fn genInitializer(c: *CodeGen, ptr: Ir.Ref, dest_ty: Type, initializer: NodeIndex) Error!void {
1266 std.debug.assert(initializer != .none);
1267 switch (c.node_tag[@intFromEnum(initializer)]) {
1268 .array_init_expr_two,
1269 .array_init_expr,
1270 .struct_init_expr_two,
1271 .struct_init_expr,
1272 .union_init_expr,
1273 .array_filler_expr,
1274 .default_init_expr,
1275 => return c.fail("TODO CodeGen.genInitializer {}\n", .{c.node_tag[@intFromEnum(initializer)]}),
1276 .string_literal_expr => {
1277 const val = c.tree.value_map.get(initializer).?;
1278 const str_ptr = try c.builder.addConstant(val.ref(), .ptr);
1279 if (dest_ty.isArray()) {
1280 return c.fail("TODO memcpy\n", .{});
1281 } else {
1282 try c.builder.addStore(ptr, str_ptr);
1283 }
1284 },
1285 else => {
1286 const res = try c.genExpr(initializer);
1287 try c.builder.addStore(ptr, res);
1288 },
1289 }
1290}
1291
1292fn genVar(c: *CodeGen, decl: NodeIndex) Error!void {
1293 _ = decl;
1294 return c.fail("TODO CodeGen.genVar\n", .{});
1295}
lib/compiler/aro/aro/Compilation.zig created+1678
......@@ -0,0 +1,1678 @@
1const std = @import("std");
2const Allocator = mem.Allocator;
3const assert = std.debug.assert;
4const EpochSeconds = std.time.epoch.EpochSeconds;
5const mem = std.mem;
6const Interner = @import("../backend.zig").Interner;
7const Builtins = @import("Builtins.zig");
8const Builtin = Builtins.Builtin;
9const Diagnostics = @import("Diagnostics.zig");
10const LangOpts = @import("LangOpts.zig");
11const Source = @import("Source.zig");
12const Tokenizer = @import("Tokenizer.zig");
13const Token = Tokenizer.Token;
14const Type = @import("Type.zig");
15const Pragma = @import("Pragma.zig");
16const StrInt = @import("StringInterner.zig");
17const record_layout = @import("record_layout.zig");
18const target_util = @import("target.zig");
19
20pub const Error = error{
21 /// A fatal error has ocurred and compilation has stopped.
22 FatalError,
23} || Allocator.Error;
24
25pub const bit_int_max_bits = std.math.maxInt(u16);
26const path_buf_stack_limit = 1024;
27
28/// Environment variables used during compilation / linking.
29pub const Environment = struct {
30 /// Directory to use for temporary files
31 /// TODO: not implemented yet
32 tmpdir: ?[]const u8 = null,
33
34 /// PATH environment variable used to search for programs
35 path: ?[]const u8 = null,
36
37 /// Directories to try when searching for subprograms.
38 /// TODO: not implemented yet
39 compiler_path: ?[]const u8 = null,
40
41 /// Directories to try when searching for special linker files, if compiling for the native target
42 /// TODO: not implemented yet
43 library_path: ?[]const u8 = null,
44
45 /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
46 /// Used regardless of the language being compiled
47 /// TODO: not implemented yet
48 cpath: ?[]const u8 = null,
49
50 /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line
51 /// Used if the language being compiled is C
52 /// TODO: not implemented yet
53 c_include_path: ?[]const u8 = null,
54
55 /// UNIX timestamp to be used instead of the current date and time in the __DATE__ and __TIME__ macros
56 source_date_epoch: ?[]const u8 = null,
57
58 /// Load all of the environment variables using the std.process API. Do not use if using Aro as a shared library on Linux without libc
59 /// See https://github.com/ziglang/zig/issues/4524
60 pub fn loadAll(allocator: std.mem.Allocator) !Environment {
61 var env: Environment = .{};
62 errdefer env.deinit(allocator);
63
64 inline for (@typeInfo(@TypeOf(env)).Struct.fields) |field| {
65 std.debug.assert(@field(env, field.name) == null);
66
67 var env_var_buf: [field.name.len]u8 = undefined;
68 const env_var_name = std.ascii.upperString(&env_var_buf, field.name);
69 const val: ?[]const u8 = std.process.getEnvVarOwned(allocator, env_var_name) catch |err| switch (err) {
70 error.OutOfMemory => |e| return e,
71 error.EnvironmentVariableNotFound => null,
72 error.InvalidWtf8 => null,
73 };
74 @field(env, field.name) = val;
75 }
76 return env;
77 }
78
79 /// Use this only if environment slices were allocated with `allocator` (such as via `loadAll`)
80 pub fn deinit(self: *Environment, allocator: std.mem.Allocator) void {
81 inline for (@typeInfo(@TypeOf(self.*)).Struct.fields) |field| {
82 if (@field(self, field.name)) |slice| {
83 allocator.free(slice);
84 }
85 }
86 self.* = undefined;
87 }
88};
89
90const Compilation = @This();
91
92gpa: Allocator,
93diagnostics: Diagnostics,
94
95environment: Environment = .{},
96sources: std.StringArrayHashMapUnmanaged(Source) = .{},
97include_dirs: std.ArrayListUnmanaged([]const u8) = .{},
98system_include_dirs: std.ArrayListUnmanaged([]const u8) = .{},
99target: std.Target = @import("builtin").target,
100pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .{},
101langopts: LangOpts = .{},
102generated_buf: std.ArrayListUnmanaged(u8) = .{},
103builtins: Builtins = .{},
104types: struct {
105 wchar: Type = undefined,
106 uint_least16_t: Type = undefined,
107 uint_least32_t: Type = undefined,
108 ptrdiff: Type = undefined,
109 size: Type = undefined,
110 va_list: Type = undefined,
111 pid_t: Type = undefined,
112 ns_constant_string: struct {
113 ty: Type = undefined,
114 record: Type.Record = undefined,
115 fields: [4]Type.Record.Field = undefined,
116 int_ty: Type = .{ .specifier = .int, .qual = .{ .@"const" = true } },
117 char_ty: Type = .{ .specifier = .char, .qual = .{ .@"const" = true } },
118 } = .{},
119 file: Type = .{ .specifier = .invalid },
120 jmp_buf: Type = .{ .specifier = .invalid },
121 sigjmp_buf: Type = .{ .specifier = .invalid },
122 ucontext_t: Type = .{ .specifier = .invalid },
123 intmax: Type = .{ .specifier = .invalid },
124 intptr: Type = .{ .specifier = .invalid },
125 int16: Type = .{ .specifier = .invalid },
126 int64: Type = .{ .specifier = .invalid },
127} = .{},
128string_interner: StrInt = .{},
129interner: Interner = .{},
130ms_cwd_source_id: ?Source.Id = null,
131
132pub fn init(gpa: Allocator) Compilation {
133 return .{
134 .gpa = gpa,
135 .diagnostics = Diagnostics.init(gpa),
136 };
137}
138
139/// Initialize Compilation with default environment,
140/// pragma handlers and emulation mode set to target.
141pub fn initDefault(gpa: Allocator) !Compilation {
142 var comp: Compilation = .{
143 .gpa = gpa,
144 .environment = try Environment.loadAll(gpa),
145 .diagnostics = Diagnostics.init(gpa),
146 };
147 errdefer comp.deinit();
148 try comp.addDefaultPragmaHandlers();
149 comp.langopts.setEmulatedCompiler(target_util.systemCompiler(comp.target));
150 return comp;
151}
152
153pub fn deinit(comp: *Compilation) void {
154 for (comp.pragma_handlers.values()) |pragma| {
155 pragma.deinit(pragma, comp);
156 }
157 for (comp.sources.values()) |source| {
158 comp.gpa.free(source.path);
159 comp.gpa.free(source.buf);
160 comp.gpa.free(source.splice_locs);
161 }
162 comp.sources.deinit(comp.gpa);
163 comp.diagnostics.deinit();
164 comp.include_dirs.deinit(comp.gpa);
165 for (comp.system_include_dirs.items) |path| comp.gpa.free(path);
166 comp.system_include_dirs.deinit(comp.gpa);
167 comp.pragma_handlers.deinit(comp.gpa);
168 comp.generated_buf.deinit(comp.gpa);
169 comp.builtins.deinit(comp.gpa);
170 comp.string_interner.deinit(comp.gpa);
171 comp.interner.deinit(comp.gpa);
172 comp.environment.deinit(comp.gpa);
173}
174
175pub fn getSourceEpoch(self: *const Compilation, max: i64) !?i64 {
176 const provided = self.environment.source_date_epoch orelse return null;
177 const parsed = std.fmt.parseInt(i64, provided, 10) catch return error.InvalidEpoch;
178 if (parsed < 0 or parsed > max) return error.InvalidEpoch;
179 return parsed;
180}
181
182/// Dec 31 9999 23:59:59
183const max_timestamp = 253402300799;
184
185fn getTimestamp(comp: *Compilation) !u47 {
186 const provided: ?i64 = comp.getSourceEpoch(max_timestamp) catch blk: {
187 try comp.addDiagnostic(.{
188 .tag = .invalid_source_epoch,
189 .loc = .{ .id = .unused, .byte_offset = 0, .line = 0 },
190 }, &.{});
191 break :blk null;
192 };
193 const timestamp = provided orelse std.time.timestamp();
194 return @intCast(std.math.clamp(timestamp, 0, max_timestamp));
195}
196
197fn generateDateAndTime(w: anytype, timestamp: u47) !void {
198 const epoch_seconds = EpochSeconds{ .secs = timestamp };
199 const epoch_day = epoch_seconds.getEpochDay();
200 const day_seconds = epoch_seconds.getDaySeconds();
201 const year_day = epoch_day.calculateYearDay();
202 const month_day = year_day.calculateMonthDay();
203
204 const month_names = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
205 std.debug.assert(std.time.epoch.Month.jan.numeric() == 1);
206
207 const month_name = month_names[month_day.month.numeric() - 1];
208 try w.print("#define __DATE__ \"{s} {d: >2} {d}\"\n", .{
209 month_name,
210 month_day.day_index + 1,
211 year_day.year,
212 });
213 try w.print("#define __TIME__ \"{d:0>2}:{d:0>2}:{d:0>2}\"\n", .{
214 day_seconds.getHoursIntoDay(),
215 day_seconds.getMinutesIntoHour(),
216 day_seconds.getSecondsIntoMinute(),
217 });
218
219 const day_names = [_][]const u8{ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
220 // days since Thu Oct 1 1970
221 const day_name = day_names[@intCast((epoch_day.day + 3) % 7)];
222 try w.print("#define __TIMESTAMP__ \"{s} {s} {d: >2} {d:0>2}:{d:0>2}:{d:0>2} {d}\"\n", .{
223 day_name,
224 month_name,
225 month_day.day_index + 1,
226 day_seconds.getHoursIntoDay(),
227 day_seconds.getMinutesIntoHour(),
228 day_seconds.getSecondsIntoMinute(),
229 year_day.year,
230 });
231}
232
233/// Which set of system defines to generate via generateBuiltinMacros
234pub const SystemDefinesMode = enum {
235 /// Only define macros required by the C standard (date/time macros and those beginning with `__STDC`)
236 no_system_defines,
237 /// Define the standard set of system macros
238 include_system_defines,
239};
240
241fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
242 const ptr_width = comp.target.ptrBitWidth();
243
244 // os macros
245 switch (comp.target.os.tag) {
246 .linux => try w.writeAll(
247 \\#define linux 1
248 \\#define __linux 1
249 \\#define __linux__ 1
250 \\
251 ),
252 .windows => if (ptr_width == 32) try w.writeAll(
253 \\#define WIN32 1
254 \\#define _WIN32 1
255 \\#define __WIN32 1
256 \\#define __WIN32__ 1
257 \\
258 ) else try w.writeAll(
259 \\#define WIN32 1
260 \\#define WIN64 1
261 \\#define _WIN32 1
262 \\#define _WIN64 1
263 \\#define __WIN32 1
264 \\#define __WIN64 1
265 \\#define __WIN32__ 1
266 \\#define __WIN64__ 1
267 \\
268 ),
269 .freebsd => try w.print("#define __FreeBSD__ {d}\n", .{comp.target.os.version_range.semver.min.major}),
270 .netbsd => try w.writeAll("#define __NetBSD__ 1\n"),
271 .openbsd => try w.writeAll("#define __OpenBSD__ 1\n"),
272 .dragonfly => try w.writeAll("#define __DragonFly__ 1\n"),
273 .solaris => try w.writeAll(
274 \\#define sun 1
275 \\#define __sun 1
276 \\
277 ),
278 .macos => try w.writeAll(
279 \\#define __APPLE__ 1
280 \\#define __MACH__ 1
281 \\
282 ),
283 else => {},
284 }
285
286 // unix and other additional os macros
287 switch (comp.target.os.tag) {
288 .freebsd,
289 .netbsd,
290 .openbsd,
291 .dragonfly,
292 .linux,
293 => try w.writeAll(
294 \\#define unix 1
295 \\#define __unix 1
296 \\#define __unix__ 1
297 \\
298 ),
299 else => {},
300 }
301 if (comp.target.abi == .android) {
302 try w.writeAll("#define __ANDROID__ 1\n");
303 }
304
305 // architecture macros
306 switch (comp.target.cpu.arch) {
307 .x86_64 => try w.writeAll(
308 \\#define __amd64__ 1
309 \\#define __amd64 1
310 \\#define __x86_64 1
311 \\#define __x86_64__ 1
312 \\
313 ),
314 .x86 => try w.writeAll(
315 \\#define i386 1
316 \\#define __i386 1
317 \\#define __i386__ 1
318 \\
319 ),
320 .mips,
321 .mipsel,
322 .mips64,
323 .mips64el,
324 => try w.writeAll(
325 \\#define __mips__ 1
326 \\#define mips 1
327 \\
328 ),
329 .powerpc,
330 .powerpcle,
331 => try w.writeAll(
332 \\#define __powerpc__ 1
333 \\#define __POWERPC__ 1
334 \\#define __ppc__ 1
335 \\#define __PPC__ 1
336 \\#define _ARCH_PPC 1
337 \\
338 ),
339 .powerpc64,
340 .powerpc64le,
341 => try w.writeAll(
342 \\#define __powerpc 1
343 \\#define __powerpc__ 1
344 \\#define __powerpc64__ 1
345 \\#define __POWERPC__ 1
346 \\#define __ppc__ 1
347 \\#define __ppc64__ 1
348 \\#define __PPC__ 1
349 \\#define __PPC64__ 1
350 \\#define _ARCH_PPC 1
351 \\#define _ARCH_PPC64 1
352 \\
353 ),
354 .sparc64 => try w.writeAll(
355 \\#define __sparc__ 1
356 \\#define __sparc 1
357 \\#define __sparc_v9__ 1
358 \\
359 ),
360 .sparc, .sparcel => try w.writeAll(
361 \\#define __sparc__ 1
362 \\#define __sparc 1
363 \\
364 ),
365 .arm, .armeb => try w.writeAll(
366 \\#define __arm__ 1
367 \\#define __arm 1
368 \\
369 ),
370 .thumb, .thumbeb => try w.writeAll(
371 \\#define __arm__ 1
372 \\#define __arm 1
373 \\#define __thumb__ 1
374 \\
375 ),
376 .aarch64, .aarch64_be => try w.writeAll("#define __aarch64__ 1\n"),
377 .msp430 => try w.writeAll(
378 \\#define MSP430 1
379 \\#define __MSP430__ 1
380 \\
381 ),
382 else => {},
383 }
384
385 if (comp.target.os.tag != .windows) switch (ptr_width) {
386 64 => try w.writeAll(
387 \\#define _LP64 1
388 \\#define __LP64__ 1
389 \\
390 ),
391 32 => try w.writeAll("#define _ILP32 1\n"),
392 else => {},
393 };
394
395 try w.writeAll(
396 \\#define __ORDER_LITTLE_ENDIAN__ 1234
397 \\#define __ORDER_BIG_ENDIAN__ 4321
398 \\#define __ORDER_PDP_ENDIAN__ 3412
399 \\
400 );
401 if (comp.target.cpu.arch.endian() == .little) try w.writeAll(
402 \\#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
403 \\#define __LITTLE_ENDIAN__ 1
404 \\
405 ) else try w.writeAll(
406 \\#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
407 \\#define __BIG_ENDIAN__ 1
408 \\
409 );
410
411 // atomics
412 try w.writeAll(
413 \\#define __ATOMIC_RELAXED 0
414 \\#define __ATOMIC_CONSUME 1
415 \\#define __ATOMIC_ACQUIRE 2
416 \\#define __ATOMIC_RELEASE 3
417 \\#define __ATOMIC_ACQ_REL 4
418 \\#define __ATOMIC_SEQ_CST 5
419 \\
420 );
421
422 // types
423 if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
424 try w.writeAll("#define __CHAR_BIT__ 8\n");
425
426 // int maxs
427 try comp.generateIntWidth(w, "BOOL", .{ .specifier = .bool });
428 try comp.generateIntMaxAndWidth(w, "SCHAR", .{ .specifier = .schar });
429 try comp.generateIntMaxAndWidth(w, "SHRT", .{ .specifier = .short });
430 try comp.generateIntMaxAndWidth(w, "INT", .{ .specifier = .int });
431 try comp.generateIntMaxAndWidth(w, "LONG", .{ .specifier = .long });
432 try comp.generateIntMaxAndWidth(w, "LONG_LONG", .{ .specifier = .long_long });
433 try comp.generateIntMaxAndWidth(w, "WCHAR", comp.types.wchar);
434 // try comp.generateIntMax(w, "WINT", comp.types.wchar);
435 try comp.generateIntMaxAndWidth(w, "INTMAX", comp.types.intmax);
436 try comp.generateIntMaxAndWidth(w, "SIZE", comp.types.size);
437 try comp.generateIntMaxAndWidth(w, "UINTMAX", comp.types.intmax.makeIntegerUnsigned());
438 try comp.generateIntMaxAndWidth(w, "PTRDIFF", comp.types.ptrdiff);
439 try comp.generateIntMaxAndWidth(w, "INTPTR", comp.types.intptr);
440 try comp.generateIntMaxAndWidth(w, "UINTPTR", comp.types.intptr.makeIntegerUnsigned());
441
442 // int widths
443 try w.print("#define __BITINT_MAXWIDTH__ {d}\n", .{bit_int_max_bits});
444
445 // sizeof types
446 try comp.generateSizeofType(w, "__SIZEOF_FLOAT__", .{ .specifier = .float });
447 try comp.generateSizeofType(w, "__SIZEOF_DOUBLE__", .{ .specifier = .double });
448 try comp.generateSizeofType(w, "__SIZEOF_LONG_DOUBLE__", .{ .specifier = .long_double });
449 try comp.generateSizeofType(w, "__SIZEOF_SHORT__", .{ .specifier = .short });
450 try comp.generateSizeofType(w, "__SIZEOF_INT__", .{ .specifier = .int });
451 try comp.generateSizeofType(w, "__SIZEOF_LONG__", .{ .specifier = .long });
452 try comp.generateSizeofType(w, "__SIZEOF_LONG_LONG__", .{ .specifier = .long_long });
453 try comp.generateSizeofType(w, "__SIZEOF_POINTER__", .{ .specifier = .pointer });
454 try comp.generateSizeofType(w, "__SIZEOF_PTRDIFF_T__", comp.types.ptrdiff);
455 try comp.generateSizeofType(w, "__SIZEOF_SIZE_T__", comp.types.size);
456 try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar);
457 // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer });
458
459 if (target_util.hasInt128(comp.target)) {
460 try comp.generateSizeofType(w, "__SIZEOF_INT128__", .{ .specifier = .int128 });
461 }
462
463 // various int types
464 const mapper = comp.string_interner.getSlowTypeMapper();
465 try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts);
466 try generateTypeMacro(w, mapper, "__UINTPTR_TYPE__", comp.types.intptr.makeIntegerUnsigned(), comp.langopts);
467
468 try generateTypeMacro(w, mapper, "__INTMAX_TYPE__", comp.types.intmax, comp.langopts);
469 try comp.generateSuffixMacro("__INTMAX", w, comp.types.intptr);
470
471 try generateTypeMacro(w, mapper, "__UINTMAX_TYPE__", comp.types.intmax.makeIntegerUnsigned(), comp.langopts);
472 try comp.generateSuffixMacro("__UINTMAX", w, comp.types.intptr.makeIntegerUnsigned());
473
474 try generateTypeMacro(w, mapper, "__PTRDIFF_TYPE__", comp.types.ptrdiff, comp.langopts);
475 try generateTypeMacro(w, mapper, "__SIZE_TYPE__", comp.types.size, comp.langopts);
476 try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts);
477
478 try comp.generateExactWidthTypes(w, mapper);
479 try comp.generateFastAndLeastWidthTypes(w, mapper);
480
481 if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| {
482 try generateFloatMacros(w, "FLT16", half, "F16");
483 }
484 try generateFloatMacros(w, "FLT", target_util.FPSemantics.forType(.float, comp.target), "F");
485 try generateFloatMacros(w, "DBL", target_util.FPSemantics.forType(.double, comp.target), "");
486 try generateFloatMacros(w, "LDBL", target_util.FPSemantics.forType(.longdouble, comp.target), "L");
487
488 // TODO: clang treats __FLT_EVAL_METHOD__ as a special-cased macro because evaluating it within a scope
489 // where `#pragma clang fp eval_method(X)` has been called produces an error diagnostic.
490 const flt_eval_method = comp.langopts.fp_eval_method orelse target_util.defaultFpEvalMethod(comp.target);
491 try w.print("#define __FLT_EVAL_METHOD__ {d}\n", .{@intFromEnum(flt_eval_method)});
492
493 try w.writeAll(
494 \\#define __FLT_RADIX__ 2
495 \\#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
496 \\
497 );
498}
499
500/// Generate builtin macros that will be available to each source file.
501pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) !Source {
502 try comp.generateBuiltinTypes();
503
504 var buf = std.ArrayList(u8).init(comp.gpa);
505 defer buf.deinit();
506
507 if (system_defines_mode == .include_system_defines) {
508 try buf.appendSlice(
509 \\#define __VERSION__ "Aro
510 ++ @import("../backend.zig").version_str ++ "\"\n" ++
511 \\#define __Aro__
512 \\
513 );
514 }
515
516 try buf.appendSlice("#define __STDC__ 1\n");
517 try buf.writer().print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)});
518
519 // standard macros
520 try buf.appendSlice(
521 \\#define __STDC_NO_ATOMICS__ 1
522 \\#define __STDC_NO_COMPLEX__ 1
523 \\#define __STDC_NO_THREADS__ 1
524 \\#define __STDC_NO_VLA__ 1
525 \\#define __STDC_UTF_16__ 1
526 \\#define __STDC_UTF_32__ 1
527 \\
528 );
529 if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| {
530 try buf.appendSlice("#define __STDC_VERSION__ ");
531 try buf.appendSlice(stdc_version);
532 try buf.append('\n');
533 }
534
535 // timestamps
536 const timestamp = try comp.getTimestamp();
537 try generateDateAndTime(buf.writer(), timestamp);
538
539 if (system_defines_mode == .include_system_defines) {
540 try comp.generateSystemDefines(buf.writer());
541 }
542
543 return comp.addSourceFromBuffer("<builtin>", buf.items);
544}
545
546fn generateFloatMacros(w: anytype, prefix: []const u8, semantics: target_util.FPSemantics, ext: []const u8) !void {
547 const denormMin = semantics.chooseValue(
548 []const u8,
549 .{
550 "5.9604644775390625e-8",
551 "1.40129846e-45",
552 "4.9406564584124654e-324",
553 "3.64519953188247460253e-4951",
554 "4.94065645841246544176568792868221e-324",
555 "6.47517511943802511092443895822764655e-4966",
556 },
557 );
558 const digits = semantics.chooseValue(i32, .{ 3, 6, 15, 18, 31, 33 });
559 const decimalDigits = semantics.chooseValue(i32, .{ 5, 9, 17, 21, 33, 36 });
560 const epsilon = semantics.chooseValue(
561 []const u8,
562 .{
563 "9.765625e-4",
564 "1.19209290e-7",
565 "2.2204460492503131e-16",
566 "1.08420217248550443401e-19",
567 "4.94065645841246544176568792868221e-324",
568 "1.92592994438723585305597794258492732e-34",
569 },
570 );
571 const mantissaDigits = semantics.chooseValue(i32, .{ 11, 24, 53, 64, 106, 113 });
572
573 const min10Exp = semantics.chooseValue(i32, .{ -4, -37, -307, -4931, -291, -4931 });
574 const max10Exp = semantics.chooseValue(i32, .{ 4, 38, 308, 4932, 308, 4932 });
575
576 const minExp = semantics.chooseValue(i32, .{ -13, -125, -1021, -16381, -968, -16381 });
577 const maxExp = semantics.chooseValue(i32, .{ 16, 128, 1024, 16384, 1024, 16384 });
578
579 const min = semantics.chooseValue(
580 []const u8,
581 .{
582 "6.103515625e-5",
583 "1.17549435e-38",
584 "2.2250738585072014e-308",
585 "3.36210314311209350626e-4932",
586 "2.00416836000897277799610805135016e-292",
587 "3.36210314311209350626267781732175260e-4932",
588 },
589 );
590 const max = semantics.chooseValue(
591 []const u8,
592 .{
593 "6.5504e+4",
594 "3.40282347e+38",
595 "1.7976931348623157e+308",
596 "1.18973149535723176502e+4932",
597 "1.79769313486231580793728971405301e+308",
598 "1.18973149535723176508575932662800702e+4932",
599 },
600 );
601
602 var def_prefix_buf: [32]u8 = undefined;
603 const prefix_slice = std.fmt.bufPrint(&def_prefix_buf, "__{s}_", .{prefix}) catch
604 return error.OutOfMemory;
605
606 try w.print("#define {s}DENORM_MIN__ {s}{s}\n", .{ prefix_slice, denormMin, ext });
607 try w.print("#define {s}HAS_DENORM__\n", .{prefix_slice});
608 try w.print("#define {s}DIG__ {d}\n", .{ prefix_slice, digits });
609 try w.print("#define {s}DECIMAL_DIG__ {d}\n", .{ prefix_slice, decimalDigits });
610
611 try w.print("#define {s}EPSILON__ {s}{s}\n", .{ prefix_slice, epsilon, ext });
612 try w.print("#define {s}HAS_INFINITY__\n", .{prefix_slice});
613 try w.print("#define {s}HAS_QUIET_NAN__\n", .{prefix_slice});
614 try w.print("#define {s}MANT_DIG__ {d}\n", .{ prefix_slice, mantissaDigits });
615
616 try w.print("#define {s}MAX_10_EXP__ {d}\n", .{ prefix_slice, max10Exp });
617 try w.print("#define {s}MAX_EXP__ {d}\n", .{ prefix_slice, maxExp });
618 try w.print("#define {s}MAX__ {s}{s}\n", .{ prefix_slice, max, ext });
619
620 try w.print("#define {s}MIN_10_EXP__ ({d})\n", .{ prefix_slice, min10Exp });
621 try w.print("#define {s}MIN_EXP__ ({d})\n", .{ prefix_slice, minExp });
622 try w.print("#define {s}MIN__ {s}{s}\n", .{ prefix_slice, min, ext });
623}
624
625fn generateTypeMacro(w: anytype, mapper: StrInt.TypeMapper, name: []const u8, ty: Type, langopts: LangOpts) !void {
626 try w.print("#define {s} ", .{name});
627 try ty.print(mapper, langopts, w);
628 try w.writeByte('\n');
629}
630
631fn generateBuiltinTypes(comp: *Compilation) !void {
632 const os = comp.target.os.tag;
633 const wchar: Type = switch (comp.target.cpu.arch) {
634 .xcore => .{ .specifier = .uchar },
635 .ve, .msp430 => .{ .specifier = .uint },
636 .arm, .armeb, .thumb, .thumbeb => .{
637 .specifier = if (os != .windows and os != .netbsd and os != .openbsd) .uint else .int,
638 },
639 .aarch64, .aarch64_be, .aarch64_32 => .{
640 .specifier = if (!os.isDarwin() and os != .netbsd) .uint else .int,
641 },
642 .x86_64, .x86 => .{ .specifier = if (os == .windows) .ushort else .int },
643 else => .{ .specifier = .int },
644 };
645
646 const ptr_width = comp.target.ptrBitWidth();
647 const ptrdiff = if (os == .windows and ptr_width == 64)
648 Type{ .specifier = .long_long }
649 else switch (ptr_width) {
650 16 => Type{ .specifier = .int },
651 32 => Type{ .specifier = .int },
652 64 => Type{ .specifier = .long },
653 else => unreachable,
654 };
655
656 const size = if (os == .windows and ptr_width == 64)
657 Type{ .specifier = .ulong_long }
658 else switch (ptr_width) {
659 16 => Type{ .specifier = .uint },
660 32 => Type{ .specifier = .uint },
661 64 => Type{ .specifier = .ulong },
662 else => unreachable,
663 };
664
665 const va_list = try comp.generateVaListType();
666
667 const pid_t: Type = switch (os) {
668 .haiku => .{ .specifier = .long },
669 // Todo: pid_t is required to "a signed integer type"; are there any systems
670 // on which it is `short int`?
671 else => .{ .specifier = .int },
672 };
673
674 const intmax = target_util.intMaxType(comp.target);
675 const intptr = target_util.intPtrType(comp.target);
676 const int16 = target_util.int16Type(comp.target);
677 const int64 = target_util.int64Type(comp.target);
678
679 comp.types = .{
680 .wchar = wchar,
681 .ptrdiff = ptrdiff,
682 .size = size,
683 .va_list = va_list,
684 .pid_t = pid_t,
685 .intmax = intmax,
686 .intptr = intptr,
687 .int16 = int16,
688 .int64 = int64,
689 .uint_least16_t = comp.intLeastN(16, .unsigned),
690 .uint_least32_t = comp.intLeastN(32, .unsigned),
691 };
692
693 try comp.generateNsConstantStringType();
694}
695
696/// Smallest integer type with at least N bits
697fn intLeastN(comp: *const Compilation, bits: usize, signedness: std.builtin.Signedness) Type {
698 if (bits == 64 and (comp.target.isDarwin() or comp.target.isWasm())) {
699 // WebAssembly and Darwin use `long long` for `int_least64_t` and `int_fast64_t`.
700 return .{ .specifier = if (signedness == .signed) .long_long else .ulong_long };
701 }
702 if (bits == 16 and comp.target.cpu.arch == .avr) {
703 // AVR uses int for int_least16_t and int_fast16_t.
704 return .{ .specifier = if (signedness == .signed) .int else .uint };
705 }
706 const candidates = switch (signedness) {
707 .signed => &[_]Type.Specifier{ .schar, .short, .int, .long, .long_long },
708 .unsigned => &[_]Type.Specifier{ .uchar, .ushort, .uint, .ulong, .ulong_long },
709 };
710 for (candidates) |specifier| {
711 const ty: Type = .{ .specifier = specifier };
712 if (ty.sizeof(comp).? * 8 >= bits) return ty;
713 } else unreachable;
714}
715
716fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 {
717 const ty = Type{ .specifier = specifier };
718 return ty.sizeof(comp).?;
719}
720
721fn generateFastOrLeastType(
722 comp: *Compilation,
723 bits: usize,
724 kind: enum { least, fast },
725 signedness: std.builtin.Signedness,
726 w: anytype,
727 mapper: StrInt.TypeMapper,
728) !void {
729 const ty = comp.intLeastN(bits, signedness); // defining the fast types as the least types is permitted
730
731 var buf: [32]u8 = undefined;
732 const suffix = "_TYPE__";
733 const base_name = switch (signedness) {
734 .signed => "__INT_",
735 .unsigned => "__UINT_",
736 };
737 const kind_str = switch (kind) {
738 .fast => "FAST",
739 .least => "LEAST",
740 };
741
742 const full = std.fmt.bufPrint(&buf, "{s}{s}{d}{s}", .{
743 base_name, kind_str, bits, suffix,
744 }) catch return error.OutOfMemory;
745
746 try generateTypeMacro(w, mapper, full, ty, comp.langopts);
747
748 const prefix = full[2 .. full.len - suffix.len]; // remove "__" and "_TYPE__"
749
750 switch (signedness) {
751 .signed => try comp.generateIntMaxAndWidth(w, prefix, ty),
752 .unsigned => try comp.generateIntMax(w, prefix, ty),
753 }
754 try comp.generateFmt(prefix, w, ty);
755}
756
757fn generateFastAndLeastWidthTypes(comp: *Compilation, w: anytype, mapper: StrInt.TypeMapper) !void {
758 const sizes = [_]usize{ 8, 16, 32, 64 };
759 for (sizes) |size| {
760 try comp.generateFastOrLeastType(size, .least, .signed, w, mapper);
761 try comp.generateFastOrLeastType(size, .least, .unsigned, w, mapper);
762 try comp.generateFastOrLeastType(size, .fast, .signed, w, mapper);
763 try comp.generateFastOrLeastType(size, .fast, .unsigned, w, mapper);
764 }
765}
766
767fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper) !void {
768 try comp.generateExactWidthType(w, mapper, .schar);
769
770 if (comp.intSize(.short) > comp.intSize(.char)) {
771 try comp.generateExactWidthType(w, mapper, .short);
772 }
773
774 if (comp.intSize(.int) > comp.intSize(.short)) {
775 try comp.generateExactWidthType(w, mapper, .int);
776 }
777
778 if (comp.intSize(.long) > comp.intSize(.int)) {
779 try comp.generateExactWidthType(w, mapper, .long);
780 }
781
782 if (comp.intSize(.long_long) > comp.intSize(.long)) {
783 try comp.generateExactWidthType(w, mapper, .long_long);
784 }
785
786 try comp.generateExactWidthType(w, mapper, .uchar);
787 try comp.generateExactWidthIntMax(w, .uchar);
788 try comp.generateExactWidthIntMax(w, .schar);
789
790 if (comp.intSize(.short) > comp.intSize(.char)) {
791 try comp.generateExactWidthType(w, mapper, .ushort);
792 try comp.generateExactWidthIntMax(w, .ushort);
793 try comp.generateExactWidthIntMax(w, .short);
794 }
795
796 if (comp.intSize(.int) > comp.intSize(.short)) {
797 try comp.generateExactWidthType(w, mapper, .uint);
798 try comp.generateExactWidthIntMax(w, .uint);
799 try comp.generateExactWidthIntMax(w, .int);
800 }
801
802 if (comp.intSize(.long) > comp.intSize(.int)) {
803 try comp.generateExactWidthType(w, mapper, .ulong);
804 try comp.generateExactWidthIntMax(w, .ulong);
805 try comp.generateExactWidthIntMax(w, .long);
806 }
807
808 if (comp.intSize(.long_long) > comp.intSize(.long)) {
809 try comp.generateExactWidthType(w, mapper, .ulong_long);
810 try comp.generateExactWidthIntMax(w, .ulong_long);
811 try comp.generateExactWidthIntMax(w, .long_long);
812 }
813}
814
815fn generateFmt(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
816 const unsigned = ty.isUnsignedInt(comp);
817 const modifier = ty.formatModifier();
818 const formats = if (unsigned) "ouxX" else "di";
819 for (formats) |c| {
820 try w.print("#define {s}_FMT{c}__ \"{s}{c}\"\n", .{ prefix, c, modifier, c });
821 }
822}
823
824fn generateSuffixMacro(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void {
825 return w.print("#define {s}_C_SUFFIX__ {s}\n", .{ prefix, ty.intValueSuffix(comp) });
826}
827
828/// Generate the following for ty:
829/// Name macro (e.g. #define __UINT32_TYPE__ unsigned int)
830/// Format strings (e.g. #define __UINT32_FMTu__ "u")
831/// Suffix macro (e.g. #define __UINT32_C_SUFFIX__ U)
832fn generateExactWidthType(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper, specifier: Type.Specifier) !void {
833 var ty = Type{ .specifier = specifier };
834 const width = 8 * ty.sizeof(comp).?;
835 const unsigned = ty.isUnsignedInt(comp);
836
837 if (width == 16) {
838 ty = if (unsigned) comp.types.int16.makeIntegerUnsigned() else comp.types.int16;
839 } else if (width == 64) {
840 ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
841 }
842
843 var buffer: [16]u8 = undefined;
844 const suffix = "_TYPE__";
845 const full = std.fmt.bufPrint(&buffer, "{s}{d}{s}", .{
846 if (unsigned) "__UINT" else "__INT", width, suffix,
847 }) catch return error.OutOfMemory;
848
849 try generateTypeMacro(w, mapper, full, ty, comp.langopts);
850
851 const prefix = full[0 .. full.len - suffix.len]; // remove "_TYPE__"
852
853 try comp.generateFmt(prefix, w, ty);
854 try comp.generateSuffixMacro(prefix, w, ty);
855}
856
857pub fn hasFloat128(comp: *const Compilation) bool {
858 return target_util.hasFloat128(comp.target);
859}
860
861pub fn hasHalfPrecisionFloatABI(comp: *const Compilation) bool {
862 return comp.langopts.allow_half_args_and_returns or target_util.hasHalfPrecisionFloatABI(comp.target);
863}
864
865fn generateNsConstantStringType(comp: *Compilation) !void {
866 comp.types.ns_constant_string.record = .{
867 .name = try StrInt.intern(comp, "__NSConstantString_tag"),
868 .fields = &comp.types.ns_constant_string.fields,
869 .field_attributes = null,
870 .type_layout = undefined,
871 };
872 const const_int_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.int_ty } };
873 const const_char_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.char_ty } };
874
875 comp.types.ns_constant_string.fields[0] = .{ .name = try StrInt.intern(comp, "isa"), .ty = const_int_ptr };
876 comp.types.ns_constant_string.fields[1] = .{ .name = try StrInt.intern(comp, "flags"), .ty = .{ .specifier = .int } };
877 comp.types.ns_constant_string.fields[2] = .{ .name = try StrInt.intern(comp, "str"), .ty = const_char_ptr };
878 comp.types.ns_constant_string.fields[3] = .{ .name = try StrInt.intern(comp, "length"), .ty = .{ .specifier = .long } };
879 comp.types.ns_constant_string.ty = .{ .specifier = .@"struct", .data = .{ .record = &comp.types.ns_constant_string.record } };
880 record_layout.compute(&comp.types.ns_constant_string.record, comp.types.ns_constant_string.ty, comp, null);
881}
882
883fn generateVaListType(comp: *Compilation) !Type {
884 const Kind = enum { char_ptr, void_ptr, aarch64_va_list, x86_64_va_list };
885 const kind: Kind = switch (comp.target.cpu.arch) {
886 .aarch64 => switch (comp.target.os.tag) {
887 .windows => @as(Kind, .char_ptr),
888 .ios, .macos, .tvos, .watchos => .char_ptr,
889 else => .aarch64_va_list,
890 },
891 .sparc, .wasm32, .wasm64, .bpfel, .bpfeb, .riscv32, .riscv64, .avr, .spirv32, .spirv64 => .void_ptr,
892 .powerpc => switch (comp.target.os.tag) {
893 .ios, .macos, .tvos, .watchos, .aix => @as(Kind, .char_ptr),
894 else => return Type{ .specifier = .void }, // unknown
895 },
896 .x86, .msp430 => .char_ptr,
897 .x86_64 => switch (comp.target.os.tag) {
898 .windows => @as(Kind, .char_ptr),
899 else => .x86_64_va_list,
900 },
901 else => return Type{ .specifier = .void }, // unknown
902 };
903
904 // TODO this might be bad?
905 const arena = comp.diagnostics.arena.allocator();
906
907 var ty: Type = undefined;
908 switch (kind) {
909 .char_ptr => ty = .{ .specifier = .char },
910 .void_ptr => ty = .{ .specifier = .void },
911 .aarch64_va_list => {
912 const record_ty = try arena.create(Type.Record);
913 record_ty.* = .{
914 .name = try StrInt.intern(comp, "__va_list_tag"),
915 .fields = try arena.alloc(Type.Record.Field, 5),
916 .field_attributes = null,
917 .type_layout = undefined, // computed below
918 };
919 const void_ty = try arena.create(Type);
920 void_ty.* = .{ .specifier = .void };
921 const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
922 record_ty.fields[0] = .{ .name = try StrInt.intern(comp, "__stack"), .ty = void_ptr };
923 record_ty.fields[1] = .{ .name = try StrInt.intern(comp, "__gr_top"), .ty = void_ptr };
924 record_ty.fields[2] = .{ .name = try StrInt.intern(comp, "__vr_top"), .ty = void_ptr };
925 record_ty.fields[3] = .{ .name = try StrInt.intern(comp, "__gr_offs"), .ty = .{ .specifier = .int } };
926 record_ty.fields[4] = .{ .name = try StrInt.intern(comp, "__vr_offs"), .ty = .{ .specifier = .int } };
927 ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
928 record_layout.compute(record_ty, ty, comp, null);
929 },
930 .x86_64_va_list => {
931 const record_ty = try arena.create(Type.Record);
932 record_ty.* = .{
933 .name = try StrInt.intern(comp, "__va_list_tag"),
934 .fields = try arena.alloc(Type.Record.Field, 4),
935 .field_attributes = null,
936 .type_layout = undefined, // computed below
937 };
938 const void_ty = try arena.create(Type);
939 void_ty.* = .{ .specifier = .void };
940 const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
941 record_ty.fields[0] = .{ .name = try StrInt.intern(comp, "gp_offset"), .ty = .{ .specifier = .uint } };
942 record_ty.fields[1] = .{ .name = try StrInt.intern(comp, "fp_offset"), .ty = .{ .specifier = .uint } };
943 record_ty.fields[2] = .{ .name = try StrInt.intern(comp, "overflow_arg_area"), .ty = void_ptr };
944 record_ty.fields[3] = .{ .name = try StrInt.intern(comp, "reg_save_area"), .ty = void_ptr };
945 ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
946 record_layout.compute(record_ty, ty, comp, null);
947 },
948 }
949 if (kind == .char_ptr or kind == .void_ptr) {
950 const elem_ty = try arena.create(Type);
951 elem_ty.* = ty;
952 ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
953 } else {
954 const arr_ty = try arena.create(Type.Array);
955 arr_ty.* = .{ .len = 1, .elem = ty };
956 ty = Type{ .specifier = .array, .data = .{ .array = arr_ty } };
957 }
958
959 return ty;
960}
961
962fn generateIntMax(comp: *const Compilation, w: anytype, name: []const u8, ty: Type) !void {
963 const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
964 const unsigned = ty.isUnsignedInt(comp);
965 const max = if (bit_count == 128)
966 @as(u128, if (unsigned) std.math.maxInt(u128) else std.math.maxInt(u128))
967 else
968 ty.maxInt(comp);
969 try w.print("#define __{s}_MAX__ {d}{s}\n", .{ name, max, ty.intValueSuffix(comp) });
970}
971
972fn generateExactWidthIntMax(comp: *const Compilation, w: anytype, specifier: Type.Specifier) !void {
973 var ty = Type{ .specifier = specifier };
974 const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8);
975 const unsigned = ty.isUnsignedInt(comp);
976
977 if (bit_count == 64) {
978 ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64;
979 }
980
981 var name_buffer: [6]u8 = undefined;
982 const name = std.fmt.bufPrint(&name_buffer, "{s}{d}", .{
983 if (unsigned) "UINT" else "INT", bit_count,
984 }) catch return error.OutOfMemory;
985
986 return comp.generateIntMax(w, name, ty);
987}
988
989fn generateIntWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
990 try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, 8 * ty.sizeof(comp).? });
991}
992
993fn generateIntMaxAndWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
994 try comp.generateIntMax(w, name, ty);
995 try comp.generateIntWidth(w, name, ty);
996}
997
998fn generateSizeofType(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void {
999 try w.print("#define {s} {d}\n", .{ name, ty.sizeof(comp).? });
1000}
1001
1002pub fn nextLargestIntSameSign(comp: *const Compilation, ty: Type) ?Type {
1003 assert(ty.isInt());
1004 const specifiers = if (ty.isUnsignedInt(comp))
1005 [_]Type.Specifier{ .short, .int, .long, .long_long }
1006 else
1007 [_]Type.Specifier{ .ushort, .uint, .ulong, .ulong_long };
1008 const size = ty.sizeof(comp).?;
1009 for (specifiers) |specifier| {
1010 const candidate = Type{ .specifier = specifier };
1011 if (candidate.sizeof(comp).? > size) return candidate;
1012 }
1013 return null;
1014}
1015
1016/// If `enum E { ... }` syntax has a fixed underlying integer type regardless of the presence of
1017/// __attribute__((packed)) or the range of values of the corresponding enumerator constants,
1018/// specify it here.
1019/// TODO: likely incomplete
1020pub fn fixedEnumTagSpecifier(comp: *const Compilation) ?Type.Specifier {
1021 switch (comp.langopts.emulate) {
1022 .msvc => return .int,
1023 .clang => if (comp.target.os.tag == .windows) return .int,
1024 .gcc => {},
1025 }
1026 return null;
1027}
1028
1029pub fn getCharSignedness(comp: *const Compilation) std.builtin.Signedness {
1030 return comp.langopts.char_signedness_override orelse comp.target.charSignedness();
1031}
1032
1033pub fn defineSystemIncludes(comp: *Compilation, aro_dir: []const u8) !void {
1034 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1035 const allocator = stack_fallback.get();
1036 var search_path = aro_dir;
1037 while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) {
1038 var base_dir = std.fs.cwd().openDir(dirname, .{}) catch continue;
1039 defer base_dir.close();
1040
1041 base_dir.access("include/stddef.h", .{}) catch continue;
1042 const path = try std.fs.path.join(comp.gpa, &.{ dirname, "include" });
1043 errdefer comp.gpa.free(path);
1044 try comp.system_include_dirs.append(comp.gpa, path);
1045 break;
1046 } else return error.AroIncludeNotFound;
1047
1048 if (comp.target.os.tag == .linux) {
1049 const triple_str = try comp.target.linuxTriple(allocator);
1050 defer allocator.free(triple_str);
1051
1052 const multiarch_path = try std.fs.path.join(allocator, &.{ "/usr/include", triple_str });
1053 defer allocator.free(multiarch_path);
1054
1055 if (!std.meta.isError(std.fs.accessAbsolute(multiarch_path, .{}))) {
1056 const duped = try comp.gpa.dupe(u8, multiarch_path);
1057 errdefer comp.gpa.free(duped);
1058 try comp.system_include_dirs.append(comp.gpa, duped);
1059 }
1060 }
1061 const usr_include = try comp.gpa.dupe(u8, "/usr/include");
1062 errdefer comp.gpa.free(usr_include);
1063 try comp.system_include_dirs.append(comp.gpa, usr_include);
1064}
1065
1066pub fn getSource(comp: *const Compilation, id: Source.Id) Source {
1067 if (id == .generated) return .{
1068 .path = "<scratch space>",
1069 .buf = comp.generated_buf.items,
1070 .id = .generated,
1071 .splice_locs = &.{},
1072 .kind = .user,
1073 };
1074 return comp.sources.values()[@intFromEnum(id) - 2];
1075}
1076
1077/// Creates a Source from the contents of `reader` and adds it to the Compilation
1078pub fn addSourceFromReader(comp: *Compilation, reader: anytype, path: []const u8, kind: Source.Kind) !Source {
1079 const contents = try reader.readAllAlloc(comp.gpa, std.math.maxInt(u32));
1080 errdefer comp.gpa.free(contents);
1081 return comp.addSourceFromOwnedBuffer(contents, path, kind);
1082}
1083
1084/// Creates a Source from `buf` and adds it to the Compilation
1085/// Performs newline splicing and line-ending normalization to '\n'
1086/// `buf` will be modified and the allocation will be resized if newline splicing
1087/// or line-ending changes happen.
1088/// caller retains ownership of `path`
1089/// To add the contents of an arbitrary reader as a Source, see addSourceFromReader
1090/// To add a file's contents given its path, see addSourceFromPath
1091pub fn addSourceFromOwnedBuffer(comp: *Compilation, buf: []u8, path: []const u8, kind: Source.Kind) !Source {
1092 try comp.sources.ensureUnusedCapacity(comp.gpa, 1);
1093
1094 var contents = buf;
1095 const duped_path = try comp.gpa.dupe(u8, path);
1096 errdefer comp.gpa.free(duped_path);
1097
1098 var splice_list = std.ArrayList(u32).init(comp.gpa);
1099 defer splice_list.deinit();
1100
1101 const source_id: Source.Id = @enumFromInt(comp.sources.count() + 2);
1102
1103 var i: u32 = 0;
1104 var backslash_loc: u32 = undefined;
1105 var state: enum {
1106 beginning_of_file,
1107 bom1,
1108 bom2,
1109 start,
1110 back_slash,
1111 cr,
1112 back_slash_cr,
1113 trailing_ws,
1114 } = .beginning_of_file;
1115 var line: u32 = 1;
1116
1117 for (contents) |byte| {
1118 contents[i] = byte;
1119
1120 switch (byte) {
1121 '\r' => {
1122 switch (state) {
1123 .start, .cr, .beginning_of_file => {
1124 state = .start;
1125 line += 1;
1126 state = .cr;
1127 contents[i] = '\n';
1128 i += 1;
1129 },
1130 .back_slash, .trailing_ws, .back_slash_cr => {
1131 i = backslash_loc;
1132 try splice_list.append(i);
1133 if (state == .trailing_ws) {
1134 try comp.addDiagnostic(.{
1135 .tag = .backslash_newline_escape,
1136 .loc = .{ .id = source_id, .byte_offset = i, .line = line },
1137 }, &.{});
1138 }
1139 state = if (state == .back_slash_cr) .cr else .back_slash_cr;
1140 },
1141 .bom1, .bom2 => break, // invalid utf-8
1142 }
1143 },
1144 '\n' => {
1145 switch (state) {
1146 .start, .beginning_of_file => {
1147 state = .start;
1148 line += 1;
1149 i += 1;
1150 },
1151 .cr, .back_slash_cr => {},
1152 .back_slash, .trailing_ws => {
1153 i = backslash_loc;
1154 if (state == .back_slash or state == .trailing_ws) {
1155 try splice_list.append(i);
1156 }
1157 if (state == .trailing_ws) {
1158 try comp.addDiagnostic(.{
1159 .tag = .backslash_newline_escape,
1160 .loc = .{ .id = source_id, .byte_offset = i, .line = line },
1161 }, &.{});
1162 }
1163 },
1164 .bom1, .bom2 => break,
1165 }
1166 state = .start;
1167 },
1168 '\\' => {
1169 backslash_loc = i;
1170 state = .back_slash;
1171 i += 1;
1172 },
1173 '\t', '\x0B', '\x0C', ' ' => {
1174 switch (state) {
1175 .start, .trailing_ws => {},
1176 .beginning_of_file => state = .start,
1177 .cr, .back_slash_cr => state = .start,
1178 .back_slash => state = .trailing_ws,
1179 .bom1, .bom2 => break,
1180 }
1181 i += 1;
1182 },
1183 '\xEF' => {
1184 i += 1;
1185 state = switch (state) {
1186 .beginning_of_file => .bom1,
1187 else => .start,
1188 };
1189 },
1190 '\xBB' => {
1191 i += 1;
1192 state = switch (state) {
1193 .bom1 => .bom2,
1194 else => .start,
1195 };
1196 },
1197 '\xBF' => {
1198 switch (state) {
1199 .bom2 => i = 0, // rewind and overwrite the BOM
1200 else => i += 1,
1201 }
1202 state = .start;
1203 },
1204 else => {
1205 i += 1;
1206 state = .start;
1207 },
1208 }
1209 }
1210
1211 const splice_locs = try splice_list.toOwnedSlice();
1212 errdefer comp.gpa.free(splice_locs);
1213
1214 if (i != contents.len) contents = try comp.gpa.realloc(contents, i);
1215 errdefer @compileError("errdefers in callers would possibly free the realloced slice using the original len");
1216
1217 const source = Source{
1218 .id = source_id,
1219 .path = duped_path,
1220 .buf = contents,
1221 .splice_locs = splice_locs,
1222 .kind = kind,
1223 };
1224
1225 comp.sources.putAssumeCapacityNoClobber(duped_path, source);
1226 return source;
1227}
1228
1229/// Caller retains ownership of `path` and `buf`.
1230/// Dupes the source buffer; if it is acceptable to modify the source buffer and possibly resize
1231/// the allocation, please use `addSourceFromOwnedBuffer`
1232pub fn addSourceFromBuffer(comp: *Compilation, path: []const u8, buf: []const u8) !Source {
1233 if (comp.sources.get(path)) |some| return some;
1234 if (@as(u64, buf.len) > std.math.maxInt(u32)) return error.StreamTooLong;
1235
1236 const contents = try comp.gpa.dupe(u8, buf);
1237 errdefer comp.gpa.free(contents);
1238
1239 return comp.addSourceFromOwnedBuffer(contents, path, .user);
1240}
1241
1242/// Caller retains ownership of `path`.
1243pub fn addSourceFromPath(comp: *Compilation, path: []const u8) !Source {
1244 return comp.addSourceFromPathExtra(path, .user);
1245}
1246
1247/// Caller retains ownership of `path`.
1248fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kind) !Source {
1249 if (comp.sources.get(path)) |some| return some;
1250
1251 if (mem.indexOfScalar(u8, path, 0) != null) {
1252 return error.FileNotFound;
1253 }
1254
1255 const file = try std.fs.cwd().openFile(path, .{});
1256 defer file.close();
1257
1258 const contents = file.readToEndAlloc(comp.gpa, std.math.maxInt(u32)) catch |err| switch (err) {
1259 error.FileTooBig => return error.StreamTooLong,
1260 else => |e| return e,
1261 };
1262 errdefer comp.gpa.free(contents);
1263
1264 return comp.addSourceFromOwnedBuffer(contents, path, kind);
1265}
1266
1267pub const IncludeDirIterator = struct {
1268 comp: *const Compilation,
1269 cwd_source_id: ?Source.Id,
1270 include_dirs_idx: usize = 0,
1271 sys_include_dirs_idx: usize = 0,
1272 tried_ms_cwd: bool = false,
1273
1274 const FoundSource = struct {
1275 path: []const u8,
1276 kind: Source.Kind,
1277 };
1278
1279 fn next(self: *IncludeDirIterator) ?FoundSource {
1280 if (self.cwd_source_id) |source_id| {
1281 self.cwd_source_id = null;
1282 const path = self.comp.getSource(source_id).path;
1283 return .{ .path = std.fs.path.dirname(path) orelse ".", .kind = .user };
1284 }
1285 if (self.include_dirs_idx < self.comp.include_dirs.items.len) {
1286 defer self.include_dirs_idx += 1;
1287 return .{ .path = self.comp.include_dirs.items[self.include_dirs_idx], .kind = .user };
1288 }
1289 if (self.sys_include_dirs_idx < self.comp.system_include_dirs.items.len) {
1290 defer self.sys_include_dirs_idx += 1;
1291 return .{ .path = self.comp.system_include_dirs.items[self.sys_include_dirs_idx], .kind = .system };
1292 }
1293 if (self.comp.ms_cwd_source_id) |source_id| {
1294 if (self.tried_ms_cwd) return null;
1295 self.tried_ms_cwd = true;
1296 const path = self.comp.getSource(source_id).path;
1297 return .{ .path = std.fs.path.dirname(path) orelse ".", .kind = .user };
1298 }
1299 return null;
1300 }
1301
1302 /// Returned value's path field must be freed by allocator
1303 fn nextWithFile(self: *IncludeDirIterator, filename: []const u8, allocator: Allocator) !?FoundSource {
1304 while (self.next()) |found| {
1305 const path = try std.fs.path.join(allocator, &.{ found.path, filename });
1306 if (self.comp.langopts.ms_extensions) {
1307 std.mem.replaceScalar(u8, path, '\\', '/');
1308 }
1309 return .{ .path = path, .kind = found.kind };
1310 }
1311 return null;
1312 }
1313
1314 /// Advance the iterator until it finds an include directory that matches
1315 /// the directory which contains `source`.
1316 fn skipUntilDirMatch(self: *IncludeDirIterator, source: Source.Id) void {
1317 const path = self.comp.getSource(source).path;
1318 const includer_path = std.fs.path.dirname(path) orelse ".";
1319 while (self.next()) |found| {
1320 if (mem.eql(u8, includer_path, found.path)) break;
1321 }
1322 }
1323};
1324
1325pub fn hasInclude(
1326 comp: *const Compilation,
1327 filename: []const u8,
1328 includer_token_source: Source.Id,
1329 /// angle bracket vs quotes
1330 include_type: IncludeType,
1331 /// __has_include vs __has_include_next
1332 which: WhichInclude,
1333) !bool {
1334 const cwd = std.fs.cwd();
1335 if (std.fs.path.isAbsolute(filename)) {
1336 if (which == .next) return false;
1337 return !std.meta.isError(cwd.access(filename, .{}));
1338 }
1339
1340 const cwd_source_id = switch (include_type) {
1341 .quotes => switch (which) {
1342 .first => includer_token_source,
1343 .next => null,
1344 },
1345 .angle_brackets => null,
1346 };
1347 var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
1348 if (which == .next) {
1349 it.skipUntilDirMatch(includer_token_source);
1350 }
1351
1352 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1353 const sf_allocator = stack_fallback.get();
1354
1355 while (try it.nextWithFile(filename, sf_allocator)) |found| {
1356 defer sf_allocator.free(found.path);
1357 if (!std.meta.isError(cwd.access(found.path, .{}))) return true;
1358 }
1359 return false;
1360}
1361
1362pub const WhichInclude = enum {
1363 first,
1364 next,
1365};
1366
1367pub const IncludeType = enum {
1368 quotes,
1369 angle_brackets,
1370};
1371
1372fn getFileContents(comp: *Compilation, path: []const u8, limit: ?u32) ![]const u8 {
1373 if (mem.indexOfScalar(u8, path, 0) != null) {
1374 return error.FileNotFound;
1375 }
1376
1377 const file = try std.fs.cwd().openFile(path, .{});
1378 defer file.close();
1379
1380 var buf = std.ArrayList(u8).init(comp.gpa);
1381 defer buf.deinit();
1382
1383 const max = limit orelse std.math.maxInt(u32);
1384 file.reader().readAllArrayList(&buf, max) catch |e| switch (e) {
1385 error.StreamTooLong => if (limit == null) return e,
1386 else => return e,
1387 };
1388
1389 return buf.toOwnedSlice();
1390}
1391
1392pub fn findEmbed(
1393 comp: *Compilation,
1394 filename: []const u8,
1395 includer_token_source: Source.Id,
1396 /// angle bracket vs quotes
1397 include_type: IncludeType,
1398 limit: ?u32,
1399) !?[]const u8 {
1400 if (std.fs.path.isAbsolute(filename)) {
1401 return if (comp.getFileContents(filename, limit)) |some|
1402 some
1403 else |err| switch (err) {
1404 error.OutOfMemory => |e| return e,
1405 else => null,
1406 };
1407 }
1408
1409 const cwd_source_id = switch (include_type) {
1410 .quotes => includer_token_source,
1411 .angle_brackets => null,
1412 };
1413 var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
1414 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1415 const sf_allocator = stack_fallback.get();
1416
1417 while (try it.nextWithFile(filename, sf_allocator)) |found| {
1418 defer sf_allocator.free(found.path);
1419 if (comp.getFileContents(found.path, limit)) |some|
1420 return some
1421 else |err| switch (err) {
1422 error.OutOfMemory => return error.OutOfMemory,
1423 else => {},
1424 }
1425 }
1426 return null;
1427}
1428
1429pub fn findInclude(
1430 comp: *Compilation,
1431 filename: []const u8,
1432 includer_token: Token,
1433 /// angle bracket vs quotes
1434 include_type: IncludeType,
1435 /// include vs include_next
1436 which: WhichInclude,
1437) !?Source {
1438 if (std.fs.path.isAbsolute(filename)) {
1439 if (which == .next) return null;
1440 // TODO: classify absolute file as belonging to system includes or not?
1441 return if (comp.addSourceFromPath(filename)) |some|
1442 some
1443 else |err| switch (err) {
1444 error.OutOfMemory => |e| return e,
1445 else => null,
1446 };
1447 }
1448 const cwd_source_id = switch (include_type) {
1449 .quotes => switch (which) {
1450 .first => includer_token.source,
1451 .next => null,
1452 },
1453 .angle_brackets => null,
1454 };
1455 var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id };
1456
1457 if (which == .next) {
1458 it.skipUntilDirMatch(includer_token.source);
1459 }
1460
1461 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);
1462 const sf_allocator = stack_fallback.get();
1463
1464 while (try it.nextWithFile(filename, sf_allocator)) |found| {
1465 defer sf_allocator.free(found.path);
1466 if (comp.addSourceFromPathExtra(found.path, found.kind)) |some| {
1467 if (it.tried_ms_cwd) {
1468 try comp.addDiagnostic(.{
1469 .tag = .ms_search_rule,
1470 .extra = .{ .str = some.path },
1471 .loc = .{
1472 .id = includer_token.source,
1473 .byte_offset = includer_token.start,
1474 .line = includer_token.line,
1475 },
1476 }, &.{});
1477 }
1478 return some;
1479 } else |err| switch (err) {
1480 error.OutOfMemory => return error.OutOfMemory,
1481 else => {},
1482 }
1483 }
1484 return null;
1485}
1486
1487pub fn addPragmaHandler(comp: *Compilation, name: []const u8, handler: *Pragma) Allocator.Error!void {
1488 try comp.pragma_handlers.putNoClobber(comp.gpa, name, handler);
1489}
1490
1491pub fn addDefaultPragmaHandlers(comp: *Compilation) Allocator.Error!void {
1492 const GCC = @import("pragmas/gcc.zig");
1493 var gcc = try GCC.init(comp.gpa);
1494 errdefer gcc.deinit(gcc, comp);
1495
1496 const Once = @import("pragmas/once.zig");
1497 var once = try Once.init(comp.gpa);
1498 errdefer once.deinit(once, comp);
1499
1500 const Message = @import("pragmas/message.zig");
1501 var message = try Message.init(comp.gpa);
1502 errdefer message.deinit(message, comp);
1503
1504 const Pack = @import("pragmas/pack.zig");
1505 var pack = try Pack.init(comp.gpa);
1506 errdefer pack.deinit(pack, comp);
1507
1508 try comp.addPragmaHandler("GCC", gcc);
1509 try comp.addPragmaHandler("once", once);
1510 try comp.addPragmaHandler("message", message);
1511 try comp.addPragmaHandler("pack", pack);
1512}
1513
1514pub fn getPragma(comp: *Compilation, name: []const u8) ?*Pragma {
1515 return comp.pragma_handlers.get(name);
1516}
1517
1518const PragmaEvent = enum {
1519 before_preprocess,
1520 before_parse,
1521 after_parse,
1522};
1523
1524pub fn pragmaEvent(comp: *Compilation, event: PragmaEvent) void {
1525 for (comp.pragma_handlers.values()) |pragma| {
1526 const maybe_func = switch (event) {
1527 .before_preprocess => pragma.beforePreprocess,
1528 .before_parse => pragma.beforeParse,
1529 .after_parse => pragma.afterParse,
1530 };
1531 if (maybe_func) |func| func(pragma, comp);
1532 }
1533}
1534
1535pub fn hasBuiltin(comp: *const Compilation, name: []const u8) bool {
1536 if (std.mem.eql(u8, name, "__builtin_va_arg") or
1537 std.mem.eql(u8, name, "__builtin_choose_expr") or
1538 std.mem.eql(u8, name, "__builtin_bitoffsetof") or
1539 std.mem.eql(u8, name, "__builtin_offsetof") or
1540 std.mem.eql(u8, name, "__builtin_types_compatible_p")) return true;
1541
1542 const builtin = Builtin.fromName(name) orelse return false;
1543 return comp.hasBuiltinFunction(builtin);
1544}
1545
1546pub fn hasBuiltinFunction(comp: *const Compilation, builtin: Builtin) bool {
1547 if (!target_util.builtinEnabled(comp.target, builtin.properties.target_set)) return false;
1548
1549 switch (builtin.properties.language) {
1550 .all_languages => return true,
1551 .all_ms_languages => return comp.langopts.emulate == .msvc,
1552 .gnu_lang, .all_gnu_languages => return comp.langopts.standard.isGNU(),
1553 }
1554}
1555
1556pub const CharUnitSize = enum(u32) {
1557 @"1" = 1,
1558 @"2" = 2,
1559 @"4" = 4,
1560
1561 pub fn Type(comptime self: CharUnitSize) type {
1562 return switch (self) {
1563 .@"1" => u8,
1564 .@"2" => u16,
1565 .@"4" => u32,
1566 };
1567 }
1568};
1569
1570pub const addDiagnostic = Diagnostics.add;
1571
1572test "addSourceFromReader" {
1573 const Test = struct {
1574 fn addSourceFromReader(str: []const u8, expected: []const u8, warning_count: u32, splices: []const u32) !void {
1575 var comp = Compilation.init(std.testing.allocator);
1576 defer comp.deinit();
1577
1578 var buf_reader = std.io.fixedBufferStream(str);
1579 const source = try comp.addSourceFromReader(buf_reader.reader(), "path", .user);
1580
1581 try std.testing.expectEqualStrings(expected, source.buf);
1582 try std.testing.expectEqual(warning_count, @as(u32, @intCast(comp.diagnostics.list.items.len)));
1583 try std.testing.expectEqualSlices(u32, splices, source.splice_locs);
1584 }
1585
1586 fn withAllocationFailures(allocator: std.mem.Allocator) !void {
1587 var comp = Compilation.init(allocator);
1588 defer comp.deinit();
1589
1590 _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n");
1591 _ = try comp.addSourceFromBuffer("path", "non-spliced buffer\n");
1592 }
1593 };
1594 try Test.addSourceFromReader("ab\\\nc", "abc", 0, &.{2});
1595 try Test.addSourceFromReader("ab\\\rc", "abc", 0, &.{2});
1596 try Test.addSourceFromReader("ab\\\r\nc", "abc", 0, &.{2});
1597 try Test.addSourceFromReader("ab\\ \nc", "abc", 1, &.{2});
1598 try Test.addSourceFromReader("ab\\\t\nc", "abc", 1, &.{2});
1599 try Test.addSourceFromReader("ab\\ \t\nc", "abc", 1, &.{2});
1600 try Test.addSourceFromReader("ab\\\r \nc", "ab \nc", 0, &.{2});
1601 try Test.addSourceFromReader("ab\\\\\nc", "ab\\c", 0, &.{3});
1602 try Test.addSourceFromReader("ab\\ \r\nc", "abc", 1, &.{2});
1603 try Test.addSourceFromReader("ab\\ \\\nc", "ab\\ c", 0, &.{4});
1604 try Test.addSourceFromReader("ab\\\r\\\nc", "abc", 0, &.{ 2, 2 });
1605 try Test.addSourceFromReader("ab\\ \rc", "abc", 1, &.{2});
1606 try Test.addSourceFromReader("ab\\", "ab\\", 0, &.{});
1607 try Test.addSourceFromReader("ab\\\\", "ab\\\\", 0, &.{});
1608 try Test.addSourceFromReader("ab\\ ", "ab\\ ", 0, &.{});
1609 try Test.addSourceFromReader("ab\\\n", "ab", 0, &.{2});
1610 try Test.addSourceFromReader("ab\\\r\n", "ab", 0, &.{2});
1611 try Test.addSourceFromReader("ab\\\r", "ab", 0, &.{2});
1612
1613 // carriage return normalization
1614 try Test.addSourceFromReader("ab\r", "ab\n", 0, &.{});
1615 try Test.addSourceFromReader("ab\r\r", "ab\n\n", 0, &.{});
1616 try Test.addSourceFromReader("ab\r\r\n", "ab\n\n", 0, &.{});
1617 try Test.addSourceFromReader("ab\r\r\n\r", "ab\n\n\n", 0, &.{});
1618 try Test.addSourceFromReader("\r\\", "\n\\", 0, &.{});
1619 try Test.addSourceFromReader("\\\r\\", "\\", 0, &.{0});
1620
1621 try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.withAllocationFailures, .{});
1622}
1623
1624test "addSourceFromReader - exhaustive check for carriage return elimination" {
1625 const alphabet = [_]u8{ '\r', '\n', ' ', '\\', 'a' };
1626 const alen = alphabet.len;
1627 var buf: [alphabet.len]u8 = [1]u8{alphabet[0]} ** alen;
1628
1629 var comp = Compilation.init(std.testing.allocator);
1630 defer comp.deinit();
1631
1632 var source_count: u32 = 0;
1633
1634 while (true) {
1635 const source = try comp.addSourceFromBuffer(&buf, &buf);
1636 source_count += 1;
1637 try std.testing.expect(std.mem.indexOfScalar(u8, source.buf, '\r') == null);
1638
1639 if (std.mem.allEqual(u8, &buf, alphabet[alen - 1])) break;
1640
1641 var idx = std.mem.indexOfScalar(u8, &alphabet, buf[buf.len - 1]).?;
1642 buf[buf.len - 1] = alphabet[(idx + 1) % alen];
1643 var j = buf.len - 1;
1644 while (j > 0) : (j -= 1) {
1645 idx = std.mem.indexOfScalar(u8, &alphabet, buf[j - 1]).?;
1646 if (buf[j] == alphabet[0]) buf[j - 1] = alphabet[(idx + 1) % alen] else break;
1647 }
1648 }
1649 try std.testing.expect(source_count == std.math.powi(usize, alen, alen) catch unreachable);
1650}
1651
1652test "ignore BOM at beginning of file" {
1653 const BOM = "\xEF\xBB\xBF";
1654
1655 const Test = struct {
1656 fn run(buf: []const u8) !void {
1657 var comp = Compilation.init(std.testing.allocator);
1658 defer comp.deinit();
1659
1660 var buf_reader = std.io.fixedBufferStream(buf);
1661 const source = try comp.addSourceFromReader(buf_reader.reader(), "file.c", .user);
1662 const expected_output = if (mem.startsWith(u8, buf, BOM)) buf[BOM.len..] else buf;
1663 try std.testing.expectEqualStrings(expected_output, source.buf);
1664 }
1665 };
1666
1667 try Test.run(BOM);
1668 try Test.run(BOM ++ "x");
1669 try Test.run("x" ++ BOM);
1670 try Test.run(BOM ++ " ");
1671 try Test.run(BOM ++ "\n");
1672 try Test.run(BOM ++ "\\");
1673
1674 try Test.run(BOM[0..1] ++ "x");
1675 try Test.run(BOM[0..2] ++ "x");
1676 try Test.run(BOM[1..] ++ "x");
1677 try Test.run(BOM[2..] ++ "x");
1678}
lib/compiler/aro/aro/Diagnostics.zig created+589
......@@ -0,0 +1,589 @@
1const std = @import("std");
2const Allocator = mem.Allocator;
3const mem = std.mem;
4const Source = @import("Source.zig");
5const Compilation = @import("Compilation.zig");
6const Attribute = @import("Attribute.zig");
7const Builtins = @import("Builtins.zig");
8const Builtin = Builtins.Builtin;
9const Header = @import("Builtins/Properties.zig").Header;
10const Tree = @import("Tree.zig");
11const is_windows = @import("builtin").os.tag == .windows;
12const LangOpts = @import("LangOpts.zig");
13
14pub const Message = struct {
15 tag: Tag,
16 kind: Kind = undefined,
17 loc: Source.Location = .{},
18 extra: Extra = .{ .none = {} },
19
20 pub const Extra = union {
21 str: []const u8,
22 tok_id: struct {
23 expected: Tree.Token.Id,
24 actual: Tree.Token.Id,
25 },
26 tok_id_expected: Tree.Token.Id,
27 arguments: struct {
28 expected: u32,
29 actual: u32,
30 },
31 codepoints: struct {
32 actual: u21,
33 resembles: u21,
34 },
35 attr_arg_count: struct {
36 attribute: Attribute.Tag,
37 expected: u32,
38 },
39 attr_arg_type: struct {
40 expected: Attribute.ArgumentType,
41 actual: Attribute.ArgumentType,
42 },
43 attr_enum: struct {
44 tag: Attribute.Tag,
45 },
46 ignored_record_attr: struct {
47 tag: Attribute.Tag,
48 specifier: enum { @"struct", @"union", @"enum" },
49 },
50 builtin_with_header: struct {
51 builtin: Builtin.Tag,
52 header: Header,
53 },
54 invalid_escape: struct {
55 offset: u32,
56 char: u8,
57 },
58 actual_codepoint: u21,
59 ascii: u7,
60 unsigned: u64,
61 offset: u64,
62 pow_2_as_string: u8,
63 signed: i64,
64 normalized: []const u8,
65 none: void,
66 };
67};
68
69const Properties = struct {
70 msg: []const u8,
71 kind: Kind,
72 extra: std.meta.FieldEnum(Message.Extra) = .none,
73 opt: ?u8 = null,
74 all: bool = false,
75 w_extra: bool = false,
76 pedantic: bool = false,
77 suppress_version: ?LangOpts.Standard = null,
78 suppress_unless_version: ?LangOpts.Standard = null,
79 suppress_gnu: bool = false,
80 suppress_gcc: bool = false,
81 suppress_clang: bool = false,
82 suppress_msvc: bool = false,
83
84 pub fn makeOpt(comptime str: []const u8) u16 {
85 return @offsetOf(Options, str);
86 }
87 pub fn getKind(prop: Properties, options: *Options) Kind {
88 const opt = @as([*]Kind, @ptrCast(options))[prop.opt orelse return prop.kind];
89 if (opt == .default) return prop.kind;
90 return opt;
91 }
92 pub const max_bits = Compilation.bit_int_max_bits;
93};
94
95pub const Tag = @import("Diagnostics/messages.zig").with(Properties).Tag;
96
97pub const Kind = enum { @"fatal error", @"error", note, warning, off, default };
98
99pub const Options = struct {
100 // do not directly use these, instead add `const NAME = true;`
101 all: Kind = .default,
102 extra: Kind = .default,
103 pedantic: Kind = .default,
104
105 @"unsupported-pragma": Kind = .default,
106 @"c99-extensions": Kind = .default,
107 @"implicit-int": Kind = .default,
108 @"duplicate-decl-specifier": Kind = .default,
109 @"missing-declaration": Kind = .default,
110 @"extern-initializer": Kind = .default,
111 @"implicit-function-declaration": Kind = .default,
112 @"unused-value": Kind = .default,
113 @"unreachable-code": Kind = .default,
114 @"unknown-warning-option": Kind = .default,
115 @"gnu-empty-struct": Kind = .default,
116 @"gnu-alignof-expression": Kind = .default,
117 @"macro-redefined": Kind = .default,
118 @"generic-qual-type": Kind = .default,
119 multichar: Kind = .default,
120 @"pointer-integer-compare": Kind = .default,
121 @"compare-distinct-pointer-types": Kind = .default,
122 @"literal-conversion": Kind = .default,
123 @"cast-qualifiers": Kind = .default,
124 @"array-bounds": Kind = .default,
125 @"int-conversion": Kind = .default,
126 @"pointer-type-mismatch": Kind = .default,
127 @"c23-extensions": Kind = .default,
128 @"incompatible-pointer-types": Kind = .default,
129 @"excess-initializers": Kind = .default,
130 @"division-by-zero": Kind = .default,
131 @"initializer-overrides": Kind = .default,
132 @"incompatible-pointer-types-discards-qualifiers": Kind = .default,
133 @"unknown-attributes": Kind = .default,
134 @"ignored-attributes": Kind = .default,
135 @"builtin-macro-redefined": Kind = .default,
136 @"gnu-label-as-value": Kind = .default,
137 @"malformed-warning-check": Kind = .default,
138 @"#pragma-messages": Kind = .default,
139 @"newline-eof": Kind = .default,
140 @"empty-translation-unit": Kind = .default,
141 @"implicitly-unsigned-literal": Kind = .default,
142 @"c99-compat": Kind = .default,
143 @"unicode-zero-width": Kind = .default,
144 @"unicode-homoglyph": Kind = .default,
145 unicode: Kind = .default,
146 @"return-type": Kind = .default,
147 @"dollar-in-identifier-extension": Kind = .default,
148 @"unknown-pragmas": Kind = .default,
149 @"predefined-identifier-outside-function": Kind = .default,
150 @"many-braces-around-scalar-init": Kind = .default,
151 uninitialized: Kind = .default,
152 @"gnu-statement-expression": Kind = .default,
153 @"gnu-imaginary-constant": Kind = .default,
154 @"gnu-complex-integer": Kind = .default,
155 @"ignored-qualifiers": Kind = .default,
156 @"integer-overflow": Kind = .default,
157 @"extra-semi": Kind = .default,
158 @"gnu-binary-literal": Kind = .default,
159 @"variadic-macros": Kind = .default,
160 varargs: Kind = .default,
161 @"#warnings": Kind = .default,
162 @"deprecated-declarations": Kind = .default,
163 @"backslash-newline-escape": Kind = .default,
164 @"pointer-to-int-cast": Kind = .default,
165 @"gnu-case-range": Kind = .default,
166 @"c++-compat": Kind = .default,
167 vla: Kind = .default,
168 @"float-overflow-conversion": Kind = .default,
169 @"float-zero-conversion": Kind = .default,
170 @"float-conversion": Kind = .default,
171 @"gnu-folding-constant": Kind = .default,
172 undef: Kind = .default,
173 @"ignored-pragmas": Kind = .default,
174 @"gnu-include-next": Kind = .default,
175 @"include-next-outside-header": Kind = .default,
176 @"include-next-absolute-path": Kind = .default,
177 @"enum-too-large": Kind = .default,
178 @"fixed-enum-extension": Kind = .default,
179 @"designated-init": Kind = .default,
180 @"attribute-warning": Kind = .default,
181 @"invalid-noreturn": Kind = .default,
182 @"zero-length-array": Kind = .default,
183 @"old-style-flexible-struct": Kind = .default,
184 @"gnu-zero-variadic-macro-arguments": Kind = .default,
185 @"main-return-type": Kind = .default,
186 @"expansion-to-defined": Kind = .default,
187 @"bit-int-extension": Kind = .default,
188 @"keyword-macro": Kind = .default,
189 @"pointer-arith": Kind = .default,
190 @"sizeof-array-argument": Kind = .default,
191 @"pre-c23-compat": Kind = .default,
192 @"pointer-bool-conversion": Kind = .default,
193 @"string-conversion": Kind = .default,
194 @"gnu-auto-type": Kind = .default,
195 @"gnu-union-cast": Kind = .default,
196 @"pointer-sign": Kind = .default,
197 @"fuse-ld-path": Kind = .default,
198 @"language-extension-token": Kind = .default,
199 @"complex-component-init": Kind = .default,
200 @"microsoft-include": Kind = .default,
201 @"microsoft-end-of-file": Kind = .default,
202 @"invalid-source-encoding": Kind = .default,
203 @"four-char-constants": Kind = .default,
204 @"unknown-escape-sequence": Kind = .default,
205 @"invalid-pp-token": Kind = .default,
206 @"deprecated-non-prototype": Kind = .default,
207 @"duplicate-embed-param": Kind = .default,
208 @"unsupported-embed-param": Kind = .default,
209 @"unused-result": Kind = .default,
210 normalized: Kind = .default,
211};
212
213const Diagnostics = @This();
214
215list: std.ArrayListUnmanaged(Message) = .{},
216arena: std.heap.ArenaAllocator,
217fatal_errors: bool = false,
218options: Options = .{},
219errors: u32 = 0,
220macro_backtrace_limit: u32 = 6,
221
222pub fn warningExists(name: []const u8) bool {
223 inline for (std.meta.fields(Options)) |f| {
224 if (mem.eql(u8, f.name, name)) return true;
225 }
226 return false;
227}
228
229pub fn set(d: *Diagnostics, name: []const u8, to: Kind) !void {
230 inline for (std.meta.fields(Options)) |f| {
231 if (mem.eql(u8, f.name, name)) {
232 @field(d.options, f.name) = to;
233 return;
234 }
235 }
236 try d.addExtra(.{}, .{
237 .tag = .unknown_warning,
238 .extra = .{ .str = name },
239 }, &.{}, true);
240}
241
242pub fn init(gpa: Allocator) Diagnostics {
243 return .{
244 .arena = std.heap.ArenaAllocator.init(gpa),
245 };
246}
247
248pub fn deinit(d: *Diagnostics) void {
249 d.list.deinit(d.arena.child_allocator);
250 d.arena.deinit();
251}
252
253pub fn add(comp: *Compilation, msg: Message, expansion_locs: []const Source.Location) Compilation.Error!void {
254 return comp.diagnostics.addExtra(comp.langopts, msg, expansion_locs, true);
255}
256
257pub fn addExtra(
258 d: *Diagnostics,
259 langopts: LangOpts,
260 msg: Message,
261 expansion_locs: []const Source.Location,
262 note_msg_loc: bool,
263) Compilation.Error!void {
264 const kind = d.tagKind(msg.tag, langopts);
265 if (kind == .off) return;
266 var copy = msg;
267 copy.kind = kind;
268
269 if (expansion_locs.len != 0) copy.loc = expansion_locs[expansion_locs.len - 1];
270 try d.list.append(d.arena.child_allocator, copy);
271 if (expansion_locs.len != 0) {
272 // Add macro backtrace notes in reverse order omitting from the middle if needed.
273 var i = expansion_locs.len - 1;
274 const half = d.macro_backtrace_limit / 2;
275 const limit = if (i < d.macro_backtrace_limit) 0 else i - half;
276 try d.list.ensureUnusedCapacity(
277 d.arena.child_allocator,
278 if (limit == 0) expansion_locs.len else d.macro_backtrace_limit + 1,
279 );
280 while (i > limit) {
281 i -= 1;
282 d.list.appendAssumeCapacity(.{
283 .tag = .expanded_from_here,
284 .kind = .note,
285 .loc = expansion_locs[i],
286 });
287 }
288 if (limit != 0) {
289 d.list.appendAssumeCapacity(.{
290 .tag = .skipping_macro_backtrace,
291 .kind = .note,
292 .extra = .{ .unsigned = expansion_locs.len - d.macro_backtrace_limit },
293 });
294 i = half - 1;
295 while (i > 0) {
296 i -= 1;
297 d.list.appendAssumeCapacity(.{
298 .tag = .expanded_from_here,
299 .kind = .note,
300 .loc = expansion_locs[i],
301 });
302 }
303 }
304
305 if (note_msg_loc) d.list.appendAssumeCapacity(.{
306 .tag = .expanded_from_here,
307 .kind = .note,
308 .loc = msg.loc,
309 });
310 }
311 if (kind == .@"fatal error" or (kind == .@"error" and d.fatal_errors))
312 return error.FatalError;
313}
314
315pub fn render(comp: *Compilation, config: std.io.tty.Config) void {
316 if (comp.diagnostics.list.items.len == 0) return;
317 var m = defaultMsgWriter(config);
318 defer m.deinit();
319 renderMessages(comp, &m);
320}
321pub fn defaultMsgWriter(config: std.io.tty.Config) MsgWriter {
322 return MsgWriter.init(config);
323}
324
325pub fn renderMessages(comp: *Compilation, m: anytype) void {
326 var errors: u32 = 0;
327 var warnings: u32 = 0;
328 for (comp.diagnostics.list.items) |msg| {
329 switch (msg.kind) {
330 .@"fatal error", .@"error" => errors += 1,
331 .warning => warnings += 1,
332 .note => {},
333 .off => continue, // happens if an error is added before it is disabled
334 .default => unreachable,
335 }
336 renderMessage(comp, m, msg);
337 }
338 const w_s: []const u8 = if (warnings == 1) "" else "s";
339 const e_s: []const u8 = if (errors == 1) "" else "s";
340 if (errors != 0 and warnings != 0) {
341 m.print("{d} warning{s} and {d} error{s} generated.\n", .{ warnings, w_s, errors, e_s });
342 } else if (warnings != 0) {
343 m.print("{d} warning{s} generated.\n", .{ warnings, w_s });
344 } else if (errors != 0) {
345 m.print("{d} error{s} generated.\n", .{ errors, e_s });
346 }
347
348 comp.diagnostics.list.items.len = 0;
349 comp.diagnostics.errors += errors;
350}
351
352pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
353 var line: ?[]const u8 = null;
354 var end_with_splice = false;
355 const width = if (msg.loc.id != .unused) blk: {
356 var loc = msg.loc;
357 switch (msg.tag) {
358 .escape_sequence_overflow,
359 .invalid_universal_character,
360 => loc.byte_offset += @truncate(msg.extra.offset),
361 .non_standard_escape_char,
362 .unknown_escape_sequence,
363 => loc.byte_offset += msg.extra.invalid_escape.offset,
364 else => {},
365 }
366 const source = comp.getSource(loc.id);
367 var line_col = source.lineCol(loc);
368 line = line_col.line;
369 end_with_splice = line_col.end_with_splice;
370 if (msg.tag == .backslash_newline_escape) {
371 line = line_col.line[0 .. line_col.col - 1];
372 line_col.col += 1;
373 line_col.width += 1;
374 }
375 m.location(source.path, line_col.line_no, line_col.col);
376 break :blk line_col.width;
377 } else 0;
378
379 m.start(msg.kind);
380 const prop = msg.tag.property();
381 switch (prop.extra) {
382 .str => printRt(m, prop.msg, .{"{s}"}, .{msg.extra.str}),
383 .tok_id => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
384 msg.extra.tok_id.expected.symbol(),
385 msg.extra.tok_id.actual.symbol(),
386 }),
387 .tok_id_expected => printRt(m, prop.msg, .{"{s}"}, .{msg.extra.tok_id_expected.symbol()}),
388 .arguments => printRt(m, prop.msg, .{ "{d}", "{d}" }, .{
389 msg.extra.arguments.expected,
390 msg.extra.arguments.actual,
391 }),
392 .codepoints => printRt(m, prop.msg, .{ "{X:0>4}", "{u}" }, .{
393 msg.extra.codepoints.actual,
394 msg.extra.codepoints.resembles,
395 }),
396 .attr_arg_count => printRt(m, prop.msg, .{ "{s}", "{d}" }, .{
397 @tagName(msg.extra.attr_arg_count.attribute),
398 msg.extra.attr_arg_count.expected,
399 }),
400 .attr_arg_type => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
401 msg.extra.attr_arg_type.expected.toString(),
402 msg.extra.attr_arg_type.actual.toString(),
403 }),
404 .actual_codepoint => printRt(m, prop.msg, .{"{X:0>4}"}, .{msg.extra.actual_codepoint}),
405 .ascii => printRt(m, prop.msg, .{"{c}"}, .{msg.extra.ascii}),
406 .unsigned => printRt(m, prop.msg, .{"{d}"}, .{msg.extra.unsigned}),
407 .pow_2_as_string => printRt(m, prop.msg, .{"{s}"}, .{switch (msg.extra.pow_2_as_string) {
408 63 => "9223372036854775808",
409 64 => "18446744073709551616",
410 127 => "170141183460469231731687303715884105728",
411 128 => "340282366920938463463374607431768211456",
412 else => unreachable,
413 }}),
414 .signed => printRt(m, prop.msg, .{"{d}"}, .{msg.extra.signed}),
415 .attr_enum => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
416 @tagName(msg.extra.attr_enum.tag),
417 Attribute.Formatting.choices(msg.extra.attr_enum.tag),
418 }),
419 .ignored_record_attr => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
420 @tagName(msg.extra.ignored_record_attr.tag),
421 @tagName(msg.extra.ignored_record_attr.specifier),
422 }),
423 .builtin_with_header => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
424 @tagName(msg.extra.builtin_with_header.header),
425 Builtin.nameFromTag(msg.extra.builtin_with_header.builtin).span(),
426 }),
427 .invalid_escape => {
428 if (std.ascii.isPrint(msg.extra.invalid_escape.char)) {
429 const str: [1]u8 = .{msg.extra.invalid_escape.char};
430 printRt(m, prop.msg, .{"{s}"}, .{&str});
431 } else {
432 var buf: [3]u8 = undefined;
433 const str = std.fmt.bufPrint(&buf, "x{x}", .{std.fmt.fmtSliceHexLower(&.{msg.extra.invalid_escape.char})}) catch unreachable;
434 printRt(m, prop.msg, .{"{s}"}, .{str});
435 }
436 },
437 .normalized => {
438 const f = struct {
439 pub fn f(
440 bytes: []const u8,
441 comptime _: []const u8,
442 _: std.fmt.FormatOptions,
443 writer: anytype,
444 ) !void {
445 var it: std.unicode.Utf8Iterator = .{
446 .bytes = bytes,
447 .i = 0,
448 };
449 while (it.nextCodepoint()) |codepoint| {
450 if (codepoint < 0x7F) {
451 try writer.writeByte(@intCast(codepoint));
452 } else if (codepoint < 0xFFFF) {
453 try writer.writeAll("\\u");
454 try std.fmt.formatInt(codepoint, 16, .upper, .{
455 .fill = '0',
456 .width = 4,
457 }, writer);
458 } else {
459 try writer.writeAll("\\U");
460 try std.fmt.formatInt(codepoint, 16, .upper, .{
461 .fill = '0',
462 .width = 8,
463 }, writer);
464 }
465 }
466 }
467 }.f;
468 printRt(m, prop.msg, .{"{s}"}, .{
469 std.fmt.Formatter(f){ .data = msg.extra.normalized },
470 });
471 },
472 .none, .offset => m.write(prop.msg),
473 }
474
475 if (prop.opt) |some| {
476 if (msg.kind == .@"error" and prop.kind != .@"error") {
477 m.print(" [-Werror,-W{s}]", .{optName(some)});
478 } else if (msg.kind != .note) {
479 m.print(" [-W{s}]", .{optName(some)});
480 }
481 }
482
483 m.end(line, width, end_with_splice);
484}
485
486fn printRt(m: anytype, str: []const u8, comptime fmts: anytype, args: anytype) void {
487 var i: usize = 0;
488 inline for (fmts, args) |fmt, arg| {
489 const new = std.mem.indexOfPos(u8, str, i, fmt).?;
490 m.write(str[i..new]);
491 i = new + fmt.len;
492 m.print(fmt, .{arg});
493 }
494 m.write(str[i..]);
495}
496
497fn optName(offset: u16) []const u8 {
498 return std.meta.fieldNames(Options)[offset / @sizeOf(Kind)];
499}
500
501fn tagKind(d: *Diagnostics, tag: Tag, langopts: LangOpts) Kind {
502 const prop = tag.property();
503 var kind = prop.getKind(&d.options);
504
505 if (prop.all) {
506 if (d.options.all != .default) kind = d.options.all;
507 }
508 if (prop.w_extra) {
509 if (d.options.extra != .default) kind = d.options.extra;
510 }
511 if (prop.pedantic) {
512 if (d.options.pedantic != .default) kind = d.options.pedantic;
513 }
514 if (prop.suppress_version) |some| if (langopts.standard.atLeast(some)) return .off;
515 if (prop.suppress_unless_version) |some| if (!langopts.standard.atLeast(some)) return .off;
516 if (prop.suppress_gnu and langopts.standard.isExplicitGNU()) return .off;
517 if (prop.suppress_gcc and langopts.emulate == .gcc) return .off;
518 if (prop.suppress_clang and langopts.emulate == .clang) return .off;
519 if (prop.suppress_msvc and langopts.emulate == .msvc) return .off;
520 if (kind == .@"error" and d.fatal_errors) kind = .@"fatal error";
521 return kind;
522}
523
524const MsgWriter = struct {
525 w: std.io.BufferedWriter(4096, std.fs.File.Writer),
526 config: std.io.tty.Config,
527
528 fn init(config: std.io.tty.Config) MsgWriter {
529 std.debug.getStderrMutex().lock();
530 return .{
531 .w = std.io.bufferedWriter(std.io.getStdErr().writer()),
532 .config = config,
533 };
534 }
535
536 pub fn deinit(m: *MsgWriter) void {
537 m.w.flush() catch {};
538 std.debug.getStderrMutex().unlock();
539 }
540
541 pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void {
542 m.w.writer().print(fmt, args) catch {};
543 }
544
545 fn write(m: *MsgWriter, msg: []const u8) void {
546 m.w.writer().writeAll(msg) catch {};
547 }
548
549 fn setColor(m: *MsgWriter, color: std.io.tty.Color) void {
550 m.config.setColor(m.w.writer(), color) catch {};
551 }
552
553 fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void {
554 m.setColor(.bold);
555 m.print("{s}:{d}:{d}: ", .{ path, line, col });
556 }
557
558 fn start(m: *MsgWriter, kind: Kind) void {
559 switch (kind) {
560 .@"fatal error", .@"error" => m.setColor(.bright_red),
561 .note => m.setColor(.bright_cyan),
562 .warning => m.setColor(.bright_magenta),
563 .off, .default => unreachable,
564 }
565 m.write(switch (kind) {
566 .@"fatal error" => "fatal error: ",
567 .@"error" => "error: ",
568 .note => "note: ",
569 .warning => "warning: ",
570 .off, .default => unreachable,
571 });
572 m.setColor(.white);
573 }
574
575 fn end(m: *MsgWriter, maybe_line: ?[]const u8, col: u32, end_with_splice: bool) void {
576 const line = maybe_line orelse {
577 m.write("\n");
578 m.setColor(.reset);
579 return;
580 };
581 const trailer = if (end_with_splice) "\\ " else "";
582 m.setColor(.reset);
583 m.print("\n{s}{s}\n{s: >[3]}", .{ line, trailer, "", col });
584 m.setColor(.bold);
585 m.setColor(.bright_green);
586 m.write("^\n");
587 m.setColor(.reset);
588 }
589};
lib/compiler/aro/aro/Diagnostics/messages.zig created+1010
......@@ -0,0 +1,1010 @@
1//! Autogenerated by GenerateDef from deps/aro/aro/Diagnostics/messages.def, do not edit
2
3const std = @import("std");
4
5pub fn with(comptime Properties: type) type {
6return struct {
7const W = Properties.makeOpt;
8const pointer_sign_message = " converts between pointers to integer types with different sign";
9const expected_arguments = "expected {d} argument(s) got {d}";
10pub const Tag = enum {
11 todo,
12 error_directive,
13 warning_directive,
14 elif_without_if,
15 elif_after_else,
16 elifdef_without_if,
17 elifdef_after_else,
18 elifndef_without_if,
19 elifndef_after_else,
20 else_without_if,
21 else_after_else,
22 endif_without_if,
23 unknown_pragma,
24 line_simple_digit,
25 line_invalid_filename,
26 unterminated_conditional_directive,
27 invalid_preprocessing_directive,
28 macro_name_missing,
29 extra_tokens_directive_end,
30 expected_value_in_expr,
31 closing_paren,
32 to_match_paren,
33 to_match_brace,
34 to_match_bracket,
35 header_str_closing,
36 header_str_match,
37 string_literal_in_pp_expr,
38 float_literal_in_pp_expr,
39 defined_as_macro_name,
40 macro_name_must_be_identifier,
41 whitespace_after_macro_name,
42 hash_hash_at_start,
43 hash_hash_at_end,
44 pasting_formed_invalid,
45 missing_paren_param_list,
46 unterminated_macro_param_list,
47 invalid_token_param_list,
48 expected_comma_param_list,
49 hash_not_followed_param,
50 expected_filename,
51 empty_filename,
52 expected_invalid,
53 expected_eof,
54 expected_token,
55 expected_expr,
56 expected_integer_constant_expr,
57 missing_type_specifier,
58 missing_type_specifier_c23,
59 multiple_storage_class,
60 static_assert_failure,
61 static_assert_failure_message,
62 expected_type,
63 cannot_combine_spec,
64 duplicate_decl_spec,
65 restrict_non_pointer,
66 expected_external_decl,
67 expected_ident_or_l_paren,
68 missing_declaration,
69 func_not_in_root,
70 illegal_initializer,
71 extern_initializer,
72 spec_from_typedef,
73 param_before_var_args,
74 void_only_param,
75 void_param_qualified,
76 void_must_be_first_param,
77 invalid_storage_on_param,
78 threadlocal_non_var,
79 func_spec_non_func,
80 illegal_storage_on_func,
81 illegal_storage_on_global,
82 expected_stmt,
83 func_cannot_return_func,
84 func_cannot_return_array,
85 undeclared_identifier,
86 not_callable,
87 unsupported_str_cat,
88 static_func_not_global,
89 implicit_func_decl,
90 unknown_builtin,
91 implicit_builtin,
92 implicit_builtin_header_note,
93 expected_param_decl,
94 invalid_old_style_params,
95 expected_fn_body,
96 invalid_void_param,
97 unused_value,
98 continue_not_in_loop,
99 break_not_in_loop_or_switch,
100 unreachable_code,
101 duplicate_label,
102 previous_label,
103 undeclared_label,
104 case_not_in_switch,
105 duplicate_switch_case,
106 multiple_default,
107 previous_case,
108 expected_arguments,
109 expected_arguments_old,
110 expected_at_least_arguments,
111 invalid_static_star,
112 static_non_param,
113 array_qualifiers,
114 star_non_param,
115 variable_len_array_file_scope,
116 useless_static,
117 negative_array_size,
118 array_incomplete_elem,
119 array_func_elem,
120 static_non_outermost_array,
121 qualifier_non_outermost_array,
122 unterminated_macro_arg_list,
123 unknown_warning,
124 overflow,
125 int_literal_too_big,
126 indirection_ptr,
127 addr_of_rvalue,
128 addr_of_bitfield,
129 not_assignable,
130 ident_or_l_brace,
131 empty_enum,
132 redefinition,
133 previous_definition,
134 expected_identifier,
135 expected_str_literal,
136 expected_str_literal_in,
137 parameter_missing,
138 empty_record,
139 empty_record_size,
140 wrong_tag,
141 expected_parens_around_typename,
142 alignof_expr,
143 invalid_alignof,
144 invalid_sizeof,
145 macro_redefined,
146 generic_qual_type,
147 generic_array_type,
148 generic_func_type,
149 generic_duplicate,
150 generic_duplicate_here,
151 generic_duplicate_default,
152 generic_no_match,
153 escape_sequence_overflow,
154 invalid_universal_character,
155 incomplete_universal_character,
156 multichar_literal_warning,
157 invalid_multichar_literal,
158 wide_multichar_literal,
159 char_lit_too_wide,
160 char_too_large,
161 must_use_struct,
162 must_use_union,
163 must_use_enum,
164 redefinition_different_sym,
165 redefinition_incompatible,
166 redefinition_of_parameter,
167 invalid_bin_types,
168 comparison_ptr_int,
169 comparison_distinct_ptr,
170 incompatible_pointers,
171 invalid_argument_un,
172 incompatible_assign,
173 implicit_ptr_to_int,
174 invalid_cast_to_float,
175 invalid_cast_to_pointer,
176 invalid_cast_type,
177 qual_cast,
178 invalid_index,
179 invalid_subscript,
180 array_after,
181 array_before,
182 statement_int,
183 statement_scalar,
184 func_should_return,
185 incompatible_return,
186 incompatible_return_sign,
187 implicit_int_to_ptr,
188 func_does_not_return,
189 void_func_returns_value,
190 incompatible_arg,
191 incompatible_ptr_arg,
192 incompatible_ptr_arg_sign,
193 parameter_here,
194 atomic_array,
195 atomic_func,
196 atomic_incomplete,
197 addr_of_register,
198 variable_incomplete_ty,
199 parameter_incomplete_ty,
200 tentative_array,
201 deref_incomplete_ty_ptr,
202 alignas_on_func,
203 alignas_on_param,
204 minimum_alignment,
205 maximum_alignment,
206 negative_alignment,
207 align_ignored,
208 zero_align_ignored,
209 non_pow2_align,
210 pointer_mismatch,
211 static_assert_not_constant,
212 static_assert_missing_message,
213 pre_c23_compat,
214 unbound_vla,
215 array_too_large,
216 incompatible_ptr_init,
217 incompatible_ptr_init_sign,
218 incompatible_ptr_assign,
219 incompatible_ptr_assign_sign,
220 vla_init,
221 func_init,
222 incompatible_init,
223 empty_scalar_init,
224 excess_scalar_init,
225 excess_str_init,
226 excess_struct_init,
227 excess_array_init,
228 str_init_too_long,
229 arr_init_too_long,
230 invalid_typeof,
231 division_by_zero,
232 division_by_zero_macro,
233 builtin_choose_cond,
234 alignas_unavailable,
235 case_val_unavailable,
236 enum_val_unavailable,
237 incompatible_array_init,
238 array_init_str,
239 initializer_overrides,
240 previous_initializer,
241 invalid_array_designator,
242 negative_array_designator,
243 oob_array_designator,
244 invalid_field_designator,
245 no_such_field_designator,
246 empty_aggregate_init_braces,
247 ptr_init_discards_quals,
248 ptr_assign_discards_quals,
249 ptr_ret_discards_quals,
250 ptr_arg_discards_quals,
251 unknown_attribute,
252 ignored_attribute,
253 invalid_fallthrough,
254 cannot_apply_attribute_to_statement,
255 builtin_macro_redefined,
256 feature_check_requires_identifier,
257 missing_tok_builtin,
258 gnu_label_as_value,
259 expected_record_ty,
260 member_expr_not_ptr,
261 member_expr_ptr,
262 no_such_member,
263 malformed_warning_check,
264 invalid_computed_goto,
265 pragma_warning_message,
266 pragma_error_message,
267 pragma_message,
268 pragma_requires_string_literal,
269 poisoned_identifier,
270 pragma_poison_identifier,
271 pragma_poison_macro,
272 newline_eof,
273 empty_translation_unit,
274 omitting_parameter_name,
275 non_int_bitfield,
276 negative_bitwidth,
277 zero_width_named_field,
278 bitfield_too_big,
279 invalid_utf8,
280 implicitly_unsigned_literal,
281 invalid_preproc_operator,
282 invalid_preproc_expr_start,
283 c99_compat,
284 unexpected_character,
285 invalid_identifier_start_char,
286 unicode_zero_width,
287 unicode_homoglyph,
288 meaningless_asm_qual,
289 duplicate_asm_qual,
290 invalid_asm_str,
291 dollar_in_identifier_extension,
292 dollars_in_identifiers,
293 expanded_from_here,
294 skipping_macro_backtrace,
295 pragma_operator_string_literal,
296 unknown_gcc_pragma,
297 unknown_gcc_pragma_directive,
298 predefined_top_level,
299 incompatible_va_arg,
300 too_many_scalar_init_braces,
301 uninitialized_in_own_init,
302 gnu_statement_expression,
303 stmt_expr_not_allowed_file_scope,
304 gnu_imaginary_constant,
305 plain_complex,
306 complex_int,
307 qual_on_ret_type,
308 cli_invalid_standard,
309 cli_invalid_target,
310 cli_invalid_emulate,
311 cli_unknown_arg,
312 cli_error,
313 cli_unused_link_object,
314 cli_unknown_linker,
315 extra_semi,
316 func_field,
317 vla_field,
318 field_incomplete_ty,
319 flexible_in_union,
320 flexible_non_final,
321 flexible_in_empty,
322 duplicate_member,
323 binary_integer_literal,
324 gnu_va_macro,
325 builtin_must_be_called,
326 va_start_not_in_func,
327 va_start_fixed_args,
328 va_start_not_last_param,
329 attribute_not_enough_args,
330 attribute_too_many_args,
331 attribute_arg_invalid,
332 unknown_attr_enum,
333 attribute_requires_identifier,
334 declspec_not_enabled,
335 declspec_attr_not_supported,
336 deprecated_declarations,
337 deprecated_note,
338 unavailable,
339 unavailable_note,
340 warning_attribute,
341 error_attribute,
342 ignored_record_attr,
343 backslash_newline_escape,
344 array_size_non_int,
345 cast_to_smaller_int,
346 gnu_switch_range,
347 empty_case_range,
348 non_standard_escape_char,
349 invalid_pp_stringify_escape,
350 vla,
351 float_overflow_conversion,
352 float_out_of_range,
353 float_zero_conversion,
354 float_value_changed,
355 float_to_int,
356 const_decl_folded,
357 const_decl_folded_vla,
358 redefinition_of_typedef,
359 undefined_macro,
360 fn_macro_undefined,
361 preprocessing_directive_only,
362 missing_lparen_after_builtin,
363 offsetof_ty,
364 offsetof_incomplete,
365 offsetof_array,
366 pragma_pack_lparen,
367 pragma_pack_rparen,
368 pragma_pack_unknown_action,
369 pragma_pack_show,
370 pragma_pack_int,
371 pragma_pack_int_ident,
372 pragma_pack_undefined_pop,
373 pragma_pack_empty_stack,
374 cond_expr_type,
375 too_many_includes,
376 enumerator_too_small,
377 enumerator_too_large,
378 include_next,
379 include_next_outside_header,
380 enumerator_overflow,
381 enum_not_representable,
382 enum_too_large,
383 enum_fixed,
384 enum_prev_nonfixed,
385 enum_prev_fixed,
386 enum_different_explicit_ty,
387 enum_not_representable_fixed,
388 transparent_union_wrong_type,
389 transparent_union_one_field,
390 transparent_union_size,
391 transparent_union_size_note,
392 designated_init_invalid,
393 designated_init_needed,
394 ignore_common,
395 ignore_nocommon,
396 non_string_ignored,
397 local_variable_attribute,
398 ignore_cold,
399 ignore_hot,
400 ignore_noinline,
401 ignore_always_inline,
402 invalid_noreturn,
403 nodiscard_unused,
404 warn_unused_result,
405 invalid_vec_elem_ty,
406 vec_size_not_multiple,
407 invalid_imag,
408 invalid_real,
409 zero_length_array,
410 old_style_flexible_struct,
411 comma_deletion_va_args,
412 main_return_type,
413 expansion_to_defined,
414 invalid_int_suffix,
415 invalid_float_suffix,
416 invalid_octal_digit,
417 invalid_binary_digit,
418 exponent_has_no_digits,
419 hex_floating_constant_requires_exponent,
420 sizeof_returns_zero,
421 declspec_not_allowed_after_declarator,
422 declarator_name_tok,
423 type_not_supported_on_target,
424 bit_int,
425 unsigned_bit_int_too_small,
426 signed_bit_int_too_small,
427 bit_int_too_big,
428 keyword_macro,
429 ptr_arithmetic_incomplete,
430 callconv_not_supported,
431 pointer_arith_void,
432 sizeof_array_arg,
433 array_address_to_bool,
434 string_literal_to_bool,
435 constant_expression_conversion_not_allowed,
436 invalid_object_cast,
437 cli_invalid_fp_eval_method,
438 suggest_pointer_for_invalid_fp16,
439 bitint_suffix,
440 auto_type_extension,
441 auto_type_not_allowed,
442 auto_type_requires_initializer,
443 auto_type_requires_single_declarator,
444 auto_type_requires_plain_declarator,
445 invalid_cast_to_auto_type,
446 auto_type_from_bitfield,
447 array_of_auto_type,
448 auto_type_with_init_list,
449 missing_semicolon,
450 tentative_definition_incomplete,
451 forward_declaration_here,
452 gnu_union_cast,
453 invalid_union_cast,
454 cast_to_incomplete_type,
455 invalid_source_epoch,
456 fuse_ld_path,
457 invalid_rtlib,
458 unsupported_rtlib_gcc,
459 invalid_unwindlib,
460 incompatible_unwindlib,
461 gnu_asm_disabled,
462 extension_token_used,
463 complex_component_init,
464 complex_prefix_postfix_op,
465 not_floating_type,
466 argument_types_differ,
467 ms_search_rule,
468 ctrl_z_eof,
469 illegal_char_encoding_warning,
470 illegal_char_encoding_error,
471 ucn_basic_char_error,
472 ucn_basic_char_warning,
473 ucn_control_char_error,
474 ucn_control_char_warning,
475 c89_ucn_in_literal,
476 four_char_char_literal,
477 multi_char_char_literal,
478 missing_hex_escape,
479 unknown_escape_sequence,
480 attribute_requires_string,
481 unterminated_string_literal_warning,
482 unterminated_string_literal_error,
483 empty_char_literal_warning,
484 empty_char_literal_error,
485 unterminated_char_literal_warning,
486 unterminated_char_literal_error,
487 unterminated_comment,
488 def_no_proto_deprecated,
489 passing_args_to_kr,
490 unknown_type_name,
491 label_compound_end,
492 u8_char_lit,
493 malformed_embed_param,
494 malformed_embed_limit,
495 duplicate_embed_param,
496 unsupported_embed_param,
497 invalid_compound_literal_storage_class,
498 va_opt_lparen,
499 va_opt_rparen,
500 attribute_int_out_of_range,
501 identifier_not_normalized,
502 c23_auto_plain_declarator,
503 c23_auto_single_declarator,
504 c32_auto_requires_initializer,
505 c23_auto_scalar_init,
506
507 pub fn property(tag: Tag) Properties {
508 return named_data[@intFromEnum(tag)];
509 }
510
511 const named_data = [_]Properties{
512 .{ .msg = "TODO: {s}", .extra = .str, .kind = .@"error" },
513 .{ .msg = "{s}", .extra = .str, .kind = .@"error" },
514 .{ .msg = "{s}", .opt = W("#warnings"), .extra = .str, .kind = .warning },
515 .{ .msg = "#elif without #if", .kind = .@"error" },
516 .{ .msg = "#elif after #else", .kind = .@"error" },
517 .{ .msg = "#elifdef without #if", .kind = .@"error" },
518 .{ .msg = "#elifdef after #else", .kind = .@"error" },
519 .{ .msg = "#elifndef without #if", .kind = .@"error" },
520 .{ .msg = "#elifndef after #else", .kind = .@"error" },
521 .{ .msg = "#else without #if", .kind = .@"error" },
522 .{ .msg = "#else after #else", .kind = .@"error" },
523 .{ .msg = "#endif without #if", .kind = .@"error" },
524 .{ .msg = "unknown pragma ignored", .opt = W("unknown-pragmas"), .kind = .off, .all = true },
525 .{ .msg = "#line directive requires a simple digit sequence", .kind = .@"error" },
526 .{ .msg = "invalid filename for #line directive", .kind = .@"error" },
527 .{ .msg = "unterminated conditional directive", .kind = .@"error" },
528 .{ .msg = "invalid preprocessing directive", .kind = .@"error" },
529 .{ .msg = "macro name missing", .kind = .@"error" },
530 .{ .msg = "extra tokens at end of macro directive", .kind = .@"error" },
531 .{ .msg = "expected value in expression", .kind = .@"error" },
532 .{ .msg = "expected closing ')'", .kind = .@"error" },
533 .{ .msg = "to match this '('", .kind = .note },
534 .{ .msg = "to match this '{'", .kind = .note },
535 .{ .msg = "to match this '['", .kind = .note },
536 .{ .msg = "expected closing '>'", .kind = .@"error" },
537 .{ .msg = "to match this '<'", .kind = .note },
538 .{ .msg = "string literal in preprocessor expression", .kind = .@"error" },
539 .{ .msg = "floating point literal in preprocessor expression", .kind = .@"error" },
540 .{ .msg = "'defined' cannot be used as a macro name", .kind = .@"error" },
541 .{ .msg = "macro name must be an identifier", .kind = .@"error" },
542 .{ .msg = "ISO C99 requires whitespace after the macro name", .opt = W("c99-extensions"), .kind = .warning },
543 .{ .msg = "'##' cannot appear at the start of a macro expansion", .kind = .@"error" },
544 .{ .msg = "'##' cannot appear at the end of a macro expansion", .kind = .@"error" },
545 .{ .msg = "pasting formed '{s}', an invalid preprocessing token", .extra = .str, .kind = .@"error" },
546 .{ .msg = "missing ')' in macro parameter list", .kind = .@"error" },
547 .{ .msg = "unterminated macro param list", .kind = .@"error" },
548 .{ .msg = "invalid token in macro parameter list", .kind = .@"error" },
549 .{ .msg = "expected comma in macro parameter list", .kind = .@"error" },
550 .{ .msg = "'#' is not followed by a macro parameter", .kind = .@"error" },
551 .{ .msg = "expected \"FILENAME\" or <FILENAME>", .kind = .@"error" },
552 .{ .msg = "empty filename", .kind = .@"error" },
553 .{ .msg = "expected '{s}', found invalid bytes", .extra = .tok_id_expected, .kind = .@"error" },
554 .{ .msg = "expected '{s}' before end of file", .extra = .tok_id_expected, .kind = .@"error" },
555 .{ .msg = "expected '{s}', found '{s}'", .extra = .tok_id, .kind = .@"error" },
556 .{ .msg = "expected expression", .kind = .@"error" },
557 .{ .msg = "expression is not an integer constant expression", .kind = .@"error" },
558 .{ .msg = "type specifier missing, defaults to 'int'", .opt = W("implicit-int"), .kind = .warning, .all = true },
559 .{ .msg = "a type specifier is required for all declarations", .kind = .@"error" },
560 .{ .msg = "cannot combine with previous '{s}' declaration specifier", .extra = .str, .kind = .@"error" },
561 .{ .msg = "static assertion failed", .kind = .@"error" },
562 .{ .msg = "static assertion failed {s}", .extra = .str, .kind = .@"error" },
563 .{ .msg = "expected a type", .kind = .@"error" },
564 .{ .msg = "cannot combine with previous '{s}' specifier", .extra = .str, .kind = .@"error" },
565 .{ .msg = "duplicate '{s}' declaration specifier", .extra = .str, .opt = W("duplicate-decl-specifier"), .kind = .warning, .all = true },
566 .{ .msg = "restrict requires a pointer or reference ('{s}' is invalid)", .extra = .str, .kind = .@"error" },
567 .{ .msg = "expected external declaration", .kind = .@"error" },
568 .{ .msg = "expected identifier or '('", .kind = .@"error" },
569 .{ .msg = "declaration does not declare anything", .opt = W("missing-declaration"), .kind = .warning },
570 .{ .msg = "function definition is not allowed here", .kind = .@"error" },
571 .{ .msg = "illegal initializer (only variables can be initialized)", .kind = .@"error" },
572 .{ .msg = "extern variable has initializer", .opt = W("extern-initializer"), .kind = .warning },
573 .{ .msg = "'{s}' came from typedef", .extra = .str, .kind = .note },
574 .{ .msg = "ISO C requires a named parameter before '...'", .kind = .@"error", .suppress_version = .c23 },
575 .{ .msg = "'void' must be the only parameter if specified", .kind = .@"error" },
576 .{ .msg = "'void' parameter cannot be qualified", .kind = .@"error" },
577 .{ .msg = "'void' must be the first parameter if specified", .kind = .@"error" },
578 .{ .msg = "invalid storage class on function parameter", .kind = .@"error" },
579 .{ .msg = "_Thread_local only allowed on variables", .kind = .@"error" },
580 .{ .msg = "'{s}' can only appear on functions", .extra = .str, .kind = .@"error" },
581 .{ .msg = "illegal storage class on function", .kind = .@"error" },
582 .{ .msg = "illegal storage class on global variable", .kind = .@"error" },
583 .{ .msg = "expected statement", .kind = .@"error" },
584 .{ .msg = "function cannot return a function", .kind = .@"error" },
585 .{ .msg = "function cannot return an array", .kind = .@"error" },
586 .{ .msg = "use of undeclared identifier '{s}'", .extra = .str, .kind = .@"error" },
587 .{ .msg = "cannot call non function type '{s}'", .extra = .str, .kind = .@"error" },
588 .{ .msg = "unsupported string literal concatenation", .kind = .@"error" },
589 .{ .msg = "static functions must be global", .kind = .@"error" },
590 .{ .msg = "call to undeclared function '{s}'; ISO C99 and later do not support implicit function declarations", .extra = .str, .opt = W("implicit-function-declaration"), .kind = .@"error", .all = true },
591 .{ .msg = "use of unknown builtin '{s}'", .extra = .str, .opt = W("implicit-function-declaration"), .kind = .@"error", .all = true },
592 .{ .msg = "implicitly declaring library function '{s}'", .extra = .str, .opt = W("implicit-function-declaration"), .kind = .@"error", .all = true },
593 .{ .msg = "include the header <{s}.h> or explicitly provide a declaration for '{s}'", .extra = .builtin_with_header, .opt = W("implicit-function-declaration"), .kind = .note, .all = true },
594 .{ .msg = "expected parameter declaration", .kind = .@"error" },
595 .{ .msg = "identifier parameter lists are only allowed in function definitions", .kind = .@"error" },
596 .{ .msg = "expected function body after function declaration", .kind = .@"error" },
597 .{ .msg = "parameter cannot have void type", .kind = .@"error" },
598 .{ .msg = "expression result unused", .opt = W("unused-value"), .kind = .warning, .all = true },
599 .{ .msg = "'continue' statement not in a loop", .kind = .@"error" },
600 .{ .msg = "'break' statement not in a loop or a switch", .kind = .@"error" },
601 .{ .msg = "unreachable code", .opt = W("unreachable-code"), .kind = .warning, .all = true },
602 .{ .msg = "duplicate label '{s}'", .extra = .str, .kind = .@"error" },
603 .{ .msg = "previous definition of label '{s}' was here", .extra = .str, .kind = .note },
604 .{ .msg = "use of undeclared label '{s}'", .extra = .str, .kind = .@"error" },
605 .{ .msg = "'{s}' statement not in a switch statement", .extra = .str, .kind = .@"error" },
606 .{ .msg = "duplicate case value '{s}'", .extra = .str, .kind = .@"error" },
607 .{ .msg = "multiple default cases in the same switch", .kind = .@"error" },
608 .{ .msg = "previous case defined here", .kind = .note },
609 .{ .msg = expected_arguments, .extra = .arguments, .kind = .@"error" },
610 .{ .msg = expected_arguments, .extra = .arguments, .kind = .warning },
611 .{ .msg = "expected at least {d} argument(s) got {d}", .extra = .arguments, .kind = .warning },
612 .{ .msg = "'static' may not be used with an unspecified variable length array size", .kind = .@"error" },
613 .{ .msg = "'static' used outside of function parameters", .kind = .@"error" },
614 .{ .msg = "type qualifier in non parameter array type", .kind = .@"error" },
615 .{ .msg = "star modifier used outside of function parameters", .kind = .@"error" },
616 .{ .msg = "variable length arrays not allowed at file scope", .kind = .@"error" },
617 .{ .msg = "'static' useless without a constant size", .kind = .warning, .w_extra = true },
618 .{ .msg = "array size must be 0 or greater", .kind = .@"error" },
619 .{ .msg = "array has incomplete element type '{s}'", .extra = .str, .kind = .@"error" },
620 .{ .msg = "arrays cannot have functions as their element type", .kind = .@"error" },
621 .{ .msg = "'static' used in non-outermost array type", .kind = .@"error" },
622 .{ .msg = "type qualifier used in non-outermost array type", .kind = .@"error" },
623 .{ .msg = "unterminated function macro argument list", .kind = .@"error" },
624 .{ .msg = "unknown warning '{s}'", .extra = .str, .opt = W("unknown-warning-option"), .kind = .warning },
625 .{ .msg = "overflow in expression; result is '{s}'", .extra = .str, .opt = W("integer-overflow"), .kind = .warning },
626 .{ .msg = "integer literal is too large to be represented in any integer type", .kind = .@"error" },
627 .{ .msg = "indirection requires pointer operand", .kind = .@"error" },
628 .{ .msg = "cannot take the address of an rvalue", .kind = .@"error" },
629 .{ .msg = "address of bit-field requested", .kind = .@"error" },
630 .{ .msg = "expression is not assignable", .kind = .@"error" },
631 .{ .msg = "expected identifier or '{'", .kind = .@"error" },
632 .{ .msg = "empty enum is invalid", .kind = .@"error" },
633 .{ .msg = "redefinition of '{s}'", .extra = .str, .kind = .@"error" },
634 .{ .msg = "previous definition is here", .kind = .note },
635 .{ .msg = "expected identifier", .kind = .@"error" },
636 .{ .msg = "expected string literal for diagnostic message in static_assert", .kind = .@"error" },
637 .{ .msg = "expected string literal in '{s}'", .extra = .str, .kind = .@"error" },
638 .{ .msg = "parameter named '{s}' is missing", .extra = .str, .kind = .@"error" },
639 .{ .msg = "empty {s} is a GNU extension", .extra = .str, .opt = W("gnu-empty-struct"), .kind = .off, .pedantic = true },
640 .{ .msg = "empty {s} has size 0 in C, size 1 in C++", .extra = .str, .opt = W("c++-compat"), .kind = .off },
641 .{ .msg = "use of '{s}' with tag type that does not match previous definition", .extra = .str, .kind = .@"error" },
642 .{ .msg = "expected parentheses around type name", .kind = .@"error" },
643 .{ .msg = "'_Alignof' applied to an expression is a GNU extension", .opt = W("gnu-alignof-expression"), .kind = .warning, .suppress_gnu = true },
644 .{ .msg = "invalid application of 'alignof' to an incomplete type '{s}'", .extra = .str, .kind = .@"error" },
645 .{ .msg = "invalid application of 'sizeof' to an incomplete type '{s}'", .extra = .str, .kind = .@"error" },
646 .{ .msg = "'{s}' macro redefined", .extra = .str, .opt = W("macro-redefined"), .kind = .warning },
647 .{ .msg = "generic association with qualifiers cannot be matched with", .opt = W("generic-qual-type"), .kind = .warning },
648 .{ .msg = "generic association array type cannot be matched with", .opt = W("generic-qual-type"), .kind = .warning },
649 .{ .msg = "generic association function type cannot be matched with", .opt = W("generic-qual-type"), .kind = .warning },
650 .{ .msg = "type '{s}' in generic association compatible with previously specified type", .extra = .str, .kind = .@"error" },
651 .{ .msg = "compatible type '{s}' specified here", .extra = .str, .kind = .note },
652 .{ .msg = "duplicate default generic association", .kind = .@"error" },
653 .{ .msg = "controlling expression type '{s}' not compatible with any generic association type", .extra = .str, .kind = .@"error" },
654 .{ .msg = "escape sequence out of range", .kind = .@"error" },
655 .{ .msg = "invalid universal character", .kind = .@"error" },
656 .{ .msg = "incomplete universal character name", .kind = .@"error" },
657 .{ .msg = "multi-character character constant", .opt = W("multichar"), .kind = .warning, .all = true },
658 .{ .msg = "{s} character literals may not contain multiple characters", .kind = .@"error", .extra = .str },
659 .{ .msg = "extraneous characters in character constant ignored", .kind = .warning },
660 .{ .msg = "character constant too long for its type", .kind = .warning, .all = true },
661 .{ .msg = "character too large for enclosing character literal type", .kind = .@"error" },
662 .{ .msg = "must use 'struct' tag to refer to type '{s}'", .extra = .str, .kind = .@"error" },
663 .{ .msg = "must use 'union' tag to refer to type '{s}'", .extra = .str, .kind = .@"error" },
664 .{ .msg = "must use 'enum' tag to refer to type '{s}'", .extra = .str, .kind = .@"error" },
665 .{ .msg = "redefinition of '{s}' as different kind of symbol", .extra = .str, .kind = .@"error" },
666 .{ .msg = "redefinition of '{s}' with a different type", .extra = .str, .kind = .@"error" },
667 .{ .msg = "redefinition of parameter '{s}'", .extra = .str, .kind = .@"error" },
668 .{ .msg = "invalid operands to binary expression ({s})", .extra = .str, .kind = .@"error" },
669 .{ .msg = "comparison between pointer and integer ({s})", .extra = .str, .opt = W("pointer-integer-compare"), .kind = .warning },
670 .{ .msg = "comparison of distinct pointer types ({s})", .extra = .str, .opt = W("compare-distinct-pointer-types"), .kind = .warning },
671 .{ .msg = "incompatible pointer types ({s})", .extra = .str, .kind = .@"error" },
672 .{ .msg = "invalid argument type '{s}' to unary expression", .extra = .str, .kind = .@"error" },
673 .{ .msg = "assignment to {s}", .extra = .str, .kind = .@"error" },
674 .{ .msg = "implicit pointer to integer conversion from {s}", .extra = .str, .opt = W("int-conversion"), .kind = .warning },
675 .{ .msg = "pointer cannot be cast to type '{s}'", .extra = .str, .kind = .@"error" },
676 .{ .msg = "operand of type '{s}' cannot be cast to a pointer type", .extra = .str, .kind = .@"error" },
677 .{ .msg = "cannot cast to non arithmetic or pointer type '{s}'", .extra = .str, .kind = .@"error" },
678 .{ .msg = "cast to type '{s}' will not preserve qualifiers", .extra = .str, .opt = W("cast-qualifiers"), .kind = .warning },
679 .{ .msg = "array subscript is not an integer", .kind = .@"error" },
680 .{ .msg = "subscripted value is not an array or pointer", .kind = .@"error" },
681 .{ .msg = "array index {s} is past the end of the array", .extra = .str, .opt = W("array-bounds"), .kind = .warning },
682 .{ .msg = "array index {s} is before the beginning of the array", .extra = .str, .opt = W("array-bounds"), .kind = .warning },
683 .{ .msg = "statement requires expression with integer type ('{s}' invalid)", .extra = .str, .kind = .@"error" },
684 .{ .msg = "statement requires expression with scalar type ('{s}' invalid)", .extra = .str, .kind = .@"error" },
685 .{ .msg = "non-void function '{s}' should return a value", .extra = .str, .opt = W("return-type"), .kind = .@"error", .all = true },
686 .{ .msg = "returning {s}", .extra = .str, .kind = .@"error" },
687 .{ .msg = "returning {s}" ++ pointer_sign_message, .extra = .str, .kind = .warning, .opt = W("pointer-sign") },
688 .{ .msg = "implicit integer to pointer conversion from {s}", .extra = .str, .opt = W("int-conversion"), .kind = .warning },
689 .{ .msg = "non-void function '{s}' does not return a value", .extra = .str, .opt = W("return-type"), .kind = .warning, .all = true },
690 .{ .msg = "void function '{s}' should not return a value", .extra = .str, .opt = W("return-type"), .kind = .@"error", .all = true },
691 .{ .msg = "passing {s}", .extra = .str, .kind = .@"error" },
692 .{ .msg = "passing {s}", .extra = .str, .kind = .warning, .opt = W("incompatible-pointer-types") },
693 .{ .msg = "passing {s}" ++ pointer_sign_message, .extra = .str, .kind = .warning, .opt = W("pointer-sign") },
694 .{ .msg = "passing argument to parameter here", .kind = .note },
695 .{ .msg = "atomic cannot be applied to array type '{s}'", .extra = .str, .kind = .@"error" },
696 .{ .msg = "atomic cannot be applied to function type '{s}'", .extra = .str, .kind = .@"error" },
697 .{ .msg = "atomic cannot be applied to incomplete type '{s}'", .extra = .str, .kind = .@"error" },
698 .{ .msg = "address of register variable requested", .kind = .@"error" },
699 .{ .msg = "variable has incomplete type '{s}'", .extra = .str, .kind = .@"error" },
700 .{ .msg = "parameter has incomplete type '{s}'", .extra = .str, .kind = .@"error" },
701 .{ .msg = "tentative array definition assumed to have one element", .kind = .warning },
702 .{ .msg = "dereferencing pointer to incomplete type '{s}'", .extra = .str, .kind = .@"error" },
703 .{ .msg = "'_Alignas' attribute only applies to variables and fields", .kind = .@"error" },
704 .{ .msg = "'_Alignas' attribute cannot be applied to a function parameter", .kind = .@"error" },
705 .{ .msg = "requested alignment is less than minimum alignment of {d}", .extra = .unsigned, .kind = .@"error" },
706 .{ .msg = "requested alignment of {s} is too large", .extra = .str, .kind = .@"error" },
707 .{ .msg = "requested negative alignment of {s} is invalid", .extra = .str, .kind = .@"error" },
708 .{ .msg = "'_Alignas' attribute is ignored here", .kind = .warning },
709 .{ .msg = "requested alignment of zero is ignored", .kind = .warning },
710 .{ .msg = "requested alignment is not a power of 2", .kind = .@"error" },
711 .{ .msg = "pointer type mismatch ({s})", .extra = .str, .opt = W("pointer-type-mismatch"), .kind = .warning },
712 .{ .msg = "static_assert expression is not an integral constant expression", .kind = .@"error" },
713 .{ .msg = "static_assert with no message is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 },
714 .{ .msg = "{s} is incompatible with C standards before C23", .extra = .str, .kind = .off, .suppress_unless_version = .c23, .opt = W("pre-c23-compat") },
715 .{ .msg = "variable length array must be bound in function definition", .kind = .@"error" },
716 .{ .msg = "array is too large", .kind = .@"error" },
717 .{ .msg = "incompatible pointer types initializing {s}", .extra = .str, .opt = W("incompatible-pointer-types"), .kind = .warning },
718 .{ .msg = "incompatible pointer types initializing {s}" ++ pointer_sign_message, .extra = .str, .opt = W("pointer-sign"), .kind = .warning },
719 .{ .msg = "incompatible pointer types assigning to {s}", .extra = .str, .opt = W("incompatible-pointer-types"), .kind = .warning },
720 .{ .msg = "incompatible pointer types assigning to {s} " ++ pointer_sign_message, .extra = .str, .opt = W("pointer-sign"), .kind = .warning },
721 .{ .msg = "variable-sized object may not be initialized", .kind = .@"error" },
722 .{ .msg = "illegal initializer type", .kind = .@"error" },
723 .{ .msg = "initializing {s}", .extra = .str, .kind = .@"error" },
724 .{ .msg = "scalar initializer cannot be empty", .kind = .@"error" },
725 .{ .msg = "excess elements in scalar initializer", .opt = W("excess-initializers"), .kind = .warning },
726 .{ .msg = "excess elements in string initializer", .opt = W("excess-initializers"), .kind = .warning },
727 .{ .msg = "excess elements in struct initializer", .opt = W("excess-initializers"), .kind = .warning },
728 .{ .msg = "excess elements in array initializer", .opt = W("excess-initializers"), .kind = .warning },
729 .{ .msg = "initializer-string for char array is too long", .opt = W("excess-initializers"), .kind = .warning },
730 .{ .msg = "cannot initialize type ({s})", .extra = .str, .kind = .@"error" },
731 .{ .msg = "'{s} typeof' is invalid", .extra = .str, .kind = .@"error" },
732 .{ .msg = "{s} by zero is undefined", .extra = .str, .opt = W("division-by-zero"), .kind = .warning },
733 .{ .msg = "{s} by zero in preprocessor expression", .extra = .str, .kind = .@"error" },
734 .{ .msg = "'__builtin_choose_expr' requires a constant expression", .kind = .@"error" },
735 .{ .msg = "'_Alignas' attribute requires integer constant expression", .kind = .@"error" },
736 .{ .msg = "case value must be an integer constant expression", .kind = .@"error" },
737 .{ .msg = "enum value must be an integer constant expression", .kind = .@"error" },
738 .{ .msg = "cannot initialize array of type {s}", .extra = .str, .kind = .@"error" },
739 .{ .msg = "array initializer must be an initializer list or wide string literal", .kind = .@"error" },
740 .{ .msg = "initializer overrides previous initialization", .opt = W("initializer-overrides"), .kind = .warning, .w_extra = true },
741 .{ .msg = "previous initialization", .kind = .note },
742 .{ .msg = "array designator used for non-array type '{s}'", .extra = .str, .kind = .@"error" },
743 .{ .msg = "array designator value {s} is negative", .extra = .str, .kind = .@"error" },
744 .{ .msg = "array designator index {s} exceeds array bounds", .extra = .str, .kind = .@"error" },
745 .{ .msg = "field designator used for non-record type '{s}'", .extra = .str, .kind = .@"error" },
746 .{ .msg = "record type has no field named '{s}'", .extra = .str, .kind = .@"error" },
747 .{ .msg = "initializer for aggregate with no elements requires explicit braces", .kind = .@"error" },
748 .{ .msg = "initializing {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning },
749 .{ .msg = "assigning to {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning },
750 .{ .msg = "returning {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning },
751 .{ .msg = "passing {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning },
752 .{ .msg = "unknown attribute '{s}' ignored", .extra = .str, .opt = W("unknown-attributes"), .kind = .warning },
753 .{ .msg = "{s}", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning },
754 .{ .msg = "fallthrough annotation does not directly precede switch label", .kind = .@"error" },
755 .{ .msg = "'{s}' attribute cannot be applied to a statement", .extra = .str, .kind = .@"error" },
756 .{ .msg = "redefining builtin macro", .opt = W("builtin-macro-redefined"), .kind = .warning },
757 .{ .msg = "builtin feature check macro requires a parenthesized identifier", .kind = .@"error" },
758 .{ .msg = "missing '{s}', after builtin feature-check macro", .extra = .tok_id_expected, .kind = .@"error" },
759 .{ .msg = "use of GNU address-of-label extension", .opt = W("gnu-label-as-value"), .kind = .off, .pedantic = true },
760 .{ .msg = "member reference base type '{s}' is not a structure or union", .extra = .str, .kind = .@"error" },
761 .{ .msg = "member reference type '{s}' is not a pointer; did you mean to use '.'?", .extra = .str, .kind = .@"error" },
762 .{ .msg = "member reference type '{s}' is a pointer; did you mean to use '->'?", .extra = .str, .kind = .@"error" },
763 .{ .msg = "no member named {s}", .extra = .str, .kind = .@"error" },
764 .{ .msg = "{s} expected option name (e.g. \"-Wundef\")", .extra = .str, .opt = W("malformed-warning-check"), .kind = .warning, .all = true },
765 .{ .msg = "computed goto in function with no address-of-label expressions", .kind = .@"error" },
766 .{ .msg = "{s}", .extra = .str, .opt = W("#pragma-messages"), .kind = .warning },
767 .{ .msg = "{s}", .extra = .str, .kind = .@"error" },
768 .{ .msg = "#pragma message: {s}", .extra = .str, .kind = .note },
769 .{ .msg = "pragma {s} requires string literal", .extra = .str, .kind = .@"error" },
770 .{ .msg = "attempt to use a poisoned identifier", .kind = .@"error" },
771 .{ .msg = "can only poison identifier tokens", .kind = .@"error" },
772 .{ .msg = "poisoning existing macro", .kind = .warning },
773 .{ .msg = "no newline at end of file", .opt = W("newline-eof"), .kind = .off, .pedantic = true },
774 .{ .msg = "ISO C requires a translation unit to contain at least one declaration", .opt = W("empty-translation-unit"), .kind = .off, .pedantic = true },
775 .{ .msg = "omitting the parameter name in a function definition is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 },
776 .{ .msg = "bit-field has non-integer type '{s}'", .extra = .str, .kind = .@"error" },
777 .{ .msg = "bit-field has negative width ({s})", .extra = .str, .kind = .@"error" },
778 .{ .msg = "named bit-field has zero width", .kind = .@"error" },
779 .{ .msg = "width of bit-field exceeds width of its type", .kind = .@"error" },
780 .{ .msg = "source file is not valid UTF-8", .kind = .@"error" },
781 .{ .msg = "integer literal is too large to be represented in a signed integer type, interpreting as unsigned", .opt = W("implicitly-unsigned-literal"), .kind = .warning },
782 .{ .msg = "token is not a valid binary operator in a preprocessor subexpression", .kind = .@"error" },
783 .{ .msg = "invalid token at start of a preprocessor expression", .kind = .@"error" },
784 .{ .msg = "using this character in an identifier is incompatible with C99", .opt = W("c99-compat"), .kind = .off },
785 .{ .msg = "unexpected character <U+{X:0>4}>", .extra = .actual_codepoint, .kind = .@"error" },
786 .{ .msg = "character <U+{X:0>4}> not allowed at the start of an identifier", .extra = .actual_codepoint, .kind = .@"error" },
787 .{ .msg = "identifier contains Unicode character <U+{X:0>4}> that is invisible in some environments", .opt = W("unicode-homoglyph"), .extra = .actual_codepoint, .kind = .warning },
788 .{ .msg = "treating Unicode character <U+{X:0>4}> as identifier character rather than as '{u}' symbol", .extra = .codepoints, .opt = W("unicode-homoglyph"), .kind = .warning },
789 .{ .msg = "meaningless '{s}' on assembly outside function", .extra = .str, .kind = .@"error" },
790 .{ .msg = "duplicate asm qualifier '{s}'", .extra = .str, .kind = .@"error" },
791 .{ .msg = "cannot use {s} string literal in assembly", .extra = .str, .kind = .@"error" },
792 .{ .msg = "'$' in identifier", .opt = W("dollar-in-identifier-extension"), .kind = .off, .pedantic = true },
793 .{ .msg = "illegal character '$' in identifier", .kind = .@"error" },
794 .{ .msg = "expanded from here", .kind = .note },
795 .{ .msg = "(skipping {d} expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)", .extra = .unsigned, .kind = .note },
796 .{ .msg = "_Pragma requires exactly one string literal token", .kind = .@"error" },
797 .{ .msg = "pragma GCC expected 'error', 'warning', 'diagnostic', 'poison'", .opt = W("unknown-pragmas"), .kind = .off, .all = true },
798 .{ .msg = "pragma GCC diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'", .opt = W("unknown-pragmas"), .kind = .warning, .all = true },
799 .{ .msg = "predefined identifier is only valid inside function", .opt = W("predefined-identifier-outside-function"), .kind = .warning },
800 .{ .msg = "first argument to va_arg, is of type '{s}' and not 'va_list'", .extra = .str, .kind = .@"error" },
801 .{ .msg = "too many braces around scalar initializer", .opt = W("many-braces-around-scalar-init"), .kind = .warning },
802 .{ .msg = "variable '{s}' is uninitialized when used within its own initialization", .extra = .str, .opt = W("uninitialized"), .kind = .off, .all = true },
803 .{ .msg = "use of GNU statement expression extension", .opt = W("gnu-statement-expression"), .kind = .off, .suppress_gnu = true, .pedantic = true },
804 .{ .msg = "statement expression not allowed at file scope", .kind = .@"error" },
805 .{ .msg = "imaginary constants are a GNU extension", .opt = W("gnu-imaginary-constant"), .kind = .off, .suppress_gnu = true, .pedantic = true },
806 .{ .msg = "plain '_Complex' requires a type specifier; assuming '_Complex double'", .kind = .warning },
807 .{ .msg = "complex integer types are a GNU extension", .opt = W("gnu-complex-integer"), .suppress_gnu = true, .kind = .off },
808 .{ .msg = "'{s}' type qualifier on return type has no effect", .opt = W("ignored-qualifiers"), .extra = .str, .kind = .off, .all = true },
809 .{ .msg = "invalid standard '{s}'", .extra = .str, .kind = .@"error" },
810 .{ .msg = "invalid target '{s}'", .extra = .str, .kind = .@"error" },
811 .{ .msg = "invalid compiler '{s}'", .extra = .str, .kind = .@"error" },
812 .{ .msg = "unknown argument '{s}'", .extra = .str, .kind = .@"error" },
813 .{ .msg = "{s}", .extra = .str, .kind = .@"error" },
814 .{ .msg = "{s}: linker input file unused because linking not done", .extra = .str, .kind = .warning },
815 .{ .msg = "unrecognized linker '{s}'", .extra = .str, .kind = .@"error" },
816 .{ .msg = "extra ';' outside of a function", .opt = W("extra-semi"), .kind = .off, .pedantic = true },
817 .{ .msg = "field declared as a function", .kind = .@"error" },
818 .{ .msg = "variable length array fields extension is not supported", .kind = .@"error" },
819 .{ .msg = "field has incomplete type '{s}'", .extra = .str, .kind = .@"error" },
820 .{ .msg = "flexible array member in union is not allowed", .kind = .@"error", .suppress_msvc = true },
821 .{ .msg = "flexible array member is not at the end of struct", .kind = .@"error" },
822 .{ .msg = "flexible array member in otherwise empty struct", .kind = .@"error", .suppress_msvc = true },
823 .{ .msg = "duplicate member '{s}'", .extra = .str, .kind = .@"error" },
824 .{ .msg = "binary integer literals are a GNU extension", .kind = .off, .opt = W("gnu-binary-literal"), .pedantic = true },
825 .{ .msg = "named variadic macros are a GNU extension", .opt = W("variadic-macros"), .kind = .off, .pedantic = true },
826 .{ .msg = "builtin function must be directly called", .kind = .@"error" },
827 .{ .msg = "'va_start' cannot be used outside a function", .kind = .@"error" },
828 .{ .msg = "'va_start' used in a function with fixed args", .kind = .@"error" },
829 .{ .msg = "second argument to 'va_start' is not the last named parameter", .opt = W("varargs"), .kind = .warning },
830 .{ .msg = "'{s}' attribute takes at least {d} argument(s)", .kind = .@"error", .extra = .attr_arg_count },
831 .{ .msg = "'{s}' attribute takes at most {d} argument(s)", .kind = .@"error", .extra = .attr_arg_count },
832 .{ .msg = "Attribute argument is invalid, expected {s} but got {s}", .kind = .@"error", .extra = .attr_arg_type },
833 .{ .msg = "Unknown `{s}` argument. Possible values are: {s}", .kind = .@"error", .extra = .attr_enum },
834 .{ .msg = "'{s}' attribute requires an identifier", .kind = .@"error", .extra = .str },
835 .{ .msg = "'__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes", .kind = .@"error" },
836 .{ .msg = "__declspec attribute '{s}' is not supported", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning },
837 .{ .msg = "{s}", .extra = .str, .opt = W("deprecated-declarations"), .kind = .warning },
838 .{ .msg = "'{s}' has been explicitly marked deprecated here", .extra = .str, .opt = W("deprecated-declarations"), .kind = .note },
839 .{ .msg = "{s}", .extra = .str, .kind = .@"error" },
840 .{ .msg = "'{s}' has been explicitly marked unavailable here", .extra = .str, .kind = .note },
841 .{ .msg = "{s}", .extra = .str, .kind = .warning, .opt = W("attribute-warning") },
842 .{ .msg = "{s}", .extra = .str, .kind = .@"error" },
843 .{ .msg = "attribute '{s}' is ignored, place it after \"{s}\" to apply attribute to type declaration", .extra = .ignored_record_attr, .kind = .warning, .opt = W("ignored-attributes") },
844 .{ .msg = "backslash and newline separated by space", .kind = .warning, .opt = W("backslash-newline-escape") },
845 .{ .msg = "size of array has non-integer type '{s}'", .extra = .str, .kind = .@"error" },
846 .{ .msg = "cast to smaller integer type {s}", .extra = .str, .kind = .warning, .opt = W("pointer-to-int-cast") },
847 .{ .msg = "use of GNU case range extension", .opt = W("gnu-case-range"), .kind = .off, .pedantic = true },
848 .{ .msg = "empty case range specified", .kind = .warning },
849 .{ .msg = "use of non-standard escape character '\\{s}'", .kind = .off, .opt = W("pedantic"), .extra = .invalid_escape },
850 .{ .msg = "invalid string literal, ignoring final '\\'", .kind = .warning },
851 .{ .msg = "variable length array used", .kind = .off, .opt = W("vla") },
852 .{ .msg = "implicit conversion of non-finite value from {s} is undefined", .extra = .str, .kind = .off, .opt = W("float-overflow-conversion") },
853 .{ .msg = "implicit conversion of out of range value from {s} is undefined", .extra = .str, .kind = .warning, .opt = W("literal-conversion") },
854 .{ .msg = "implicit conversion from {s}", .extra = .str, .kind = .off, .opt = W("float-zero-conversion") },
855 .{ .msg = "implicit conversion from {s}", .extra = .str, .kind = .warning, .opt = W("float-conversion") },
856 .{ .msg = "implicit conversion turns floating-point number into integer: {s}", .extra = .str, .kind = .off, .opt = W("literal-conversion") },
857 .{ .msg = "expression is not an integer constant expression; folding it to a constant is a GNU extension", .kind = .off, .opt = W("gnu-folding-constant"), .pedantic = true },
858 .{ .msg = "variable length array folded to constant array as an extension", .kind = .off, .opt = W("gnu-folding-constant"), .pedantic = true },
859 .{ .msg = "typedef redefinition with different types ({s})", .extra = .str, .kind = .@"error" },
860 .{ .msg = "'{s}' is not defined, evaluates to 0", .extra = .str, .kind = .off, .opt = W("undef") },
861 .{ .msg = "function-like macro '{s}' is not defined", .extra = .str, .kind = .@"error" },
862 .{ .msg = "'{s}' must be used within a preprocessing directive", .extra = .tok_id_expected, .kind = .@"error" },
863 .{ .msg = "Missing '(' after built-in macro '{s}'", .extra = .str, .kind = .@"error" },
864 .{ .msg = "offsetof requires struct or union type, '{s}' invalid", .extra = .str, .kind = .@"error" },
865 .{ .msg = "offsetof of incomplete type '{s}'", .extra = .str, .kind = .@"error" },
866 .{ .msg = "offsetof requires array type, '{s}' invalid", .extra = .str, .kind = .@"error" },
867 .{ .msg = "missing '(' after '#pragma pack' - ignoring", .kind = .warning, .opt = W("ignored-pragmas") },
868 .{ .msg = "missing ')' after '#pragma pack' - ignoring", .kind = .warning, .opt = W("ignored-pragmas") },
869 .{ .msg = "unknown action for '#pragma pack' - ignoring", .opt = W("ignored-pragmas"), .kind = .warning },
870 .{ .msg = "value of #pragma pack(show) == {d}", .extra = .unsigned, .kind = .warning },
871 .{ .msg = "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'", .opt = W("ignored-pragmas"), .kind = .warning },
872 .{ .msg = "expected integer or identifier in '#pragma pack' - ignored", .opt = W("ignored-pragmas"), .kind = .warning },
873 .{ .msg = "specifying both a name and alignment to 'pop' is undefined", .kind = .warning },
874 .{ .msg = "#pragma pack(pop, ...) failed: stack empty", .opt = W("ignored-pragmas"), .kind = .warning },
875 .{ .msg = "used type '{s}' where arithmetic or pointer type is required", .extra = .str, .kind = .@"error" },
876 .{ .msg = "#include nested too deeply", .kind = .@"error" },
877 .{ .msg = "ISO C restricts enumerator values to range of 'int' ({s} is too small)", .extra = .str, .kind = .off, .opt = W("pedantic") },
878 .{ .msg = "ISO C restricts enumerator values to range of 'int' ({s} is too large)", .extra = .str, .kind = .off, .opt = W("pedantic") },
879 .{ .msg = "#include_next is a language extension", .kind = .off, .pedantic = true, .opt = W("gnu-include-next") },
880 .{ .msg = "#include_next in primary source file; will search from start of include path", .kind = .warning, .opt = W("include-next-outside-header") },
881 .{ .msg = "overflow in enumeration value", .kind = .warning },
882 .{ .msg = "incremented enumerator value {s} is not representable in the largest integer type", .kind = .warning, .opt = W("enum-too-large"), .extra = .pow_2_as_string },
883 .{ .msg = "enumeration values exceed range of largest integer", .kind = .warning, .opt = W("enum-too-large") },
884 .{ .msg = "enumeration types with a fixed underlying type are a Clang extension", .kind = .off, .pedantic = true, .opt = W("fixed-enum-extension") },
885 .{ .msg = "enumeration previously declared with nonfixed underlying type", .kind = .@"error" },
886 .{ .msg = "enumeration previously declared with fixed underlying type", .kind = .@"error" },
887 .{ .msg = "enumeration redeclared with different underlying type {s})", .extra = .str, .kind = .@"error" },
888 .{ .msg = "enumerator value is not representable in the underlying type '{s}'", .extra = .str, .kind = .@"error" },
889 .{ .msg = "'transparent_union' attribute only applies to unions", .opt = W("ignored-attributes"), .kind = .warning },
890 .{ .msg = "transparent union definition must contain at least one field; transparent_union attribute ignored", .opt = W("ignored-attributes"), .kind = .warning },
891 .{ .msg = "size of field {s} bits) does not match the size of the first field in transparent union; transparent_union attribute ignored", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning },
892 .{ .msg = "size of first field is {d}", .extra = .unsigned, .kind = .note },
893 .{ .msg = "'designated_init' attribute is only valid on 'struct' type'", .kind = .@"error" },
894 .{ .msg = "positional initialization of field in 'struct' declared with 'designated_init' attribute", .opt = W("designated-init"), .kind = .warning },
895 .{ .msg = "ignoring attribute 'common' because it conflicts with attribute 'nocommon'", .opt = W("ignored-attributes"), .kind = .warning },
896 .{ .msg = "ignoring attribute 'nocommon' because it conflicts with attribute 'common'", .opt = W("ignored-attributes"), .kind = .warning },
897 .{ .msg = "'nonstring' attribute ignored on objects of type '{s}'", .opt = W("ignored-attributes"), .kind = .warning },
898 .{ .msg = "'{s}' attribute only applies to local variables", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning },
899 .{ .msg = "ignoring attribute 'cold' because it conflicts with attribute 'hot'", .opt = W("ignored-attributes"), .kind = .warning },
900 .{ .msg = "ignoring attribute 'hot' because it conflicts with attribute 'cold'", .opt = W("ignored-attributes"), .kind = .warning },
901 .{ .msg = "ignoring attribute 'noinline' because it conflicts with attribute 'always_inline'", .opt = W("ignored-attributes"), .kind = .warning },
902 .{ .msg = "ignoring attribute 'always_inline' because it conflicts with attribute 'noinline'", .opt = W("ignored-attributes"), .kind = .warning },
903 .{ .msg = "function '{s}' declared 'noreturn' should not return", .extra = .str, .kind = .warning, .opt = W("invalid-noreturn") },
904 .{ .msg = "ignoring return value of '{s}', declared with 'nodiscard' attribute", .extra = .str, .kind = .warning, .opt = W("unused-result") },
905 .{ .msg = "ignoring return value of '{s}', declared with 'warn_unused_result' attribute", .extra = .str, .kind = .warning, .opt = W("unused-result") },
906 .{ .msg = "invalid vector element type '{s}'", .extra = .str, .kind = .@"error" },
907 .{ .msg = "vector size not an integral multiple of component size", .kind = .@"error" },
908 .{ .msg = "invalid type '{s}' to __imag operator", .extra = .str, .kind = .@"error" },
909 .{ .msg = "invalid type '{s}' to __real operator", .extra = .str, .kind = .@"error" },
910 .{ .msg = "zero size arrays are an extension", .kind = .off, .pedantic = true, .opt = W("zero-length-array") },
911 .{ .msg = "array index {s} is past the end of the array", .extra = .str, .kind = .off, .pedantic = true, .opt = W("old-style-flexible-struct") },
912 .{ .msg = "token pasting of ',' and __VA_ARGS__ is a GNU extension", .kind = .off, .pedantic = true, .opt = W("gnu-zero-variadic-macro-arguments"), .suppress_gcc = true },
913 .{ .msg = "return type of 'main' is not 'int'", .kind = .warning, .opt = W("main-return-type") },
914 .{ .msg = "macro expansion producing 'defined' has undefined behavior", .kind = .off, .pedantic = true, .opt = W("expansion-to-defined") },
915 .{ .msg = "invalid suffix '{s}' on integer constant", .extra = .str, .kind = .@"error" },
916 .{ .msg = "invalid suffix '{s}' on floating constant", .extra = .str, .kind = .@"error" },
917 .{ .msg = "invalid digit '{c}' in octal constant", .extra = .ascii, .kind = .@"error" },
918 .{ .msg = "invalid digit '{c}' in binary constant", .extra = .ascii, .kind = .@"error" },
919 .{ .msg = "exponent has no digits", .kind = .@"error" },
920 .{ .msg = "hexadecimal floating constant requires an exponent", .kind = .@"error" },
921 .{ .msg = "sizeof returns 0", .kind = .warning, .suppress_gcc = true, .suppress_clang = true },
922 .{ .msg = "'declspec' attribute not allowed after declarator", .kind = .@"error" },
923 .{ .msg = "this declarator", .kind = .note },
924 .{ .msg = "{s} is not supported on this target", .extra = .str, .kind = .@"error" },
925 .{ .msg = "'_BitInt' in C17 and earlier is a Clang extension'", .kind = .off, .pedantic = true, .opt = W("bit-int-extension"), .suppress_version = .c23 },
926 .{ .msg = "{s} must have a bit size of at least 1", .extra = .str, .kind = .@"error" },
927 .{ .msg = "{s} must have a bit size of at least 2", .extra = .str, .kind = .@"error" },
928 .{ .msg = "{s} of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Properties.max_bits}) ++ " not supported", .extra = .str, .kind = .@"error" },
929 .{ .msg = "keyword is hidden by macro definition", .kind = .off, .pedantic = true, .opt = W("keyword-macro") },
930 .{ .msg = "arithmetic on a pointer to an incomplete type '{s}'", .extra = .str, .kind = .@"error" },
931 .{ .msg = "'{s}' calling convention is not supported for this target", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning },
932 .{ .msg = "invalid application of '{s}' to a void type", .extra = .str, .kind = .off, .pedantic = true, .opt = W("pointer-arith") },
933 .{ .msg = "sizeof on array function parameter will return size of {s}", .extra = .str, .kind = .warning, .opt = W("sizeof-array-argument") },
934 .{ .msg = "address of array '{s}' will always evaluate to 'true'", .extra = .str, .kind = .warning, .opt = W("pointer-bool-conversion") },
935 .{ .msg = "implicit conversion turns string literal into bool: {s}", .extra = .str, .kind = .off, .opt = W("string-conversion") },
936 .{ .msg = "this conversion is not allowed in a constant expression", .kind = .note },
937 .{ .msg = "cannot cast an object of type {s}", .extra = .str, .kind = .@"error" },
938 .{ .msg = "unsupported argument '{s}' to option '-ffp-eval-method='; expected 'source', 'double', or 'extended'", .extra = .str, .kind = .@"error" },
939 .{ .msg = "{s} cannot have __fp16 type; did you forget * ?", .extra = .str, .kind = .@"error" },
940 .{ .msg = "'_BitInt' suffix for literals is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 },
941 .{ .msg = "'__auto_type' is a GNU extension", .opt = W("gnu-auto-type"), .kind = .off, .pedantic = true },
942 .{ .msg = "'__auto_type' not allowed in {s}", .kind = .@"error", .extra = .str },
943 .{ .msg = "declaration of variable '{s}' with deduced type requires an initializer", .kind = .@"error", .extra = .str },
944 .{ .msg = "'__auto_type' may only be used with a single declarator", .kind = .@"error" },
945 .{ .msg = "'__auto_type' requires a plain identifier as declarator", .kind = .@"error" },
946 .{ .msg = "invalid cast to '__auto_type'", .kind = .@"error" },
947 .{ .msg = "cannot use bit-field as '__auto_type' initializer", .kind = .@"error" },
948 .{ .msg = "'{s}' declared as array of '__auto_type'", .kind = .@"error", .extra = .str },
949 .{ .msg = "cannot use '__auto_type' with initializer list", .kind = .@"error" },
950 .{ .msg = "expected ';' at end of declaration list", .kind = .warning },
951 .{ .msg = "tentative definition has type '{s}' that is never completed", .kind = .@"error", .extra = .str },
952 .{ .msg = "forward declaration of '{s}'", .kind = .note, .extra = .str },
953 .{ .msg = "cast to union type is a GNU extension", .opt = W("gnu-union-cast"), .kind = .off, .pedantic = true },
954 .{ .msg = "cast to union type from type '{s}' not present in union", .kind = .@"error", .extra = .str },
955 .{ .msg = "cast to incomplete type '{s}'", .kind = .@"error", .extra = .str },
956 .{ .msg = "environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799", .kind = .@"error" },
957 .{ .msg = "'-fuse-ld=' taking a path is deprecated; use '--ld-path=' instead", .kind = .off, .opt = W("fuse-ld-path") },
958 .{ .msg = "invalid runtime library name '{s}'", .kind = .@"error", .extra = .str },
959 .{ .msg = "unsupported runtime library 'libgcc' for platform '{s}'", .kind = .@"error", .extra = .str },
960 .{ .msg = "invalid unwind library name '{s}'", .kind = .@"error", .extra = .str },
961 .{ .msg = "--rtlib=libgcc requires --unwindlib=libgcc", .kind = .@"error" },
962 .{ .msg = "GNU-style inline assembly is disabled", .kind = .@"error" },
963 .{ .msg = "extension used", .kind = .off, .pedantic = true, .opt = W("language-extension-token") },
964 .{ .msg = "complex initialization specifying real and imaginary components is an extension", .opt = W("complex-component-init"), .kind = .off, .pedantic = true },
965 .{ .msg = "ISO C does not support '++'/'--' on complex type '{s}'", .opt = W("pedantic"), .extra = .str, .kind = .off },
966 .{ .msg = "argument type '{s}' is not a real floating point type", .extra = .str, .kind = .@"error" },
967 .{ .msg = "arguments are of different types ({s})", .extra = .str, .kind = .@"error" },
968 .{ .msg = "#include resolved using non-portable Microsoft search rules as: {s}", .extra = .str, .opt = W("microsoft-include"), .kind = .warning },
969 .{ .msg = "treating Ctrl-Z as end-of-file is a Microsoft extension", .opt = W("microsoft-end-of-file"), .kind = .off, .pedantic = true },
970 .{ .msg = "illegal character encoding in character literal", .opt = W("invalid-source-encoding"), .kind = .warning },
971 .{ .msg = "illegal character encoding in character literal", .kind = .@"error" },
972 .{ .msg = "character '{c}' cannot be specified by a universal character name", .kind = .@"error", .extra = .ascii },
973 .{ .msg = "specifying character '{c}' with a universal character name is incompatible with C standards before C23", .kind = .off, .extra = .ascii, .suppress_unless_version = .c23, .opt = W("pre-c23-compat") },
974 .{ .msg = "universal character name refers to a control character", .kind = .@"error" },
975 .{ .msg = "universal character name referring to a control character is incompatible with C standards before C23", .kind = .off, .suppress_unless_version = .c23, .opt = W("pre-c23-compat") },
976 .{ .msg = "universal character names are only valid in C99 or later", .suppress_version = .c99, .kind = .warning, .opt = W("unicode") },
977 .{ .msg = "multi-character character constant", .opt = W("four-char-constants"), .kind = .off },
978 .{ .msg = "multi-character character constant", .kind = .off },
979 .{ .msg = "\\{c} used with no following hex digits", .kind = .@"error", .extra = .ascii },
980 .{ .msg = "unknown escape sequence '\\{s}'", .kind = .warning, .opt = W("unknown-escape-sequence"), .extra = .invalid_escape },
981 .{ .msg = "attribute '{s}' requires an ordinary string", .kind = .@"error", .extra = .str },
982 .{ .msg = "missing terminating '\"' character", .kind = .warning, .opt = W("invalid-pp-token") },
983 .{ .msg = "missing terminating '\"' character", .kind = .@"error" },
984 .{ .msg = "empty character constant", .kind = .warning, .opt = W("invalid-pp-token") },
985 .{ .msg = "empty character constant", .kind = .@"error" },
986 .{ .msg = "missing terminating ' character", .kind = .warning, .opt = W("invalid-pp-token") },
987 .{ .msg = "missing terminating ' character", .kind = .@"error" },
988 .{ .msg = "unterminated comment", .kind = .@"error" },
989 .{ .msg = "a function definition without a prototype is deprecated in all versions of C and is not supported in C23", .kind = .warning, .opt = W("deprecated-non-prototype") },
990 .{ .msg = "passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23", .kind = .warning, .opt = W("deprecated-non-prototype") },
991 .{ .msg = "unknown type name '{s}'", .kind = .@"error", .extra = .str },
992 .{ .msg = "label at end of compound statement is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 },
993 .{ .msg = "UTF-8 character literal is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 },
994 .{ .msg = "unexpected token in embed parameter", .kind = .@"error" },
995 .{ .msg = "the limit parameter expects one non-negative integer as a parameter", .kind = .@"error" },
996 .{ .msg = "duplicate embed parameter '{s}'", .kind = .warning, .extra = .str, .opt = W("duplicate-embed-param") },
997 .{ .msg = "unsupported embed parameter '{s}' embed parameter", .kind = .warning, .extra = .str, .opt = W("unsupported-embed-param") },
998 .{ .msg = "compound literal cannot have {s} storage class", .kind = .@"error", .extra = .str },
999 .{ .msg = "missing '(' following __VA_OPT__", .kind = .@"error" },
1000 .{ .msg = "unterminated __VA_OPT__ argument list", .kind = .@"error" },
1001 .{ .msg = "attribute value '{s}' out of range", .kind = .@"error", .extra = .str },
1002 .{ .msg = "'{s}' is not in NFC", .kind = .warning, .extra = .normalized, .opt = W("normalized") },
1003 .{ .msg = "'auto' requires a plain identifier declarator", .kind = .@"error" },
1004 .{ .msg = "'auto' can only be used with a single declarator", .kind = .@"error" },
1005 .{ .msg = "'auto' requires an initializer", .kind = .@"error" },
1006 .{ .msg = "'auto' requires a scalar initializer", .kind = .@"error" },
1007 };
1008};
1009};
1010}
lib/compiler/aro/aro/Driver.zig created+811
......@@ -0,0 +1,811 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const process = std.process;
5const backend = @import("../backend.zig");
6const Ir = backend.Ir;
7const Object = backend.Object;
8const Compilation = @import("Compilation.zig");
9const Diagnostics = @import("Diagnostics.zig");
10const LangOpts = @import("LangOpts.zig");
11const Preprocessor = @import("Preprocessor.zig");
12const Source = @import("Source.zig");
13const Toolchain = @import("Toolchain.zig");
14const target_util = @import("target.zig");
15
16pub const Linker = enum {
17 ld,
18 bfd,
19 gold,
20 lld,
21 mold,
22};
23
24const Driver = @This();
25
26comp: *Compilation,
27inputs: std.ArrayListUnmanaged(Source) = .{},
28link_objects: std.ArrayListUnmanaged([]const u8) = .{},
29output_name: ?[]const u8 = null,
30sysroot: ?[]const u8 = null,
31system_defines: Compilation.SystemDefinesMode = .include_system_defines,
32temp_file_count: u32 = 0,
33/// If false, do not emit line directives in -E mode
34line_commands: bool = true,
35/// If true, use `#line <num>` instead of `# <num>` for line directives
36use_line_directives: bool = false,
37only_preprocess: bool = false,
38only_syntax: bool = false,
39only_compile: bool = false,
40only_preprocess_and_compile: bool = false,
41verbose_ast: bool = false,
42verbose_pp: bool = false,
43verbose_ir: bool = false,
44verbose_linker_args: bool = false,
45color: ?bool = null,
46
47/// Full path to the aro executable
48aro_name: []const u8 = "",
49
50/// Value of --triple= passed via CLI
51raw_target_triple: ?[]const u8 = null,
52
53// linker options
54use_linker: ?[]const u8 = null,
55linker_path: ?[]const u8 = null,
56nodefaultlibs: bool = false,
57nolibc: bool = false,
58nostartfiles: bool = false,
59nostdlib: bool = false,
60pie: ?bool = null,
61rdynamic: bool = false,
62relocatable: bool = false,
63rtlib: ?[]const u8 = null,
64shared: bool = false,
65shared_libgcc: bool = false,
66static: bool = false,
67static_libgcc: bool = false,
68static_pie: bool = false,
69strip: bool = false,
70unwindlib: ?[]const u8 = null,
71
72pub fn deinit(d: *Driver) void {
73 for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
74 std.fs.deleteFileAbsolute(obj) catch {};
75 d.comp.gpa.free(obj);
76 }
77 d.inputs.deinit(d.comp.gpa);
78 d.link_objects.deinit(d.comp.gpa);
79 d.* = undefined;
80}
81
82pub const usage =
83 \\Usage {s}: [options] file..
84 \\
85 \\General options:
86 \\ -h, --help Print this message.
87 \\ -v, --version Print aro version.
88 \\
89 \\Compile options:
90 \\ -c, --compile Only run preprocess, compile, and assemble steps
91 \\ -D <macro>=<value> Define <macro> to <value> (defaults to 1)
92 \\ -E Only run the preprocessor
93 \\ -fchar8_t Enable char8_t (enabled by default in C23 and later)
94 \\ -fno-char8_t Disable char8_t (disabled by default for pre-C23)
95 \\ -fcolor-diagnostics Enable colors in diagnostics
96 \\ -fno-color-diagnostics Disable colors in diagnostics
97 \\ -fdeclspec Enable support for __declspec attributes
98 \\ -fno-declspec Disable support for __declspec attributes
99 \\ -ffp-eval-method=[source|double|extended]
100 \\ Evaluation method to use for floating-point arithmetic
101 \\ -ffreestanding Compilation in a freestanding environment
102 \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled)
103 \\ -fno-gnu-inline-asm Disable GNU style inline asm
104 \\ -fhosted Compilation in a hosted environment
105 \\ -fms-extensions Enable support for Microsoft extensions
106 \\ -fno-ms-extensions Disable support for Microsoft extensions
107 \\ -fdollars-in-identifiers
108 \\ Allow '$' in identifiers
109 \\ -fno-dollars-in-identifiers
110 \\ Disallow '$' in identifiers
111 \\ -fmacro-backtrace-limit=<limit>
112 \\ Set limit on how many macro expansion traces are shown in errors (default 6)
113 \\ -fnative-half-type Use the native half type for __fp16 instead of promoting to float
114 \\ -fnative-half-arguments-and-returns
115 \\ Allow half-precision function arguments and return values
116 \\ -fshort-enums Use the narrowest possible integer type for enums
117 \\ -fno-short-enums Use "int" as the tag type for enums
118 \\ -fsigned-char "char" is signed
119 \\ -fno-signed-char "char" is unsigned
120 \\ -fsyntax-only Only run the preprocessor, parser, and semantic analysis stages
121 \\ -funsigned-char "char" is unsigned
122 \\ -fno-unsigned-char "char" is signed
123 \\ -fuse-line-directives Use `#line <num>` linemarkers in preprocessed output
124 \\ -fno-use-line-directives
125 \\ Use `# <num>` linemarkers in preprocessed output
126 \\ -I <dir> Add directory to include search path
127 \\ -isystem Add directory to SYSTEM include search path
128 \\ --emulate=[clang|gcc|msvc]
129 \\ Select which C compiler to emulate (default clang)
130 \\ -o <file> Write output to <file>
131 \\ -P, --no-line-commands Disable linemarker output in -E mode
132 \\ -pedantic Warn on language extensions
133 \\ --rtlib=<arg> Compiler runtime library to use (libgcc or compiler-rt)
134 \\ -std=<standard> Specify language standard
135 \\ -S, --assemble Only run preprocess and compilation steps
136 \\ --sysroot=<dir> Use dir as the logical root directory for headers and libraries (not fully implemented)
137 \\ --target=<value> Generate code for the given target
138 \\ -U <macro> Undefine <macro>
139 \\ -undef Do not predefine any system-specific macros. Standard predefined macros remain defined.
140 \\ -Werror Treat all warnings as errors
141 \\ -Werror=<warning> Treat warning as error
142 \\ -W<warning> Enable the specified warning
143 \\ -Wno-<warning> Disable the specified warning
144 \\
145 \\Link options:
146 \\ -fuse-ld=[bfd|gold|lld|mold]
147 \\ Use specific linker
148 \\ -nodefaultlibs Do not use the standard system libraries when linking.
149 \\ -nolibc Do not use the C library or system libraries tightly coupled with it when linking.
150 \\ -nostdlib Do not use the standard system startup files or libraries when linking
151 \\ -nostartfiles Do not use the standard system startup files when linking.
152 \\ -pie Produce a dynamically linked position independent executable on targets that support it.
153 \\ --ld-path=<path> Use linker specified by <path>
154 \\ -r Produce a relocatable object as output.
155 \\ -rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it.
156 \\ -s Remove all symbol table and relocation information from the executable.
157 \\ -shared Produce a shared object which can then be linked with other objects to form an executable.
158 \\ -shared-libgcc On systems that provide libgcc as a shared library, force the use of the shared version
159 \\ -static On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries.
160 \\ -static-libgcc On systems that provide libgcc as a shared library, force the use of the static version
161 \\ -static-pie Produce a static position independent executable on targets that support it.
162 \\ --unwindlib=<arg> Unwind library to use ("none", "libgcc", or "libunwind") If not specified, will match runtime library
163 \\
164 \\Debug options:
165 \\ --verbose-ast Dump produced AST to stdout
166 \\ --verbose-pp Dump preprocessor state
167 \\ --verbose-ir Dump ir to stdout
168 \\ --verbose-linker-args Dump linker args to stdout
169 \\
170 \\
171;
172
173/// Process command line arguments, returns true if something was written to std_out.
174pub fn parseArgs(
175 d: *Driver,
176 std_out: anytype,
177 macro_buf: anytype,
178 args: []const []const u8,
179) !bool {
180 var i: usize = 1;
181 var comment_arg: []const u8 = "";
182 var hosted: ?bool = null;
183 while (i < args.len) : (i += 1) {
184 const arg = args[i];
185 if (mem.startsWith(u8, arg, "-") and arg.len > 1) {
186 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
187 std_out.print(usage, .{args[0]}) catch |er| {
188 return d.fatal("unable to print usage: {s}", .{errorDescription(er)});
189 };
190 return true;
191 } else if (mem.eql(u8, arg, "-v") or mem.eql(u8, arg, "--version")) {
192 std_out.writeAll(@import("../backend.zig").version_str ++ "\n") catch |er| {
193 return d.fatal("unable to print version: {s}", .{errorDescription(er)});
194 };
195 return true;
196 } else if (mem.startsWith(u8, arg, "-D")) {
197 var macro = arg["-D".len..];
198 if (macro.len == 0) {
199 i += 1;
200 if (i >= args.len) {
201 try d.err("expected argument after -I");
202 continue;
203 }
204 macro = args[i];
205 }
206 var value: []const u8 = "1";
207 if (mem.indexOfScalar(u8, macro, '=')) |some| {
208 value = macro[some + 1 ..];
209 macro = macro[0..some];
210 }
211 try macro_buf.print("#define {s} {s}\n", .{ macro, value });
212 } else if (mem.startsWith(u8, arg, "-U")) {
213 var macro = arg["-U".len..];
214 if (macro.len == 0) {
215 i += 1;
216 if (i >= args.len) {
217 try d.err("expected argument after -I");
218 continue;
219 }
220 macro = args[i];
221 }
222 try macro_buf.print("#undef {s}\n", .{macro});
223 } else if (mem.eql(u8, arg, "-undef")) {
224 d.system_defines = .no_system_defines;
225 } else if (mem.eql(u8, arg, "-c") or mem.eql(u8, arg, "--compile")) {
226 d.only_compile = true;
227 } else if (mem.eql(u8, arg, "-E")) {
228 d.only_preprocess = true;
229 } else if (mem.eql(u8, arg, "-P") or mem.eql(u8, arg, "--no-line-commands")) {
230 d.line_commands = false;
231 } else if (mem.eql(u8, arg, "-fuse-line-directives")) {
232 d.use_line_directives = true;
233 } else if (mem.eql(u8, arg, "-fno-use-line-directives")) {
234 d.use_line_directives = false;
235 } else if (mem.eql(u8, arg, "-fchar8_t")) {
236 d.comp.langopts.has_char8_t_override = true;
237 } else if (mem.eql(u8, arg, "-fno-char8_t")) {
238 d.comp.langopts.has_char8_t_override = false;
239 } else if (mem.eql(u8, arg, "-fcolor-diagnostics")) {
240 d.color = true;
241 } else if (mem.eql(u8, arg, "-fno-color-diagnostics")) {
242 d.color = false;
243 } else if (mem.eql(u8, arg, "-fdollars-in-identifiers")) {
244 d.comp.langopts.dollars_in_identifiers = true;
245 } else if (mem.eql(u8, arg, "-fno-dollars-in-identifiers")) {
246 d.comp.langopts.dollars_in_identifiers = false;
247 } else if (mem.eql(u8, arg, "-fdigraphs")) {
248 d.comp.langopts.digraphs = true;
249 } else if (mem.eql(u8, arg, "-fgnu-inline-asm")) {
250 d.comp.langopts.gnu_asm = true;
251 } else if (mem.eql(u8, arg, "-fno-gnu-inline-asm")) {
252 d.comp.langopts.gnu_asm = false;
253 } else if (mem.eql(u8, arg, "-fno-digraphs")) {
254 d.comp.langopts.digraphs = false;
255 } else if (option(arg, "-fmacro-backtrace-limit=")) |limit_str| {
256 var limit = std.fmt.parseInt(u32, limit_str, 10) catch {
257 try d.err("-fmacro-backtrace-limit takes a number argument");
258 continue;
259 };
260
261 if (limit == 0) limit = std.math.maxInt(u32);
262 d.comp.diagnostics.macro_backtrace_limit = limit;
263 } else if (mem.eql(u8, arg, "-fnative-half-type")) {
264 d.comp.langopts.use_native_half_type = true;
265 } else if (mem.eql(u8, arg, "-fnative-half-arguments-and-returns")) {
266 d.comp.langopts.allow_half_args_and_returns = true;
267 } else if (mem.eql(u8, arg, "-fshort-enums")) {
268 d.comp.langopts.short_enums = true;
269 } else if (mem.eql(u8, arg, "-fno-short-enums")) {
270 d.comp.langopts.short_enums = false;
271 } else if (mem.eql(u8, arg, "-fsigned-char")) {
272 d.comp.langopts.setCharSignedness(.signed);
273 } else if (mem.eql(u8, arg, "-fno-signed-char")) {
274 d.comp.langopts.setCharSignedness(.unsigned);
275 } else if (mem.eql(u8, arg, "-funsigned-char")) {
276 d.comp.langopts.setCharSignedness(.unsigned);
277 } else if (mem.eql(u8, arg, "-fno-unsigned-char")) {
278 d.comp.langopts.setCharSignedness(.signed);
279 } else if (mem.eql(u8, arg, "-fdeclspec")) {
280 d.comp.langopts.declspec_attrs = true;
281 } else if (mem.eql(u8, arg, "-fno-declspec")) {
282 d.comp.langopts.declspec_attrs = false;
283 } else if (mem.eql(u8, arg, "-ffreestanding")) {
284 hosted = false;
285 } else if (mem.eql(u8, arg, "-fhosted")) {
286 hosted = true;
287 } else if (mem.eql(u8, arg, "-fms-extensions")) {
288 d.comp.langopts.enableMSExtensions();
289 } else if (mem.eql(u8, arg, "-fno-ms-extensions")) {
290 d.comp.langopts.disableMSExtensions();
291 } else if (mem.startsWith(u8, arg, "-I")) {
292 var path = arg["-I".len..];
293 if (path.len == 0) {
294 i += 1;
295 if (i >= args.len) {
296 try d.err("expected argument after -I");
297 continue;
298 }
299 path = args[i];
300 }
301 try d.comp.include_dirs.append(d.comp.gpa, path);
302 } else if (mem.startsWith(u8, arg, "-fsyntax-only")) {
303 d.only_syntax = true;
304 } else if (mem.startsWith(u8, arg, "-fno-syntax-only")) {
305 d.only_syntax = false;
306 } else if (mem.startsWith(u8, arg, "-isystem")) {
307 var path = arg["-isystem".len..];
308 if (path.len == 0) {
309 i += 1;
310 if (i >= args.len) {
311 try d.err("expected argument after -isystem");
312 continue;
313 }
314 path = args[i];
315 }
316 const duped = try d.comp.gpa.dupe(u8, path);
317 errdefer d.comp.gpa.free(duped);
318 try d.comp.system_include_dirs.append(d.comp.gpa, duped);
319 } else if (option(arg, "--emulate=")) |compiler_str| {
320 const compiler = std.meta.stringToEnum(LangOpts.Compiler, compiler_str) orelse {
321 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_emulate, .extra = .{ .str = arg } }, &.{});
322 continue;
323 };
324 d.comp.langopts.setEmulatedCompiler(compiler);
325 } else if (option(arg, "-ffp-eval-method=")) |fp_method_str| {
326 const fp_eval_method = std.meta.stringToEnum(LangOpts.FPEvalMethod, fp_method_str) orelse .indeterminate;
327 if (fp_eval_method == .indeterminate) {
328 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_fp_eval_method, .extra = .{ .str = fp_method_str } }, &.{});
329 continue;
330 }
331 d.comp.langopts.setFpEvalMethod(fp_eval_method);
332 } else if (mem.startsWith(u8, arg, "-o")) {
333 var file = arg["-o".len..];
334 if (file.len == 0) {
335 i += 1;
336 if (i >= args.len) {
337 try d.err("expected argument after -o");
338 continue;
339 }
340 file = args[i];
341 }
342 d.output_name = file;
343 } else if (option(arg, "--sysroot=")) |sysroot| {
344 d.sysroot = sysroot;
345 } else if (mem.eql(u8, arg, "-pedantic")) {
346 d.comp.diagnostics.options.pedantic = .warning;
347 } else if (option(arg, "--rtlib=")) |rtlib| {
348 if (mem.eql(u8, rtlib, "compiler-rt") or mem.eql(u8, rtlib, "libgcc") or mem.eql(u8, rtlib, "platform")) {
349 d.rtlib = rtlib;
350 } else {
351 try d.comp.addDiagnostic(.{ .tag = .invalid_rtlib, .extra = .{ .str = rtlib } }, &.{});
352 }
353 } else if (option(arg, "-Werror=")) |err_name| {
354 try d.comp.diagnostics.set(err_name, .@"error");
355 } else if (mem.eql(u8, arg, "-Wno-fatal-errors")) {
356 d.comp.diagnostics.fatal_errors = false;
357 } else if (option(arg, "-Wno-")) |err_name| {
358 try d.comp.diagnostics.set(err_name, .off);
359 } else if (mem.eql(u8, arg, "-Wfatal-errors")) {
360 d.comp.diagnostics.fatal_errors = true;
361 } else if (option(arg, "-W")) |err_name| {
362 try d.comp.diagnostics.set(err_name, .warning);
363 } else if (option(arg, "-std=")) |standard| {
364 d.comp.langopts.setStandard(standard) catch
365 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_standard, .extra = .{ .str = arg } }, &.{});
366 } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) {
367 d.only_preprocess_and_compile = true;
368 } else if (option(arg, "--target=")) |triple| {
369 const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch {
370 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{});
371 continue;
372 };
373 const target = std.zig.system.resolveTargetQuery(query) catch |e| {
374 return d.fatal("unable to resolve target: {s}", .{errorDescription(e)});
375 };
376 d.comp.target = target;
377 d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(target));
378 d.raw_target_triple = triple;
379 } else if (mem.eql(u8, arg, "--verbose-ast")) {
380 d.verbose_ast = true;
381 } else if (mem.eql(u8, arg, "--verbose-pp")) {
382 d.verbose_pp = true;
383 } else if (mem.eql(u8, arg, "--verbose-ir")) {
384 d.verbose_ir = true;
385 } else if (mem.eql(u8, arg, "--verbose-linker-args")) {
386 d.verbose_linker_args = true;
387 } else if (mem.eql(u8, arg, "-C") or mem.eql(u8, arg, "--comments")) {
388 d.comp.langopts.preserve_comments = true;
389 comment_arg = arg;
390 } else if (mem.eql(u8, arg, "-CC") or mem.eql(u8, arg, "--comments-in-macros")) {
391 d.comp.langopts.preserve_comments = true;
392 d.comp.langopts.preserve_comments_in_macros = true;
393 comment_arg = arg;
394 } else if (option(arg, "-fuse-ld=")) |linker_name| {
395 d.use_linker = linker_name;
396 } else if (mem.eql(u8, arg, "-fuse-ld=")) {
397 d.use_linker = null;
398 } else if (option(arg, "--ld-path=")) |linker_path| {
399 d.linker_path = linker_path;
400 } else if (mem.eql(u8, arg, "-r")) {
401 d.relocatable = true;
402 } else if (mem.eql(u8, arg, "-shared")) {
403 d.shared = true;
404 } else if (mem.eql(u8, arg, "-shared-libgcc")) {
405 d.shared_libgcc = true;
406 } else if (mem.eql(u8, arg, "-static")) {
407 d.static = true;
408 } else if (mem.eql(u8, arg, "-static-libgcc")) {
409 d.static_libgcc = true;
410 } else if (mem.eql(u8, arg, "-static-pie")) {
411 d.static_pie = true;
412 } else if (mem.eql(u8, arg, "-pie")) {
413 d.pie = true;
414 } else if (mem.eql(u8, arg, "-no-pie") or mem.eql(u8, arg, "-nopie")) {
415 d.pie = false;
416 } else if (mem.eql(u8, arg, "-rdynamic")) {
417 d.rdynamic = true;
418 } else if (mem.eql(u8, arg, "-s")) {
419 d.strip = true;
420 } else if (mem.eql(u8, arg, "-nodefaultlibs")) {
421 d.nodefaultlibs = true;
422 } else if (mem.eql(u8, arg, "-nolibc")) {
423 d.nolibc = true;
424 } else if (mem.eql(u8, arg, "-nostdlib")) {
425 d.nostdlib = true;
426 } else if (mem.eql(u8, arg, "-nostartfiles")) {
427 d.nostartfiles = true;
428 } else if (option(arg, "--unwindlib=")) |unwindlib| {
429 const valid_unwindlibs: [5][]const u8 = .{ "", "none", "platform", "libunwind", "libgcc" };
430 for (valid_unwindlibs) |name| {
431 if (mem.eql(u8, name, unwindlib)) {
432 d.unwindlib = unwindlib;
433 break;
434 }
435 } else {
436 try d.comp.addDiagnostic(.{ .tag = .invalid_unwindlib, .extra = .{ .str = unwindlib } }, &.{});
437 }
438 } else {
439 try d.comp.addDiagnostic(.{ .tag = .cli_unknown_arg, .extra = .{ .str = arg } }, &.{});
440 }
441 } else if (std.mem.endsWith(u8, arg, ".o") or std.mem.endsWith(u8, arg, ".obj")) {
442 try d.link_objects.append(d.comp.gpa, arg);
443 } else {
444 const source = d.addSource(arg) catch |er| {
445 return d.fatal("unable to add source file '{s}': {s}", .{ arg, errorDescription(er) });
446 };
447 try d.inputs.append(d.comp.gpa, source);
448 }
449 }
450 if (d.comp.langopts.preserve_comments and !d.only_preprocess) {
451 return d.fatal("invalid argument '{s}' only allowed with '-E'", .{comment_arg});
452 }
453 if (hosted) |is_hosted| {
454 if (is_hosted) {
455 if (d.comp.target.os.tag == .freestanding) {
456 return d.fatal("Cannot use freestanding target with `-fhosted`", .{});
457 }
458 } else {
459 d.comp.target.os.tag = .freestanding;
460 }
461 }
462 return false;
463}
464
465fn option(arg: []const u8, name: []const u8) ?[]const u8 {
466 if (std.mem.startsWith(u8, arg, name) and arg.len > name.len) {
467 return arg[name.len..];
468 }
469 return null;
470}
471
472fn addSource(d: *Driver, path: []const u8) !Source {
473 if (mem.eql(u8, "-", path)) {
474 const stdin = std.io.getStdIn().reader();
475 const input = try stdin.readAllAlloc(d.comp.gpa, std.math.maxInt(u32));
476 defer d.comp.gpa.free(input);
477 return d.comp.addSourceFromBuffer("<stdin>", input);
478 }
479 return d.comp.addSourceFromPath(path);
480}
481
482pub fn err(d: *Driver, msg: []const u8) !void {
483 try d.comp.addDiagnostic(.{ .tag = .cli_error, .extra = .{ .str = msg } }, &.{});
484}
485
486pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {
487 try d.comp.diagnostics.list.append(d.comp.gpa, .{
488 .tag = .cli_error,
489 .kind = .@"fatal error",
490 .extra = .{ .str = try std.fmt.allocPrint(d.comp.diagnostics.arena.allocator(), fmt, args) },
491 });
492 return error.FatalError;
493}
494
495pub fn renderErrors(d: *Driver) void {
496 Diagnostics.render(d.comp, d.detectConfig(std.io.getStdErr()));
497}
498
499pub fn detectConfig(d: *Driver, file: std.fs.File) std.io.tty.Config {
500 if (d.color == true) return .escape_codes;
501 if (d.color == false) return .no_color;
502
503 if (file.supportsAnsiEscapeCodes()) return .escape_codes;
504 if (@import("builtin").os.tag == .windows and file.isTty()) {
505 var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
506 if (std.os.windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != std.os.windows.TRUE) {
507 return .no_color;
508 }
509 return .{ .windows_api = .{
510 .handle = file.handle,
511 .reset_attributes = info.wAttributes,
512 } };
513 }
514
515 return .no_color;
516}
517
518pub fn errorDescription(e: anyerror) []const u8 {
519 return switch (e) {
520 error.OutOfMemory => "ran out of memory",
521 error.FileNotFound => "file not found",
522 error.IsDir => "is a directory",
523 error.NotDir => "is not a directory",
524 error.NotOpenForReading => "file is not open for reading",
525 error.NotOpenForWriting => "file is not open for writing",
526 error.InvalidUtf8 => "path is not valid UTF-8",
527 error.InvalidWtf8 => "path is not valid WTF-8",
528 error.FileBusy => "file is busy",
529 error.NameTooLong => "file name is too long",
530 error.AccessDenied => "access denied",
531 error.FileTooBig => "file is too big",
532 error.ProcessFdQuotaExceeded, error.SystemFdQuotaExceeded => "ran out of file descriptors",
533 error.SystemResources => "ran out of system resources",
534 error.FatalError => "a fatal error occurred",
535 error.Unexpected => "an unexpected error occurred",
536 else => @errorName(e),
537 };
538}
539
540/// The entry point of the Aro compiler.
541/// **MAY call `exit` if `fast_exit` is set.**
542pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_exit: bool) !void {
543 var macro_buf = std.ArrayList(u8).init(d.comp.gpa);
544 defer macro_buf.deinit();
545
546 const std_out = std.io.getStdOut().writer();
547 if (try parseArgs(d, std_out, macro_buf.writer(), args)) return;
548
549 const linking = !(d.only_preprocess or d.only_syntax or d.only_compile or d.only_preprocess_and_compile);
550
551 if (d.inputs.items.len == 0) {
552 return d.fatal("no input files", .{});
553 } else if (d.inputs.items.len != 1 and d.output_name != null and !linking) {
554 return d.fatal("cannot specify -o when generating multiple output files", .{});
555 }
556
557 if (!linking) for (d.link_objects.items) |obj| {
558 try d.comp.addDiagnostic(.{ .tag = .cli_unused_link_object, .extra = .{ .str = obj } }, &.{});
559 };
560
561 d.comp.defineSystemIncludes(d.aro_name) catch |er| switch (er) {
562 error.OutOfMemory => return error.OutOfMemory,
563 error.AroIncludeNotFound => return d.fatal("unable to find Aro builtin headers", .{}),
564 };
565
566 const builtin = try d.comp.generateBuiltinMacros(d.system_defines);
567 const user_macros = try d.comp.addSourceFromBuffer("<command line>", macro_buf.items);
568
569 if (fast_exit and d.inputs.items.len == 1) {
570 d.processSource(tc, d.inputs.items[0], builtin, user_macros, fast_exit) catch |e| switch (e) {
571 error.FatalError => {
572 d.renderErrors();
573 d.exitWithCleanup(1);
574 },
575 else => |er| return er,
576 };
577 unreachable;
578 }
579
580 for (d.inputs.items) |source| {
581 d.processSource(tc, source, builtin, user_macros, fast_exit) catch |e| switch (e) {
582 error.FatalError => {
583 d.renderErrors();
584 },
585 else => |er| return er,
586 };
587 }
588 if (d.comp.diagnostics.errors != 0) {
589 if (fast_exit) d.exitWithCleanup(1);
590 return;
591 }
592 if (linking) {
593 try d.invokeLinker(tc, fast_exit);
594 }
595 if (fast_exit) std.process.exit(0);
596}
597
598fn processSource(
599 d: *Driver,
600 tc: *Toolchain,
601 source: Source,
602 builtin: Source,
603 user_macros: Source,
604 comptime fast_exit: bool,
605) !void {
606 d.comp.generated_buf.items.len = 0;
607 var pp = try Preprocessor.initDefault(d.comp);
608 defer pp.deinit();
609
610 if (d.comp.langopts.ms_extensions) {
611 d.comp.ms_cwd_source_id = source.id;
612 }
613
614 if (d.verbose_pp) pp.verbose = true;
615 if (d.only_preprocess) {
616 pp.preserve_whitespace = true;
617 if (d.line_commands) {
618 pp.linemarkers = if (d.use_line_directives) .line_directives else .numeric_directives;
619 }
620 }
621
622 try pp.preprocessSources(&.{ source, builtin, user_macros });
623
624 if (d.only_preprocess) {
625 d.renderErrors();
626
627 if (d.comp.diagnostics.errors != 0) {
628 if (fast_exit) std.process.exit(1); // Not linking, no need for cleanup.
629 return;
630 }
631
632 const file = if (d.output_name) |some|
633 std.fs.cwd().createFile(some, .{}) catch |er|
634 return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) })
635 else
636 std.io.getStdOut();
637 defer if (d.output_name != null) file.close();
638
639 var buf_w = std.io.bufferedWriter(file.writer());
640 pp.prettyPrintTokens(buf_w.writer()) catch |er|
641 return d.fatal("unable to write result: {s}", .{errorDescription(er)});
642
643 buf_w.flush() catch |er|
644 return d.fatal("unable to write result: {s}", .{errorDescription(er)});
645 if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
646 return;
647 }
648
649 var tree = try pp.parse();
650 defer tree.deinit();
651
652 if (d.verbose_ast) {
653 const stdout = std.io.getStdOut();
654 var buf_writer = std.io.bufferedWriter(stdout.writer());
655 tree.dump(d.detectConfig(stdout), buf_writer.writer()) catch {};
656 buf_writer.flush() catch {};
657 }
658
659 const prev_errors = d.comp.diagnostics.errors;
660 d.renderErrors();
661
662 if (d.comp.diagnostics.errors != prev_errors) {
663 if (fast_exit) d.exitWithCleanup(1);
664 return; // do not compile if there were errors
665 }
666
667 if (d.only_syntax) {
668 if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
669 return;
670 }
671
672 if (d.comp.target.ofmt != .elf or d.comp.target.cpu.arch != .x86_64) {
673 return d.fatal(
674 "unsupported target {s}-{s}-{s}, currently only x86-64 elf is supported",
675 .{ @tagName(d.comp.target.cpu.arch), @tagName(d.comp.target.os.tag), @tagName(d.comp.target.abi) },
676 );
677 }
678
679 var ir = try tree.genIr();
680 defer ir.deinit(d.comp.gpa);
681
682 if (d.verbose_ir) {
683 const stdout = std.io.getStdOut();
684 var buf_writer = std.io.bufferedWriter(stdout.writer());
685 ir.dump(d.comp.gpa, d.detectConfig(stdout), buf_writer.writer()) catch {};
686 buf_writer.flush() catch {};
687 }
688
689 var render_errors: Ir.Renderer.ErrorList = .{};
690 defer {
691 for (render_errors.values()) |msg| d.comp.gpa.free(msg);
692 render_errors.deinit(d.comp.gpa);
693 }
694
695 var obj = ir.render(d.comp.gpa, d.comp.target, &render_errors) catch |e| switch (e) {
696 error.OutOfMemory => return error.OutOfMemory,
697 error.LowerFail => {
698 return d.fatal(
699 "unable to render Ir to machine code: {s}",
700 .{render_errors.values()[0]},
701 );
702 },
703 };
704 defer obj.deinit();
705
706 // If it's used, name_buf will either hold a filename or `/tmp/<12 random bytes with base-64 encoding>.<extension>`
707 // both of which should fit into MAX_NAME_BYTES for all systems
708 var name_buf: [std.fs.MAX_NAME_BYTES]u8 = undefined;
709
710 const out_file_name = if (d.only_compile) blk: {
711 const fmt_template = "{s}{s}";
712 const fmt_args = .{
713 std.fs.path.stem(source.path),
714 d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
715 };
716 break :blk d.output_name orelse
717 std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
718 } else blk: {
719 const random_bytes_count = 12;
720 const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count);
721
722 var random_bytes: [random_bytes_count]u8 = undefined;
723 std.crypto.random.bytes(&random_bytes);
724 var random_name: [sub_path_len]u8 = undefined;
725 _ = std.fs.base64_encoder.encode(&random_name, &random_bytes);
726
727 const fmt_template = "/tmp/{s}{s}";
728 const fmt_args = .{
729 random_name,
730 d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch),
731 };
732 break :blk std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args);
733 };
734
735 const out_file = std.fs.cwd().createFile(out_file_name, .{}) catch |er|
736 return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) });
737 defer out_file.close();
738
739 obj.finish(out_file) catch |er|
740 return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, errorDescription(er) });
741
742 if (d.only_compile) {
743 if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
744 return;
745 }
746 try d.link_objects.ensureUnusedCapacity(d.comp.gpa, 1);
747 d.link_objects.appendAssumeCapacity(try d.comp.gpa.dupe(u8, out_file_name));
748 d.temp_file_count += 1;
749 if (fast_exit) {
750 try d.invokeLinker(tc, fast_exit);
751 }
752}
753
754fn dumpLinkerArgs(items: []const []const u8) !void {
755 const stdout = std.io.getStdOut().writer();
756 for (items, 0..) |item, i| {
757 if (i > 0) try stdout.writeByte(' ');
758 try stdout.print("\"{}\"", .{std.zig.fmtEscapes(item)});
759 }
760 try stdout.writeByte('\n');
761}
762
763/// The entry point of the Aro compiler.
764/// **MAY call `exit` if `fast_exit` is set.**
765pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) !void {
766 try tc.discover();
767
768 var argv = std.ArrayList([]const u8).init(d.comp.gpa);
769 defer argv.deinit();
770
771 var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
772 const linker_path = try tc.getLinkerPath(&linker_path_buf);
773 try argv.append(linker_path);
774
775 try tc.buildLinkerArgs(&argv);
776
777 if (d.verbose_linker_args) {
778 dumpLinkerArgs(argv.items) catch |er| {
779 return d.fatal("unable to dump linker args: {s}", .{errorDescription(er)});
780 };
781 }
782 var child = std.ChildProcess.init(argv.items, d.comp.gpa);
783 // TODO handle better
784 child.stdin_behavior = .Inherit;
785 child.stdout_behavior = .Inherit;
786 child.stderr_behavior = .Inherit;
787
788 const term = child.spawnAndWait() catch |er| {
789 return d.fatal("unable to spawn linker: {s}", .{errorDescription(er)});
790 };
791 switch (term) {
792 .Exited => |code| if (code != 0) {
793 const e = d.fatal("linker exited with an error code", .{});
794 if (fast_exit) d.exitWithCleanup(code);
795 return e;
796 },
797 else => {
798 const e = d.fatal("linker crashed", .{});
799 if (fast_exit) d.exitWithCleanup(1);
800 return e;
801 },
802 }
803 if (fast_exit) d.exitWithCleanup(0);
804}
805
806fn exitWithCleanup(d: *Driver, code: u8) noreturn {
807 for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| {
808 std.fs.deleteFileAbsolute(obj) catch {};
809 }
810 std.process.exit(code);
811}
lib/compiler/aro/aro/Driver/Distro.zig created+328
......@@ -0,0 +1,328 @@
1//! Tools for figuring out what Linux distro we're running on
2
3const std = @import("std");
4const mem = std.mem;
5const Filesystem = @import("Filesystem.zig").Filesystem;
6
7const MAX_BYTES = 1024; // TODO: Can we assume 1024 bytes enough for the info we need?
8
9/// Value for linker `--hash-style=` argument
10pub const HashStyle = enum {
11 both,
12 gnu,
13};
14
15pub const Tag = enum {
16 alpine,
17 arch,
18 debian_lenny,
19 debian_squeeze,
20 debian_wheezy,
21 debian_jessie,
22 debian_stretch,
23 debian_buster,
24 debian_bullseye,
25 debian_bookworm,
26 debian_trixie,
27 exherbo,
28 rhel5,
29 rhel6,
30 rhel7,
31 fedora,
32 gentoo,
33 open_suse,
34 ubuntu_hardy,
35 ubuntu_intrepid,
36 ubuntu_jaunty,
37 ubuntu_karmic,
38 ubuntu_lucid,
39 ubuntu_maverick,
40 ubuntu_natty,
41 ubuntu_oneiric,
42 ubuntu_precise,
43 ubuntu_quantal,
44 ubuntu_raring,
45 ubuntu_saucy,
46 ubuntu_trusty,
47 ubuntu_utopic,
48 ubuntu_vivid,
49 ubuntu_wily,
50 ubuntu_xenial,
51 ubuntu_yakkety,
52 ubuntu_zesty,
53 ubuntu_artful,
54 ubuntu_bionic,
55 ubuntu_cosmic,
56 ubuntu_disco,
57 ubuntu_eoan,
58 ubuntu_focal,
59 ubuntu_groovy,
60 ubuntu_hirsute,
61 ubuntu_impish,
62 ubuntu_jammy,
63 ubuntu_kinetic,
64 ubuntu_lunar,
65 unknown,
66
67 pub fn getHashStyle(self: Tag) HashStyle {
68 if (self.isOpenSUSE()) return .both;
69 return switch (self) {
70 .ubuntu_lucid,
71 .ubuntu_jaunty,
72 .ubuntu_karmic,
73 => .both,
74 else => .gnu,
75 };
76 }
77
78 pub fn isRedhat(self: Tag) bool {
79 return switch (self) {
80 .fedora,
81 .rhel5,
82 .rhel6,
83 .rhel7,
84 => true,
85 else => false,
86 };
87 }
88
89 pub fn isOpenSUSE(self: Tag) bool {
90 return self == .open_suse;
91 }
92
93 pub fn isDebian(self: Tag) bool {
94 return switch (self) {
95 .debian_lenny,
96 .debian_squeeze,
97 .debian_wheezy,
98 .debian_jessie,
99 .debian_stretch,
100 .debian_buster,
101 .debian_bullseye,
102 .debian_bookworm,
103 .debian_trixie,
104 => true,
105 else => false,
106 };
107 }
108 pub fn isUbuntu(self: Tag) bool {
109 return switch (self) {
110 .ubuntu_hardy,
111 .ubuntu_intrepid,
112 .ubuntu_jaunty,
113 .ubuntu_karmic,
114 .ubuntu_lucid,
115 .ubuntu_maverick,
116 .ubuntu_natty,
117 .ubuntu_oneiric,
118 .ubuntu_precise,
119 .ubuntu_quantal,
120 .ubuntu_raring,
121 .ubuntu_saucy,
122 .ubuntu_trusty,
123 .ubuntu_utopic,
124 .ubuntu_vivid,
125 .ubuntu_wily,
126 .ubuntu_xenial,
127 .ubuntu_yakkety,
128 .ubuntu_zesty,
129 .ubuntu_artful,
130 .ubuntu_bionic,
131 .ubuntu_cosmic,
132 .ubuntu_disco,
133 .ubuntu_eoan,
134 .ubuntu_focal,
135 .ubuntu_groovy,
136 .ubuntu_hirsute,
137 .ubuntu_impish,
138 .ubuntu_jammy,
139 .ubuntu_kinetic,
140 .ubuntu_lunar,
141 => true,
142
143 else => false,
144 };
145 }
146 pub fn isAlpine(self: Tag) bool {
147 return self == .alpine;
148 }
149 pub fn isGentoo(self: Tag) bool {
150 return self == .gentoo;
151 }
152};
153
154fn scanForOsRelease(buf: []const u8) ?Tag {
155 var it = mem.splitScalar(u8, buf, '\n');
156 while (it.next()) |line| {
157 if (mem.startsWith(u8, line, "ID=")) {
158 const rest = line["ID=".len..];
159 if (mem.eql(u8, rest, "alpine")) return .alpine;
160 if (mem.eql(u8, rest, "fedora")) return .fedora;
161 if (mem.eql(u8, rest, "gentoo")) return .gentoo;
162 if (mem.eql(u8, rest, "arch")) return .arch;
163 if (mem.eql(u8, rest, "sles")) return .open_suse;
164 if (mem.eql(u8, rest, "opensuse")) return .open_suse;
165 if (mem.eql(u8, rest, "exherbo")) return .exherbo;
166 }
167 }
168 return null;
169}
170
171fn detectOsRelease(fs: Filesystem) ?Tag {
172 var buf: [MAX_BYTES]u8 = undefined;
173 const data = fs.readFile("/etc/os-release", &buf) orelse fs.readFile("/usr/lib/os-release", &buf) orelse return null;
174 return scanForOsRelease(data);
175}
176
177fn scanForLSBRelease(buf: []const u8) ?Tag {
178 var it = mem.splitScalar(u8, buf, '\n');
179 while (it.next()) |line| {
180 if (mem.startsWith(u8, line, "DISTRIB_CODENAME=")) {
181 const rest = line["DISTRIB_CODENAME=".len..];
182 if (mem.eql(u8, rest, "hardy")) return .ubuntu_hardy;
183 if (mem.eql(u8, rest, "intrepid")) return .ubuntu_intrepid;
184 if (mem.eql(u8, rest, "jaunty")) return .ubuntu_jaunty;
185 if (mem.eql(u8, rest, "karmic")) return .ubuntu_karmic;
186 if (mem.eql(u8, rest, "lucid")) return .ubuntu_lucid;
187 if (mem.eql(u8, rest, "maverick")) return .ubuntu_maverick;
188 if (mem.eql(u8, rest, "natty")) return .ubuntu_natty;
189 if (mem.eql(u8, rest, "oneiric")) return .ubuntu_oneiric;
190 if (mem.eql(u8, rest, "precise")) return .ubuntu_precise;
191 if (mem.eql(u8, rest, "quantal")) return .ubuntu_quantal;
192 if (mem.eql(u8, rest, "raring")) return .ubuntu_raring;
193 if (mem.eql(u8, rest, "saucy")) return .ubuntu_saucy;
194 if (mem.eql(u8, rest, "trusty")) return .ubuntu_trusty;
195 if (mem.eql(u8, rest, "utopic")) return .ubuntu_utopic;
196 if (mem.eql(u8, rest, "vivid")) return .ubuntu_vivid;
197 if (mem.eql(u8, rest, "wily")) return .ubuntu_wily;
198 if (mem.eql(u8, rest, "xenial")) return .ubuntu_xenial;
199 if (mem.eql(u8, rest, "yakkety")) return .ubuntu_yakkety;
200 if (mem.eql(u8, rest, "zesty")) return .ubuntu_zesty;
201 if (mem.eql(u8, rest, "artful")) return .ubuntu_artful;
202 if (mem.eql(u8, rest, "bionic")) return .ubuntu_bionic;
203 if (mem.eql(u8, rest, "cosmic")) return .ubuntu_cosmic;
204 if (mem.eql(u8, rest, "disco")) return .ubuntu_disco;
205 if (mem.eql(u8, rest, "eoan")) return .ubuntu_eoan;
206 if (mem.eql(u8, rest, "focal")) return .ubuntu_focal;
207 if (mem.eql(u8, rest, "groovy")) return .ubuntu_groovy;
208 if (mem.eql(u8, rest, "hirsute")) return .ubuntu_hirsute;
209 if (mem.eql(u8, rest, "impish")) return .ubuntu_impish;
210 if (mem.eql(u8, rest, "jammy")) return .ubuntu_jammy;
211 if (mem.eql(u8, rest, "kinetic")) return .ubuntu_kinetic;
212 if (mem.eql(u8, rest, "lunar")) return .ubuntu_lunar;
213 }
214 }
215 return null;
216}
217
218fn detectLSBRelease(fs: Filesystem) ?Tag {
219 var buf: [MAX_BYTES]u8 = undefined;
220 const data = fs.readFile("/etc/lsb-release", &buf) orelse return null;
221
222 return scanForLSBRelease(data);
223}
224
225fn scanForRedHat(buf: []const u8) Tag {
226 if (mem.startsWith(u8, buf, "Fedora release")) return .fedora;
227 if (mem.startsWith(u8, buf, "Red Hat Enterprise Linux") or mem.startsWith(u8, buf, "CentOS") or mem.startsWith(u8, buf, "Scientific Linux")) {
228 if (mem.indexOfPos(u8, buf, 0, "release 7") != null) return .rhel7;
229 if (mem.indexOfPos(u8, buf, 0, "release 6") != null) return .rhel6;
230 if (mem.indexOfPos(u8, buf, 0, "release 5") != null) return .rhel5;
231 }
232
233 return .unknown;
234}
235
236fn detectRedhat(fs: Filesystem) ?Tag {
237 var buf: [MAX_BYTES]u8 = undefined;
238 const data = fs.readFile("/etc/redhat-release", &buf) orelse return null;
239 return scanForRedHat(data);
240}
241
242fn scanForDebian(buf: []const u8) Tag {
243 var it = mem.splitScalar(u8, buf, '.');
244 if (std.fmt.parseInt(u8, it.next().?, 10)) |major| {
245 return switch (major) {
246 5 => .debian_lenny,
247 6 => .debian_squeeze,
248 7 => .debian_wheezy,
249 8 => .debian_jessie,
250 9 => .debian_stretch,
251 10 => .debian_buster,
252 11 => .debian_bullseye,
253 12 => .debian_bookworm,
254 13 => .debian_trixie,
255 else => .unknown,
256 };
257 } else |_| {}
258
259 it = mem.splitScalar(u8, buf, '\n');
260 const name = it.next().?;
261 if (mem.eql(u8, name, "squeeze/sid")) return .debian_squeeze;
262 if (mem.eql(u8, name, "wheezy/sid")) return .debian_wheezy;
263 if (mem.eql(u8, name, "jessie/sid")) return .debian_jessie;
264 if (mem.eql(u8, name, "stretch/sid")) return .debian_stretch;
265 if (mem.eql(u8, name, "buster/sid")) return .debian_buster;
266 if (mem.eql(u8, name, "bullseye/sid")) return .debian_bullseye;
267 if (mem.eql(u8, name, "bookworm/sid")) return .debian_bookworm;
268
269 return .unknown;
270}
271
272fn detectDebian(fs: Filesystem) ?Tag {
273 var buf: [MAX_BYTES]u8 = undefined;
274 const data = fs.readFile("/etc/debian_version", &buf) orelse return null;
275 return scanForDebian(data);
276}
277
278pub fn detect(target: std.Target, fs: Filesystem) Tag {
279 if (target.os.tag != .linux) return .unknown;
280
281 if (detectOsRelease(fs)) |tag| return tag;
282 if (detectLSBRelease(fs)) |tag| return tag;
283 if (detectRedhat(fs)) |tag| return tag;
284 if (detectDebian(fs)) |tag| return tag;
285
286 if (fs.exists("/etc/gentoo-release")) return .gentoo;
287
288 return .unknown;
289}
290
291test scanForDebian {
292 try std.testing.expectEqual(Tag.debian_squeeze, scanForDebian("squeeze/sid"));
293 try std.testing.expectEqual(Tag.debian_bullseye, scanForDebian("11.1.2"));
294 try std.testing.expectEqual(Tag.unknown, scanForDebian("None"));
295 try std.testing.expectEqual(Tag.unknown, scanForDebian(""));
296}
297
298test scanForRedHat {
299 try std.testing.expectEqual(Tag.fedora, scanForRedHat("Fedora release 7"));
300 try std.testing.expectEqual(Tag.rhel7, scanForRedHat("Red Hat Enterprise Linux release 7"));
301 try std.testing.expectEqual(Tag.rhel5, scanForRedHat("CentOS release 5"));
302 try std.testing.expectEqual(Tag.unknown, scanForRedHat("CentOS release 4"));
303 try std.testing.expectEqual(Tag.unknown, scanForRedHat(""));
304}
305
306test scanForLSBRelease {
307 const text =
308 \\DISTRIB_ID=Ubuntu
309 \\DISTRIB_RELEASE=20.04
310 \\DISTRIB_CODENAME=focal
311 \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
312 \\
313 ;
314 try std.testing.expectEqual(Tag.ubuntu_focal, scanForLSBRelease(text).?);
315}
316
317test scanForOsRelease {
318 const text =
319 \\NAME="Alpine Linux"
320 \\ID=alpine
321 \\VERSION_ID=3.18.2
322 \\PRETTY_NAME="Alpine Linux v3.18"
323 \\HOME_URL="https://alpinelinux.org/"
324 \\BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
325 \\
326 ;
327 try std.testing.expectEqual(Tag.alpine, scanForOsRelease(text).?);
328}
lib/compiler/aro/aro/Driver/Filesystem.zig created+239
......@@ -0,0 +1,239 @@
1const std = @import("std");
2const mem = std.mem;
3const builtin = @import("builtin");
4const is_windows = builtin.os.tag == .windows;
5
6fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 {
7 @setCold(true);
8 for (entries) |entry| {
9 if (mem.eql(u8, entry.path, path)) {
10 const len = @min(entry.contents.len, buf.len);
11 @memcpy(buf[0..len], entry.contents[0..len]);
12 return buf[0..len];
13 }
14 }
15 return null;
16}
17
18fn findProgramByNameFake(entries: []const Filesystem.Entry, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
19 @setCold(true);
20 if (mem.indexOfScalar(u8, name, '/') != null) {
21 @memcpy(buf[0..name.len], name);
22 return buf[0..name.len];
23 }
24 const path_env = path orelse return null;
25 var fib = std.heap.FixedBufferAllocator.init(buf);
26
27 var it = mem.tokenizeScalar(u8, path_env, std.fs.path.delimiter);
28 while (it.next()) |path_dir| {
29 defer fib.reset();
30 const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
31 if (canExecuteFake(entries, full_path)) return full_path;
32 }
33
34 return null;
35}
36
37fn canExecuteFake(entries: []const Filesystem.Entry, path: []const u8) bool {
38 @setCold(true);
39 for (entries) |entry| {
40 if (mem.eql(u8, entry.path, path)) {
41 return entry.executable;
42 }
43 }
44 return false;
45}
46
47fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool {
48 @setCold(true);
49 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
50 var fib = std.heap.FixedBufferAllocator.init(&buf);
51 const resolved = std.fs.path.resolvePosix(fib.allocator(), &.{path}) catch return false;
52 for (entries) |entry| {
53 if (mem.eql(u8, entry.path, resolved)) return true;
54 }
55 return false;
56}
57
58fn canExecutePosix(path: []const u8) bool {
59 std.os.access(path, std.os.X_OK) catch return false;
60 // Todo: ensure path is not a directory
61 return true;
62}
63
64/// TODO
65fn canExecuteWindows(path: []const u8) bool {
66 _ = path;
67 return true;
68}
69
70/// TODO
71fn findProgramByNameWindows(allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
72 _ = path;
73 _ = buf;
74 _ = name;
75 _ = allocator;
76 return null;
77}
78
79/// TODO: does WASI need special handling?
80fn findProgramByNamePosix(name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
81 if (mem.indexOfScalar(u8, name, '/') != null) {
82 @memcpy(buf[0..name.len], name);
83 return buf[0..name.len];
84 }
85 const path_env = path orelse return null;
86 var fib = std.heap.FixedBufferAllocator.init(buf);
87
88 var it = mem.tokenizeScalar(u8, path_env, std.fs.path.delimiter);
89 while (it.next()) |path_dir| {
90 defer fib.reset();
91 const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue;
92 if (canExecutePosix(full_path)) return full_path;
93 }
94
95 return null;
96}
97
98pub const Filesystem = union(enum) {
99 real: void,
100 fake: []const Entry,
101
102 const Entry = struct {
103 path: []const u8,
104 contents: []const u8 = "",
105 executable: bool = false,
106 };
107
108 const FakeDir = struct {
109 entries: []const Entry,
110 path: []const u8,
111
112 fn iterate(self: FakeDir) FakeDir.Iterator {
113 return .{
114 .entries = self.entries,
115 .base = self.path,
116 };
117 }
118
119 const Iterator = struct {
120 entries: []const Entry,
121 base: []const u8,
122 i: usize = 0,
123
124 fn next(self: *@This()) !?std.fs.Dir.Entry {
125 while (self.i < self.entries.len) {
126 const entry = self.entries[self.i];
127 self.i += 1;
128 if (entry.path.len == self.base.len) continue;
129 if (std.mem.startsWith(u8, entry.path, self.base)) {
130 const remaining = entry.path[self.base.len + 1 ..];
131 if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue;
132 const extension = std.fs.path.extension(remaining);
133 const kind: std.fs.Dir.Entry.Kind = if (extension.len == 0) .directory else .file;
134 return .{ .name = remaining, .kind = kind };
135 }
136 }
137 return null;
138 }
139 };
140 };
141
142 const Dir = union(enum) {
143 dir: std.fs.Dir,
144 fake: FakeDir,
145
146 pub fn iterate(self: Dir) Iterator {
147 return switch (self) {
148 .dir => |dir| .{ .iterator = dir.iterate() },
149 .fake => |fake| .{ .fake = fake.iterate() },
150 };
151 }
152
153 pub fn close(self: *Dir) void {
154 switch (self.*) {
155 .dir => |*d| d.close(),
156 .fake => {},
157 }
158 }
159 };
160
161 const Iterator = union(enum) {
162 iterator: std.fs.Dir.Iterator,
163 fake: FakeDir.Iterator,
164
165 pub fn next(self: *Iterator) std.fs.Dir.Iterator.Error!?std.fs.Dir.Entry {
166 return switch (self.*) {
167 .iterator => |*it| it.next(),
168 .fake => |*it| it.next(),
169 };
170 }
171 };
172
173 pub fn exists(fs: Filesystem, path: []const u8) bool {
174 switch (fs) {
175 .real => {
176 std.os.access(path, std.os.F_OK) catch return false;
177 return true;
178 },
179 .fake => |paths| return existsFake(paths, path),
180 }
181 }
182
183 pub fn joinedExists(fs: Filesystem, parts: []const []const u8) bool {
184 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
185 var fib = std.heap.FixedBufferAllocator.init(&buf);
186 const joined = std.fs.path.join(fib.allocator(), parts) catch return false;
187 return fs.exists(joined);
188 }
189
190 pub fn canExecute(fs: Filesystem, path: []const u8) bool {
191 return switch (fs) {
192 .real => if (is_windows) canExecuteWindows(path) else canExecutePosix(path),
193 .fake => |entries| canExecuteFake(entries, path),
194 };
195 }
196
197 /// Search for an executable named `name` using platform-specific logic
198 /// If it's found, write the full path to `buf` and return a slice of it
199 /// Otherwise retun null
200 pub fn findProgramByName(fs: Filesystem, allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 {
201 std.debug.assert(name.len > 0);
202 return switch (fs) {
203 .real => if (is_windows) findProgramByNameWindows(allocator, name, path, buf) else findProgramByNamePosix(name, path, buf),
204 .fake => |entries| findProgramByNameFake(entries, name, path, buf),
205 };
206 }
207
208 /// Read the file at `path` into `buf`.
209 /// Returns null if any errors are encountered
210 /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned
211 pub fn readFile(fs: Filesystem, path: []const u8, buf: []u8) ?[]const u8 {
212 return switch (fs) {
213 .real => {
214 const file = std.fs.cwd().openFile(path, .{}) catch return null;
215 defer file.close();
216
217 const bytes_read = file.readAll(buf) catch return null;
218 return buf[0..bytes_read];
219 },
220 .fake => |entries| readFileFake(entries, path, buf),
221 };
222 }
223
224 pub fn openDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!Dir {
225 return switch (fs) {
226 .real => .{ .dir = try std.fs.cwd().openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) },
227 .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },
228 };
229 }
230};
231
232test "Fake filesystem" {
233 const fs: Filesystem = .{ .fake = &.{
234 .{ .path = "/usr/bin" },
235 } };
236 try std.testing.expect(fs.exists("/usr/bin"));
237 try std.testing.expect(fs.exists("/usr/bin/foo/.."));
238 try std.testing.expect(!fs.exists("/usr/bin/bar"));
239}
lib/compiler/aro/aro/Driver/GCCDetector.zig created+638
......@@ -0,0 +1,638 @@
1const std = @import("std");
2const Toolchain = @import("../Toolchain.zig");
3const target_util = @import("../target.zig");
4const system_defaults = @import("system_defaults");
5const GCCVersion = @import("GCCVersion.zig");
6const Multilib = @import("Multilib.zig");
7
8const GCCDetector = @This();
9
10is_valid: bool = false,
11install_path: []const u8 = "",
12parent_lib_path: []const u8 = "",
13version: GCCVersion = .{},
14gcc_triple: []const u8 = "",
15selected: Multilib = .{},
16biarch_sibling: ?Multilib = null,
17
18pub fn deinit(self: *GCCDetector) void {
19 if (!self.is_valid) return;
20}
21
22pub fn appendToolPath(self: *const GCCDetector, tc: *Toolchain) !void {
23 if (!self.is_valid) return;
24 return tc.addPathFromComponents(&.{
25 self.parent_lib_path,
26 "..",
27 self.gcc_triple,
28 "bin",
29 }, .program);
30}
31
32fn addDefaultGCCPrefixes(prefixes: *std.ArrayListUnmanaged([]const u8), tc: *const Toolchain) !void {
33 const sysroot = tc.getSysroot();
34 const target = tc.getTarget();
35 if (sysroot.len == 0 and target.os.tag == .linux and tc.filesystem.exists("/opt/rh")) {
36 prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-12/root/usr");
37 prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-11/root/usr");
38 prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-10/root/usr");
39 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-12/root/usr");
40 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-11/root/usr");
41 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-10/root/usr");
42 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-9/root/usr");
43 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-8/root/usr");
44 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-7/root/usr");
45 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-6/root/usr");
46 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-4/root/usr");
47 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-3/root/usr");
48 prefixes.appendAssumeCapacity("/opt/rh/devtoolset-2/root/usr");
49 }
50 if (sysroot.len == 0) {
51 prefixes.appendAssumeCapacity("/usr");
52 } else {
53 var usr_path = try tc.arena.alloc(u8, 4 + sysroot.len);
54 @memcpy(usr_path[0..4], "/usr");
55 @memcpy(usr_path[4..], sysroot);
56 prefixes.appendAssumeCapacity(usr_path);
57 }
58}
59
60fn collectLibDirsAndTriples(
61 tc: *Toolchain,
62 lib_dirs: *std.ArrayListUnmanaged([]const u8),
63 triple_aliases: *std.ArrayListUnmanaged([]const u8),
64 biarch_libdirs: *std.ArrayListUnmanaged([]const u8),
65 biarch_triple_aliases: *std.ArrayListUnmanaged([]const u8),
66) !void {
67 const AArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
68 const AArch64Triples: [4][]const u8 = .{ "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux" };
69 const AArch64beLibDirs: [1][]const u8 = .{"/lib"};
70 const AArch64beTriples: [2][]const u8 = .{ "aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu" };
71
72 const ARMLibDirs: [1][]const u8 = .{"/lib"};
73 const ARMTriples: [1][]const u8 = .{"arm-linux-gnueabi"};
74 const ARMHFTriples: [4][]const u8 = .{ "arm-linux-gnueabihf", "armv7hl-redhat-linux-gnueabi", "armv6hl-suse-linux-gnueabi", "armv7hl-suse-linux-gnueabi" };
75
76 const ARMebLibDirs: [1][]const u8 = .{"/lib"};
77 const ARMebTriples: [1][]const u8 = .{"armeb-linux-gnueabi"};
78 const ARMebHFTriples: [2][]const u8 = .{ "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi" };
79
80 const AVRLibDirs: [1][]const u8 = .{"/lib"};
81 const AVRTriples: [1][]const u8 = .{"avr"};
82
83 const CSKYLibDirs: [1][]const u8 = .{"/lib"};
84 const CSKYTriples: [3][]const u8 = .{ "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2" };
85
86 const X86_64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
87 const X86_64Triples: [11][]const u8 = .{
88 "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",
89 "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",
90 "x86_64-redhat-linux", "x86_64-suse-linux",
91 "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
92 "x86_64-slackware-linux", "x86_64-unknown-linux",
93 "x86_64-amazon-linux",
94 };
95 const X32Triples: [2][]const u8 = .{ "x86_64-linux-gnux32", "x86_64-pc-linux-gnux32" };
96 const X32LibDirs: [2][]const u8 = .{ "/libx32", "/lib" };
97 const X86LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
98 const X86Triples: [9][]const u8 = .{
99 "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu",
100 "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux",
101 "i586-suse-linux", "i686-montavista-linux", "i686-gnu",
102 };
103
104 const LoongArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
105 const LoongArch64Triples: [2][]const u8 = .{ "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu" };
106
107 const M68kLibDirs: [1][]const u8 = .{"/lib"};
108 const M68kTriples: [3][]const u8 = .{ "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux" };
109
110 const MIPSLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
111 const MIPSTriples: [5][]const u8 = .{
112 "mips-linux-gnu", "mips-mti-linux",
113 "mips-mti-linux-gnu", "mips-img-linux-gnu",
114 "mipsisa32r6-linux-gnu",
115 };
116 const MIPSELLibDirs: [2][]const u8 = .{ "/libo32", "/lib" };
117 const MIPSELTriples: [3][]const u8 = .{ "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu" };
118
119 const MIPS64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
120 const MIPS64Triples: [6][]const u8 = .{
121 "mips64-linux-gnu", "mips-mti-linux-gnu",
122 "mips-img-linux-gnu", "mips64-linux-gnuabi64",
123 "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64",
124 };
125 const MIPS64ELLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
126 const MIPS64ELTriples: [6][]const u8 = .{
127 "mips64el-linux-gnu", "mips-mti-linux-gnu",
128 "mips-img-linux-gnu", "mips64el-linux-gnuabi64",
129 "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64",
130 };
131
132 const MIPSN32LibDirs: [1][]const u8 = .{"/lib32"};
133 const MIPSN32Triples: [2][]const u8 = .{ "mips64-linux-gnuabin32", "mipsisa64r6-linux-gnuabin32" };
134 const MIPSN32ELLibDirs: [1][]const u8 = .{"/lib32"};
135 const MIPSN32ELTriples: [2][]const u8 = .{ "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32" };
136
137 const MSP430LibDirs: [1][]const u8 = .{"/lib"};
138 const MSP430Triples: [1][]const u8 = .{"msp430-elf"};
139
140 const PPCLibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
141 const PPCTriples: [5][]const u8 = .{
142 "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
143 // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
144 // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".
145 "powerpc64-suse-linux", "powerpc-montavista-linuxspe",
146 };
147 const PPCLELibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
148 const PPCLETriples: [3][]const u8 = .{ "powerpcle-linux-gnu", "powerpcle-unknown-linux-gnu", "powerpcle-linux-musl" };
149
150 const PPC64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
151 const PPC64Triples: [4][]const u8 = .{
152 "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
153 "powerpc64-suse-linux", "ppc64-redhat-linux",
154 };
155 const PPC64LELibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
156 const PPC64LETriples: [5][]const u8 = .{
157 "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
158 "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux",
159 "ppc64le-redhat-linux",
160 };
161
162 const RISCV32LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
163 const RISCV32Triples: [3][]const u8 = .{ "riscv32-unknown-linux-gnu", "riscv32-linux-gnu", "riscv32-unknown-elf" };
164 const RISCV64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
165 const RISCV64Triples: [3][]const u8 = .{
166 "riscv64-unknown-linux-gnu",
167 "riscv64-linux-gnu",
168 "riscv64-unknown-elf",
169 };
170
171 const SPARCv8LibDirs: [2][]const u8 = .{ "/lib32", "/lib" };
172 const SPARCv8Triples: [2][]const u8 = .{ "sparc-linux-gnu", "sparcv8-linux-gnu" };
173 const SPARCv9LibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
174 const SPARCv9Triples: [2][]const u8 = .{ "sparc64-linux-gnu", "sparcv9-linux-gnu" };
175
176 const SystemZLibDirs: [2][]const u8 = .{ "/lib64", "/lib" };
177 const SystemZTriples: [5][]const u8 = .{
178 "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
179 "s390x-suse-linux", "s390x-redhat-linux",
180 };
181 const target = tc.getTarget();
182 if (target.os.tag == .solaris) {
183 // TODO
184 return;
185 }
186 if (target.isAndroid()) {
187 const AArch64AndroidTriples: [1][]const u8 = .{"aarch64-linux-android"};
188 const ARMAndroidTriples: [1][]const u8 = .{"arm-linux-androideabi"};
189 const MIPSELAndroidTriples: [1][]const u8 = .{"mipsel-linux-android"};
190 const MIPS64ELAndroidTriples: [1][]const u8 = .{"mips64el-linux-android"};
191 const X86AndroidTriples: [1][]const u8 = .{"i686-linux-android"};
192 const X86_64AndroidTriples: [1][]const u8 = .{"x86_64-linux-android"};
193
194 switch (target.cpu.arch) {
195 .aarch64 => {
196 lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
197 triple_aliases.appendSliceAssumeCapacity(&AArch64AndroidTriples);
198 },
199 .arm,
200 .thumb,
201 => {
202 lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
203 triple_aliases.appendSliceAssumeCapacity(&ARMAndroidTriples);
204 },
205 .mipsel => {
206 lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
207 triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
208 biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
209 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
210 },
211 .mips64el => {
212 lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
213 triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples);
214 biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
215 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples);
216 },
217 .x86_64 => {
218 lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
219 triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
220 biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
221 biarch_triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
222 },
223 .x86 => {
224 lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
225 triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples);
226 biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
227 biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples);
228 },
229 else => {},
230 }
231 return;
232 }
233 switch (target.cpu.arch) {
234 .aarch64 => {
235 lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs);
236 triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
237 biarch_libdirs.appendSliceAssumeCapacity(&AArch64LibDirs);
238 biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64Triples);
239 },
240 .aarch64_be => {
241 lib_dirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
242 triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
243 biarch_libdirs.appendSliceAssumeCapacity(&AArch64beLibDirs);
244 biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples);
245 },
246 .arm, .thumb => {
247 lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs);
248 if (target.abi == .gnueabihf) {
249 triple_aliases.appendSliceAssumeCapacity(&ARMHFTriples);
250 } else {
251 triple_aliases.appendSliceAssumeCapacity(&ARMTriples);
252 }
253 },
254 .armeb, .thumbeb => {
255 lib_dirs.appendSliceAssumeCapacity(&ARMebLibDirs);
256 if (target.abi == .gnueabihf) {
257 triple_aliases.appendSliceAssumeCapacity(&ARMebHFTriples);
258 } else {
259 triple_aliases.appendSliceAssumeCapacity(&ARMebTriples);
260 }
261 },
262 .avr => {
263 lib_dirs.appendSliceAssumeCapacity(&AVRLibDirs);
264 triple_aliases.appendSliceAssumeCapacity(&AVRTriples);
265 },
266 .csky => {
267 lib_dirs.appendSliceAssumeCapacity(&CSKYLibDirs);
268 triple_aliases.appendSliceAssumeCapacity(&CSKYTriples);
269 },
270 .x86_64 => {
271 if (target.abi == .gnux32 or target.abi == .muslx32) {
272 lib_dirs.appendSliceAssumeCapacity(&X32LibDirs);
273 triple_aliases.appendSliceAssumeCapacity(&X32Triples);
274 biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
275 biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
276 } else {
277 lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs);
278 triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
279 biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
280 biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
281 }
282 biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs);
283 biarch_triple_aliases.appendSliceAssumeCapacity(&X86Triples);
284 },
285 .x86 => {
286 lib_dirs.appendSliceAssumeCapacity(&X86LibDirs);
287 // MCU toolchain is 32 bit only and its triple alias is TargetTriple
288 // itself, which will be appended below.
289 if (target.os.tag != .elfiamcu) {
290 triple_aliases.appendSliceAssumeCapacity(&X86Triples);
291 biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs);
292 biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples);
293 biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs);
294 biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples);
295 }
296 },
297 .loongarch64 => {
298 lib_dirs.appendSliceAssumeCapacity(&LoongArch64LibDirs);
299 triple_aliases.appendSliceAssumeCapacity(&LoongArch64Triples);
300 },
301 .m68k => {
302 lib_dirs.appendSliceAssumeCapacity(&M68kLibDirs);
303 triple_aliases.appendSliceAssumeCapacity(&M68kTriples);
304 },
305 .mips => {
306 lib_dirs.appendSliceAssumeCapacity(&MIPSLibDirs);
307 triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
308 biarch_libdirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
309 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
310 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
311 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
312 },
313 .mipsel => {
314 lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
315 triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
316 triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
317 biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
318 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
319 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
320 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
321 },
322 .mips64 => {
323 lib_dirs.appendSliceAssumeCapacity(&MIPS64LibDirs);
324 triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples);
325 biarch_libdirs.appendSliceAssumeCapacity(&MIPSLibDirs);
326 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
327 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs);
328 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples);
329 },
330 .mips64el => {
331 lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs);
332 triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples);
333 biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs);
334 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples);
335 biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs);
336 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples);
337 biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples);
338 },
339 .msp430 => {
340 lib_dirs.appendSliceAssumeCapacity(&MSP430LibDirs);
341 triple_aliases.appendSliceAssumeCapacity(&MSP430Triples);
342 },
343 .powerpc => {
344 lib_dirs.appendSliceAssumeCapacity(&PPCLibDirs);
345 triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
346 biarch_libdirs.appendSliceAssumeCapacity(&PPC64LibDirs);
347 biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
348 },
349 .powerpcle => {
350 lib_dirs.appendSliceAssumeCapacity(&PPCLELibDirs);
351 triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
352 biarch_libdirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
353 biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
354 },
355 .powerpc64 => {
356 lib_dirs.appendSliceAssumeCapacity(&PPC64LibDirs);
357 triple_aliases.appendSliceAssumeCapacity(&PPC64Triples);
358 biarch_libdirs.appendSliceAssumeCapacity(&PPCLibDirs);
359 biarch_triple_aliases.appendSliceAssumeCapacity(&PPCTriples);
360 },
361 .powerpc64le => {
362 lib_dirs.appendSliceAssumeCapacity(&PPC64LELibDirs);
363 triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples);
364 biarch_libdirs.appendSliceAssumeCapacity(&PPCLELibDirs);
365 biarch_triple_aliases.appendSliceAssumeCapacity(&PPCLETriples);
366 },
367 .riscv32 => {
368 lib_dirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
369 triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
370 biarch_libdirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
371 biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
372 },
373 .riscv64 => {
374 lib_dirs.appendSliceAssumeCapacity(&RISCV64LibDirs);
375 triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples);
376 biarch_libdirs.appendSliceAssumeCapacity(&RISCV32LibDirs);
377 biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples);
378 },
379 .sparc, .sparcel => {
380 lib_dirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
381 triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
382 biarch_libdirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
383 biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
384 },
385 .sparc64 => {
386 lib_dirs.appendSliceAssumeCapacity(&SPARCv9LibDirs);
387 triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples);
388 biarch_libdirs.appendSliceAssumeCapacity(&SPARCv8LibDirs);
389 biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples);
390 },
391 .s390x => {
392 lib_dirs.appendSliceAssumeCapacity(&SystemZLibDirs);
393 triple_aliases.appendSliceAssumeCapacity(&SystemZTriples);
394 },
395 else => {},
396 }
397}
398
399pub fn discover(self: *GCCDetector, tc: *Toolchain) !void {
400 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
401 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
402
403 const target = tc.getTarget();
404 const biarch_variant_target = if (target.ptrBitWidth() == 32)
405 target_util.get64BitArchVariant(target)
406 else
407 target_util.get32BitArchVariant(target);
408
409 var candidate_lib_dirs_buffer: [16][]const u8 = undefined;
410 var candidate_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_lib_dirs_buffer);
411
412 var candidate_triple_aliases_buffer: [16][]const u8 = undefined;
413 var candidate_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_triple_aliases_buffer);
414
415 var candidate_biarch_lib_dirs_buffer: [16][]const u8 = undefined;
416 var candidate_biarch_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_lib_dirs_buffer);
417
418 var candidate_biarch_triple_aliases_buffer: [16][]const u8 = undefined;
419 var candidate_biarch_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_triple_aliases_buffer);
420
421 try collectLibDirsAndTriples(
422 tc,
423 &candidate_lib_dirs,
424 &candidate_triple_aliases,
425 &candidate_biarch_lib_dirs,
426 &candidate_biarch_triple_aliases,
427 );
428
429 var target_buf: [64]u8 = undefined;
430 const triple_str = target_util.toLLVMTriple(target, &target_buf);
431 candidate_triple_aliases.appendAssumeCapacity(triple_str);
432
433 // Also include the multiarch variant if it's different.
434 var biarch_buf: [64]u8 = undefined;
435 if (biarch_variant_target) |biarch_target| {
436 const biarch_triple_str = target_util.toLLVMTriple(biarch_target, &biarch_buf);
437 if (!std.mem.eql(u8, biarch_triple_str, triple_str)) {
438 candidate_triple_aliases.appendAssumeCapacity(biarch_triple_str);
439 }
440 }
441
442 var prefixes_buf: [16][]const u8 = undefined;
443 var prefixes = std.ArrayListUnmanaged([]const u8).initBuffer(&prefixes_buf);
444 const gcc_toolchain_dir = gccToolchainDir(tc);
445 if (gcc_toolchain_dir.len != 0) {
446 const adjusted = if (gcc_toolchain_dir[gcc_toolchain_dir.len - 1] == '/')
447 gcc_toolchain_dir[0 .. gcc_toolchain_dir.len - 1]
448 else
449 gcc_toolchain_dir;
450 prefixes.appendAssumeCapacity(adjusted);
451 } else {
452 const sysroot = tc.getSysroot();
453 if (sysroot.len > 0) {
454 prefixes.appendAssumeCapacity(sysroot);
455 try addDefaultGCCPrefixes(&prefixes, tc);
456 }
457
458 if (sysroot.len == 0) {
459 try addDefaultGCCPrefixes(&prefixes, tc);
460 }
461 // TODO: Special-case handling for Gentoo
462 }
463
464 const v0 = GCCVersion.parse("0.0.0");
465 for (prefixes.items) |prefix| {
466 if (!tc.filesystem.exists(prefix)) continue;
467
468 for (candidate_lib_dirs.items) |suffix| {
469 defer fib.reset();
470 const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
471 if (!tc.filesystem.exists(lib_dir)) continue;
472
473 const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
474 const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
475
476 try self.scanLibDirForGCCTriple(tc, target, lib_dir, triple_str, false, gcc_dir_exists, gcc_cross_dir_exists);
477 for (candidate_triple_aliases.items) |candidate| {
478 try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, false, gcc_dir_exists, gcc_cross_dir_exists);
479 }
480 }
481 for (candidate_biarch_lib_dirs.items) |suffix| {
482 const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue;
483 if (!tc.filesystem.exists(lib_dir)) continue;
484
485 const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" });
486 const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" });
487 for (candidate_biarch_triple_aliases.items) |candidate| {
488 try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, true, gcc_dir_exists, gcc_cross_dir_exists);
489 }
490 }
491 if (self.version.order(v0) == .gt) break;
492 }
493}
494
495fn findBiarchMultilibs(
496 tc: *const Toolchain,
497 result: *Multilib.Detected,
498 target: std.Target,
499 path: [2][]const u8,
500 needs_biarch_suffix: bool,
501) !bool {
502 const suff64 = if (target.os.tag == .solaris) switch (target.cpu.arch) {
503 .x86, .x86_64 => "/amd64",
504 .sparc => "/sparcv9",
505 else => "/64",
506 } else "/64";
507
508 const alt_64 = Multilib.init(suff64, suff64, &.{ "-m32", "+m64", "-mx32" });
509 const alt_32 = Multilib.init("/32", "/32", &.{ "+m32", "-m64", "-mx32" });
510 const alt_x32 = Multilib.init("/x32", "/x32", &.{ "-m32", "-m64", "+mx32" });
511
512 const multilib_filter = Multilib.Filter{
513 .base = path,
514 .file = if (target.os.tag == .elfiamcu) "libgcc.a" else "crtbegin.o",
515 };
516
517 const Want = enum {
518 want32,
519 want64,
520 wantx32,
521 };
522 const is_x32 = target.abi == .gnux32 or target.abi == .muslx32;
523 const target_ptr_width = target.ptrBitWidth();
524 const want: Want = if (target_ptr_width == 32 and multilib_filter.exists(alt_32, tc.filesystem))
525 .want64
526 else if (target_ptr_width == 64 and is_x32 and multilib_filter.exists(alt_x32, tc.filesystem))
527 .want64
528 else if (target_ptr_width == 64 and !is_x32 and multilib_filter.exists(alt_64, tc.filesystem))
529 .want32
530 else if (target_ptr_width == 32)
531 if (needs_biarch_suffix) .want64 else .want32
532 else if (is_x32)
533 if (needs_biarch_suffix) .want64 else .wantx32
534 else if (needs_biarch_suffix) .want32 else .want64;
535
536 const default = switch (want) {
537 .want32 => Multilib.init("", "", &.{ "+m32", "-m64", "-mx32" }),
538 .want64 => Multilib.init("", "", &.{ "-m32", "+m64", "-mx32" }),
539 .wantx32 => Multilib.init("", "", &.{ "-m32", "-m64", "+mx32" }),
540 };
541 result.multilibs.appendSliceAssumeCapacity(&.{
542 default,
543 alt_64,
544 alt_32,
545 alt_x32,
546 });
547 result.filter(multilib_filter, tc.filesystem);
548 var flags: Multilib.Flags = .{};
549 flags.appendAssumeCapacity(if (target_ptr_width == 64 and !is_x32) "+m64" else "-m64");
550 flags.appendAssumeCapacity(if (target_ptr_width == 32) "+m32" else "-m32");
551 flags.appendAssumeCapacity(if (target_ptr_width == 64 and is_x32) "+mx32" else "-mx32");
552
553 return result.select(flags);
554}
555
556fn scanGCCForMultilibs(
557 self: *GCCDetector,
558 tc: *const Toolchain,
559 target: std.Target,
560 path: [2][]const u8,
561 needs_biarch_suffix: bool,
562) !bool {
563 var detected: Multilib.Detected = .{};
564 if (target.cpu.arch == .csky) {
565 // TODO
566 } else if (target.cpu.arch.isMIPS()) {
567 // TODO
568 } else if (target.cpu.arch.isRISCV()) {
569 // TODO
570 } else if (target.cpu.arch == .msp430) {
571 // TODO
572 } else if (target.cpu.arch == .avr) {
573 // No multilibs
574 } else if (!try findBiarchMultilibs(tc, &detected, target, path, needs_biarch_suffix)) {
575 return false;
576 }
577 self.selected = detected.selected;
578 self.biarch_sibling = detected.biarch_sibling;
579 return true;
580}
581
582fn scanLibDirForGCCTriple(
583 self: *GCCDetector,
584 tc: *const Toolchain,
585 target: std.Target,
586 lib_dir: []const u8,
587 candidate_triple: []const u8,
588 needs_biarch_suffix: bool,
589 gcc_dir_exists: bool,
590 gcc_cross_dir_exists: bool,
591) !void {
592 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
593 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
594 for (0..2) |i| {
595 if (i == 0 and !gcc_dir_exists) continue;
596 if (i == 1 and !gcc_cross_dir_exists) continue;
597 defer fib.reset();
598
599 const base: []const u8 = if (i == 0) "gcc" else "gcc-cross";
600 var lib_suffix_buf: [64]u8 = undefined;
601 var suffix_buf_fib = std.heap.FixedBufferAllocator.init(&lib_suffix_buf);
602 const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue;
603
604 const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue;
605 var parent_dir = tc.filesystem.openDir(dir_name) catch continue;
606 defer parent_dir.close();
607
608 var it = parent_dir.iterate();
609 while (it.next() catch continue) |entry| {
610 if (entry.kind != .directory) continue;
611
612 const version_text = entry.name;
613 const candidate_version = GCCVersion.parse(version_text);
614 if (candidate_version.major != -1) {
615 // TODO: cache path so we're not repeatedly scanning
616 }
617 if (candidate_version.isLessThan(4, 1, 1, "")) continue;
618 switch (candidate_version.order(self.version)) {
619 .lt, .eq => continue,
620 .gt => {},
621 }
622
623 if (!try self.scanGCCForMultilibs(tc, target, .{ dir_name, version_text }, needs_biarch_suffix)) continue;
624
625 self.version = candidate_version;
626 self.gcc_triple = try tc.arena.dupe(u8, candidate_triple);
627 self.install_path = try std.fs.path.join(tc.arena, &.{ lib_dir, lib_suffix, version_text });
628 self.parent_lib_path = try std.fs.path.join(tc.arena, &.{ self.install_path, "..", "..", ".." });
629 self.is_valid = true;
630 }
631 }
632}
633
634fn gccToolchainDir(tc: *const Toolchain) []const u8 {
635 const sysroot = tc.getSysroot();
636 if (sysroot.len != 0) return "";
637 return system_defaults.gcc_install_prefix;
638}
lib/compiler/aro/aro/Driver/GCCVersion.zig created+122
......@@ -0,0 +1,122 @@
1const std = @import("std");
2const mem = std.mem;
3const Order = std.math.Order;
4
5const GCCVersion = @This();
6
7/// Raw version number text
8raw: []const u8 = "",
9
10/// -1 indicates not present
11major: i32 = -1,
12/// -1 indicates not present
13minor: i32 = -1,
14/// -1 indicates not present
15patch: i32 = -1,
16
17/// Text of parsed major version number
18major_str: []const u8 = "",
19/// Text of parsed major + minor version number
20minor_str: []const u8 = "",
21
22/// Patch number suffix
23suffix: []const u8 = "",
24
25/// This orders versions according to the preferred usage order, not a notion of release-time ordering
26/// Higher version numbers are preferred, but nonexistent minor/patch/suffix is preferred to one that does exist
27/// e.g. `4.1` is preferred over `4.0` but `4` is preferred over both `4.0` and `4.1`
28pub fn isLessThan(self: GCCVersion, rhs_major: i32, rhs_minor: i32, rhs_patch: i32, rhs_suffix: []const u8) bool {
29 if (self.major != rhs_major) {
30 return self.major < rhs_major;
31 }
32 if (self.minor != rhs_minor) {
33 if (rhs_minor == -1) return true;
34 if (self.minor == -1) return false;
35 return self.minor < rhs_minor;
36 }
37 if (self.patch != rhs_patch) {
38 if (rhs_patch == -1) return true;
39 if (self.patch == -1) return false;
40 return self.patch < rhs_patch;
41 }
42 if (!mem.eql(u8, self.suffix, rhs_suffix)) {
43 if (rhs_suffix.len == 0) return true;
44 if (self.suffix.len == 0) return false;
45 return switch (std.mem.order(u8, self.suffix, rhs_suffix)) {
46 .lt => true,
47 .eq => unreachable,
48 .gt => false,
49 };
50 }
51 return false;
52}
53
54/// Strings in the returned GCCVersion struct have the same lifetime as `text`
55pub fn parse(text: []const u8) GCCVersion {
56 const bad = GCCVersion{ .major = -1 };
57 var good = bad;
58
59 var it = mem.splitScalar(u8, text, '.');
60 const first = it.next().?;
61 const second = it.next() orelse "";
62 const rest = it.next() orelse "";
63
64 good.major = std.fmt.parseInt(i32, first, 10) catch return bad;
65 if (good.major < 0) return bad;
66 good.major_str = first;
67
68 if (second.len == 0) return good;
69 var minor_str = second;
70
71 if (rest.len == 0) {
72 const end = mem.indexOfNone(u8, minor_str, "0123456789") orelse minor_str.len;
73 if (end > 0) {
74 good.suffix = minor_str[end..];
75 minor_str = minor_str[0..end];
76 }
77 }
78 good.minor = std.fmt.parseInt(i32, minor_str, 10) catch return bad;
79 if (good.minor < 0) return bad;
80 good.minor_str = minor_str;
81
82 if (rest.len > 0) {
83 const end = mem.indexOfNone(u8, rest, "0123456789") orelse rest.len;
84 if (end > 0) {
85 const patch_num_text = rest[0..end];
86 good.patch = std.fmt.parseInt(i32, patch_num_text, 10) catch return bad;
87 if (good.patch < 0) return bad;
88 good.suffix = rest[end..];
89 }
90 }
91
92 return good;
93}
94
95pub fn order(a: GCCVersion, b: GCCVersion) Order {
96 if (a.isLessThan(b.major, b.minor, b.patch, b.suffix)) return .lt;
97 if (b.isLessThan(a.major, a.minor, a.patch, a.suffix)) return .gt;
98 return .eq;
99}
100
101test parse {
102 const versions = [10]GCCVersion{
103 parse("5"),
104 parse("4"),
105 parse("4.2"),
106 parse("4.0"),
107 parse("4.0-patched"),
108 parse("4.0.2"),
109 parse("4.0.1"),
110 parse("4.0.1-patched"),
111 parse("4.0.0"),
112 parse("4.0.0-patched"),
113 };
114
115 for (versions[0 .. versions.len - 1], versions[1..versions.len]) |first, second| {
116 try std.testing.expectEqual(Order.eq, first.order(first));
117 try std.testing.expectEqual(Order.gt, first.order(second));
118 try std.testing.expectEqual(Order.lt, second.order(first));
119 }
120 const last = versions[versions.len - 1];
121 try std.testing.expectEqual(Order.eq, last.order(last));
122}
lib/compiler/aro/aro/Driver/Multilib.zig created+71
......@@ -0,0 +1,71 @@
1const std = @import("std");
2const Filesystem = @import("Filesystem.zig").Filesystem;
3
4pub const Flags = std.BoundedArray([]const u8, 6);
5
6/// Large enough for GCCDetector for Linux; may need to be increased to support other toolchains.
7const max_multilibs = 4;
8
9const MultilibArray = std.BoundedArray(Multilib, max_multilibs);
10
11pub const Detected = struct {
12 multilibs: MultilibArray = .{},
13 selected: Multilib = .{},
14 biarch_sibling: ?Multilib = null,
15
16 pub fn filter(self: *Detected, multilib_filter: Filter, fs: Filesystem) void {
17 var found_count: usize = 0;
18 for (self.multilibs.constSlice()) |multilib| {
19 if (multilib_filter.exists(multilib, fs)) {
20 self.multilibs.set(found_count, multilib);
21 found_count += 1;
22 }
23 }
24 self.multilibs.resize(found_count) catch unreachable;
25 }
26
27 pub fn select(self: *Detected, flags: Flags) !bool {
28 var filtered: MultilibArray = .{};
29 for (self.multilibs.constSlice()) |multilib| {
30 for (multilib.flags.constSlice()) |multilib_flag| {
31 const matched = for (flags.constSlice()) |arg_flag| {
32 if (std.mem.eql(u8, arg_flag[1..], multilib_flag[1..])) break arg_flag;
33 } else multilib_flag;
34 if (matched[0] != multilib_flag[0]) break;
35 } else {
36 filtered.appendAssumeCapacity(multilib);
37 }
38 }
39 if (filtered.len == 0) return false;
40 if (filtered.len == 1) {
41 self.selected = filtered.get(0);
42 return true;
43 }
44 return error.TooManyMultilibs;
45 }
46};
47
48pub const Filter = struct {
49 base: [2][]const u8,
50 file: []const u8,
51 pub fn exists(self: Filter, m: Multilib, fs: Filesystem) bool {
52 return fs.joinedExists(&.{ self.base[0], self.base[1], m.gcc_suffix, self.file });
53 }
54};
55
56const Multilib = @This();
57
58gcc_suffix: []const u8 = "",
59os_suffix: []const u8 = "",
60include_suffix: []const u8 = "",
61flags: Flags = .{},
62priority: u32 = 0,
63
64pub fn init(gcc_suffix: []const u8, os_suffix: []const u8, flags: []const []const u8) Multilib {
65 var self: Multilib = .{
66 .gcc_suffix = gcc_suffix,
67 .os_suffix = os_suffix,
68 };
69 self.flags.appendSliceAssumeCapacity(flags);
70 return self;
71}
lib/compiler/aro/aro/InitList.zig created+153
......@@ -0,0 +1,153 @@
1//! Sparsely populated list of used indexes.
2//! Used for detecting duplicate initializers.
3const std = @import("std");
4const Allocator = std.mem.Allocator;
5const testing = std.testing;
6const Tree = @import("Tree.zig");
7const Token = Tree.Token;
8const TokenIndex = Tree.TokenIndex;
9const NodeIndex = Tree.NodeIndex;
10const Type = @import("Type.zig");
11const Diagnostics = @import("Diagnostics.zig");
12const NodeList = std.ArrayList(NodeIndex);
13const Parser = @import("Parser.zig");
14
15const Item = struct {
16 list: InitList = .{},
17 index: u64,
18
19 fn order(_: void, a: Item, b: Item) std.math.Order {
20 return std.math.order(a.index, b.index);
21 }
22};
23
24const InitList = @This();
25
26list: std.ArrayListUnmanaged(Item) = .{},
27node: NodeIndex = .none,
28tok: TokenIndex = 0,
29
30/// Deinitialize freeing all memory.
31pub fn deinit(il: *InitList, gpa: Allocator) void {
32 for (il.list.items) |*item| item.list.deinit(gpa);
33 il.list.deinit(gpa);
34 il.* = undefined;
35}
36
37/// Insert initializer at index, returning previous entry if one exists.
38pub fn put(il: *InitList, gpa: Allocator, index: usize, node: NodeIndex, tok: TokenIndex) !?TokenIndex {
39 const items = il.list.items;
40 var left: usize = 0;
41 var right: usize = items.len;
42
43 // Append new value to empty list
44 if (left == right) {
45 const item = try il.list.addOne(gpa);
46 item.* = .{
47 .list = .{ .node = node, .tok = tok },
48 .index = index,
49 };
50 return null;
51 }
52
53 while (left < right) {
54 // Avoid overflowing in the midpoint calculation
55 const mid = left + (right - left) / 2;
56 // Compare the key with the midpoint element
57 switch (std.math.order(index, items[mid].index)) {
58 .eq => {
59 // Replace previous entry.
60 const prev = items[mid].list.tok;
61 items[mid].list.deinit(gpa);
62 items[mid] = .{
63 .list = .{ .node = node, .tok = tok },
64 .index = index,
65 };
66 return prev;
67 },
68 .gt => left = mid + 1,
69 .lt => right = mid,
70 }
71 }
72
73 // Insert a new value into a sorted position.
74 try il.list.insert(gpa, left, .{
75 .list = .{ .node = node, .tok = tok },
76 .index = index,
77 });
78 return null;
79}
80
81/// Find item at index, create new if one does not exist.
82pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
83 const items = il.list.items;
84 var left: usize = 0;
85 var right: usize = items.len;
86
87 // Append new value to empty list
88 if (left == right) {
89 const item = try il.list.addOne(gpa);
90 item.* = .{
91 .list = .{ .node = .none, .tok = 0 },
92 .index = index,
93 };
94 return &item.list;
95 }
96
97 while (left < right) {
98 // Avoid overflowing in the midpoint calculation
99 const mid = left + (right - left) / 2;
100 // Compare the key with the midpoint element
101 switch (std.math.order(index, items[mid].index)) {
102 .eq => return &items[mid].list,
103 .gt => left = mid + 1,
104 .lt => right = mid,
105 }
106 }
107
108 // Insert a new value into a sorted position.
109 try il.list.insert(gpa, left, .{
110 .list = .{ .node = .none, .tok = 0 },
111 .index = index,
112 });
113 return &il.list.items[left].list;
114}
115
116test "basic usage" {
117 const gpa = testing.allocator;
118 var il: InitList = .{};
119 defer il.deinit(gpa);
120
121 {
122 var i: usize = 0;
123 while (i < 5) : (i += 1) {
124 const prev = try il.put(gpa, i, .none, 0);
125 try testing.expect(prev == null);
126 }
127 }
128
129 {
130 const failing = testing.failing_allocator;
131 var i: usize = 0;
132 while (i < 5) : (i += 1) {
133 _ = try il.find(failing, i);
134 }
135 }
136
137 {
138 var item = try il.find(gpa, 0);
139 var i: usize = 1;
140 while (i < 5) : (i += 1) {
141 item = try item.find(gpa, i);
142 }
143 }
144
145 {
146 const failing = testing.failing_allocator;
147 var item = try il.find(failing, 0);
148 var i: usize = 1;
149 while (i < 5) : (i += 1) {
150 item = try item.find(failing, i);
151 }
152 }
153}
lib/compiler/aro/aro/LangOpts.zig created+171
......@@ -0,0 +1,171 @@
1const std = @import("std");
2const DiagnosticTag = @import("Diagnostics.zig").Tag;
3const char_info = @import("char_info.zig");
4
5pub const Compiler = enum {
6 clang,
7 gcc,
8 msvc,
9};
10
11/// The floating-point evaluation method for intermediate results within a single expression
12pub const FPEvalMethod = enum(i8) {
13 /// The evaluation method cannot be determined or is inconsistent for this target.
14 indeterminate = -1,
15 /// Use the type declared in the source
16 source = 0,
17 /// Use double as the floating-point evaluation method for all float expressions narrower than double.
18 double = 1,
19 /// Use long double as the floating-point evaluation method for all float expressions narrower than long double.
20 extended = 2,
21};
22
23pub const Standard = enum {
24 /// ISO C 1990
25 c89,
26 /// ISO C 1990 with amendment 1
27 iso9899,
28 /// ISO C 1990 with GNU extensions
29 gnu89,
30 /// ISO C 1999
31 c99,
32 /// ISO C 1999 with GNU extensions
33 gnu99,
34 /// ISO C 2011
35 c11,
36 /// ISO C 2011 with GNU extensions
37 gnu11,
38 /// ISO C 2017
39 c17,
40 /// Default value if nothing specified; adds the GNU keywords to
41 /// C17 but does not suppress warnings about using GNU extensions
42 default,
43 /// ISO C 2017 with GNU extensions
44 gnu17,
45 /// Working Draft for ISO C23
46 c23,
47 /// Working Draft for ISO C23 with GNU extensions
48 gnu23,
49
50 const NameMap = std.ComptimeStringMap(Standard, .{
51 .{ "c89", .c89 }, .{ "c90", .c89 }, .{ "iso9899:1990", .c89 },
52 .{ "iso9899:199409", .iso9899 }, .{ "gnu89", .gnu89 }, .{ "gnu90", .gnu89 },
53 .{ "c99", .c99 }, .{ "iso9899:1999", .c99 }, .{ "c9x", .c99 },
54 .{ "iso9899:199x", .c99 }, .{ "gnu99", .gnu99 }, .{ "gnu9x", .gnu99 },
55 .{ "c11", .c11 }, .{ "iso9899:2011", .c11 }, .{ "c1x", .c11 },
56 .{ "iso9899:201x", .c11 }, .{ "gnu11", .gnu11 }, .{ "c17", .c17 },
57 .{ "iso9899:2017", .c17 }, .{ "c18", .c17 }, .{ "iso9899:2018", .c17 },
58 .{ "gnu17", .gnu17 }, .{ "gnu18", .gnu17 }, .{ "c23", .c23 },
59 .{ "gnu23", .gnu23 }, .{ "c2x", .c23 }, .{ "gnu2x", .gnu23 },
60 });
61
62 pub fn atLeast(self: Standard, other: Standard) bool {
63 return @intFromEnum(self) >= @intFromEnum(other);
64 }
65
66 pub fn isGNU(standard: Standard) bool {
67 return switch (standard) {
68 .gnu89, .gnu99, .gnu11, .default, .gnu17, .gnu23 => true,
69 else => false,
70 };
71 }
72
73 pub fn isExplicitGNU(standard: Standard) bool {
74 return standard.isGNU() and standard != .default;
75 }
76
77 /// Value reported by __STDC_VERSION__ macro
78 pub fn StdCVersionMacro(standard: Standard) ?[]const u8 {
79 return switch (standard) {
80 .c89, .gnu89 => null,
81 .iso9899 => "199409L",
82 .c99, .gnu99 => "199901L",
83 .c11, .gnu11 => "201112L",
84 .default, .c17, .gnu17 => "201710L",
85 .c23, .gnu23 => "202311L",
86 };
87 }
88
89 pub fn codepointAllowedInIdentifier(standard: Standard, codepoint: u21, is_start: bool) bool {
90 if (is_start) {
91 return if (standard.atLeast(.c23))
92 char_info.isXidStart(codepoint)
93 else if (standard.atLeast(.c11))
94 char_info.isC11IdChar(codepoint) and !char_info.isC11DisallowedInitialIdChar(codepoint)
95 else
96 char_info.isC99IdChar(codepoint) and !char_info.isC99DisallowedInitialIDChar(codepoint);
97 } else {
98 return if (standard.atLeast(.c23))
99 char_info.isXidContinue(codepoint)
100 else if (standard.atLeast(.c11))
101 char_info.isC11IdChar(codepoint)
102 else
103 char_info.isC99IdChar(codepoint);
104 }
105 }
106};
107
108const LangOpts = @This();
109
110emulate: Compiler = .clang,
111standard: Standard = .default,
112/// -fshort-enums option, makes enums only take up as much space as they need to hold all the values.
113short_enums: bool = false,
114dollars_in_identifiers: bool = true,
115declspec_attrs: bool = false,
116ms_extensions: bool = false,
117/// true or false if digraph support explicitly enabled/disabled with -fdigraphs/-fno-digraphs
118digraphs: ?bool = null,
119/// If set, use the native half type instead of promoting to float
120use_native_half_type: bool = false,
121/// If set, function arguments and return values may be of type __fp16 even if there is no standard ABI for it
122allow_half_args_and_returns: bool = false,
123/// null indicates that the user did not select a value, use target to determine default
124fp_eval_method: ?FPEvalMethod = null,
125/// If set, use specified signedness for `char` instead of the target's default char signedness
126char_signedness_override: ?std.builtin.Signedness = null,
127/// If set, override the default availability of char8_t (by default, enabled in C23 and later; disabled otherwise)
128has_char8_t_override: ?bool = null,
129
130/// Whether to allow GNU-style inline assembly
131gnu_asm: bool = true,
132
133/// Preserve comments when preprocessing
134preserve_comments: bool = false,
135/// Preserve comments in macros when preprocessing
136preserve_comments_in_macros: bool = false,
137
138pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void {
139 self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard;
140}
141
142pub fn enableMSExtensions(self: *LangOpts) void {
143 self.declspec_attrs = true;
144 self.ms_extensions = true;
145}
146
147pub fn disableMSExtensions(self: *LangOpts) void {
148 self.declspec_attrs = false;
149 self.ms_extensions = true;
150}
151
152pub fn hasChar8_T(self: *const LangOpts) bool {
153 return self.has_char8_t_override orelse self.standard.atLeast(.c23);
154}
155
156pub fn hasDigraphs(self: *const LangOpts) bool {
157 return self.digraphs orelse self.standard.atLeast(.gnu89);
158}
159
160pub fn setEmulatedCompiler(self: *LangOpts, compiler: Compiler) void {
161 self.emulate = compiler;
162 if (compiler == .msvc) self.enableMSExtensions();
163}
164
165pub fn setFpEvalMethod(self: *LangOpts, fp_eval_method: FPEvalMethod) void {
166 self.fp_eval_method = fp_eval_method;
167}
168
169pub fn setCharSignedness(self: *LangOpts, signedness: std.builtin.Signedness) void {
170 self.char_signedness_override = signedness;
171}
lib/compiler/aro/aro/Parser.zig created+8437
......@@ -0,0 +1,8437 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const assert = std.debug.assert;
5const big = std.math.big;
6const Compilation = @import("Compilation.zig");
7const Source = @import("Source.zig");
8const Tokenizer = @import("Tokenizer.zig");
9const Preprocessor = @import("Preprocessor.zig");
10const Tree = @import("Tree.zig");
11const Token = Tree.Token;
12const NumberPrefix = Token.NumberPrefix;
13const NumberSuffix = Token.NumberSuffix;
14const TokenIndex = Tree.TokenIndex;
15const NodeIndex = Tree.NodeIndex;
16const Type = @import("Type.zig");
17const Diagnostics = @import("Diagnostics.zig");
18const NodeList = std.ArrayList(NodeIndex);
19const InitList = @import("InitList.zig");
20const Attribute = @import("Attribute.zig");
21const char_info = @import("char_info.zig");
22const text_literal = @import("text_literal.zig");
23const Value = @import("Value.zig");
24const SymbolStack = @import("SymbolStack.zig");
25const Symbol = SymbolStack.Symbol;
26const record_layout = @import("record_layout.zig");
27const StrInt = @import("StringInterner.zig");
28const StringId = StrInt.StringId;
29const Builtins = @import("Builtins.zig");
30const Builtin = Builtins.Builtin;
31const target_util = @import("target.zig");
32
33const Switch = struct {
34 default: ?TokenIndex = null,
35 ranges: std.ArrayList(Range),
36 ty: Type,
37 comp: *Compilation,
38
39 const Range = struct {
40 first: Value,
41 last: Value,
42 tok: TokenIndex,
43 };
44
45 fn add(self: *Switch, first: Value, last: Value, tok: TokenIndex) !?Range {
46 for (self.ranges.items) |range| {
47 if (last.compare(.gte, range.first, self.comp) and first.compare(.lte, range.last, self.comp)) {
48 return range; // They overlap.
49 }
50 }
51 try self.ranges.append(.{
52 .first = first,
53 .last = last,
54 .tok = tok,
55 });
56 return null;
57 }
58};
59
60const Label = union(enum) {
61 unresolved_goto: TokenIndex,
62 label: TokenIndex,
63};
64
65pub const Error = Compilation.Error || error{ParsingFailed};
66
67/// An attribute that has been parsed but not yet validated in its context
68const TentativeAttribute = struct {
69 attr: Attribute,
70 tok: TokenIndex,
71};
72
73/// How the parser handles const int decl references when it is expecting an integer
74/// constant expression.
75const ConstDeclFoldingMode = enum {
76 /// fold const decls as if they were literals
77 fold_const_decls,
78 /// fold const decls as if they were literals and issue GNU extension diagnostic
79 gnu_folding_extension,
80 /// fold const decls as if they were literals and issue VLA diagnostic
81 gnu_vla_folding_extension,
82 /// folding const decls is prohibited; return an unavailable value
83 no_const_decl_folding,
84};
85
86const Parser = @This();
87
88// values from preprocessor
89pp: *Preprocessor,
90comp: *Compilation,
91gpa: mem.Allocator,
92tok_ids: []const Token.Id,
93tok_i: TokenIndex = 0,
94
95// values of the incomplete Tree
96arena: Allocator,
97nodes: Tree.Node.List = .{},
98data: NodeList,
99value_map: Tree.ValueMap,
100
101// buffers used during compilation
102syms: SymbolStack = .{},
103strings: std.ArrayList(u8),
104labels: std.ArrayList(Label),
105list_buf: NodeList,
106decl_buf: NodeList,
107param_buf: std.ArrayList(Type.Func.Param),
108enum_buf: std.ArrayList(Type.Enum.Field),
109record_buf: std.ArrayList(Type.Record.Field),
110attr_buf: std.MultiArrayList(TentativeAttribute) = .{},
111attr_application_buf: std.ArrayListUnmanaged(Attribute) = .{},
112field_attr_buf: std.ArrayList([]const Attribute),
113/// type name -> variable name location for tentative definitions (top-level defs with thus-far-incomplete types)
114/// e.g. `struct Foo bar;` where `struct Foo` is not defined yet.
115/// The key is the StringId of `Foo` and the value is the TokenIndex of `bar`
116/// Items are removed if the type is subsequently completed with a definition.
117/// We only store the first tentative definition that uses a given type because this map is only used
118/// for issuing an error message, and correcting the first error for a type will fix all of them for that type.
119tentative_defs: std.AutoHashMapUnmanaged(StringId, TokenIndex) = .{},
120
121// configuration and miscellaneous info
122no_eval: bool = false,
123in_macro: bool = false,
124extension_suppressed: bool = false,
125contains_address_of_label: bool = false,
126label_count: u32 = 0,
127const_decl_folding: ConstDeclFoldingMode = .fold_const_decls,
128/// location of first computed goto in function currently being parsed
129/// if a computed goto is used, the function must contain an
130/// address-of-label expression (tracked with contains_address_of_label)
131computed_goto_tok: ?TokenIndex = null,
132
133/// Various variables that are different for each function.
134func: struct {
135 /// null if not in function, will always be plain func, var_args_func or old_style_func
136 ty: ?Type = null,
137 name: TokenIndex = 0,
138 ident: ?Result = null,
139 pretty_ident: ?Result = null,
140} = .{},
141/// Various variables that are different for each record.
142record: struct {
143 // invalid means we're not parsing a record
144 kind: Token.Id = .invalid,
145 flexible_field: ?TokenIndex = null,
146 start: usize = 0,
147 field_attr_start: usize = 0,
148
149 fn addField(r: @This(), p: *Parser, name: StringId, tok: TokenIndex) Error!void {
150 var i = p.record_members.items.len;
151 while (i > r.start) {
152 i -= 1;
153 if (p.record_members.items[i].name == name) {
154 try p.errStr(.duplicate_member, tok, p.tokSlice(tok));
155 try p.errTok(.previous_definition, p.record_members.items[i].tok);
156 break;
157 }
158 }
159 try p.record_members.append(p.gpa, .{ .name = name, .tok = tok });
160 }
161
162 fn addFieldsFromAnonymous(r: @This(), p: *Parser, ty: Type) Error!void {
163 for (ty.data.record.fields) |f| {
164 if (f.isAnonymousRecord()) {
165 try r.addFieldsFromAnonymous(p, f.ty.canonicalize(.standard));
166 } else if (f.name_tok != 0) {
167 try r.addField(p, f.name, f.name_tok);
168 }
169 }
170 }
171} = .{},
172record_members: std.ArrayListUnmanaged(struct { tok: TokenIndex, name: StringId }) = .{},
173@"switch": ?*Switch = null,
174in_loop: bool = false,
175pragma_pack: ?u8 = null,
176string_ids: struct {
177 declspec_id: StringId,
178 main_id: StringId,
179 file: StringId,
180 jmp_buf: StringId,
181 sigjmp_buf: StringId,
182 ucontext_t: StringId,
183},
184
185/// Checks codepoint for various pedantic warnings
186/// Returns true if diagnostic issued
187fn checkIdentifierCodepointWarnings(comp: *Compilation, codepoint: u21, loc: Source.Location) Compilation.Error!bool {
188 assert(codepoint >= 0x80);
189
190 const err_start = comp.diagnostics.list.items.len;
191
192 if (!char_info.isC99IdChar(codepoint)) {
193 try comp.addDiagnostic(.{
194 .tag = .c99_compat,
195 .loc = loc,
196 }, &.{});
197 }
198 if (char_info.isInvisible(codepoint)) {
199 try comp.addDiagnostic(.{
200 .tag = .unicode_zero_width,
201 .loc = loc,
202 .extra = .{ .actual_codepoint = codepoint },
203 }, &.{});
204 }
205 if (char_info.homoglyph(codepoint)) |resembles| {
206 try comp.addDiagnostic(.{
207 .tag = .unicode_homoglyph,
208 .loc = loc,
209 .extra = .{ .codepoints = .{ .actual = codepoint, .resembles = resembles } },
210 }, &.{});
211 }
212 return comp.diagnostics.list.items.len != err_start;
213}
214
215/// Issues diagnostics for the current extended identifier token
216/// Return value indicates whether the token should be considered an identifier
217/// true means consider the token to actually be an identifier
218/// false means it is not
219fn validateExtendedIdentifier(p: *Parser) !bool {
220 assert(p.tok_ids[p.tok_i] == .extended_identifier);
221
222 const slice = p.tokSlice(p.tok_i);
223 const view = std.unicode.Utf8View.init(slice) catch {
224 try p.errTok(.invalid_utf8, p.tok_i);
225 return error.FatalError;
226 };
227 var it = view.iterator();
228
229 var valid_identifier = true;
230 var warned = false;
231 var len: usize = 0;
232 var invalid_char: u21 = undefined;
233 var loc = p.pp.tokens.items(.loc)[p.tok_i];
234
235 var normalized = true;
236 var last_canonical_class: char_info.CanonicalCombiningClass = .not_reordered;
237 const standard = p.comp.langopts.standard;
238 while (it.nextCodepoint()) |codepoint| {
239 defer {
240 len += 1;
241 loc.byte_offset += std.unicode.utf8CodepointSequenceLength(codepoint) catch unreachable;
242 }
243 if (codepoint == '$') {
244 warned = true;
245 if (p.comp.langopts.dollars_in_identifiers) try p.comp.addDiagnostic(.{
246 .tag = .dollar_in_identifier_extension,
247 .loc = loc,
248 }, &.{});
249 }
250
251 if (codepoint <= 0x7F) continue;
252 if (!valid_identifier) continue;
253
254 const allowed = standard.codepointAllowedInIdentifier(codepoint, len == 0);
255 if (!allowed) {
256 invalid_char = codepoint;
257 valid_identifier = false;
258 continue;
259 }
260
261 if (!warned) {
262 warned = try checkIdentifierCodepointWarnings(p.comp, codepoint, loc);
263 }
264
265 // Check NFC normalization.
266 if (!normalized) continue;
267 const canonical_class = char_info.getCanonicalClass(codepoint);
268 if (@intFromEnum(last_canonical_class) > @intFromEnum(canonical_class) and
269 canonical_class != .not_reordered)
270 {
271 normalized = false;
272 try p.errStr(.identifier_not_normalized, p.tok_i, slice);
273 continue;
274 }
275 if (char_info.isNormalized(codepoint) != .yes) {
276 normalized = false;
277 try p.errExtra(.identifier_not_normalized, p.tok_i, .{ .normalized = slice });
278 }
279 last_canonical_class = canonical_class;
280 }
281
282 if (!valid_identifier) {
283 if (len == 1) {
284 try p.errExtra(.unexpected_character, p.tok_i, .{ .actual_codepoint = invalid_char });
285 return false;
286 } else {
287 try p.errExtra(.invalid_identifier_start_char, p.tok_i, .{ .actual_codepoint = invalid_char });
288 }
289 }
290
291 return true;
292}
293
294fn eatIdentifier(p: *Parser) !?TokenIndex {
295 switch (p.tok_ids[p.tok_i]) {
296 .identifier => {},
297 .extended_identifier => {
298 if (!try p.validateExtendedIdentifier()) {
299 p.tok_i += 1;
300 return null;
301 }
302 },
303 else => return null,
304 }
305 p.tok_i += 1;
306
307 // Handle illegal '$' characters in identifiers
308 if (!p.comp.langopts.dollars_in_identifiers) {
309 if (p.tok_ids[p.tok_i] == .invalid and p.tokSlice(p.tok_i)[0] == '$') {
310 try p.err(.dollars_in_identifiers);
311 p.tok_i += 1;
312 return error.ParsingFailed;
313 }
314 }
315
316 return p.tok_i - 1;
317}
318
319fn expectIdentifier(p: *Parser) Error!TokenIndex {
320 const actual = p.tok_ids[p.tok_i];
321 if (actual != .identifier and actual != .extended_identifier) {
322 return p.errExpectedToken(.identifier, actual);
323 }
324
325 return (try p.eatIdentifier()) orelse error.ParsingFailed;
326}
327
328fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex {
329 assert(id != .identifier and id != .extended_identifier); // use eatIdentifier
330 if (p.tok_ids[p.tok_i] == id) {
331 defer p.tok_i += 1;
332 return p.tok_i;
333 } else return null;
334}
335
336fn expectToken(p: *Parser, expected: Token.Id) Error!TokenIndex {
337 assert(expected != .identifier and expected != .extended_identifier); // use expectIdentifier
338 const actual = p.tok_ids[p.tok_i];
339 if (actual != expected) return p.errExpectedToken(expected, actual);
340 defer p.tok_i += 1;
341 return p.tok_i;
342}
343
344pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 {
345 if (p.tok_ids[tok].lexeme()) |some| return some;
346 const loc = p.pp.tokens.items(.loc)[tok];
347 var tmp_tokenizer = Tokenizer{
348 .buf = p.comp.getSource(loc.id).buf,
349 .langopts = p.comp.langopts,
350 .index = loc.byte_offset,
351 .source = .generated,
352 };
353 const res = tmp_tokenizer.next();
354 return tmp_tokenizer.buf[res.start..res.end];
355}
356
357fn expectClosing(p: *Parser, opening: TokenIndex, id: Token.Id) Error!void {
358 _ = p.expectToken(id) catch |e| {
359 if (e == error.ParsingFailed) {
360 try p.errTok(switch (id) {
361 .r_paren => .to_match_paren,
362 .r_brace => .to_match_brace,
363 .r_bracket => .to_match_brace,
364 else => unreachable,
365 }, opening);
366 }
367 return e;
368 };
369}
370
371fn errOverflow(p: *Parser, op_tok: TokenIndex, res: Result) !void {
372 try p.errStr(.overflow, op_tok, try res.str(p));
373}
374
375fn errExpectedToken(p: *Parser, expected: Token.Id, actual: Token.Id) Error {
376 switch (actual) {
377 .invalid => try p.errExtra(.expected_invalid, p.tok_i, .{ .tok_id_expected = expected }),
378 .eof => try p.errExtra(.expected_eof, p.tok_i, .{ .tok_id_expected = expected }),
379 else => try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{
380 .expected = expected,
381 .actual = actual,
382 } }),
383 }
384 return error.ParsingFailed;
385}
386
387pub fn errStr(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, str: []const u8) Compilation.Error!void {
388 @setCold(true);
389 return p.errExtra(tag, tok_i, .{ .str = str });
390}
391
392pub fn errExtra(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, extra: Diagnostics.Message.Extra) Compilation.Error!void {
393 @setCold(true);
394 const tok = p.pp.tokens.get(tok_i);
395 var loc = tok.loc;
396 if (tok_i != 0 and tok.id == .eof) {
397 // if the token is EOF, point at the end of the previous token instead
398 const prev = p.pp.tokens.get(tok_i - 1);
399 loc = prev.loc;
400 loc.byte_offset += @intCast(p.tokSlice(tok_i - 1).len);
401 }
402 try p.comp.addDiagnostic(.{
403 .tag = tag,
404 .loc = loc,
405 .extra = extra,
406 }, tok.expansionSlice());
407}
408
409pub fn errTok(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex) Compilation.Error!void {
410 @setCold(true);
411 return p.errExtra(tag, tok_i, .{ .none = {} });
412}
413
414pub fn err(p: *Parser, tag: Diagnostics.Tag) Compilation.Error!void {
415 @setCold(true);
416 return p.errExtra(tag, p.tok_i, .{ .none = {} });
417}
418
419pub fn todo(p: *Parser, msg: []const u8) Error {
420 try p.errStr(.todo, p.tok_i, msg);
421 return error.ParsingFailed;
422}
423
424pub fn removeNull(p: *Parser, str: Value) !Value {
425 const strings_top = p.strings.items.len;
426 defer p.strings.items.len = strings_top;
427 {
428 const bytes = p.comp.interner.get(str.ref()).bytes;
429 try p.strings.appendSlice(bytes[0 .. bytes.len - 1]);
430 }
431 return Value.intern(p.comp, .{ .bytes = p.strings.items[strings_top..] });
432}
433
434pub fn typeStr(p: *Parser, ty: Type) ![]const u8 {
435 if (Type.Builder.fromType(ty).str(p.comp.langopts)) |str| return str;
436 const strings_top = p.strings.items.len;
437 defer p.strings.items.len = strings_top;
438
439 const mapper = p.comp.string_interner.getSlowTypeMapper();
440 try ty.print(mapper, p.comp.langopts, p.strings.writer());
441 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
442}
443
444pub fn typePairStr(p: *Parser, a: Type, b: Type) ![]const u8 {
445 return p.typePairStrExtra(a, " and ", b);
446}
447
448pub fn typePairStrExtra(p: *Parser, a: Type, msg: []const u8, b: Type) ![]const u8 {
449 const strings_top = p.strings.items.len;
450 defer p.strings.items.len = strings_top;
451
452 try p.strings.append('\'');
453 const mapper = p.comp.string_interner.getSlowTypeMapper();
454 try a.print(mapper, p.comp.langopts, p.strings.writer());
455 try p.strings.append('\'');
456 try p.strings.appendSlice(msg);
457 try p.strings.append('\'');
458 try b.print(mapper, p.comp.langopts, p.strings.writer());
459 try p.strings.append('\'');
460 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
461}
462
463pub fn floatValueChangedStr(p: *Parser, res: *Result, old_value: Value, int_ty: Type) ![]const u8 {
464 const strings_top = p.strings.items.len;
465 defer p.strings.items.len = strings_top;
466
467 var w = p.strings.writer();
468 const type_pair_str = try p.typePairStrExtra(res.ty, " to ", int_ty);
469 try w.writeAll(type_pair_str);
470
471 try w.writeAll(" changes ");
472 if (res.val.isZero(p.comp)) try w.writeAll("non-zero ");
473 try w.writeAll("value from ");
474 try old_value.print(res.ty, p.comp, w);
475 try w.writeAll(" to ");
476 try res.val.print(int_ty, p.comp, w);
477
478 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
479}
480
481fn checkDeprecatedUnavailable(p: *Parser, ty: Type, usage_tok: TokenIndex, decl_tok: TokenIndex) !void {
482 if (ty.getAttribute(.@"error")) |@"error"| {
483 const strings_top = p.strings.items.len;
484 defer p.strings.items.len = strings_top;
485
486 const w = p.strings.writer();
487 const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes;
488 try w.print("call to '{s}' declared with attribute error: {}", .{
489 p.tokSlice(@"error".__name_tok), std.zig.fmtEscapes(msg_str),
490 });
491 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
492 try p.errStr(.error_attribute, usage_tok, str);
493 }
494 if (ty.getAttribute(.warning)) |warning| {
495 const strings_top = p.strings.items.len;
496 defer p.strings.items.len = strings_top;
497
498 const w = p.strings.writer();
499 const msg_str = p.comp.interner.get(warning.msg.ref()).bytes;
500 try w.print("call to '{s}' declared with attribute warning: {}", .{
501 p.tokSlice(warning.__name_tok), std.zig.fmtEscapes(msg_str),
502 });
503 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
504 try p.errStr(.warning_attribute, usage_tok, str);
505 }
506 if (ty.getAttribute(.unavailable)) |unavailable| {
507 try p.errDeprecated(.unavailable, usage_tok, unavailable.msg);
508 try p.errStr(.unavailable_note, unavailable.__name_tok, p.tokSlice(decl_tok));
509 return error.ParsingFailed;
510 } else if (ty.getAttribute(.deprecated)) |deprecated| {
511 try p.errDeprecated(.deprecated_declarations, usage_tok, deprecated.msg);
512 try p.errStr(.deprecated_note, deprecated.__name_tok, p.tokSlice(decl_tok));
513 }
514}
515
516fn errDeprecated(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, msg: ?Value) Compilation.Error!void {
517 const strings_top = p.strings.items.len;
518 defer p.strings.items.len = strings_top;
519
520 const w = p.strings.writer();
521 try w.print("'{s}' is ", .{p.tokSlice(tok_i)});
522 const reason: []const u8 = switch (tag) {
523 .unavailable => "unavailable",
524 .deprecated_declarations => "deprecated",
525 else => unreachable,
526 };
527 try w.writeAll(reason);
528 if (msg) |m| {
529 const str = p.comp.interner.get(m.ref()).bytes;
530 try w.print(": {}", .{std.zig.fmtEscapes(str)});
531 }
532 const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
533 return p.errStr(tag, tok_i, str);
534}
535
536fn addNode(p: *Parser, node: Tree.Node) Allocator.Error!NodeIndex {
537 if (p.in_macro) return .none;
538 const res = p.nodes.len;
539 try p.nodes.append(p.gpa, node);
540 return @enumFromInt(res);
541}
542
543fn addList(p: *Parser, nodes: []const NodeIndex) Allocator.Error!Tree.Node.Range {
544 if (p.in_macro) return Tree.Node.Range{ .start = 0, .end = 0 };
545 const start: u32 = @intCast(p.data.items.len);
546 try p.data.appendSlice(nodes);
547 const end: u32 = @intCast(p.data.items.len);
548 return Tree.Node.Range{ .start = start, .end = end };
549}
550
551fn findLabel(p: *Parser, name: []const u8) ?TokenIndex {
552 for (p.labels.items) |item| {
553 switch (item) {
554 .label => |l| if (mem.eql(u8, p.tokSlice(l), name)) return l,
555 .unresolved_goto => {},
556 }
557 }
558 return null;
559}
560
561fn nodeIs(p: *Parser, node: NodeIndex, tag: Tree.Tag) bool {
562 return p.getNode(node, tag) != null;
563}
564
565fn getNode(p: *Parser, node: NodeIndex, tag: Tree.Tag) ?NodeIndex {
566 var cur = node;
567 const tags = p.nodes.items(.tag);
568 const data = p.nodes.items(.data);
569 while (true) {
570 const cur_tag = tags[@intFromEnum(cur)];
571 if (cur_tag == .paren_expr) {
572 cur = data[@intFromEnum(cur)].un;
573 } else if (cur_tag == tag) {
574 return cur;
575 } else {
576 return null;
577 }
578 }
579}
580
581fn nodeIsCompoundLiteral(p: *Parser, node: NodeIndex) bool {
582 var cur = node;
583 const tags = p.nodes.items(.tag);
584 const data = p.nodes.items(.data);
585 while (true) {
586 switch (tags[@intFromEnum(cur)]) {
587 .paren_expr => cur = data[@intFromEnum(cur)].un,
588 .compound_literal_expr,
589 .static_compound_literal_expr,
590 .thread_local_compound_literal_expr,
591 .static_thread_local_compound_literal_expr,
592 => return true,
593 else => return false,
594 }
595 }
596}
597
598fn tmpTree(p: *Parser) Tree {
599 return .{
600 .nodes = p.nodes.slice(),
601 .data = p.data.items,
602 .value_map = p.value_map,
603 .comp = p.comp,
604 .arena = undefined,
605 .generated = undefined,
606 .tokens = undefined,
607 .root_decls = undefined,
608 };
609}
610
611fn pragma(p: *Parser) Compilation.Error!bool {
612 var found_pragma = false;
613 while (p.eatToken(.keyword_pragma)) |_| {
614 found_pragma = true;
615
616 const name_tok = p.tok_i;
617 const name = p.tokSlice(name_tok);
618
619 const end_idx = mem.indexOfScalarPos(Token.Id, p.tok_ids, p.tok_i, .nl).?;
620 const pragma_len = @as(TokenIndex, @intCast(end_idx)) - p.tok_i;
621 defer p.tok_i += pragma_len + 1; // skip past .nl as well
622 if (p.comp.getPragma(name)) |prag| {
623 try prag.parserCB(p, p.tok_i);
624 }
625 }
626 return found_pragma;
627}
628
629/// Issue errors for top-level definitions whose type was never completed.
630fn diagnoseIncompleteDefinitions(p: *Parser) !void {
631 @setCold(true);
632
633 const node_slices = p.nodes.slice();
634 const tags = node_slices.items(.tag);
635 const tys = node_slices.items(.ty);
636 const data = node_slices.items(.data);
637
638 const err_start = p.comp.diagnostics.list.items.len;
639 for (p.decl_buf.items) |decl_node| {
640 const idx = @intFromEnum(decl_node);
641 switch (tags[idx]) {
642 .struct_forward_decl, .union_forward_decl, .enum_forward_decl => {},
643 else => continue,
644 }
645
646 const ty = tys[idx];
647 const decl_type_name = if (ty.getRecord()) |rec|
648 rec.name
649 else if (ty.get(.@"enum")) |en|
650 en.data.@"enum".name
651 else
652 unreachable;
653
654 const tentative_def_tok = p.tentative_defs.get(decl_type_name) orelse continue;
655 const type_str = try p.typeStr(ty);
656 try p.errStr(.tentative_definition_incomplete, tentative_def_tok, type_str);
657 try p.errStr(.forward_declaration_here, data[idx].decl_ref, type_str);
658 }
659 const errors_added = p.comp.diagnostics.list.items.len - err_start;
660 assert(errors_added == 2 * p.tentative_defs.count()); // Each tentative def should add an error + note
661}
662
663/// root : (decl | assembly ';' | staticAssert)*
664pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {
665 assert(pp.linemarkers == .none);
666 pp.comp.pragmaEvent(.before_parse);
667
668 var arena = std.heap.ArenaAllocator.init(pp.comp.gpa);
669 errdefer arena.deinit();
670 var p = Parser{
671 .pp = pp,
672 .comp = pp.comp,
673 .gpa = pp.comp.gpa,
674 .arena = arena.allocator(),
675 .tok_ids = pp.tokens.items(.id),
676 .strings = std.ArrayList(u8).init(pp.comp.gpa),
677 .value_map = Tree.ValueMap.init(pp.comp.gpa),
678 .data = NodeList.init(pp.comp.gpa),
679 .labels = std.ArrayList(Label).init(pp.comp.gpa),
680 .list_buf = NodeList.init(pp.comp.gpa),
681 .decl_buf = NodeList.init(pp.comp.gpa),
682 .param_buf = std.ArrayList(Type.Func.Param).init(pp.comp.gpa),
683 .enum_buf = std.ArrayList(Type.Enum.Field).init(pp.comp.gpa),
684 .record_buf = std.ArrayList(Type.Record.Field).init(pp.comp.gpa),
685 .field_attr_buf = std.ArrayList([]const Attribute).init(pp.comp.gpa),
686 .string_ids = .{
687 .declspec_id = try StrInt.intern(pp.comp, "__declspec"),
688 .main_id = try StrInt.intern(pp.comp, "main"),
689 .file = try StrInt.intern(pp.comp, "FILE"),
690 .jmp_buf = try StrInt.intern(pp.comp, "jmp_buf"),
691 .sigjmp_buf = try StrInt.intern(pp.comp, "sigjmp_buf"),
692 .ucontext_t = try StrInt.intern(pp.comp, "ucontext_t"),
693 },
694 };
695 errdefer {
696 p.nodes.deinit(pp.comp.gpa);
697 p.value_map.deinit();
698 }
699 defer {
700 p.data.deinit();
701 p.labels.deinit();
702 p.strings.deinit();
703 p.syms.deinit(pp.comp.gpa);
704 p.list_buf.deinit();
705 p.decl_buf.deinit();
706 p.param_buf.deinit();
707 p.enum_buf.deinit();
708 p.record_buf.deinit();
709 p.record_members.deinit(pp.comp.gpa);
710 p.attr_buf.deinit(pp.comp.gpa);
711 p.attr_application_buf.deinit(pp.comp.gpa);
712 p.tentative_defs.deinit(pp.comp.gpa);
713 assert(p.field_attr_buf.items.len == 0);
714 p.field_attr_buf.deinit();
715 }
716
717 try p.syms.pushScope(&p);
718 defer p.syms.popScope();
719
720 // NodeIndex 0 must be invalid
721 _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined });
722
723 {
724 if (p.comp.langopts.hasChar8_T()) {
725 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "char8_t"), .{ .specifier = .uchar }, 0, .none);
726 }
727 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__int128_t"), .{ .specifier = .int128 }, 0, .none);
728 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__uint128_t"), .{ .specifier = .uint128 }, 0, .none);
729
730 const elem_ty = try p.arena.create(Type);
731 elem_ty.* = .{ .specifier = .char };
732 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__builtin_ms_va_list"), .{
733 .specifier = .pointer,
734 .data = .{ .sub_type = elem_ty },
735 }, 0, .none);
736
737 const ty = &pp.comp.types.va_list;
738 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__builtin_va_list"), ty.*, 0, .none);
739
740 if (ty.isArray()) ty.decayArray();
741
742 try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__NSConstantString"), pp.comp.types.ns_constant_string.ty, 0, .none);
743 }
744
745 while (p.eatToken(.eof) == null) {
746 if (try p.pragma()) continue;
747 if (try p.parseOrNextDecl(staticAssert)) continue;
748 if (try p.parseOrNextDecl(decl)) continue;
749 if (p.eatToken(.keyword_extension)) |_| {
750 const saved_extension = p.extension_suppressed;
751 defer p.extension_suppressed = saved_extension;
752 p.extension_suppressed = true;
753
754 if (try p.parseOrNextDecl(decl)) continue;
755 switch (p.tok_ids[p.tok_i]) {
756 .semicolon => p.tok_i += 1,
757 .keyword_static_assert,
758 .keyword_c23_static_assert,
759 .keyword_pragma,
760 .keyword_extension,
761 .keyword_asm,
762 .keyword_asm1,
763 .keyword_asm2,
764 => {},
765 else => try p.err(.expected_external_decl),
766 }
767 continue;
768 }
769 if (p.assembly(.global) catch |er| switch (er) {
770 error.ParsingFailed => {
771 p.nextExternDecl();
772 continue;
773 },
774 else => |e| return e,
775 }) |node| {
776 try p.decl_buf.append(node);
777 continue;
778 }
779 if (p.eatToken(.semicolon)) |tok| {
780 try p.errTok(.extra_semi, tok);
781 continue;
782 }
783 try p.err(.expected_external_decl);
784 p.tok_i += 1;
785 }
786 if (p.tentative_defs.count() > 0) {
787 try p.diagnoseIncompleteDefinitions();
788 }
789
790 const root_decls = try p.decl_buf.toOwnedSlice();
791 errdefer pp.comp.gpa.free(root_decls);
792 if (root_decls.len == 0) {
793 try p.errTok(.empty_translation_unit, p.tok_i - 1);
794 }
795 pp.comp.pragmaEvent(.after_parse);
796
797 const data = try p.data.toOwnedSlice();
798 errdefer pp.comp.gpa.free(data);
799 return Tree{
800 .comp = pp.comp,
801 .tokens = pp.tokens.slice(),
802 .arena = arena,
803 .generated = pp.comp.generated_buf.items,
804 .nodes = p.nodes.toOwnedSlice(),
805 .data = data,
806 .root_decls = root_decls,
807 .value_map = p.value_map,
808 };
809}
810
811fn skipToPragmaSentinel(p: *Parser) void {
812 while (true) : (p.tok_i += 1) {
813 if (p.tok_ids[p.tok_i] == .nl) return;
814 if (p.tok_ids[p.tok_i] == .eof) {
815 p.tok_i -= 1;
816 return;
817 }
818 }
819}
820
821fn parseOrNextDecl(p: *Parser, comptime func: fn (*Parser) Error!bool) Compilation.Error!bool {
822 return func(p) catch |er| switch (er) {
823 error.ParsingFailed => {
824 p.nextExternDecl();
825 return true;
826 },
827 else => |e| return e,
828 };
829}
830
831fn nextExternDecl(p: *Parser) void {
832 var parens: u32 = 0;
833 while (true) : (p.tok_i += 1) {
834 switch (p.tok_ids[p.tok_i]) {
835 .l_paren, .l_brace, .l_bracket => parens += 1,
836 .r_paren, .r_brace, .r_bracket => if (parens != 0) {
837 parens -= 1;
838 },
839 .keyword_typedef,
840 .keyword_extern,
841 .keyword_static,
842 .keyword_auto,
843 .keyword_register,
844 .keyword_thread_local,
845 .keyword_c23_thread_local,
846 .keyword_inline,
847 .keyword_inline1,
848 .keyword_inline2,
849 .keyword_noreturn,
850 .keyword_void,
851 .keyword_bool,
852 .keyword_c23_bool,
853 .keyword_char,
854 .keyword_short,
855 .keyword_int,
856 .keyword_long,
857 .keyword_signed,
858 .keyword_unsigned,
859 .keyword_float,
860 .keyword_double,
861 .keyword_complex,
862 .keyword_atomic,
863 .keyword_enum,
864 .keyword_struct,
865 .keyword_union,
866 .keyword_alignas,
867 .keyword_c23_alignas,
868 .identifier,
869 .extended_identifier,
870 .keyword_typeof,
871 .keyword_typeof1,
872 .keyword_typeof2,
873 .keyword_typeof_unqual,
874 .keyword_extension,
875 .keyword_bit_int,
876 => if (parens == 0) return,
877 .keyword_pragma => p.skipToPragmaSentinel(),
878 .eof => return,
879 .semicolon => if (parens == 0) {
880 p.tok_i += 1;
881 return;
882 },
883 else => {},
884 }
885 }
886}
887
888fn skipTo(p: *Parser, id: Token.Id) void {
889 var parens: u32 = 0;
890 while (true) : (p.tok_i += 1) {
891 if (p.tok_ids[p.tok_i] == id and parens == 0) {
892 p.tok_i += 1;
893 return;
894 }
895 switch (p.tok_ids[p.tok_i]) {
896 .l_paren, .l_brace, .l_bracket => parens += 1,
897 .r_paren, .r_brace, .r_bracket => if (parens != 0) {
898 parens -= 1;
899 },
900 .keyword_pragma => p.skipToPragmaSentinel(),
901 .eof => return,
902 else => {},
903 }
904 }
905}
906
907/// Called after a typedef is defined
908fn typedefDefined(p: *Parser, name: StringId, ty: Type) void {
909 if (name == p.string_ids.file) {
910 p.comp.types.file = ty;
911 } else if (name == p.string_ids.jmp_buf) {
912 p.comp.types.jmp_buf = ty;
913 } else if (name == p.string_ids.sigjmp_buf) {
914 p.comp.types.sigjmp_buf = ty;
915 } else if (name == p.string_ids.ucontext_t) {
916 p.comp.types.ucontext_t = ty;
917 }
918}
919
920// ====== declarations ======
921
922/// decl
923/// : declSpec (initDeclarator ( ',' initDeclarator)*)? ';'
924/// | declSpec declarator decl* compoundStmt
925fn decl(p: *Parser) Error!bool {
926 _ = try p.pragma();
927 const first_tok = p.tok_i;
928 const attr_buf_top = p.attr_buf.len;
929 defer p.attr_buf.len = attr_buf_top;
930
931 try p.attributeSpecifier();
932
933 var decl_spec = if (try p.declSpec()) |some| some else blk: {
934 if (p.func.ty != null) {
935 p.tok_i = first_tok;
936 return false;
937 }
938 switch (p.tok_ids[first_tok]) {
939 .asterisk, .l_paren, .identifier, .extended_identifier => {},
940 else => if (p.tok_i != first_tok) {
941 try p.err(.expected_ident_or_l_paren);
942 return error.ParsingFailed;
943 } else return false,
944 }
945 var spec: Type.Builder = .{};
946 break :blk DeclSpec{ .ty = try spec.finish(p) };
947 };
948 if (decl_spec.noreturn) |tok| {
949 const attr = Attribute{ .tag = .noreturn, .args = .{ .noreturn = .{} }, .syntax = .keyword };
950 try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = tok });
951 }
952 var init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
953 _ = try p.expectToken(.semicolon);
954 if (decl_spec.ty.is(.@"enum") or
955 (decl_spec.ty.isRecord() and !decl_spec.ty.isAnonymousRecord(p.comp) and
956 !decl_spec.ty.isTypeof())) // we follow GCC and clang's behavior here
957 {
958 const specifier = decl_spec.ty.canonicalize(.standard).specifier;
959 const attrs = p.attr_buf.items(.attr)[attr_buf_top..];
960 const toks = p.attr_buf.items(.tok)[attr_buf_top..];
961 for (attrs, toks) |attr, tok| {
962 try p.errExtra(.ignored_record_attr, tok, .{
963 .ignored_record_attr = .{ .tag = attr.tag, .specifier = switch (specifier) {
964 .@"enum" => .@"enum",
965 .@"struct" => .@"struct",
966 .@"union" => .@"union",
967 else => unreachable,
968 } },
969 });
970 }
971 return true;
972 }
973
974 try p.errTok(.missing_declaration, first_tok);
975 return true;
976 };
977
978 // Check for function definition.
979 if (init_d.d.func_declarator != null and init_d.initializer.node == .none and init_d.d.ty.isFunc()) fn_def: {
980 if (decl_spec.auto_type) |tok_i| {
981 try p.errStr(.auto_type_not_allowed, tok_i, "function return type");
982 return error.ParsingFailed;
983 }
984
985 switch (p.tok_ids[p.tok_i]) {
986 .comma, .semicolon => break :fn_def,
987 .l_brace => {},
988 else => if (init_d.d.old_style_func == null) {
989 try p.err(.expected_fn_body);
990 return true;
991 },
992 }
993 if (p.func.ty != null) try p.err(.func_not_in_root);
994
995 const node = try p.addNode(undefined); // reserve space
996 const interned_declarator_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name));
997 try p.syms.defineSymbol(p, interned_declarator_name, init_d.d.ty, init_d.d.name, node, .{}, false);
998
999 const func = p.func;
1000 p.func = .{
1001 .ty = init_d.d.ty,
1002 .name = init_d.d.name,
1003 };
1004 if (interned_declarator_name == p.string_ids.main_id and !init_d.d.ty.returnType().is(.int)) {
1005 try p.errTok(.main_return_type, init_d.d.name);
1006 }
1007 defer p.func = func;
1008
1009 try p.syms.pushScope(p);
1010 defer p.syms.popScope();
1011
1012 // Collect old style parameter declarations.
1013 if (init_d.d.old_style_func != null) {
1014 const attrs = init_d.d.ty.getAttributes();
1015 var base_ty = if (init_d.d.ty.specifier == .attributed) init_d.d.ty.data.attributed.base else init_d.d.ty;
1016 base_ty.specifier = .func;
1017 init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);
1018
1019 const param_buf_top = p.param_buf.items.len;
1020 defer p.param_buf.items.len = param_buf_top;
1021
1022 param_loop: while (true) {
1023 const param_decl_spec = (try p.declSpec()) orelse break;
1024 if (p.eatToken(.semicolon)) |semi| {
1025 try p.errTok(.missing_declaration, semi);
1026 continue :param_loop;
1027 }
1028
1029 while (true) {
1030 const attr_buf_top_declarator = p.attr_buf.len;
1031 defer p.attr_buf.len = attr_buf_top_declarator;
1032
1033 var d = (try p.declarator(param_decl_spec.ty, .param)) orelse {
1034 try p.errTok(.missing_declaration, first_tok);
1035 _ = try p.expectToken(.semicolon);
1036 continue :param_loop;
1037 };
1038 try p.attributeSpecifier();
1039
1040 if (d.ty.hasIncompleteSize() and !d.ty.is(.void)) try p.errStr(.parameter_incomplete_ty, d.name, try p.typeStr(d.ty));
1041 if (d.ty.isFunc()) {
1042 // Params declared as functions are converted to function pointers.
1043 const elem_ty = try p.arena.create(Type);
1044 elem_ty.* = d.ty;
1045 d.ty = Type{
1046 .specifier = .pointer,
1047 .data = .{ .sub_type = elem_ty },
1048 };
1049 } else if (d.ty.isArray()) {
1050 // params declared as arrays are converted to pointers
1051 d.ty.decayArray();
1052 } else if (d.ty.is(.void)) {
1053 try p.errTok(.invalid_void_param, d.name);
1054 }
1055
1056 // find and correct parameter types
1057 // TODO check for missing declarations and redefinitions
1058 const name_str = p.tokSlice(d.name);
1059 const interned_name = try StrInt.intern(p.comp, name_str);
1060 for (init_d.d.ty.params()) |*param| {
1061 if (param.name == interned_name) {
1062 param.ty = d.ty;
1063 break;
1064 }
1065 } else {
1066 try p.errStr(.parameter_missing, d.name, name_str);
1067 }
1068 d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param);
1069
1070 // bypass redefinition check to avoid duplicate errors
1071 try p.syms.define(p.gpa, .{
1072 .kind = .def,
1073 .name = interned_name,
1074 .tok = d.name,
1075 .ty = d.ty,
1076 .val = .{},
1077 });
1078 if (p.eatToken(.comma) == null) break;
1079 }
1080 _ = try p.expectToken(.semicolon);
1081 }
1082 } else {
1083 for (init_d.d.ty.params()) |param| {
1084 if (param.ty.hasUnboundVLA()) try p.errTok(.unbound_vla, param.name_tok);
1085 if (param.ty.hasIncompleteSize() and !param.ty.is(.void) and param.ty.specifier != .invalid) try p.errStr(.parameter_incomplete_ty, param.name_tok, try p.typeStr(param.ty));
1086
1087 if (param.name == .empty) {
1088 try p.errTok(.omitting_parameter_name, param.name_tok);
1089 continue;
1090 }
1091
1092 // bypass redefinition check to avoid duplicate errors
1093 try p.syms.define(p.gpa, .{
1094 .kind = .def,
1095 .name = param.name,
1096 .tok = param.name_tok,
1097 .ty = param.ty,
1098 .val = .{},
1099 });
1100 }
1101 }
1102
1103 const body = (try p.compoundStmt(true, null)) orelse {
1104 assert(init_d.d.old_style_func != null);
1105 try p.err(.expected_fn_body);
1106 return true;
1107 };
1108 p.nodes.set(@intFromEnum(node), .{
1109 .ty = init_d.d.ty,
1110 .tag = try decl_spec.validateFnDef(p),
1111 .data = .{ .decl = .{ .name = init_d.d.name, .node = body } },
1112 });
1113 try p.decl_buf.append(node);
1114
1115 // check gotos
1116 if (func.ty == null) {
1117 for (p.labels.items) |item| {
1118 if (item == .unresolved_goto)
1119 try p.errStr(.undeclared_label, item.unresolved_goto, p.tokSlice(item.unresolved_goto));
1120 }
1121 if (p.computed_goto_tok) |goto_tok| {
1122 if (!p.contains_address_of_label) try p.errTok(.invalid_computed_goto, goto_tok);
1123 }
1124 p.labels.items.len = 0;
1125 p.label_count = 0;
1126 p.contains_address_of_label = false;
1127 p.computed_goto_tok = null;
1128 }
1129 return true;
1130 }
1131
1132 // Declare all variable/typedef declarators.
1133 var warned_auto = false;
1134 while (true) {
1135 if (init_d.d.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
1136 const tag = try decl_spec.validate(p, &init_d.d.ty, init_d.initializer.node != .none);
1137
1138 const node = try p.addNode(.{ .ty = init_d.d.ty, .tag = tag, .data = .{
1139 .decl = .{ .name = init_d.d.name, .node = init_d.initializer.node },
1140 } });
1141 try p.decl_buf.append(node);
1142
1143 const interned_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name));
1144 if (decl_spec.storage_class == .typedef) {
1145 try p.syms.defineTypedef(p, interned_name, init_d.d.ty, init_d.d.name, node);
1146 p.typedefDefined(interned_name, init_d.d.ty);
1147 } else if (init_d.initializer.node != .none or
1148 (p.func.ty != null and decl_spec.storage_class != .@"extern"))
1149 {
1150 // TODO validate global variable/constexpr initializer comptime known
1151 try p.syms.defineSymbol(
1152 p,
1153 interned_name,
1154 init_d.d.ty,
1155 init_d.d.name,
1156 node,
1157 if (init_d.d.ty.isConst() or decl_spec.constexpr != null) init_d.initializer.val else .{},
1158 decl_spec.constexpr != null,
1159 );
1160 } else {
1161 try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, node);
1162 }
1163
1164 if (p.eatToken(.comma) == null) break;
1165
1166 if (!warned_auto) {
1167 if (decl_spec.auto_type) |tok_i| {
1168 try p.errTok(.auto_type_requires_single_declarator, tok_i);
1169 warned_auto = true;
1170 }
1171 if (p.comp.langopts.standard.atLeast(.c23) and decl_spec.storage_class == .auto) {
1172 try p.errTok(.c23_auto_single_declarator, decl_spec.storage_class.auto);
1173 warned_auto = true;
1174 }
1175 }
1176
1177 init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse {
1178 try p.err(.expected_ident_or_l_paren);
1179 continue;
1180 };
1181 }
1182
1183 _ = try p.expectToken(.semicolon);
1184 return true;
1185}
1186
1187fn staticAssertMessage(p: *Parser, cond_node: NodeIndex, message: Result) !?[]const u8 {
1188 const cond_tag = p.nodes.items(.tag)[@intFromEnum(cond_node)];
1189 if (cond_tag != .builtin_types_compatible_p and message.node == .none) return null;
1190
1191 var buf = std.ArrayList(u8).init(p.gpa);
1192 defer buf.deinit();
1193
1194 if (cond_tag == .builtin_types_compatible_p) {
1195 const mapper = p.comp.string_interner.getSlowTypeMapper();
1196 const data = p.nodes.items(.data)[@intFromEnum(cond_node)].bin;
1197
1198 try buf.appendSlice("'__builtin_types_compatible_p(");
1199
1200 const lhs_ty = p.nodes.items(.ty)[@intFromEnum(data.lhs)];
1201 try lhs_ty.print(mapper, p.comp.langopts, buf.writer());
1202 try buf.appendSlice(", ");
1203
1204 const rhs_ty = p.nodes.items(.ty)[@intFromEnum(data.rhs)];
1205 try rhs_ty.print(mapper, p.comp.langopts, buf.writer());
1206
1207 try buf.appendSlice(")'");
1208 }
1209 if (message.node != .none) {
1210 assert(p.nodes.items(.tag)[@intFromEnum(message.node)] == .string_literal_expr);
1211 if (buf.items.len > 0) {
1212 try buf.append(' ');
1213 }
1214 const bytes = p.comp.interner.get(message.val.ref()).bytes;
1215 try buf.ensureUnusedCapacity(bytes.len);
1216 try Value.printString(bytes, message.ty, p.comp, buf.writer());
1217 }
1218 return try p.comp.diagnostics.arena.allocator().dupe(u8, buf.items);
1219}
1220
1221/// staticAssert
1222/// : keyword_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
1223/// | keyword_c23_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';'
1224fn staticAssert(p: *Parser) Error!bool {
1225 const static_assert = p.eatToken(.keyword_static_assert) orelse p.eatToken(.keyword_c23_static_assert) orelse return false;
1226 const l_paren = try p.expectToken(.l_paren);
1227 const res_token = p.tok_i;
1228 var res = try p.constExpr(.gnu_folding_extension);
1229 const res_node = res.node;
1230 const str = if (p.eatToken(.comma) != null)
1231 switch (p.tok_ids[p.tok_i]) {
1232 .string_literal,
1233 .string_literal_utf_16,
1234 .string_literal_utf_8,
1235 .string_literal_utf_32,
1236 .string_literal_wide,
1237 .unterminated_string_literal,
1238 => try p.stringLiteral(),
1239 else => {
1240 try p.err(.expected_str_literal);
1241 return error.ParsingFailed;
1242 },
1243 }
1244 else
1245 Result{};
1246 try p.expectClosing(l_paren, .r_paren);
1247 _ = try p.expectToken(.semicolon);
1248 if (str.node == .none) {
1249 try p.errTok(.static_assert_missing_message, static_assert);
1250 try p.errStr(.pre_c23_compat, static_assert, "'_Static_assert' with no message");
1251 }
1252
1253 // Array will never be zero; a value of zero for a pointer is a null pointer constant
1254 if ((res.ty.isArray() or res.ty.isPtr()) and !res.val.isZero(p.comp)) {
1255 const err_start = p.comp.diagnostics.list.items.len;
1256 try p.errTok(.const_decl_folded, res_token);
1257 if (res.ty.isPtr() and err_start != p.comp.diagnostics.list.items.len) {
1258 // Don't show the note if the .const_decl_folded diagnostic was not added
1259 try p.errTok(.constant_expression_conversion_not_allowed, res_token);
1260 }
1261 }
1262 try res.boolCast(p, .{ .specifier = .bool }, res_token);
1263 if (res.val.opt_ref == .none) {
1264 if (res.ty.specifier != .invalid) {
1265 try p.errTok(.static_assert_not_constant, res_token);
1266 }
1267 } else {
1268 if (!res.val.toBool(p.comp)) {
1269 if (try p.staticAssertMessage(res_node, str)) |message| {
1270 try p.errStr(.static_assert_failure_message, static_assert, message);
1271 } else {
1272 try p.errTok(.static_assert_failure, static_assert);
1273 }
1274 }
1275 }
1276
1277 const node = try p.addNode(.{
1278 .tag = .static_assert,
1279 .data = .{ .bin = .{
1280 .lhs = res.node,
1281 .rhs = str.node,
1282 } },
1283 });
1284 try p.decl_buf.append(node);
1285 return true;
1286}
1287
1288pub const DeclSpec = struct {
1289 storage_class: union(enum) {
1290 auto: TokenIndex,
1291 @"extern": TokenIndex,
1292 register: TokenIndex,
1293 static: TokenIndex,
1294 typedef: TokenIndex,
1295 none,
1296 } = .none,
1297 thread_local: ?TokenIndex = null,
1298 constexpr: ?TokenIndex = null,
1299 @"inline": ?TokenIndex = null,
1300 noreturn: ?TokenIndex = null,
1301 auto_type: ?TokenIndex = null,
1302 ty: Type,
1303
1304 fn validateParam(d: DeclSpec, p: *Parser, ty: *Type) Error!void {
1305 switch (d.storage_class) {
1306 .none => {},
1307 .register => ty.qual.register = true,
1308 .auto, .@"extern", .static, .typedef => |tok_i| try p.errTok(.invalid_storage_on_param, tok_i),
1309 }
1310 if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
1311 if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
1312 if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
1313 if (d.constexpr) |tok_i| try p.errTok(.invalid_storage_on_param, tok_i);
1314 if (d.auto_type) |tok_i| {
1315 try p.errStr(.auto_type_not_allowed, tok_i, "function prototype");
1316 ty.* = Type.invalid;
1317 }
1318 }
1319
1320 fn validateFnDef(d: DeclSpec, p: *Parser) Error!Tree.Tag {
1321 switch (d.storage_class) {
1322 .none, .@"extern", .static => {},
1323 .auto, .register, .typedef => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
1324 }
1325 if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
1326 if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
1327
1328 const is_static = d.storage_class == .static;
1329 const is_inline = d.@"inline" != null;
1330 if (is_static) {
1331 if (is_inline) return .inline_static_fn_def;
1332 return .static_fn_def;
1333 } else {
1334 if (is_inline) return .inline_fn_def;
1335 return .fn_def;
1336 }
1337 }
1338
1339 fn validate(d: DeclSpec, p: *Parser, ty: *Type, has_init: bool) Error!Tree.Tag {
1340 const is_static = d.storage_class == .static;
1341 if (ty.isFunc() and d.storage_class != .typedef) {
1342 switch (d.storage_class) {
1343 .none, .@"extern" => {},
1344 .static => |tok_i| if (p.func.ty != null) try p.errTok(.static_func_not_global, tok_i),
1345 .typedef => unreachable,
1346 .auto, .register => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i),
1347 }
1348 if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i);
1349 if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i);
1350
1351 const is_inline = d.@"inline" != null;
1352 if (is_static) {
1353 if (is_inline) return .inline_static_fn_proto;
1354 return .static_fn_proto;
1355 } else {
1356 if (is_inline) return .inline_fn_proto;
1357 return .fn_proto;
1358 }
1359 } else {
1360 if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline");
1361 // TODO move to attribute validation
1362 if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn");
1363 switch (d.storage_class) {
1364 .auto => if (p.func.ty == null and !p.comp.langopts.standard.atLeast(.c23)) {
1365 try p.err(.illegal_storage_on_global);
1366 },
1367 .register => if (p.func.ty == null) try p.err(.illegal_storage_on_global),
1368 .typedef => return .typedef,
1369 else => {},
1370 }
1371 ty.qual.register = d.storage_class == .register;
1372
1373 const is_extern = d.storage_class == .@"extern" and !has_init;
1374 if (d.thread_local != null) {
1375 if (is_static) return .threadlocal_static_var;
1376 if (is_extern) return .threadlocal_extern_var;
1377 return .threadlocal_var;
1378 } else {
1379 if (is_static) return .static_var;
1380 if (is_extern) return .extern_var;
1381 return .@"var";
1382 }
1383 }
1384 }
1385};
1386
1387/// typeof
1388/// : keyword_typeof '(' typeName ')'
1389/// | keyword_typeof '(' expr ')'
1390fn typeof(p: *Parser) Error!?Type {
1391 var unqual = false;
1392 switch (p.tok_ids[p.tok_i]) {
1393 .keyword_typeof, .keyword_typeof1, .keyword_typeof2 => p.tok_i += 1,
1394 .keyword_typeof_unqual => {
1395 p.tok_i += 1;
1396 unqual = true;
1397 },
1398 else => return null,
1399 }
1400 const l_paren = try p.expectToken(.l_paren);
1401 if (try p.typeName()) |ty| {
1402 try p.expectClosing(l_paren, .r_paren);
1403 const typeof_ty = try p.arena.create(Type);
1404 typeof_ty.* = .{
1405 .data = ty.data,
1406 .qual = if (unqual) .{} else ty.qual.inheritFromTypeof(),
1407 .specifier = ty.specifier,
1408 };
1409
1410 return Type{
1411 .data = .{ .sub_type = typeof_ty },
1412 .specifier = .typeof_type,
1413 };
1414 }
1415 const typeof_expr = try p.parseNoEval(expr);
1416 try typeof_expr.expect(p);
1417 try p.expectClosing(l_paren, .r_paren);
1418 // Special case nullptr_t since it's defined as typeof(nullptr)
1419 if (typeof_expr.ty.is(.nullptr_t)) {
1420 return Type{
1421 .specifier = .nullptr_t,
1422 .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
1423 };
1424 }
1425
1426 const inner = try p.arena.create(Type.Expr);
1427 inner.* = .{
1428 .node = typeof_expr.node,
1429 .ty = .{
1430 .data = typeof_expr.ty.data,
1431 .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
1432 .specifier = typeof_expr.ty.specifier,
1433 .decayed = typeof_expr.ty.decayed,
1434 },
1435 };
1436
1437 return Type{
1438 .data = .{ .expr = inner },
1439 .specifier = .typeof_expr,
1440 .decayed = typeof_expr.ty.decayed,
1441 };
1442}
1443
1444/// declSpec: (storageClassSpec | typeSpec | typeQual | funcSpec | alignSpec)+
1445/// funcSpec : keyword_inline | keyword_noreturn
1446fn declSpec(p: *Parser) Error!?DeclSpec {
1447 var d: DeclSpec = .{ .ty = .{ .specifier = undefined } };
1448 var spec: Type.Builder = .{};
1449
1450 var combined_auto = !p.comp.langopts.standard.atLeast(.c23);
1451 const start = p.tok_i;
1452 while (true) {
1453 if (!combined_auto and d.storage_class == .auto) {
1454 try spec.combine(p, .c23_auto, d.storage_class.auto);
1455 combined_auto = true;
1456 }
1457 if (try p.storageClassSpec(&d)) continue;
1458 if (try p.typeSpec(&spec)) continue;
1459 const id = p.tok_ids[p.tok_i];
1460 switch (id) {
1461 .keyword_inline, .keyword_inline1, .keyword_inline2 => {
1462 if (d.@"inline" != null) {
1463 try p.errStr(.duplicate_decl_spec, p.tok_i, "inline");
1464 }
1465 d.@"inline" = p.tok_i;
1466 },
1467 .keyword_noreturn => {
1468 if (d.noreturn != null) {
1469 try p.errStr(.duplicate_decl_spec, p.tok_i, "_Noreturn");
1470 }
1471 d.noreturn = p.tok_i;
1472 },
1473 else => break,
1474 }
1475 p.tok_i += 1;
1476 }
1477
1478 if (p.tok_i == start) return null;
1479
1480 d.ty = try spec.finish(p);
1481 d.auto_type = spec.auto_type_tok;
1482 return d;
1483}
1484
1485/// storageClassSpec:
1486/// : keyword_typedef
1487/// | keyword_extern
1488/// | keyword_static
1489/// | keyword_threadlocal
1490/// | keyword_auto
1491/// | keyword_register
1492fn storageClassSpec(p: *Parser, d: *DeclSpec) Error!bool {
1493 const start = p.tok_i;
1494 while (true) {
1495 const id = p.tok_ids[p.tok_i];
1496 switch (id) {
1497 .keyword_typedef,
1498 .keyword_extern,
1499 .keyword_static,
1500 .keyword_auto,
1501 .keyword_register,
1502 => {
1503 if (d.storage_class != .none) {
1504 try p.errStr(.multiple_storage_class, p.tok_i, @tagName(d.storage_class));
1505 return error.ParsingFailed;
1506 }
1507 if (d.thread_local != null) {
1508 switch (id) {
1509 .keyword_extern, .keyword_static => {},
1510 else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
1511 }
1512 if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1513 }
1514 if (d.constexpr != null) {
1515 switch (id) {
1516 .keyword_auto, .keyword_register, .keyword_static => {},
1517 else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?),
1518 }
1519 if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1520 }
1521 switch (id) {
1522 .keyword_typedef => d.storage_class = .{ .typedef = p.tok_i },
1523 .keyword_extern => d.storage_class = .{ .@"extern" = p.tok_i },
1524 .keyword_static => d.storage_class = .{ .static = p.tok_i },
1525 .keyword_auto => d.storage_class = .{ .auto = p.tok_i },
1526 .keyword_register => d.storage_class = .{ .register = p.tok_i },
1527 else => unreachable,
1528 }
1529 },
1530 .keyword_thread_local,
1531 .keyword_c23_thread_local,
1532 => {
1533 if (d.thread_local != null) {
1534 try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
1535 }
1536 if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1537 switch (d.storage_class) {
1538 .@"extern", .none, .static => {},
1539 else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
1540 }
1541 d.thread_local = p.tok_i;
1542 },
1543 .keyword_constexpr => {
1544 if (d.constexpr != null) {
1545 try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?);
1546 }
1547 if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?);
1548 switch (d.storage_class) {
1549 .auto, .register, .none, .static => {},
1550 else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)),
1551 }
1552 d.constexpr = p.tok_i;
1553 },
1554 else => break,
1555 }
1556 p.tok_i += 1;
1557 }
1558 return p.tok_i != start;
1559}
1560
1561const InitDeclarator = struct { d: Declarator, initializer: Result = .{} };
1562
1563/// attribute
1564/// : attrIdentifier
1565/// | attrIdentifier '(' identifier ')'
1566/// | attrIdentifier '(' identifier (',' expr)+ ')'
1567/// | attrIdentifier '(' (expr (',' expr)*)? ')'
1568fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?TentativeAttribute {
1569 const name_tok = p.tok_i;
1570 switch (p.tok_ids[p.tok_i]) {
1571 .keyword_const, .keyword_const1, .keyword_const2 => p.tok_i += 1,
1572 else => _ = try p.expectIdentifier(),
1573 }
1574 const name = p.tokSlice(name_tok);
1575
1576 const attr = Attribute.fromString(kind, namespace, name) orelse {
1577 const tag: Diagnostics.Tag = if (kind == .declspec) .declspec_attr_not_supported else .unknown_attribute;
1578 try p.errStr(tag, name_tok, name);
1579 if (p.eatToken(.l_paren)) |_| p.skipTo(.r_paren);
1580 return null;
1581 };
1582
1583 const required_count = Attribute.requiredArgCount(attr);
1584 var arguments = Attribute.initArguments(attr, name_tok);
1585 var arg_idx: u32 = 0;
1586
1587 switch (p.tok_ids[p.tok_i]) {
1588 .comma, .r_paren => {}, // will be consumed in attributeList
1589 .l_paren => blk: {
1590 p.tok_i += 1;
1591 if (p.eatToken(.r_paren)) |_| break :blk;
1592
1593 if (Attribute.wantsIdentEnum(attr)) {
1594 if (try p.eatIdentifier()) |ident| {
1595 if (Attribute.diagnoseIdent(attr, &arguments, p.tokSlice(ident))) |msg| {
1596 try p.errExtra(msg.tag, ident, msg.extra);
1597 p.skipTo(.r_paren);
1598 return error.ParsingFailed;
1599 }
1600 } else {
1601 try p.errExtra(.attribute_requires_identifier, name_tok, .{ .str = name });
1602 return error.ParsingFailed;
1603 }
1604 } else {
1605 const arg_start = p.tok_i;
1606 var first_expr = try p.assignExpr();
1607 try first_expr.expect(p);
1608 if (try p.diagnose(attr, &arguments, arg_idx, first_expr)) |msg| {
1609 try p.errExtra(msg.tag, arg_start, msg.extra);
1610 p.skipTo(.r_paren);
1611 return error.ParsingFailed;
1612 }
1613 }
1614 arg_idx += 1;
1615 while (p.eatToken(.r_paren) == null) : (arg_idx += 1) {
1616 _ = try p.expectToken(.comma);
1617
1618 const arg_start = p.tok_i;
1619 var arg_expr = try p.assignExpr();
1620 try arg_expr.expect(p);
1621 if (try p.diagnose(attr, &arguments, arg_idx, arg_expr)) |msg| {
1622 try p.errExtra(msg.tag, arg_start, msg.extra);
1623 p.skipTo(.r_paren);
1624 return error.ParsingFailed;
1625 }
1626 }
1627 },
1628 else => {},
1629 }
1630 if (arg_idx < required_count) {
1631 try p.errExtra(.attribute_not_enough_args, name_tok, .{ .attr_arg_count = .{ .attribute = attr, .expected = required_count } });
1632 return error.ParsingFailed;
1633 }
1634 return TentativeAttribute{ .attr = .{ .tag = attr, .args = arguments, .syntax = kind.toSyntax() }, .tok = name_tok };
1635}
1636
1637fn diagnose(p: *Parser, attr: Attribute.Tag, arguments: *Attribute.Arguments, arg_idx: u32, res: Result) !?Diagnostics.Message {
1638 if (Attribute.wantsAlignment(attr, arg_idx)) {
1639 return Attribute.diagnoseAlignment(attr, arguments, arg_idx, res, p);
1640 }
1641 const node = p.nodes.get(@intFromEnum(res.node));
1642 return Attribute.diagnose(attr, arguments, arg_idx, res, node, p);
1643}
1644
1645/// attributeList : (attribute (',' attribute)*)?
1646fn gnuAttributeList(p: *Parser) Error!void {
1647 if (p.tok_ids[p.tok_i] == .r_paren) return;
1648
1649 if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
1650 while (p.tok_ids[p.tok_i] != .r_paren) {
1651 _ = try p.expectToken(.comma);
1652 if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr);
1653 }
1654}
1655
1656fn c23AttributeList(p: *Parser) Error!void {
1657 while (p.tok_ids[p.tok_i] != .r_bracket) {
1658 const namespace_tok = try p.expectIdentifier();
1659 var namespace: ?[]const u8 = null;
1660 if (p.eatToken(.colon_colon)) |_| {
1661 namespace = p.tokSlice(namespace_tok);
1662 } else {
1663 p.tok_i -= 1;
1664 }
1665 if (try p.attribute(.c23, namespace)) |attr| try p.attr_buf.append(p.gpa, attr);
1666 _ = p.eatToken(.comma);
1667 }
1668}
1669
1670fn msvcAttributeList(p: *Parser) Error!void {
1671 while (p.tok_ids[p.tok_i] != .r_paren) {
1672 if (try p.attribute(.declspec, null)) |attr| try p.attr_buf.append(p.gpa, attr);
1673 _ = p.eatToken(.comma);
1674 }
1675}
1676
1677fn c23Attribute(p: *Parser) !bool {
1678 if (!p.comp.langopts.standard.atLeast(.c23)) return false;
1679 const bracket1 = p.eatToken(.l_bracket) orelse return false;
1680 const bracket2 = p.eatToken(.l_bracket) orelse {
1681 p.tok_i -= 1;
1682 return false;
1683 };
1684
1685 try p.c23AttributeList();
1686
1687 _ = try p.expectClosing(bracket2, .r_bracket);
1688 _ = try p.expectClosing(bracket1, .r_bracket);
1689
1690 return true;
1691}
1692
1693fn msvcAttribute(p: *Parser) !bool {
1694 _ = p.eatToken(.keyword_declspec) orelse return false;
1695 const l_paren = try p.expectToken(.l_paren);
1696 try p.msvcAttributeList();
1697 _ = try p.expectClosing(l_paren, .r_paren);
1698
1699 return true;
1700}
1701
1702fn gnuAttribute(p: *Parser) !bool {
1703 switch (p.tok_ids[p.tok_i]) {
1704 .keyword_attribute1, .keyword_attribute2 => p.tok_i += 1,
1705 else => return false,
1706 }
1707 const paren1 = try p.expectToken(.l_paren);
1708 const paren2 = try p.expectToken(.l_paren);
1709
1710 try p.gnuAttributeList();
1711
1712 _ = try p.expectClosing(paren2, .r_paren);
1713 _ = try p.expectClosing(paren1, .r_paren);
1714 return true;
1715}
1716
1717fn attributeSpecifier(p: *Parser) Error!void {
1718 return attributeSpecifierExtra(p, null);
1719}
1720
1721/// attributeSpecifier : (keyword_attribute '( '(' attributeList ')' ')')*
1722fn attributeSpecifierExtra(p: *Parser, declarator_name: ?TokenIndex) Error!void {
1723 while (true) {
1724 if (try p.gnuAttribute()) continue;
1725 if (try p.c23Attribute()) continue;
1726 const maybe_declspec_tok = p.tok_i;
1727 const attr_buf_top = p.attr_buf.len;
1728 if (try p.msvcAttribute()) {
1729 if (declarator_name) |name_tok| {
1730 try p.errTok(.declspec_not_allowed_after_declarator, maybe_declspec_tok);
1731 try p.errTok(.declarator_name_tok, name_tok);
1732 p.attr_buf.len = attr_buf_top;
1733 }
1734 continue;
1735 }
1736 break;
1737 }
1738}
1739
1740/// initDeclarator : declarator assembly? attributeSpecifier? ('=' initializer)?
1741fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?InitDeclarator {
1742 const this_attr_buf_top = p.attr_buf.len;
1743 defer p.attr_buf.len = this_attr_buf_top;
1744
1745 var init_d = InitDeclarator{
1746 .d = (try p.declarator(decl_spec.ty, .normal)) orelse return null,
1747 };
1748
1749 if (decl_spec.ty.is(.c23_auto) and !init_d.d.ty.is(.c23_auto)) {
1750 try p.errTok(.c23_auto_plain_declarator, decl_spec.storage_class.auto);
1751 return error.ParsingFailed;
1752 }
1753
1754 try p.attributeSpecifierExtra(init_d.d.name);
1755 _ = try p.assembly(.decl_label);
1756 try p.attributeSpecifierExtra(init_d.d.name);
1757
1758 var apply_var_attributes = false;
1759 if (decl_spec.storage_class == .typedef) {
1760 if (decl_spec.auto_type) |tok_i| {
1761 try p.errStr(.auto_type_not_allowed, tok_i, "typedef");
1762 return error.ParsingFailed;
1763 }
1764 init_d.d.ty = try Attribute.applyTypeAttributes(p, init_d.d.ty, attr_buf_top, null);
1765 } else if (init_d.d.ty.isFunc()) {
1766 init_d.d.ty = try Attribute.applyFunctionAttributes(p, init_d.d.ty, attr_buf_top);
1767 } else {
1768 apply_var_attributes = true;
1769 }
1770
1771 if (p.eatToken(.equal)) |eq| init: {
1772 if (decl_spec.storage_class == .typedef or
1773 (init_d.d.func_declarator != null and init_d.d.ty.isFunc()))
1774 {
1775 try p.errTok(.illegal_initializer, eq);
1776 } else if (init_d.d.ty.is(.variable_len_array)) {
1777 try p.errTok(.vla_init, eq);
1778 } else if (decl_spec.storage_class == .@"extern") {
1779 try p.err(.extern_initializer);
1780 decl_spec.storage_class = .none;
1781 }
1782
1783 if (init_d.d.ty.hasIncompleteSize() and !init_d.d.ty.is(.incomplete_array)) {
1784 try p.errStr(.variable_incomplete_ty, init_d.d.name, try p.typeStr(init_d.d.ty));
1785 return error.ParsingFailed;
1786 }
1787 if (p.tok_ids[p.tok_i] == .l_brace and init_d.d.ty.is(.c23_auto)) {
1788 try p.errTok(.c23_auto_scalar_init, decl_spec.storage_class.auto);
1789 return error.ParsingFailed;
1790 }
1791
1792 try p.syms.pushScope(p);
1793 defer p.syms.popScope();
1794
1795 const interned_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name));
1796 try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, .none);
1797 var init_list_expr = try p.initializer(init_d.d.ty);
1798 init_d.initializer = init_list_expr;
1799 if (!init_list_expr.ty.isArray()) break :init;
1800 if (init_d.d.ty.specifier == .incomplete_array) {
1801 // Modifying .data is exceptionally allowed for .incomplete_array.
1802 init_d.d.ty.data.array.len = init_list_expr.ty.arrayLen() orelse break :init;
1803 init_d.d.ty.specifier = .array;
1804 }
1805 }
1806
1807 const name = init_d.d.name;
1808 const c23_auto = init_d.d.ty.is(.c23_auto);
1809 if (init_d.d.ty.is(.auto_type) or c23_auto) {
1810 if (init_d.initializer.node == .none) {
1811 init_d.d.ty = Type.invalid;
1812 if (c23_auto) {
1813 try p.errStr(.c32_auto_requires_initializer, decl_spec.storage_class.auto, p.tokSlice(name));
1814 } else {
1815 try p.errStr(.auto_type_requires_initializer, name, p.tokSlice(name));
1816 }
1817 return init_d;
1818 } else {
1819 init_d.d.ty.specifier = init_d.initializer.ty.specifier;
1820 init_d.d.ty.data = init_d.initializer.ty.data;
1821 init_d.d.ty.decayed = init_d.initializer.ty.decayed;
1822 }
1823 }
1824 if (apply_var_attributes) {
1825 init_d.d.ty = try Attribute.applyVariableAttributes(p, init_d.d.ty, attr_buf_top, null);
1826 }
1827 if (decl_spec.storage_class != .typedef and init_d.d.ty.hasIncompleteSize()) incomplete: {
1828 const specifier = init_d.d.ty.canonicalize(.standard).specifier;
1829 if (decl_spec.storage_class == .@"extern") switch (specifier) {
1830 .@"struct", .@"union", .@"enum" => break :incomplete,
1831 .incomplete_array => {
1832 init_d.d.ty.decayArray();
1833 break :incomplete;
1834 },
1835 else => {},
1836 };
1837 // if there was an initializer expression it must have contained an error
1838 if (init_d.initializer.node != .none) break :incomplete;
1839
1840 if (p.func.ty == null) {
1841 if (specifier == .incomplete_array) {
1842 // TODO properly check this after finishing parsing
1843 try p.errStr(.tentative_array, name, try p.typeStr(init_d.d.ty));
1844 break :incomplete;
1845 } else if (init_d.d.ty.getRecord()) |record| {
1846 _ = try p.tentative_defs.getOrPutValue(p.gpa, record.name, init_d.d.name);
1847 break :incomplete;
1848 } else if (init_d.d.ty.get(.@"enum")) |en| {
1849 _ = try p.tentative_defs.getOrPutValue(p.gpa, en.data.@"enum".name, init_d.d.name);
1850 break :incomplete;
1851 }
1852 }
1853 try p.errStr(.variable_incomplete_ty, name, try p.typeStr(init_d.d.ty));
1854 }
1855 return init_d;
1856}
1857
1858/// typeSpec
1859/// : keyword_void
1860/// | keyword_auto_type
1861/// | keyword_char
1862/// | keyword_short
1863/// | keyword_int
1864/// | keyword_long
1865/// | keyword_float
1866/// | keyword_double
1867/// | keyword_signed
1868/// | keyword_unsigned
1869/// | keyword_bool
1870/// | keyword_c23_bool
1871/// | keyword_complex
1872/// | atomicTypeSpec
1873/// | recordSpec
1874/// | enumSpec
1875/// | typedef // IDENTIFIER
1876/// | typeof
1877/// | keyword_bit_int '(' integerConstExpr ')'
1878/// atomicTypeSpec : keyword_atomic '(' typeName ')'
1879/// alignSpec
1880/// : keyword_alignas '(' typeName ')'
1881/// | keyword_alignas '(' integerConstExpr ')'
1882/// | keyword_c23_alignas '(' typeName ')'
1883/// | keyword_c23_alignas '(' integerConstExpr ')'
1884fn typeSpec(p: *Parser, ty: *Type.Builder) Error!bool {
1885 const start = p.tok_i;
1886 while (true) {
1887 try p.attributeSpecifier();
1888
1889 if (try p.typeof()) |inner_ty| {
1890 try ty.combineFromTypeof(p, inner_ty, start);
1891 continue;
1892 }
1893 if (try p.typeQual(&ty.qual)) continue;
1894 switch (p.tok_ids[p.tok_i]) {
1895 .keyword_void => try ty.combine(p, .void, p.tok_i),
1896 .keyword_auto_type => {
1897 try p.errTok(.auto_type_extension, p.tok_i);
1898 try ty.combine(p, .auto_type, p.tok_i);
1899 },
1900 .keyword_bool, .keyword_c23_bool => try ty.combine(p, .bool, p.tok_i),
1901 .keyword_int8, .keyword_int8_2, .keyword_char => try ty.combine(p, .char, p.tok_i),
1902 .keyword_int16, .keyword_int16_2, .keyword_short => try ty.combine(p, .short, p.tok_i),
1903 .keyword_int32, .keyword_int32_2, .keyword_int => try ty.combine(p, .int, p.tok_i),
1904 .keyword_long => try ty.combine(p, .long, p.tok_i),
1905 .keyword_int64, .keyword_int64_2 => try ty.combine(p, .long_long, p.tok_i),
1906 .keyword_int128 => try ty.combine(p, .int128, p.tok_i),
1907 .keyword_signed => try ty.combine(p, .signed, p.tok_i),
1908 .keyword_unsigned => try ty.combine(p, .unsigned, p.tok_i),
1909 .keyword_fp16 => try ty.combine(p, .fp16, p.tok_i),
1910 .keyword_float16 => try ty.combine(p, .float16, p.tok_i),
1911 .keyword_float => try ty.combine(p, .float, p.tok_i),
1912 .keyword_double => try ty.combine(p, .double, p.tok_i),
1913 .keyword_complex => try ty.combine(p, .complex, p.tok_i),
1914 .keyword_float80 => try ty.combine(p, .float80, p.tok_i),
1915 .keyword_float128_1, .keyword_float128_2 => {
1916 if (!p.comp.hasFloat128()) {
1917 try p.errStr(.type_not_supported_on_target, p.tok_i, p.tok_ids[p.tok_i].lexeme().?);
1918 }
1919 try ty.combine(p, .float128, p.tok_i);
1920 },
1921 .keyword_atomic => {
1922 const atomic_tok = p.tok_i;
1923 p.tok_i += 1;
1924 const l_paren = p.eatToken(.l_paren) orelse {
1925 // _Atomic qualifier not _Atomic(typeName)
1926 p.tok_i = atomic_tok;
1927 break;
1928 };
1929 const inner_ty = (try p.typeName()) orelse {
1930 try p.err(.expected_type);
1931 return error.ParsingFailed;
1932 };
1933 try p.expectClosing(l_paren, .r_paren);
1934
1935 const new_spec = Type.Builder.fromType(inner_ty);
1936 try ty.combine(p, new_spec, atomic_tok);
1937
1938 if (ty.qual.atomic != null)
1939 try p.errStr(.duplicate_decl_spec, atomic_tok, "atomic")
1940 else
1941 ty.qual.atomic = atomic_tok;
1942 continue;
1943 },
1944 .keyword_alignas,
1945 .keyword_c23_alignas,
1946 => {
1947 const align_tok = p.tok_i;
1948 p.tok_i += 1;
1949 const l_paren = try p.expectToken(.l_paren);
1950 const typename_start = p.tok_i;
1951 if (try p.typeName()) |inner_ty| {
1952 if (!inner_ty.alignable()) {
1953 try p.errStr(.invalid_alignof, typename_start, try p.typeStr(inner_ty));
1954 }
1955 const alignment = Attribute.Alignment{ .requested = inner_ty.alignof(p.comp) };
1956 try p.attr_buf.append(p.gpa, .{
1957 .attr = .{ .tag = .aligned, .args = .{
1958 .aligned = .{ .alignment = alignment, .__name_tok = align_tok },
1959 }, .syntax = .keyword },
1960 .tok = align_tok,
1961 });
1962 } else {
1963 const arg_start = p.tok_i;
1964 const res = try p.integerConstExpr(.no_const_decl_folding);
1965 if (!res.val.isZero(p.comp)) {
1966 var args = Attribute.initArguments(.aligned, align_tok);
1967 if (try p.diagnose(.aligned, &args, 0, res)) |msg| {
1968 try p.errExtra(msg.tag, arg_start, msg.extra);
1969 p.skipTo(.r_paren);
1970 return error.ParsingFailed;
1971 }
1972 args.aligned.alignment.?.node = res.node;
1973 try p.attr_buf.append(p.gpa, .{
1974 .attr = .{ .tag = .aligned, .args = args, .syntax = .keyword },
1975 .tok = align_tok,
1976 });
1977 }
1978 }
1979 try p.expectClosing(l_paren, .r_paren);
1980 continue;
1981 },
1982 .keyword_stdcall,
1983 .keyword_stdcall2,
1984 .keyword_thiscall,
1985 .keyword_thiscall2,
1986 .keyword_vectorcall,
1987 .keyword_vectorcall2,
1988 => try p.attr_buf.append(p.gpa, .{
1989 .attr = .{ .tag = .calling_convention, .args = .{
1990 .calling_convention = .{ .cc = switch (p.tok_ids[p.tok_i]) {
1991 .keyword_stdcall,
1992 .keyword_stdcall2,
1993 => .stdcall,
1994 .keyword_thiscall,
1995 .keyword_thiscall2,
1996 => .thiscall,
1997 .keyword_vectorcall,
1998 .keyword_vectorcall2,
1999 => .vectorcall,
2000 else => unreachable,
2001 } },
2002 }, .syntax = .keyword },
2003 .tok = p.tok_i,
2004 }),
2005 .keyword_struct, .keyword_union => {
2006 const tag_tok = p.tok_i;
2007 const record_ty = try p.recordSpec();
2008 try ty.combine(p, Type.Builder.fromType(record_ty), tag_tok);
2009 continue;
2010 },
2011 .keyword_enum => {
2012 const tag_tok = p.tok_i;
2013 const enum_ty = try p.enumSpec();
2014 try ty.combine(p, Type.Builder.fromType(enum_ty), tag_tok);
2015 continue;
2016 },
2017 .identifier, .extended_identifier => {
2018 var interned_name = try StrInt.intern(p.comp, p.tokSlice(p.tok_i));
2019 var declspec_found = false;
2020
2021 if (interned_name == p.string_ids.declspec_id) {
2022 try p.errTok(.declspec_not_enabled, p.tok_i);
2023 p.tok_i += 1;
2024 if (p.eatToken(.l_paren)) |_| {
2025 p.skipTo(.r_paren);
2026 continue;
2027 }
2028 declspec_found = true;
2029 }
2030 if (ty.typedef != null) break;
2031 if (declspec_found) {
2032 interned_name = try StrInt.intern(p.comp, p.tokSlice(p.tok_i));
2033 }
2034 const typedef = (try p.syms.findTypedef(p, interned_name, p.tok_i, ty.specifier != .none)) orelse break;
2035 if (!ty.combineTypedef(p, typedef.ty, typedef.tok)) break;
2036 },
2037 .keyword_bit_int => {
2038 try p.err(.bit_int);
2039 const bit_int_tok = p.tok_i;
2040 p.tok_i += 1;
2041 const l_paren = try p.expectToken(.l_paren);
2042 const res = try p.integerConstExpr(.gnu_folding_extension);
2043 try p.expectClosing(l_paren, .r_paren);
2044
2045 var bits: u64 = undefined;
2046 if (res.val.opt_ref == .none) {
2047 try p.errTok(.expected_integer_constant_expr, bit_int_tok);
2048 return error.ParsingFailed;
2049 } else if (res.val.compare(.lte, Value.zero, p.comp)) {
2050 bits = 0;
2051 } else {
2052 bits = res.val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
2053 }
2054
2055 try ty.combine(p, .{ .bit_int = bits }, bit_int_tok);
2056 continue;
2057 },
2058 else => break,
2059 }
2060 // consume single token specifiers here
2061 p.tok_i += 1;
2062 }
2063 return p.tok_i != start;
2064}
2065
2066fn getAnonymousName(p: *Parser, kind_tok: TokenIndex) !StringId {
2067 const loc = p.pp.tokens.items(.loc)[kind_tok];
2068 const source = p.comp.getSource(loc.id);
2069 const line_col = source.lineCol(loc);
2070
2071 const kind_str = switch (p.tok_ids[kind_tok]) {
2072 .keyword_struct, .keyword_union, .keyword_enum => p.tokSlice(kind_tok),
2073 else => "record field",
2074 };
2075
2076 const str = try std.fmt.allocPrint(
2077 p.arena,
2078 "(anonymous {s} at {s}:{d}:{d})",
2079 .{ kind_str, source.path, line_col.line_no, line_col.col },
2080 );
2081 return StrInt.intern(p.comp, str);
2082}
2083
2084/// recordSpec
2085/// : (keyword_struct | keyword_union) IDENTIFIER? { recordDecl* }
2086/// | (keyword_struct | keyword_union) IDENTIFIER
2087fn recordSpec(p: *Parser) Error!Type {
2088 const starting_pragma_pack = p.pragma_pack;
2089 const kind_tok = p.tok_i;
2090 const is_struct = p.tok_ids[kind_tok] == .keyword_struct;
2091 p.tok_i += 1;
2092 const attr_buf_top = p.attr_buf.len;
2093 defer p.attr_buf.len = attr_buf_top;
2094 try p.attributeSpecifier();
2095
2096 const maybe_ident = try p.eatIdentifier();
2097 const l_brace = p.eatToken(.l_brace) orelse {
2098 const ident = maybe_ident orelse {
2099 try p.err(.ident_or_l_brace);
2100 return error.ParsingFailed;
2101 };
2102 // check if this is a reference to a previous type
2103 const interned_name = try StrInt.intern(p.comp, p.tokSlice(ident));
2104 if (try p.syms.findTag(p, interned_name, p.tok_ids[kind_tok], ident, p.tok_ids[p.tok_i])) |prev| {
2105 return prev.ty;
2106 } else {
2107 // this is a forward declaration, create a new record Type.
2108 const record_ty = try Type.Record.create(p.arena, interned_name);
2109 const ty = try Attribute.applyTypeAttributes(p, .{
2110 .specifier = if (is_struct) .@"struct" else .@"union",
2111 .data = .{ .record = record_ty },
2112 }, attr_buf_top, null);
2113 try p.syms.define(p.gpa, .{
2114 .kind = if (is_struct) .@"struct" else .@"union",
2115 .name = interned_name,
2116 .tok = ident,
2117 .ty = ty,
2118 .val = .{},
2119 });
2120 try p.decl_buf.append(try p.addNode(.{
2121 .tag = if (is_struct) .struct_forward_decl else .union_forward_decl,
2122 .ty = ty,
2123 .data = .{ .decl_ref = ident },
2124 }));
2125 return ty;
2126 }
2127 };
2128
2129 var done = false;
2130 errdefer if (!done) p.skipTo(.r_brace);
2131
2132 // Get forward declared type or create a new one
2133 var defined = false;
2134 const record_ty: *Type.Record = if (maybe_ident) |ident| record_ty: {
2135 const ident_str = p.tokSlice(ident);
2136 const interned_name = try StrInt.intern(p.comp, ident_str);
2137 if (try p.syms.defineTag(p, interned_name, p.tok_ids[kind_tok], ident)) |prev| {
2138 if (!prev.ty.hasIncompleteSize()) {
2139 // if the record isn't incomplete, this is a redefinition
2140 try p.errStr(.redefinition, ident, ident_str);
2141 try p.errTok(.previous_definition, prev.tok);
2142 } else {
2143 defined = true;
2144 break :record_ty prev.ty.get(if (is_struct) .@"struct" else .@"union").?.data.record;
2145 }
2146 }
2147 break :record_ty try Type.Record.create(p.arena, interned_name);
2148 } else try Type.Record.create(p.arena, try p.getAnonymousName(kind_tok));
2149
2150 // Initially create ty as a regular non-attributed type, since attributes for a record
2151 // can be specified after the closing rbrace, which we haven't encountered yet.
2152 var ty = Type{
2153 .specifier = if (is_struct) .@"struct" else .@"union",
2154 .data = .{ .record = record_ty },
2155 };
2156
2157 // declare a symbol for the type
2158 // We need to replace the symbol's type if it has attributes
2159 if (maybe_ident != null and !defined) {
2160 try p.syms.define(p.gpa, .{
2161 .kind = if (is_struct) .@"struct" else .@"union",
2162 .name = record_ty.name,
2163 .tok = maybe_ident.?,
2164 .ty = ty,
2165 .val = .{},
2166 });
2167 }
2168
2169 // reserve space for this record
2170 try p.decl_buf.append(.none);
2171 const decl_buf_top = p.decl_buf.items.len;
2172 const record_buf_top = p.record_buf.items.len;
2173 errdefer p.decl_buf.items.len = decl_buf_top - 1;
2174 defer {
2175 p.decl_buf.items.len = decl_buf_top;
2176 p.record_buf.items.len = record_buf_top;
2177 }
2178
2179 const old_record = p.record;
2180 const old_members = p.record_members.items.len;
2181 const old_field_attr_start = p.field_attr_buf.items.len;
2182 p.record = .{
2183 .kind = p.tok_ids[kind_tok],
2184 .start = p.record_members.items.len,
2185 .field_attr_start = p.field_attr_buf.items.len,
2186 };
2187 defer p.record = old_record;
2188 defer p.record_members.items.len = old_members;
2189 defer p.field_attr_buf.items.len = old_field_attr_start;
2190
2191 try p.recordDecls();
2192
2193 if (p.record.flexible_field) |some| {
2194 if (p.record_buf.items[record_buf_top..].len == 1 and is_struct) {
2195 try p.errTok(.flexible_in_empty, some);
2196 }
2197 }
2198
2199 for (p.record_buf.items[record_buf_top..]) |field| {
2200 if (field.ty.hasIncompleteSize() and !field.ty.is(.incomplete_array)) break;
2201 } else {
2202 record_ty.fields = try p.arena.dupe(Type.Record.Field, p.record_buf.items[record_buf_top..]);
2203 }
2204 if (old_field_attr_start < p.field_attr_buf.items.len) {
2205 const field_attr_slice = p.field_attr_buf.items[old_field_attr_start..];
2206 const duped = try p.arena.dupe([]const Attribute, field_attr_slice);
2207 record_ty.field_attributes = duped.ptr;
2208 }
2209
2210 if (p.record_buf.items.len == record_buf_top) {
2211 try p.errStr(.empty_record, kind_tok, p.tokSlice(kind_tok));
2212 try p.errStr(.empty_record_size, kind_tok, p.tokSlice(kind_tok));
2213 }
2214 try p.expectClosing(l_brace, .r_brace);
2215 done = true;
2216 try p.attributeSpecifier();
2217
2218 ty = try Attribute.applyTypeAttributes(p, .{
2219 .specifier = if (is_struct) .@"struct" else .@"union",
2220 .data = .{ .record = record_ty },
2221 }, attr_buf_top, null);
2222 if (ty.specifier == .attributed and maybe_ident != null) {
2223 const ident_str = p.tokSlice(maybe_ident.?);
2224 const interned_name = try StrInt.intern(p.comp, ident_str);
2225 const ptr = p.syms.getPtr(interned_name, .tags);
2226 ptr.ty = ty;
2227 }
2228
2229 if (!ty.hasIncompleteSize()) {
2230 const pragma_pack_value = switch (p.comp.langopts.emulate) {
2231 .clang => starting_pragma_pack,
2232 .gcc => p.pragma_pack,
2233 // TODO: msvc considers `#pragma pack` on a per-field basis
2234 .msvc => p.pragma_pack,
2235 };
2236 record_layout.compute(record_ty, ty, p.comp, pragma_pack_value);
2237 }
2238
2239 // finish by creating a node
2240 var node: Tree.Node = .{
2241 .tag = if (is_struct) .struct_decl_two else .union_decl_two,
2242 .ty = ty,
2243 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
2244 };
2245 const record_decls = p.decl_buf.items[decl_buf_top..];
2246 switch (record_decls.len) {
2247 0 => {},
2248 1 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = .none } },
2249 2 => node.data = .{ .bin = .{ .lhs = record_decls[0], .rhs = record_decls[1] } },
2250 else => {
2251 node.tag = if (is_struct) .struct_decl else .union_decl;
2252 node.data = .{ .range = try p.addList(record_decls) };
2253 },
2254 }
2255 p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
2256 if (p.func.ty == null) {
2257 _ = p.tentative_defs.remove(record_ty.name);
2258 }
2259 return ty;
2260}
2261
2262/// recordDecl
2263/// : specQual (recordDeclarator (',' recordDeclarator)*)? ;
2264/// | staticAssert
2265fn recordDecls(p: *Parser) Error!void {
2266 while (true) {
2267 if (try p.pragma()) continue;
2268 if (try p.parseOrNextDecl(staticAssert)) continue;
2269 if (p.eatToken(.keyword_extension)) |_| {
2270 const saved_extension = p.extension_suppressed;
2271 defer p.extension_suppressed = saved_extension;
2272 p.extension_suppressed = true;
2273
2274 if (try p.parseOrNextDecl(recordDeclarator)) continue;
2275 try p.err(.expected_type);
2276 p.nextExternDecl();
2277 continue;
2278 }
2279 if (try p.parseOrNextDecl(recordDeclarator)) continue;
2280 break;
2281 }
2282}
2283
2284/// recordDeclarator : keyword_extension? declarator (':' integerConstExpr)?
2285fn recordDeclarator(p: *Parser) Error!bool {
2286 const attr_buf_top = p.attr_buf.len;
2287 defer p.attr_buf.len = attr_buf_top;
2288 const base_ty = (try p.specQual()) orelse return false;
2289
2290 try p.attributeSpecifier(); // .record
2291 while (true) {
2292 const this_decl_top = p.attr_buf.len;
2293 defer p.attr_buf.len = this_decl_top;
2294
2295 try p.attributeSpecifier();
2296
2297 // 0 means unnamed
2298 var name_tok: TokenIndex = 0;
2299 var ty = base_ty;
2300 if (ty.is(.auto_type)) {
2301 try p.errStr(.auto_type_not_allowed, p.tok_i, if (p.record.kind == .keyword_struct) "struct member" else "union member");
2302 ty = Type.invalid;
2303 }
2304 var bits_node: NodeIndex = .none;
2305 var bits: ?u32 = null;
2306 const first_tok = p.tok_i;
2307 if (try p.declarator(ty, .record)) |d| {
2308 name_tok = d.name;
2309 ty = d.ty;
2310 }
2311
2312 if (p.eatToken(.colon)) |_| bits: {
2313 const bits_tok = p.tok_i;
2314 const res = try p.integerConstExpr(.gnu_folding_extension);
2315 if (!ty.isInt()) {
2316 try p.errStr(.non_int_bitfield, first_tok, try p.typeStr(ty));
2317 break :bits;
2318 }
2319
2320 if (res.val.opt_ref == .none) {
2321 try p.errTok(.expected_integer_constant_expr, bits_tok);
2322 break :bits;
2323 } else if (res.val.compare(.lt, Value.zero, p.comp)) {
2324 try p.errStr(.negative_bitwidth, first_tok, try res.str(p));
2325 break :bits;
2326 }
2327
2328 // incomplete size error is reported later
2329 const bit_size = ty.bitSizeof(p.comp) orelse break :bits;
2330 const bits_unchecked = res.val.toInt(u32, p.comp) orelse std.math.maxInt(u32);
2331 if (bits_unchecked > bit_size) {
2332 try p.errTok(.bitfield_too_big, name_tok);
2333 break :bits;
2334 } else if (bits_unchecked == 0 and name_tok != 0) {
2335 try p.errTok(.zero_width_named_field, name_tok);
2336 break :bits;
2337 }
2338
2339 bits = bits_unchecked;
2340 bits_node = res.node;
2341 }
2342
2343 try p.attributeSpecifier(); // .record
2344 const to_append = try Attribute.applyFieldAttributes(p, &ty, attr_buf_top);
2345
2346 const any_fields_have_attrs = p.field_attr_buf.items.len > p.record.field_attr_start;
2347
2348 if (any_fields_have_attrs) {
2349 try p.field_attr_buf.append(to_append);
2350 } else {
2351 if (to_append.len > 0) {
2352 const preceding = p.record_members.items.len - p.record.start;
2353 if (preceding > 0) {
2354 try p.field_attr_buf.appendNTimes(&.{}, preceding);
2355 }
2356 try p.field_attr_buf.append(to_append);
2357 }
2358 }
2359
2360 if (name_tok == 0 and bits_node == .none) unnamed: {
2361 if (ty.is(.@"enum") or ty.hasIncompleteSize()) break :unnamed;
2362 if (ty.isAnonymousRecord(p.comp)) {
2363 // An anonymous record appears as indirect fields on the parent
2364 try p.record_buf.append(.{
2365 .name = try p.getAnonymousName(first_tok),
2366 .ty = ty,
2367 });
2368 const node = try p.addNode(.{
2369 .tag = .indirect_record_field_decl,
2370 .ty = ty,
2371 .data = undefined,
2372 });
2373 try p.decl_buf.append(node);
2374 try p.record.addFieldsFromAnonymous(p, ty);
2375 break; // must be followed by a semicolon
2376 }
2377 try p.err(.missing_declaration);
2378 } else {
2379 const interned_name = if (name_tok != 0) try StrInt.intern(p.comp, p.tokSlice(name_tok)) else try p.getAnonymousName(first_tok);
2380 try p.record_buf.append(.{
2381 .name = interned_name,
2382 .ty = ty,
2383 .name_tok = name_tok,
2384 .bit_width = bits,
2385 });
2386 if (name_tok != 0) try p.record.addField(p, interned_name, name_tok);
2387 const node = try p.addNode(.{
2388 .tag = .record_field_decl,
2389 .ty = ty,
2390 .data = .{ .decl = .{ .name = name_tok, .node = bits_node } },
2391 });
2392 try p.decl_buf.append(node);
2393 }
2394
2395 if (ty.isFunc()) {
2396 try p.errTok(.func_field, first_tok);
2397 } else if (ty.is(.variable_len_array)) {
2398 try p.errTok(.vla_field, first_tok);
2399 } else if (ty.is(.incomplete_array)) {
2400 if (p.record.kind == .keyword_union) {
2401 try p.errTok(.flexible_in_union, first_tok);
2402 }
2403 if (p.record.flexible_field) |some| {
2404 if (p.record.kind == .keyword_struct) {
2405 try p.errTok(.flexible_non_final, some);
2406 }
2407 }
2408 p.record.flexible_field = first_tok;
2409 } else if (ty.specifier != .invalid and ty.hasIncompleteSize()) {
2410 try p.errStr(.field_incomplete_ty, first_tok, try p.typeStr(ty));
2411 } else if (p.record.flexible_field) |some| {
2412 if (some != first_tok and p.record.kind == .keyword_struct) try p.errTok(.flexible_non_final, some);
2413 }
2414 if (p.eatToken(.comma) == null) break;
2415 }
2416
2417 if (p.eatToken(.semicolon) == null) {
2418 const tok_id = p.tok_ids[p.tok_i];
2419 if (tok_id == .r_brace) {
2420 try p.err(.missing_semicolon);
2421 } else {
2422 return p.errExpectedToken(.semicolon, tok_id);
2423 }
2424 }
2425
2426 return true;
2427}
2428
2429/// specQual : (typeSpec | typeQual | alignSpec)+
2430fn specQual(p: *Parser) Error!?Type {
2431 var spec: Type.Builder = .{};
2432 if (try p.typeSpec(&spec)) {
2433 return try spec.finish(p);
2434 }
2435 return null;
2436}
2437
2438/// enumSpec
2439/// : keyword_enum IDENTIFIER? (: typeName)? { enumerator (',' enumerator)? ',') }
2440/// | keyword_enum IDENTIFIER (: typeName)?
2441fn enumSpec(p: *Parser) Error!Type {
2442 const enum_tok = p.tok_i;
2443 p.tok_i += 1;
2444 const attr_buf_top = p.attr_buf.len;
2445 defer p.attr_buf.len = attr_buf_top;
2446 try p.attributeSpecifier();
2447
2448 const maybe_ident = try p.eatIdentifier();
2449 const fixed_ty = if (p.eatToken(.colon)) |colon| fixed: {
2450 const fixed = (try p.typeName()) orelse {
2451 if (p.record.kind != .invalid) {
2452 // This is a bit field.
2453 p.tok_i -= 1;
2454 break :fixed null;
2455 }
2456 try p.err(.expected_type);
2457 try p.errTok(.enum_fixed, colon);
2458 break :fixed null;
2459 };
2460 try p.errTok(.enum_fixed, colon);
2461 break :fixed fixed;
2462 } else null;
2463
2464 const l_brace = p.eatToken(.l_brace) orelse {
2465 const ident = maybe_ident orelse {
2466 try p.err(.ident_or_l_brace);
2467 return error.ParsingFailed;
2468 };
2469 // check if this is a reference to a previous type
2470 const interned_name = try StrInt.intern(p.comp, p.tokSlice(ident));
2471 if (try p.syms.findTag(p, interned_name, .keyword_enum, ident, p.tok_ids[p.tok_i])) |prev| {
2472 // only check fixed underlying type in forward declarations and not in references.
2473 if (p.tok_ids[p.tok_i] == .semicolon)
2474 try p.checkEnumFixedTy(fixed_ty, ident, prev);
2475 return prev.ty;
2476 } else {
2477 // this is a forward declaration, create a new enum Type.
2478 const enum_ty = try Type.Enum.create(p.arena, interned_name, fixed_ty);
2479 const ty = try Attribute.applyTypeAttributes(p, .{
2480 .specifier = .@"enum",
2481 .data = .{ .@"enum" = enum_ty },
2482 }, attr_buf_top, null);
2483 try p.syms.define(p.gpa, .{
2484 .kind = .@"enum",
2485 .name = interned_name,
2486 .tok = ident,
2487 .ty = ty,
2488 .val = .{},
2489 });
2490 try p.decl_buf.append(try p.addNode(.{
2491 .tag = .enum_forward_decl,
2492 .ty = ty,
2493 .data = .{ .decl_ref = ident },
2494 }));
2495 return ty;
2496 }
2497 };
2498
2499 var done = false;
2500 errdefer if (!done) p.skipTo(.r_brace);
2501
2502 // Get forward declared type or create a new one
2503 var defined = false;
2504 const enum_ty: *Type.Enum = if (maybe_ident) |ident| enum_ty: {
2505 const ident_str = p.tokSlice(ident);
2506 const interned_name = try StrInt.intern(p.comp, ident_str);
2507 if (try p.syms.defineTag(p, interned_name, .keyword_enum, ident)) |prev| {
2508 const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
2509 if (!enum_ty.isIncomplete() and !enum_ty.fixed) {
2510 // if the enum isn't incomplete, this is a redefinition
2511 try p.errStr(.redefinition, ident, ident_str);
2512 try p.errTok(.previous_definition, prev.tok);
2513 } else {
2514 try p.checkEnumFixedTy(fixed_ty, ident, prev);
2515 defined = true;
2516 break :enum_ty enum_ty;
2517 }
2518 }
2519 break :enum_ty try Type.Enum.create(p.arena, interned_name, fixed_ty);
2520 } else try Type.Enum.create(p.arena, try p.getAnonymousName(enum_tok), fixed_ty);
2521
2522 // reserve space for this enum
2523 try p.decl_buf.append(.none);
2524 const decl_buf_top = p.decl_buf.items.len;
2525 const list_buf_top = p.list_buf.items.len;
2526 const enum_buf_top = p.enum_buf.items.len;
2527 errdefer p.decl_buf.items.len = decl_buf_top - 1;
2528 defer {
2529 p.decl_buf.items.len = decl_buf_top;
2530 p.list_buf.items.len = list_buf_top;
2531 p.enum_buf.items.len = enum_buf_top;
2532 }
2533
2534 var e = Enumerator.init(fixed_ty);
2535 while (try p.enumerator(&e)) |field_and_node| {
2536 try p.enum_buf.append(field_and_node.field);
2537 try p.list_buf.append(field_and_node.node);
2538 if (p.eatToken(.comma) == null) break;
2539 }
2540
2541 if (p.enum_buf.items.len == enum_buf_top) try p.err(.empty_enum);
2542 try p.expectClosing(l_brace, .r_brace);
2543 done = true;
2544 try p.attributeSpecifier();
2545
2546 const ty = try Attribute.applyTypeAttributes(p, .{
2547 .specifier = .@"enum",
2548 .data = .{ .@"enum" = enum_ty },
2549 }, attr_buf_top, null);
2550 if (!enum_ty.fixed) {
2551 const tag_specifier = try e.getTypeSpecifier(p, ty.enumIsPacked(p.comp), maybe_ident orelse enum_tok);
2552 enum_ty.tag_ty = .{ .specifier = tag_specifier };
2553 }
2554
2555 const enum_fields = p.enum_buf.items[enum_buf_top..];
2556 const field_nodes = p.list_buf.items[list_buf_top..];
2557
2558 if (fixed_ty == null) {
2559 for (enum_fields, 0..) |*field, i| {
2560 if (field.ty.eql(Type.int, p.comp, false)) continue;
2561
2562 const sym = p.syms.get(field.name, .vars) orelse continue;
2563
2564 var res = Result{ .node = field.node, .ty = field.ty, .val = sym.val };
2565 const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some|
2566 Type{ .specifier = some }
2567 else if (try res.intFitsInType(p, Type.int))
2568 Type.int
2569 else if (!res.ty.eql(enum_ty.tag_ty, p.comp, false))
2570 enum_ty.tag_ty
2571 else
2572 continue;
2573
2574 const symbol = p.syms.getPtr(field.name, .vars);
2575 try symbol.val.intCast(dest_ty, p.comp);
2576 symbol.ty = dest_ty;
2577 p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty;
2578 field.ty = dest_ty;
2579 res.ty = dest_ty;
2580
2581 if (res.node != .none) {
2582 try res.implicitCast(p, .int_cast);
2583 field.node = res.node;
2584 p.nodes.items(.data)[@intFromEnum(field_nodes[i])].decl.node = res.node;
2585 }
2586 }
2587 }
2588
2589 enum_ty.fields = try p.arena.dupe(Type.Enum.Field, enum_fields);
2590
2591 // declare a symbol for the type
2592 if (maybe_ident != null and !defined) {
2593 try p.syms.define(p.gpa, .{
2594 .kind = .@"enum",
2595 .name = enum_ty.name,
2596 .ty = ty,
2597 .tok = maybe_ident.?,
2598 .val = .{},
2599 });
2600 }
2601
2602 // finish by creating a node
2603 var node: Tree.Node = .{ .tag = .enum_decl_two, .ty = ty, .data = .{
2604 .bin = .{ .lhs = .none, .rhs = .none },
2605 } };
2606 switch (field_nodes.len) {
2607 0 => {},
2608 1 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = .none } },
2609 2 => node.data = .{ .bin = .{ .lhs = field_nodes[0], .rhs = field_nodes[1] } },
2610 else => {
2611 node.tag = .enum_decl;
2612 node.data = .{ .range = try p.addList(field_nodes) };
2613 },
2614 }
2615 p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node);
2616 if (p.func.ty == null) {
2617 _ = p.tentative_defs.remove(enum_ty.name);
2618 }
2619 return ty;
2620}
2621
2622fn checkEnumFixedTy(p: *Parser, fixed_ty: ?Type, ident_tok: TokenIndex, prev: Symbol) !void {
2623 const enum_ty = prev.ty.get(.@"enum").?.data.@"enum";
2624 if (fixed_ty) |some| {
2625 if (!enum_ty.fixed) {
2626 try p.errTok(.enum_prev_nonfixed, ident_tok);
2627 try p.errTok(.previous_definition, prev.tok);
2628 return error.ParsingFailed;
2629 }
2630
2631 if (!enum_ty.tag_ty.eql(some, p.comp, false)) {
2632 const str = try p.typePairStrExtra(some, " (was ", enum_ty.tag_ty);
2633 try p.errStr(.enum_different_explicit_ty, ident_tok, str);
2634 try p.errTok(.previous_definition, prev.tok);
2635 return error.ParsingFailed;
2636 }
2637 } else if (enum_ty.fixed) {
2638 try p.errTok(.enum_prev_fixed, ident_tok);
2639 try p.errTok(.previous_definition, prev.tok);
2640 return error.ParsingFailed;
2641 }
2642}
2643
2644const Enumerator = struct {
2645 res: Result,
2646 num_positive_bits: usize = 0,
2647 num_negative_bits: usize = 0,
2648 fixed: bool,
2649
2650 fn init(fixed_ty: ?Type) Enumerator {
2651 return .{
2652 .res = .{ .ty = fixed_ty orelse .{ .specifier = .int } },
2653 .fixed = fixed_ty != null,
2654 };
2655 }
2656
2657 /// Increment enumerator value adjusting type if needed.
2658 fn incr(e: *Enumerator, p: *Parser, tok: TokenIndex) !void {
2659 e.res.node = .none;
2660 const old_val = e.res.val;
2661 if (old_val.opt_ref == .none) {
2662 // First enumerator, set to 0 fits in all types.
2663 e.res.val = Value.zero;
2664 return;
2665 }
2666 if (try e.res.val.add(e.res.val, Value.one, e.res.ty, p.comp)) {
2667 const byte_size = e.res.ty.sizeof(p.comp).?;
2668 const bit_size: u8 = @intCast(if (e.res.ty.isUnsignedInt(p.comp)) byte_size * 8 else byte_size * 8 - 1);
2669 if (e.fixed) {
2670 try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
2671 return;
2672 }
2673 const new_ty = if (p.comp.nextLargestIntSameSign(e.res.ty)) |larger| blk: {
2674 try p.errTok(.enumerator_overflow, tok);
2675 break :blk larger;
2676 } else blk: {
2677 try p.errExtra(.enum_not_representable, tok, .{ .pow_2_as_string = bit_size });
2678 break :blk Type{ .specifier = .ulong_long };
2679 };
2680 e.res.ty = new_ty;
2681 _ = try e.res.val.add(old_val, Value.one, e.res.ty, p.comp);
2682 }
2683 }
2684
2685 /// Set enumerator value to specified value.
2686 fn set(e: *Enumerator, p: *Parser, res: Result, tok: TokenIndex) !void {
2687 if (res.ty.specifier == .invalid) return;
2688 if (e.fixed and !res.ty.eql(e.res.ty, p.comp, false)) {
2689 if (!try res.intFitsInType(p, e.res.ty)) {
2690 try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty));
2691 return error.ParsingFailed;
2692 }
2693 var copy = res;
2694 copy.ty = e.res.ty;
2695 try copy.implicitCast(p, .int_cast);
2696 e.res = copy;
2697 } else {
2698 e.res = res;
2699 try e.res.intCast(p, e.res.ty.integerPromotion(p.comp), tok);
2700 }
2701 }
2702
2703 fn getTypeSpecifier(e: *const Enumerator, p: *Parser, is_packed: bool, tok: TokenIndex) !Type.Specifier {
2704 if (p.comp.fixedEnumTagSpecifier()) |tag_specifier| return tag_specifier;
2705
2706 const char_width = (Type{ .specifier = .schar }).sizeof(p.comp).? * 8;
2707 const short_width = (Type{ .specifier = .short }).sizeof(p.comp).? * 8;
2708 const int_width = (Type{ .specifier = .int }).sizeof(p.comp).? * 8;
2709 if (e.num_negative_bits > 0) {
2710 if (is_packed and e.num_negative_bits <= char_width and e.num_positive_bits < char_width) {
2711 return .schar;
2712 } else if (is_packed and e.num_negative_bits <= short_width and e.num_positive_bits < short_width) {
2713 return .short;
2714 } else if (e.num_negative_bits <= int_width and e.num_positive_bits < int_width) {
2715 return .int;
2716 }
2717 const long_width = (Type{ .specifier = .long }).sizeof(p.comp).? * 8;
2718 if (e.num_negative_bits <= long_width and e.num_positive_bits < long_width) {
2719 return .long;
2720 }
2721 const long_long_width = (Type{ .specifier = .long_long }).sizeof(p.comp).? * 8;
2722 if (e.num_negative_bits > long_long_width or e.num_positive_bits >= long_long_width) {
2723 try p.errTok(.enum_too_large, tok);
2724 }
2725 return .long_long;
2726 }
2727 if (is_packed and e.num_positive_bits <= char_width) {
2728 return .uchar;
2729 } else if (is_packed and e.num_positive_bits <= short_width) {
2730 return .ushort;
2731 } else if (e.num_positive_bits <= int_width) {
2732 return .uint;
2733 } else if (e.num_positive_bits <= (Type{ .specifier = .long }).sizeof(p.comp).? * 8) {
2734 return .ulong;
2735 }
2736 return .ulong_long;
2737 }
2738};
2739
2740const EnumFieldAndNode = struct { field: Type.Enum.Field, node: NodeIndex };
2741
2742/// enumerator : IDENTIFIER ('=' integerConstExpr)
2743fn enumerator(p: *Parser, e: *Enumerator) Error!?EnumFieldAndNode {
2744 _ = try p.pragma();
2745 const name_tok = (try p.eatIdentifier()) orelse {
2746 if (p.tok_ids[p.tok_i] == .r_brace) return null;
2747 try p.err(.expected_identifier);
2748 p.skipTo(.r_brace);
2749 return error.ParsingFailed;
2750 };
2751 const attr_buf_top = p.attr_buf.len;
2752 defer p.attr_buf.len = attr_buf_top;
2753 try p.attributeSpecifier();
2754
2755 const err_start = p.comp.diagnostics.list.items.len;
2756 if (p.eatToken(.equal)) |_| {
2757 const specified = try p.integerConstExpr(.gnu_folding_extension);
2758 if (specified.val.opt_ref == .none) {
2759 try p.errTok(.enum_val_unavailable, name_tok + 2);
2760 try e.incr(p, name_tok);
2761 } else {
2762 try e.set(p, specified, name_tok);
2763 }
2764 } else {
2765 try e.incr(p, name_tok);
2766 }
2767
2768 var res = e.res;
2769 res.ty = try Attribute.applyEnumeratorAttributes(p, res.ty, attr_buf_top);
2770
2771 if (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, Value.zero, p.comp)) {
2772 e.num_positive_bits = @max(e.num_positive_bits, res.val.minUnsignedBits(p.comp));
2773 } else {
2774 e.num_negative_bits = @max(e.num_negative_bits, res.val.minSignedBits(p.comp));
2775 }
2776
2777 if (err_start == p.comp.diagnostics.list.items.len) {
2778 // only do these warnings if we didn't already warn about overflow or non-representable values
2779 if (e.res.val.compare(.lt, Value.zero, p.comp)) {
2780 const min_int = (Type{ .specifier = .int }).minInt(p.comp);
2781 const min_val = try Value.int(min_int, p.comp);
2782 if (e.res.val.compare(.lt, min_val, p.comp)) {
2783 try p.errStr(.enumerator_too_small, name_tok, try e.res.str(p));
2784 }
2785 } else {
2786 const max_int = (Type{ .specifier = .int }).maxInt(p.comp);
2787 const max_val = try Value.int(max_int, p.comp);
2788 if (e.res.val.compare(.gt, max_val, p.comp)) {
2789 try p.errStr(.enumerator_too_large, name_tok, try e.res.str(p));
2790 }
2791 }
2792 }
2793
2794 const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok));
2795 try p.syms.defineEnumeration(p, interned_name, res.ty, name_tok, e.res.val);
2796 const node = try p.addNode(.{
2797 .tag = .enum_field_decl,
2798 .ty = res.ty,
2799 .data = .{ .decl = .{
2800 .name = name_tok,
2801 .node = res.node,
2802 } },
2803 });
2804 try p.value_map.put(node, e.res.val);
2805 return EnumFieldAndNode{ .field = .{
2806 .name = interned_name,
2807 .ty = res.ty,
2808 .name_tok = name_tok,
2809 .node = res.node,
2810 }, .node = node };
2811}
2812
2813/// typeQual : keyword_const | keyword_restrict | keyword_volatile | keyword_atomic
2814fn typeQual(p: *Parser, b: *Type.Qualifiers.Builder) Error!bool {
2815 var any = false;
2816 while (true) {
2817 switch (p.tok_ids[p.tok_i]) {
2818 .keyword_restrict, .keyword_restrict1, .keyword_restrict2 => {
2819 if (b.restrict != null)
2820 try p.errStr(.duplicate_decl_spec, p.tok_i, "restrict")
2821 else
2822 b.restrict = p.tok_i;
2823 },
2824 .keyword_const, .keyword_const1, .keyword_const2 => {
2825 if (b.@"const" != null)
2826 try p.errStr(.duplicate_decl_spec, p.tok_i, "const")
2827 else
2828 b.@"const" = p.tok_i;
2829 },
2830 .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
2831 if (b.@"volatile" != null)
2832 try p.errStr(.duplicate_decl_spec, p.tok_i, "volatile")
2833 else
2834 b.@"volatile" = p.tok_i;
2835 },
2836 .keyword_atomic => {
2837 // _Atomic(typeName) instead of just _Atomic
2838 if (p.tok_ids[p.tok_i + 1] == .l_paren) break;
2839 if (b.atomic != null)
2840 try p.errStr(.duplicate_decl_spec, p.tok_i, "atomic")
2841 else
2842 b.atomic = p.tok_i;
2843 },
2844 else => break,
2845 }
2846 p.tok_i += 1;
2847 any = true;
2848 }
2849 return any;
2850}
2851
2852const Declarator = struct {
2853 name: TokenIndex,
2854 ty: Type,
2855 func_declarator: ?TokenIndex = null,
2856 old_style_func: ?TokenIndex = null,
2857};
2858const DeclaratorKind = enum { normal, abstract, param, record };
2859
2860/// declarator : pointer? (IDENTIFIER | '(' declarator ')') directDeclarator*
2861/// abstractDeclarator
2862/// : pointer? ('(' abstractDeclarator ')')? directAbstractDeclarator*
2863fn declarator(
2864 p: *Parser,
2865 base_type: Type,
2866 kind: DeclaratorKind,
2867) Error!?Declarator {
2868 const start = p.tok_i;
2869 var d = Declarator{ .name = 0, .ty = try p.pointer(base_type) };
2870 if (base_type.is(.auto_type) and !d.ty.is(.auto_type)) {
2871 try p.errTok(.auto_type_requires_plain_declarator, start);
2872 return error.ParsingFailed;
2873 }
2874
2875 const maybe_ident = p.tok_i;
2876 if (kind != .abstract and (try p.eatIdentifier()) != null) {
2877 d.name = maybe_ident;
2878 const combine_tok = p.tok_i;
2879 d.ty = try p.directDeclarator(d.ty, &d, kind);
2880 try d.ty.validateCombinedType(p, combine_tok);
2881 return d;
2882 } else if (p.eatToken(.l_paren)) |l_paren| blk: {
2883 var res = (try p.declarator(.{ .specifier = .void }, kind)) orelse {
2884 p.tok_i = l_paren;
2885 break :blk;
2886 };
2887 try p.expectClosing(l_paren, .r_paren);
2888 const suffix_start = p.tok_i;
2889 const outer = try p.directDeclarator(d.ty, &d, kind);
2890 try res.ty.combine(outer);
2891 try res.ty.validateCombinedType(p, suffix_start);
2892 res.old_style_func = d.old_style_func;
2893 if (d.func_declarator) |some| res.func_declarator = some;
2894 return res;
2895 }
2896
2897 const expected_ident = p.tok_i;
2898
2899 d.ty = try p.directDeclarator(d.ty, &d, kind);
2900
2901 if (kind == .normal and !d.ty.isEnumOrRecord()) {
2902 try p.errTok(.expected_ident_or_l_paren, expected_ident);
2903 return error.ParsingFailed;
2904 }
2905 try d.ty.validateCombinedType(p, expected_ident);
2906 if (start == p.tok_i) return null;
2907 return d;
2908}
2909
2910/// directDeclarator
2911/// : '[' typeQual* assignExpr? ']' directDeclarator?
2912/// | '[' keyword_static typeQual* assignExpr ']' directDeclarator?
2913/// | '[' typeQual+ keyword_static assignExpr ']' directDeclarator?
2914/// | '[' typeQual* '*' ']' directDeclarator?
2915/// | '(' paramDecls ')' directDeclarator?
2916/// | '(' (IDENTIFIER (',' IDENTIFIER))? ')' directDeclarator?
2917/// directAbstractDeclarator
2918/// : '[' typeQual* assignExpr? ']'
2919/// | '[' keyword_static typeQual* assignExpr ']'
2920/// | '[' typeQual+ keyword_static assignExpr ']'
2921/// | '[' '*' ']'
2922/// | '(' paramDecls? ')'
2923fn directDeclarator(p: *Parser, base_type: Type, d: *Declarator, kind: DeclaratorKind) Error!Type {
2924 if (p.eatToken(.l_bracket)) |l_bracket| {
2925 if (p.tok_ids[p.tok_i] == .l_bracket) {
2926 switch (kind) {
2927 .normal, .record => if (p.comp.langopts.standard.atLeast(.c23)) {
2928 p.tok_i -= 1;
2929 return base_type;
2930 },
2931 .param, .abstract => {},
2932 }
2933 try p.err(.expected_expr);
2934 return error.ParsingFailed;
2935 }
2936 var res_ty = Type{
2937 // so that we can get any restrict type that might be present
2938 .specifier = .pointer,
2939 };
2940 var quals = Type.Qualifiers.Builder{};
2941
2942 var got_quals = try p.typeQual(&quals);
2943 var static = p.eatToken(.keyword_static);
2944 if (static != null and !got_quals) got_quals = try p.typeQual(&quals);
2945 var star = p.eatToken(.asterisk);
2946 const size_tok = p.tok_i;
2947
2948 const const_decl_folding = p.const_decl_folding;
2949 p.const_decl_folding = .gnu_vla_folding_extension;
2950 const size = if (star) |_| Result{} else try p.assignExpr();
2951 p.const_decl_folding = const_decl_folding;
2952
2953 try p.expectClosing(l_bracket, .r_bracket);
2954
2955 if (star != null and static != null) {
2956 try p.errTok(.invalid_static_star, static.?);
2957 static = null;
2958 }
2959 if (kind != .param) {
2960 if (static != null)
2961 try p.errTok(.static_non_param, l_bracket)
2962 else if (got_quals)
2963 try p.errTok(.array_qualifiers, l_bracket);
2964 if (star) |some| try p.errTok(.star_non_param, some);
2965 static = null;
2966 quals = .{};
2967 star = null;
2968 } else {
2969 try quals.finish(p, &res_ty);
2970 }
2971 if (static) |_| try size.expect(p);
2972
2973 if (base_type.is(.auto_type)) {
2974 try p.errStr(.array_of_auto_type, d.name, p.tokSlice(d.name));
2975 return error.ParsingFailed;
2976 }
2977
2978 const outer = try p.directDeclarator(base_type, d, kind);
2979 var max_bits = p.comp.target.ptrBitWidth();
2980 if (max_bits > 61) max_bits = 61;
2981 const max_bytes = (@as(u64, 1) << @truncate(max_bits)) - 1;
2982
2983 if (!size.ty.isInt()) {
2984 try p.errStr(.array_size_non_int, size_tok, try p.typeStr(size.ty));
2985 return error.ParsingFailed;
2986 }
2987 if (base_type.is(.c23_auto)) {
2988 // issue error later
2989 return Type.invalid;
2990 } else if (size.val.opt_ref == .none) {
2991 if (size.node != .none) {
2992 try p.errTok(.vla, size_tok);
2993 if (p.func.ty == null and kind != .param and p.record.kind == .invalid) {
2994 try p.errTok(.variable_len_array_file_scope, d.name);
2995 }
2996 const expr_ty = try p.arena.create(Type.Expr);
2997 expr_ty.ty = .{ .specifier = .void };
2998 expr_ty.node = size.node;
2999 res_ty.data = .{ .expr = expr_ty };
3000 res_ty.specifier = .variable_len_array;
3001
3002 if (static) |some| try p.errTok(.useless_static, some);
3003 } else if (star) |_| {
3004 const elem_ty = try p.arena.create(Type);
3005 elem_ty.* = .{ .specifier = .void };
3006 res_ty.data = .{ .sub_type = elem_ty };
3007 res_ty.specifier = .unspecified_variable_len_array;
3008 } else {
3009 const arr_ty = try p.arena.create(Type.Array);
3010 arr_ty.elem = .{ .specifier = .void };
3011 arr_ty.len = 0;
3012 res_ty.data = .{ .array = arr_ty };
3013 res_ty.specifier = .incomplete_array;
3014 }
3015 } else {
3016 // `outer` is validated later so it may be invalid here
3017 const outer_size = outer.sizeof(p.comp);
3018 const max_elems = max_bytes / @max(1, outer_size orelse 1);
3019
3020 var size_val = size.val;
3021 if (size_val.isZero(p.comp)) {
3022 try p.errTok(.zero_length_array, l_bracket);
3023 } else if (size_val.compare(.lt, Value.zero, p.comp)) {
3024 try p.errTok(.negative_array_size, l_bracket);
3025 return error.ParsingFailed;
3026 }
3027 const arr_ty = try p.arena.create(Type.Array);
3028 arr_ty.elem = .{ .specifier = .void };
3029 arr_ty.len = size_val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
3030 if (arr_ty.len > max_elems) {
3031 try p.errTok(.array_too_large, l_bracket);
3032 arr_ty.len = max_elems;
3033 }
3034 res_ty.data = .{ .array = arr_ty };
3035 res_ty.specifier = .array;
3036 }
3037
3038 try res_ty.combine(outer);
3039 return res_ty;
3040 } else if (p.eatToken(.l_paren)) |l_paren| {
3041 d.func_declarator = l_paren;
3042
3043 const func_ty = try p.arena.create(Type.Func);
3044 func_ty.params = &.{};
3045 func_ty.return_type.specifier = .void;
3046 var specifier: Type.Specifier = .func;
3047
3048 if (p.eatToken(.ellipsis)) |_| {
3049 try p.err(.param_before_var_args);
3050 try p.expectClosing(l_paren, .r_paren);
3051 var res_ty = Type{ .specifier = .func, .data = .{ .func = func_ty } };
3052
3053 const outer = try p.directDeclarator(base_type, d, kind);
3054 try res_ty.combine(outer);
3055 return res_ty;
3056 }
3057
3058 if (try p.paramDecls(d)) |params| {
3059 func_ty.params = params;
3060 if (p.eatToken(.ellipsis)) |_| specifier = .var_args_func;
3061 } else if (p.tok_ids[p.tok_i] == .r_paren) {
3062 specifier = if (p.comp.langopts.standard.atLeast(.c23))
3063 .func
3064 else
3065 .old_style_func;
3066 } else if (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) {
3067 d.old_style_func = p.tok_i;
3068 const param_buf_top = p.param_buf.items.len;
3069 try p.syms.pushScope(p);
3070 defer {
3071 p.param_buf.items.len = param_buf_top;
3072 p.syms.popScope();
3073 }
3074
3075 specifier = .old_style_func;
3076 while (true) {
3077 const name_tok = try p.expectIdentifier();
3078 const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok));
3079 try p.syms.defineParam(p, interned_name, undefined, name_tok);
3080 try p.param_buf.append(.{
3081 .name = interned_name,
3082 .name_tok = name_tok,
3083 .ty = .{ .specifier = .int },
3084 });
3085 if (p.eatToken(.comma) == null) break;
3086 }
3087 func_ty.params = try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
3088 } else {
3089 try p.err(.expected_param_decl);
3090 }
3091
3092 try p.expectClosing(l_paren, .r_paren);
3093 var res_ty = Type{
3094 .specifier = specifier,
3095 .data = .{ .func = func_ty },
3096 };
3097
3098 const outer = try p.directDeclarator(base_type, d, kind);
3099 try res_ty.combine(outer);
3100 return res_ty;
3101 } else return base_type;
3102}
3103
3104/// pointer : '*' typeQual* pointer?
3105fn pointer(p: *Parser, base_ty: Type) Error!Type {
3106 var ty = base_ty;
3107 while (p.eatToken(.asterisk)) |_| {
3108 const elem_ty = try p.arena.create(Type);
3109 elem_ty.* = ty;
3110 ty = Type{
3111 .specifier = .pointer,
3112 .data = .{ .sub_type = elem_ty },
3113 };
3114 var quals = Type.Qualifiers.Builder{};
3115 _ = try p.typeQual(&quals);
3116 try quals.finish(p, &ty);
3117 }
3118 return ty;
3119}
3120
3121/// paramDecls : paramDecl (',' paramDecl)* (',' '...')
3122/// paramDecl : declSpec (declarator | abstractDeclarator)
3123fn paramDecls(p: *Parser, d: *Declarator) Error!?[]Type.Func.Param {
3124 // TODO warn about visibility of types declared here
3125 const param_buf_top = p.param_buf.items.len;
3126 defer p.param_buf.items.len = param_buf_top;
3127 try p.syms.pushScope(p);
3128 defer p.syms.popScope();
3129
3130 while (true) {
3131 const attr_buf_top = p.attr_buf.len;
3132 defer p.attr_buf.len = attr_buf_top;
3133 const param_decl_spec = if (try p.declSpec()) |some|
3134 some
3135 else if (p.comp.langopts.standard.atLeast(.c23) and
3136 (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier))
3137 {
3138 // handle deprecated K&R style parameters
3139 const identifier = try p.expectIdentifier();
3140 try p.errStr(.unknown_type_name, identifier, p.tokSlice(identifier));
3141 if (d.old_style_func == null) d.old_style_func = identifier;
3142
3143 try p.param_buf.append(.{
3144 .name = try StrInt.intern(p.comp, p.tokSlice(identifier)),
3145 .name_tok = identifier,
3146 .ty = .{ .specifier = .int },
3147 });
3148
3149 if (p.eatToken(.comma) == null) break;
3150 if (p.tok_ids[p.tok_i] == .ellipsis) break;
3151 continue;
3152 } else if (p.param_buf.items.len == param_buf_top) {
3153 return null;
3154 } else blk: {
3155 var spec: Type.Builder = .{};
3156 break :blk DeclSpec{ .ty = try spec.finish(p) };
3157 };
3158
3159 var name_tok: TokenIndex = 0;
3160 const first_tok = p.tok_i;
3161 var param_ty = param_decl_spec.ty;
3162 if (try p.declarator(param_decl_spec.ty, .param)) |some| {
3163 if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
3164 try p.attributeSpecifier();
3165
3166 name_tok = some.name;
3167 param_ty = some.ty;
3168 if (some.name != 0) {
3169 const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok));
3170 try p.syms.defineParam(p, interned_name, param_ty, name_tok);
3171 }
3172 }
3173 param_ty = try Attribute.applyParameterAttributes(p, param_ty, attr_buf_top, .alignas_on_param);
3174
3175 if (param_ty.isFunc()) {
3176 // params declared as functions are converted to function pointers
3177 const elem_ty = try p.arena.create(Type);
3178 elem_ty.* = param_ty;
3179 param_ty = Type{
3180 .specifier = .pointer,
3181 .data = .{ .sub_type = elem_ty },
3182 };
3183 } else if (param_ty.isArray()) {
3184 // params declared as arrays are converted to pointers
3185 param_ty.decayArray();
3186 } else if (param_ty.is(.void)) {
3187 // validate void parameters
3188 if (p.param_buf.items.len == param_buf_top) {
3189 if (p.tok_ids[p.tok_i] != .r_paren) {
3190 try p.err(.void_only_param);
3191 if (param_ty.anyQual()) try p.err(.void_param_qualified);
3192 return error.ParsingFailed;
3193 }
3194 return &[0]Type.Func.Param{};
3195 }
3196 try p.err(.void_must_be_first_param);
3197 return error.ParsingFailed;
3198 }
3199
3200 try param_decl_spec.validateParam(p, &param_ty);
3201 try p.param_buf.append(.{
3202 .name = if (name_tok == 0) .empty else try StrInt.intern(p.comp, p.tokSlice(name_tok)),
3203 .name_tok = if (name_tok == 0) first_tok else name_tok,
3204 .ty = param_ty,
3205 });
3206
3207 if (p.eatToken(.comma) == null) break;
3208 if (p.tok_ids[p.tok_i] == .ellipsis) break;
3209 }
3210 return try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]);
3211}
3212
3213/// typeName : specQual abstractDeclarator
3214fn typeName(p: *Parser) Error!?Type {
3215 const attr_buf_top = p.attr_buf.len;
3216 defer p.attr_buf.len = attr_buf_top;
3217 const ty = (try p.specQual()) orelse return null;
3218 if (try p.declarator(ty, .abstract)) |some| {
3219 if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i);
3220 return try Attribute.applyTypeAttributes(p, some.ty, attr_buf_top, .align_ignored);
3221 }
3222 return try Attribute.applyTypeAttributes(p, ty, attr_buf_top, .align_ignored);
3223}
3224
3225/// initializer
3226/// : assignExpr
3227/// | '{' initializerItems '}'
3228fn initializer(p: *Parser, init_ty: Type) Error!Result {
3229 // fast path for non-braced initializers
3230 if (p.tok_ids[p.tok_i] != .l_brace) {
3231 const tok = p.tok_i;
3232 var res = try p.assignExpr();
3233 try res.expect(p);
3234 if (try p.coerceArrayInit(&res, tok, init_ty)) return res;
3235 try p.coerceInit(&res, tok, init_ty);
3236 return res;
3237 }
3238 if (init_ty.is(.auto_type)) {
3239 try p.err(.auto_type_with_init_list);
3240 return error.ParsingFailed;
3241 }
3242
3243 var il: InitList = .{};
3244 defer il.deinit(p.gpa);
3245
3246 _ = try p.initializerItem(&il, init_ty);
3247
3248 const res = try p.convertInitList(il, init_ty);
3249 var res_ty = p.nodes.items(.ty)[@intFromEnum(res)];
3250 res_ty.qual = init_ty.qual;
3251 return Result{ .ty = res_ty, .node = res };
3252}
3253
3254/// initializerItems : designation? initializer (',' designation? initializer)* ','?
3255/// designation : designator+ '='
3256/// designator
3257/// : '[' integerConstExpr ']'
3258/// | '.' identifier
3259fn initializerItem(p: *Parser, il: *InitList, init_ty: Type) Error!bool {
3260 const l_brace = p.eatToken(.l_brace) orelse {
3261 const tok = p.tok_i;
3262 var res = try p.assignExpr();
3263 if (res.empty(p)) return false;
3264
3265 const arr = try p.coerceArrayInit(&res, tok, init_ty);
3266 if (!arr) try p.coerceInit(&res, tok, init_ty);
3267 if (il.tok != 0) {
3268 try p.errTok(.initializer_overrides, tok);
3269 try p.errTok(.previous_initializer, il.tok);
3270 }
3271 il.node = res.node;
3272 il.tok = tok;
3273 return true;
3274 };
3275
3276 const is_scalar = init_ty.isScalar();
3277 const is_complex = init_ty.isComplex();
3278 const scalar_inits_needed: usize = if (is_complex) 2 else 1;
3279 if (p.eatToken(.r_brace)) |_| {
3280 if (is_scalar) try p.errTok(.empty_scalar_init, l_brace);
3281 if (il.tok != 0) {
3282 try p.errTok(.initializer_overrides, l_brace);
3283 try p.errTok(.previous_initializer, il.tok);
3284 }
3285 il.node = .none;
3286 il.tok = l_brace;
3287 return true;
3288 }
3289
3290 var count: u64 = 0;
3291 var warned_excess = false;
3292 var is_str_init = false;
3293 var index_hint: ?u64 = null;
3294 while (true) : (count += 1) {
3295 errdefer p.skipTo(.r_brace);
3296
3297 var first_tok = p.tok_i;
3298 var cur_ty = init_ty;
3299 var cur_il = il;
3300 var designation = false;
3301 var cur_index_hint: ?u64 = null;
3302 while (true) {
3303 if (p.eatToken(.l_bracket)) |l_bracket| {
3304 if (!cur_ty.isArray()) {
3305 try p.errStr(.invalid_array_designator, l_bracket, try p.typeStr(cur_ty));
3306 return error.ParsingFailed;
3307 }
3308 const expr_tok = p.tok_i;
3309 const index_res = try p.integerConstExpr(.gnu_folding_extension);
3310 try p.expectClosing(l_bracket, .r_bracket);
3311
3312 if (index_res.val.opt_ref == .none) {
3313 try p.errTok(.expected_integer_constant_expr, expr_tok);
3314 return error.ParsingFailed;
3315 } else if (index_res.val.compare(.lt, Value.zero, p.comp)) {
3316 try p.errStr(.negative_array_designator, l_bracket + 1, try index_res.str(p));
3317 return error.ParsingFailed;
3318 }
3319
3320 const max_len = cur_ty.arrayLen() orelse std.math.maxInt(usize);
3321 const index_int = index_res.val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
3322 if (index_int >= max_len) {
3323 try p.errStr(.oob_array_designator, l_bracket + 1, try index_res.str(p));
3324 return error.ParsingFailed;
3325 }
3326 cur_index_hint = cur_index_hint orelse index_int;
3327
3328 cur_il = try cur_il.find(p.gpa, index_int);
3329 cur_ty = cur_ty.elemType();
3330 designation = true;
3331 } else if (p.eatToken(.period)) |period| {
3332 const field_tok = try p.expectIdentifier();
3333 const field_str = p.tokSlice(field_tok);
3334 const field_name = try StrInt.intern(p.comp, field_str);
3335 cur_ty = cur_ty.canonicalize(.standard);
3336 if (!cur_ty.isRecord()) {
3337 try p.errStr(.invalid_field_designator, period, try p.typeStr(cur_ty));
3338 return error.ParsingFailed;
3339 } else if (!cur_ty.hasField(field_name)) {
3340 try p.errStr(.no_such_field_designator, period, field_str);
3341 return error.ParsingFailed;
3342 }
3343
3344 // TODO check if union already has field set
3345 outer: while (true) {
3346 for (cur_ty.data.record.fields, 0..) |f, i| {
3347 if (f.isAnonymousRecord()) {
3348 // Recurse into anonymous field if it has a field by the name.
3349 if (!f.ty.hasField(field_name)) continue;
3350 cur_ty = f.ty.canonicalize(.standard);
3351 cur_il = try il.find(p.gpa, i);
3352 cur_index_hint = cur_index_hint orelse i;
3353 continue :outer;
3354 }
3355 if (field_name == f.name) {
3356 cur_il = try cur_il.find(p.gpa, i);
3357 cur_ty = f.ty;
3358 cur_index_hint = cur_index_hint orelse i;
3359 break :outer;
3360 }
3361 }
3362 unreachable; // we already checked that the starting type has this field
3363 }
3364 designation = true;
3365 } else break;
3366 }
3367 if (designation) index_hint = null;
3368 defer index_hint = cur_index_hint orelse null;
3369
3370 if (designation) _ = try p.expectToken(.equal);
3371
3372 if (!designation and cur_ty.hasAttribute(.designated_init)) {
3373 try p.err(.designated_init_needed);
3374 }
3375
3376 var saw = false;
3377 if (is_str_init and p.isStringInit(init_ty)) {
3378 // discard further strings
3379 var tmp_il = InitList{};
3380 defer tmp_il.deinit(p.gpa);
3381 saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
3382 } else if (count == 0 and p.isStringInit(init_ty)) {
3383 is_str_init = true;
3384 saw = try p.initializerItem(il, init_ty);
3385 } else if (is_scalar and count >= scalar_inits_needed) {
3386 // discard further scalars
3387 var tmp_il = InitList{};
3388 defer tmp_il.deinit(p.gpa);
3389 saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
3390 } else if (p.tok_ids[p.tok_i] == .l_brace) {
3391 if (designation) {
3392 // designation overrides previous value, let existing mechanism handle it
3393 saw = try p.initializerItem(cur_il, cur_ty);
3394 } else if (try p.findAggregateInitializer(&cur_il, &cur_ty, &index_hint)) {
3395 saw = try p.initializerItem(cur_il, cur_ty);
3396 } else {
3397 // discard further values
3398 var tmp_il = InitList{};
3399 defer tmp_il.deinit(p.gpa);
3400 saw = try p.initializerItem(&tmp_il, .{ .specifier = .void });
3401 if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
3402 warned_excess = true;
3403 }
3404 } else single_item: {
3405 first_tok = p.tok_i;
3406 var res = try p.assignExpr();
3407 saw = !res.empty(p);
3408 if (!saw) break :single_item;
3409
3410 excess: {
3411 if (index_hint) |*hint| {
3412 if (try p.findScalarInitializerAt(&cur_il, &cur_ty, &res, first_tok, hint)) break :excess;
3413 } else if (try p.findScalarInitializer(&cur_il, &cur_ty, &res, first_tok)) break :excess;
3414
3415 if (designation) break :excess;
3416 if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok);
3417 warned_excess = true;
3418
3419 break :single_item;
3420 }
3421
3422 const arr = try p.coerceArrayInit(&res, first_tok, cur_ty);
3423 if (!arr) try p.coerceInit(&res, first_tok, cur_ty);
3424 if (cur_il.tok != 0) {
3425 try p.errTok(.initializer_overrides, first_tok);
3426 try p.errTok(.previous_initializer, cur_il.tok);
3427 }
3428 cur_il.node = res.node;
3429 cur_il.tok = first_tok;
3430 }
3431
3432 if (!saw) {
3433 if (designation) {
3434 try p.err(.expected_expr);
3435 return error.ParsingFailed;
3436 }
3437 break;
3438 } else if (count == 1) {
3439 if (is_str_init) try p.errTok(.excess_str_init, first_tok);
3440 if (is_scalar and !is_complex) try p.errTok(.excess_scalar_init, first_tok);
3441 } else if (count == 2) {
3442 if (is_scalar and is_complex) try p.errTok(.excess_scalar_init, first_tok);
3443 }
3444
3445 if (p.eatToken(.comma) == null) break;
3446 }
3447 try p.expectClosing(l_brace, .r_brace);
3448
3449 if (is_complex and count == 1) { // count of 1 means we saw exactly 2 items in the initializer list
3450 try p.errTok(.complex_component_init, l_brace);
3451 }
3452 if (is_scalar or is_str_init) return true;
3453 if (il.tok != 0) {
3454 try p.errTok(.initializer_overrides, l_brace);
3455 try p.errTok(.previous_initializer, il.tok);
3456 }
3457 il.node = .none;
3458 il.tok = l_brace;
3459 return true;
3460}
3461
3462/// Returns true if the value is unused.
3463fn findScalarInitializerAt(p: *Parser, il: **InitList, ty: *Type, res: *Result, first_tok: TokenIndex, start_index: *u64) Error!bool {
3464 if (ty.isArray()) {
3465 if (il.*.node != .none) return false;
3466 start_index.* += 1;
3467
3468 const arr_ty = ty.*;
3469 const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
3470 if (elem_count == 0) {
3471 try p.errTok(.empty_aggregate_init_braces, first_tok);
3472 return error.ParsingFailed;
3473 }
3474 const elem_ty = arr_ty.elemType();
3475 const arr_il = il.*;
3476 if (start_index.* < elem_count) {
3477 ty.* = elem_ty;
3478 il.* = try arr_il.find(p.gpa, start_index.*);
3479 _ = try p.findScalarInitializer(il, ty, res, first_tok);
3480 return true;
3481 }
3482 return false;
3483 } else if (ty.get(.@"struct")) |struct_ty| {
3484 if (il.*.node != .none) return false;
3485 start_index.* += 1;
3486
3487 const fields = struct_ty.data.record.fields;
3488 if (fields.len == 0) {
3489 try p.errTok(.empty_aggregate_init_braces, first_tok);
3490 return error.ParsingFailed;
3491 }
3492 const struct_il = il.*;
3493 if (start_index.* < fields.len) {
3494 const field = fields[@intCast(start_index.*)];
3495 ty.* = field.ty;
3496 il.* = try struct_il.find(p.gpa, start_index.*);
3497 _ = try p.findScalarInitializer(il, ty, res, first_tok);
3498 return true;
3499 }
3500 return false;
3501 } else if (ty.get(.@"union")) |_| {
3502 return false;
3503 }
3504 return il.*.node == .none;
3505}
3506
3507/// Returns true if the value is unused.
3508fn findScalarInitializer(p: *Parser, il: **InitList, ty: *Type, res: *Result, first_tok: TokenIndex) Error!bool {
3509 const actual_ty = res.ty;
3510 if (ty.isArray() or ty.isComplex()) {
3511 if (il.*.node != .none) return false;
3512 if (try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true;
3513 const start_index = il.*.list.items.len;
3514 var index = if (start_index != 0) il.*.list.items[start_index - 1].index else start_index;
3515
3516 const arr_ty = ty.*;
3517 const elem_count: u64 = arr_ty.expectedInitListSize() orelse std.math.maxInt(u64);
3518 if (elem_count == 0) {
3519 try p.errTok(.empty_aggregate_init_braces, first_tok);
3520 return error.ParsingFailed;
3521 }
3522 const elem_ty = arr_ty.elemType();
3523 const arr_il = il.*;
3524 while (index < elem_count) : (index += 1) {
3525 ty.* = elem_ty;
3526 il.* = try arr_il.find(p.gpa, index);
3527 if (il.*.node == .none and actual_ty.eql(elem_ty, p.comp, false)) return true;
3528 if (try p.findScalarInitializer(il, ty, res, first_tok)) return true;
3529 }
3530 return false;
3531 } else if (ty.get(.@"struct")) |struct_ty| {
3532 if (il.*.node != .none) return false;
3533 if (actual_ty.eql(ty.*, p.comp, false)) return true;
3534 const start_index = il.*.list.items.len;
3535 var index = if (start_index != 0) il.*.list.items[start_index - 1].index + 1 else start_index;
3536
3537 const fields = struct_ty.data.record.fields;
3538 if (fields.len == 0) {
3539 try p.errTok(.empty_aggregate_init_braces, first_tok);
3540 return error.ParsingFailed;
3541 }
3542 const struct_il = il.*;
3543 while (index < fields.len) : (index += 1) {
3544 const field = fields[@intCast(index)];
3545 ty.* = field.ty;
3546 il.* = try struct_il.find(p.gpa, index);
3547 if (il.*.node == .none and actual_ty.eql(field.ty, p.comp, false)) return true;
3548 if (il.*.node == .none and try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true;
3549 if (try p.findScalarInitializer(il, ty, res, first_tok)) return true;
3550 }
3551 return false;
3552 } else if (ty.get(.@"union")) |union_ty| {
3553 if (il.*.node != .none) return false;
3554 if (actual_ty.eql(ty.*, p.comp, false)) return true;
3555 if (union_ty.data.record.fields.len == 0) {
3556 try p.errTok(.empty_aggregate_init_braces, first_tok);
3557 return error.ParsingFailed;
3558 }
3559 ty.* = union_ty.data.record.fields[0].ty;
3560 il.* = try il.*.find(p.gpa, 0);
3561 // if (il.*.node == .none and actual_ty.eql(ty, p.comp, false)) return true;
3562 if (try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true;
3563 if (try p.findScalarInitializer(il, ty, res, first_tok)) return true;
3564 return false;
3565 }
3566 return il.*.node == .none;
3567}
3568
3569fn findAggregateInitializer(p: *Parser, il: **InitList, ty: *Type, start_index: *?u64) Error!bool {
3570 if (ty.isArray()) {
3571 if (il.*.node != .none) return false;
3572 const list_index = il.*.list.items.len;
3573 const index = if (start_index.*) |*some| blk: {
3574 some.* += 1;
3575 break :blk some.*;
3576 } else if (list_index != 0)
3577 il.*.list.items[list_index - 1].index + 1
3578 else
3579 list_index;
3580
3581 const arr_ty = ty.*;
3582 const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64);
3583 const elem_ty = arr_ty.elemType();
3584 if (index < elem_count) {
3585 ty.* = elem_ty;
3586 il.* = try il.*.find(p.gpa, index);
3587 return true;
3588 }
3589 return false;
3590 } else if (ty.get(.@"struct")) |struct_ty| {
3591 if (il.*.node != .none) return false;
3592 const list_index = il.*.list.items.len;
3593 const index = if (start_index.*) |*some| blk: {
3594 some.* += 1;
3595 break :blk some.*;
3596 } else if (list_index != 0)
3597 il.*.list.items[list_index - 1].index + 1
3598 else
3599 list_index;
3600
3601 const field_count = struct_ty.data.record.fields.len;
3602 if (index < field_count) {
3603 ty.* = struct_ty.data.record.fields[@intCast(index)].ty;
3604 il.* = try il.*.find(p.gpa, index);
3605 return true;
3606 }
3607 return false;
3608 } else if (ty.get(.@"union")) |union_ty| {
3609 if (il.*.node != .none) return false;
3610 if (start_index.*) |_| return false; // overrides
3611 if (union_ty.data.record.fields.len == 0) return false;
3612
3613 ty.* = union_ty.data.record.fields[0].ty;
3614 il.* = try il.*.find(p.gpa, 0);
3615 return true;
3616 } else {
3617 try p.err(.too_many_scalar_init_braces);
3618 return il.*.node == .none;
3619 }
3620}
3621
3622fn coerceArrayInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !bool {
3623 return p.coerceArrayInitExtra(item, tok, target, true);
3624}
3625
3626fn coerceArrayInitExtra(p: *Parser, item: *Result, tok: TokenIndex, target: Type, report_err: bool) !bool {
3627 if (!target.isArray()) return false;
3628
3629 const is_str_lit = p.nodeIs(item.node, .string_literal_expr);
3630 if (!is_str_lit and !p.nodeIsCompoundLiteral(item.node) or !item.ty.isArray()) {
3631 if (!report_err) return false;
3632 try p.errTok(.array_init_str, tok);
3633 return true; // do not do further coercion
3634 }
3635
3636 const target_spec = target.elemType().canonicalize(.standard).specifier;
3637 const item_spec = item.ty.elemType().canonicalize(.standard).specifier;
3638
3639 const compatible = target.elemType().eql(item.ty.elemType(), p.comp, false) or
3640 (is_str_lit and item_spec == .char and (target_spec == .uchar or target_spec == .schar)) or
3641 (is_str_lit and item_spec == .uchar and (target_spec == .uchar or target_spec == .schar or target_spec == .char));
3642 if (!compatible) {
3643 if (!report_err) return false;
3644 const e_msg = " with array of type ";
3645 try p.errStr(.incompatible_array_init, tok, try p.typePairStrExtra(target, e_msg, item.ty));
3646 return true; // do not do further coercion
3647 }
3648
3649 if (target.get(.array)) |arr_ty| {
3650 assert(item.ty.specifier == .array);
3651 const len = item.ty.arrayLen().?;
3652 const array_len = arr_ty.arrayLen().?;
3653 if (is_str_lit) {
3654 // the null byte of a string can be dropped
3655 if (len - 1 > array_len and report_err) {
3656 try p.errTok(.str_init_too_long, tok);
3657 }
3658 } else if (len > array_len and report_err) {
3659 try p.errStr(
3660 .arr_init_too_long,
3661 tok,
3662 try p.typePairStrExtra(target, " with array of type ", item.ty),
3663 );
3664 }
3665 }
3666 return true;
3667}
3668
3669fn coerceInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !void {
3670 if (target.is(.void)) return; // Do not do type coercion on excess items
3671
3672 const node = item.node;
3673 try item.lvalConversion(p);
3674 if (target.is(.auto_type)) {
3675 if (p.getNode(node, .member_access_expr) orelse p.getNode(node, .member_access_ptr_expr)) |member_node| {
3676 if (p.tmpTree().isBitfield(member_node)) try p.errTok(.auto_type_from_bitfield, tok);
3677 }
3678 return;
3679 } else if (target.is(.c23_auto)) {
3680 return;
3681 }
3682
3683 try item.coerce(p, target, tok, .init);
3684}
3685
3686fn isStringInit(p: *Parser, ty: Type) bool {
3687 if (!ty.isArray() or !ty.elemType().isInt()) return false;
3688 var i = p.tok_i;
3689 while (true) : (i += 1) {
3690 switch (p.tok_ids[i]) {
3691 .l_paren => {},
3692 .string_literal,
3693 .string_literal_utf_16,
3694 .string_literal_utf_8,
3695 .string_literal_utf_32,
3696 .string_literal_wide,
3697 => return true,
3698 else => return false,
3699 }
3700 }
3701}
3702
3703/// Convert InitList into an AST
3704fn convertInitList(p: *Parser, il: InitList, init_ty: Type) Error!NodeIndex {
3705 const is_complex = init_ty.isComplex();
3706 if (init_ty.isScalar() and !is_complex) {
3707 if (il.node == .none) {
3708 return p.addNode(.{ .tag = .default_init_expr, .ty = init_ty, .data = undefined });
3709 }
3710 return il.node;
3711 } else if (init_ty.is(.variable_len_array)) {
3712 return error.ParsingFailed; // vla invalid, reported earlier
3713 } else if (init_ty.isArray() or is_complex) {
3714 if (il.node != .none) {
3715 return il.node;
3716 }
3717 const list_buf_top = p.list_buf.items.len;
3718 defer p.list_buf.items.len = list_buf_top;
3719
3720 const elem_ty = init_ty.elemType();
3721
3722 const max_items: u64 = init_ty.expectedInitListSize() orelse std.math.maxInt(usize);
3723 var start: u64 = 0;
3724 for (il.list.items) |*init| {
3725 if (init.index > start) {
3726 const elem = try p.addNode(.{
3727 .tag = .array_filler_expr,
3728 .ty = elem_ty,
3729 .data = .{ .int = init.index - start },
3730 });
3731 try p.list_buf.append(elem);
3732 }
3733 start = init.index + 1;
3734
3735 const elem = try p.convertInitList(init.list, elem_ty);
3736 try p.list_buf.append(elem);
3737 }
3738
3739 var arr_init_node: Tree.Node = .{
3740 .tag = .array_init_expr_two,
3741 .ty = init_ty,
3742 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
3743 };
3744
3745 if (init_ty.specifier == .incomplete_array) {
3746 arr_init_node.ty.specifier = .array;
3747 arr_init_node.ty.data.array.len = start;
3748 } else if (init_ty.is(.incomplete_array)) {
3749 const arr_ty = try p.arena.create(Type.Array);
3750 arr_ty.* = .{ .elem = init_ty.elemType(), .len = start };
3751 arr_init_node.ty = .{
3752 .specifier = .array,
3753 .data = .{ .array = arr_ty },
3754 };
3755 const attrs = init_ty.getAttributes();
3756 arr_init_node.ty = try arr_init_node.ty.withAttributes(p.arena, attrs);
3757 } else if (start < max_items) {
3758 const elem = try p.addNode(.{
3759 .tag = .array_filler_expr,
3760 .ty = elem_ty,
3761 .data = .{ .int = max_items - start },
3762 });
3763 try p.list_buf.append(elem);
3764 }
3765
3766 const items = p.list_buf.items[list_buf_top..];
3767 switch (items.len) {
3768 0 => {},
3769 1 => arr_init_node.data.bin.lhs = items[0],
3770 2 => arr_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
3771 else => {
3772 arr_init_node.tag = .array_init_expr;
3773 arr_init_node.data = .{ .range = try p.addList(items) };
3774 },
3775 }
3776 return try p.addNode(arr_init_node);
3777 } else if (init_ty.get(.@"struct")) |struct_ty| {
3778 assert(!struct_ty.hasIncompleteSize());
3779 if (il.node != .none) {
3780 return il.node;
3781 }
3782
3783 const list_buf_top = p.list_buf.items.len;
3784 defer p.list_buf.items.len = list_buf_top;
3785
3786 var init_index: usize = 0;
3787 for (struct_ty.data.record.fields, 0..) |f, i| {
3788 if (init_index < il.list.items.len and il.list.items[init_index].index == i) {
3789 const item = try p.convertInitList(il.list.items[init_index].list, f.ty);
3790 try p.list_buf.append(item);
3791 init_index += 1;
3792 } else {
3793 const item = try p.addNode(.{ .tag = .default_init_expr, .ty = f.ty, .data = undefined });
3794 try p.list_buf.append(item);
3795 }
3796 }
3797
3798 var struct_init_node: Tree.Node = .{
3799 .tag = .struct_init_expr_two,
3800 .ty = init_ty,
3801 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
3802 };
3803 const items = p.list_buf.items[list_buf_top..];
3804 switch (items.len) {
3805 0 => {},
3806 1 => struct_init_node.data.bin.lhs = items[0],
3807 2 => struct_init_node.data.bin = .{ .lhs = items[0], .rhs = items[1] },
3808 else => {
3809 struct_init_node.tag = .struct_init_expr;
3810 struct_init_node.data = .{ .range = try p.addList(items) };
3811 },
3812 }
3813 return try p.addNode(struct_init_node);
3814 } else if (init_ty.get(.@"union")) |union_ty| {
3815 if (il.node != .none) {
3816 return il.node;
3817 }
3818
3819 var union_init_node: Tree.Node = .{
3820 .tag = .union_init_expr,
3821 .ty = init_ty,
3822 .data = .{ .union_init = .{ .field_index = 0, .node = .none } },
3823 };
3824 if (union_ty.data.record.fields.len == 0) {
3825 // do nothing for empty unions
3826 } else if (il.list.items.len == 0) {
3827 union_init_node.data.union_init.node = try p.addNode(.{
3828 .tag = .default_init_expr,
3829 .ty = init_ty,
3830 .data = undefined,
3831 });
3832 } else {
3833 const init = il.list.items[0];
3834 const index: u32 = @truncate(init.index);
3835 const field_ty = union_ty.data.record.fields[index].ty;
3836 union_init_node.data.union_init = .{
3837 .field_index = index,
3838 .node = try p.convertInitList(init.list, field_ty),
3839 };
3840 }
3841 return try p.addNode(union_init_node);
3842 } else {
3843 return error.ParsingFailed; // initializer target is invalid, reported earlier
3844 }
3845}
3846
3847fn msvcAsmStmt(p: *Parser) Error!?NodeIndex {
3848 return p.todo("MSVC assembly statements");
3849}
3850
3851/// asmOperand : ('[' IDENTIFIER ']')? asmStr '(' expr ')'
3852fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *NodeList, exprs: *NodeList) Error!void {
3853 if (p.eatToken(.l_bracket)) |l_bracket| {
3854 const ident = (try p.eatIdentifier()) orelse {
3855 try p.err(.expected_identifier);
3856 return error.ParsingFailed;
3857 };
3858 try names.append(ident);
3859 try p.expectClosing(l_bracket, .r_bracket);
3860 } else {
3861 try names.append(null);
3862 }
3863 const constraint = try p.asmStr();
3864 try constraints.append(constraint.node);
3865
3866 const l_paren = p.eatToken(.l_paren) orelse {
3867 try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .l_paren } });
3868 return error.ParsingFailed;
3869 };
3870 const res = try p.expr();
3871 try p.expectClosing(l_paren, .r_paren);
3872 try res.expect(p);
3873 try exprs.append(res.node);
3874}
3875
3876/// gnuAsmStmt
3877/// : asmStr
3878/// | asmStr ':' asmOperand*
3879/// | asmStr ':' asmOperand* ':' asmOperand*
3880/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)*
3881/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)* : IDENTIFIER (',' IDENTIFIER)*
3882fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, l_paren: TokenIndex) Error!NodeIndex {
3883 const asm_str = try p.asmStr();
3884 try p.checkAsmStr(asm_str.val, l_paren);
3885
3886 if (p.tok_ids[p.tok_i] == .r_paren) {
3887 return p.addNode(.{
3888 .tag = .gnu_asm_simple,
3889 .ty = .{ .specifier = .void },
3890 .data = .{ .un = asm_str.node },
3891 });
3892 }
3893
3894 const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names
3895 const bytes_needed = expected_items * @sizeOf(?TokenIndex) + expected_items * 3 * @sizeOf(NodeIndex);
3896
3897 var stack_fallback = std.heap.stackFallback(bytes_needed, p.gpa);
3898 const allocator = stack_fallback.get();
3899
3900 // TODO: Consider using a TokenIndex of 0 instead of null if we need to store the names in the tree
3901 var names = std.ArrayList(?TokenIndex).initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
3902 defer names.deinit();
3903 var constraints = NodeList.initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded
3904 defer constraints.deinit();
3905 var exprs = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
3906 defer exprs.deinit();
3907 var clobbers = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded
3908 defer clobbers.deinit();
3909
3910 // Outputs
3911 var ate_extra_colon = false;
3912 if (p.eatToken(.colon) orelse p.eatToken(.colon_colon)) |tok_i| {
3913 ate_extra_colon = p.tok_ids[tok_i] == .colon_colon;
3914 if (!ate_extra_colon) {
3915 if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
3916 while (true) {
3917 try p.asmOperand(&names, &constraints, &exprs);
3918 if (p.eatToken(.comma) == null) break;
3919 }
3920 }
3921 }
3922 }
3923
3924 const num_outputs = names.items.len;
3925
3926 // Inputs
3927 if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
3928 if (ate_extra_colon) {
3929 ate_extra_colon = false;
3930 } else {
3931 ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
3932 p.tok_i += 1;
3933 }
3934 if (!ate_extra_colon) {
3935 if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) {
3936 while (true) {
3937 try p.asmOperand(&names, &constraints, &exprs);
3938 if (p.eatToken(.comma) == null) break;
3939 }
3940 }
3941 }
3942 }
3943 std.debug.assert(names.items.len == constraints.items.len and constraints.items.len == exprs.items.len);
3944 const num_inputs = names.items.len - num_outputs;
3945 _ = num_inputs;
3946
3947 // Clobbers
3948 if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) {
3949 if (ate_extra_colon) {
3950 ate_extra_colon = false;
3951 } else {
3952 ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon;
3953 p.tok_i += 1;
3954 }
3955 if (!ate_extra_colon and p.tok_ids[p.tok_i].isStringLiteral()) {
3956 while (true) {
3957 const clobber = try p.asmStr();
3958 try clobbers.append(clobber.node);
3959 if (p.eatToken(.comma) == null) break;
3960 }
3961 }
3962 }
3963
3964 if (!quals.goto and (p.tok_ids[p.tok_i] != .r_paren or ate_extra_colon)) {
3965 try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .r_paren } });
3966 return error.ParsingFailed;
3967 }
3968
3969 // Goto labels
3970 var num_labels: u32 = 0;
3971 if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon) {
3972 if (!ate_extra_colon) {
3973 p.tok_i += 1;
3974 }
3975 while (true) {
3976 const ident = (try p.eatIdentifier()) orelse {
3977 try p.err(.expected_identifier);
3978 return error.ParsingFailed;
3979 };
3980 const ident_str = p.tokSlice(ident);
3981 const label = p.findLabel(ident_str) orelse blk: {
3982 try p.labels.append(.{ .unresolved_goto = ident });
3983 break :blk ident;
3984 };
3985 try names.append(ident);
3986
3987 const elem_ty = try p.arena.create(Type);
3988 elem_ty.* = .{ .specifier = .void };
3989 const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
3990
3991 const label_addr_node = try p.addNode(.{
3992 .tag = .addr_of_label,
3993 .data = .{ .decl_ref = label },
3994 .ty = result_ty,
3995 });
3996 try exprs.append(label_addr_node);
3997
3998 num_labels += 1;
3999 if (p.eatToken(.comma) == null) break;
4000 }
4001 } else if (quals.goto) {
4002 try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .colon } });
4003 return error.ParsingFailed;
4004 }
4005
4006 // TODO: validate and insert into AST
4007 return .none;
4008}
4009
4010fn checkAsmStr(p: *Parser, asm_str: Value, tok: TokenIndex) !void {
4011 if (!p.comp.langopts.gnu_asm) {
4012 const str = p.comp.interner.get(asm_str.ref()).bytes;
4013 if (str.len > 1) {
4014 // Empty string (just a NUL byte) is ok because it does not emit any assembly
4015 try p.errTok(.gnu_asm_disabled, tok);
4016 }
4017 }
4018}
4019
4020/// assembly
4021/// : keyword_asm asmQual* '(' asmStr ')'
4022/// | keyword_asm asmQual* '(' gnuAsmStmt ')'
4023/// | keyword_asm msvcAsmStmt
4024fn assembly(p: *Parser, kind: enum { global, decl_label, stmt }) Error!?NodeIndex {
4025 const asm_tok = p.tok_i;
4026 switch (p.tok_ids[p.tok_i]) {
4027 .keyword_asm => {
4028 try p.err(.extension_token_used);
4029 p.tok_i += 1;
4030 },
4031 .keyword_asm1, .keyword_asm2 => p.tok_i += 1,
4032 else => return null,
4033 }
4034
4035 if (!p.tok_ids[p.tok_i].canOpenGCCAsmStmt()) {
4036 return p.msvcAsmStmt();
4037 }
4038
4039 var quals: Tree.GNUAssemblyQualifiers = .{};
4040 while (true) : (p.tok_i += 1) switch (p.tok_ids[p.tok_i]) {
4041 .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => {
4042 if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "volatile");
4043 if (quals.@"volatile") try p.errStr(.duplicate_asm_qual, p.tok_i, "volatile");
4044 quals.@"volatile" = true;
4045 },
4046 .keyword_inline, .keyword_inline1, .keyword_inline2 => {
4047 if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "inline");
4048 if (quals.@"inline") try p.errStr(.duplicate_asm_qual, p.tok_i, "inline");
4049 quals.@"inline" = true;
4050 },
4051 .keyword_goto => {
4052 if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "goto");
4053 if (quals.goto) try p.errStr(.duplicate_asm_qual, p.tok_i, "goto");
4054 quals.goto = true;
4055 },
4056 else => break,
4057 };
4058
4059 const l_paren = try p.expectToken(.l_paren);
4060 var result_node: NodeIndex = .none;
4061 switch (kind) {
4062 .decl_label => {
4063 const asm_str = try p.asmStr();
4064 const str = try p.removeNull(asm_str.val);
4065
4066 const attr = Attribute{ .tag = .asm_label, .args = .{ .asm_label = .{ .name = str } }, .syntax = .keyword };
4067 try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = asm_tok });
4068 },
4069 .global => {
4070 const asm_str = try p.asmStr();
4071 try p.checkAsmStr(asm_str.val, l_paren);
4072 result_node = try p.addNode(.{
4073 .tag = .file_scope_asm,
4074 .ty = .{ .specifier = .void },
4075 .data = .{ .decl = .{ .name = asm_tok, .node = asm_str.node } },
4076 });
4077 },
4078 .stmt => result_node = try p.gnuAsmStmt(quals, l_paren),
4079 }
4080 try p.expectClosing(l_paren, .r_paren);
4081
4082 if (kind != .decl_label) _ = try p.expectToken(.semicolon);
4083 return result_node;
4084}
4085
4086/// Same as stringLiteral but errors on unicode and wide string literals
4087fn asmStr(p: *Parser) Error!Result {
4088 var i = p.tok_i;
4089 while (true) : (i += 1) switch (p.tok_ids[i]) {
4090 .string_literal, .unterminated_string_literal => {},
4091 .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32 => {
4092 try p.errStr(.invalid_asm_str, p.tok_i, "unicode");
4093 return error.ParsingFailed;
4094 },
4095 .string_literal_wide => {
4096 try p.errStr(.invalid_asm_str, p.tok_i, "wide");
4097 return error.ParsingFailed;
4098 },
4099 else => {
4100 if (i == p.tok_i) {
4101 try p.errStr(.expected_str_literal_in, p.tok_i, "asm");
4102 return error.ParsingFailed;
4103 }
4104 break;
4105 },
4106 };
4107 return try p.stringLiteral();
4108}
4109
4110// ====== statements ======
4111
4112/// stmt
4113/// : labeledStmt
4114/// | compoundStmt
4115/// | keyword_if '(' expr ')' stmt (keyword_else stmt)?
4116/// | keyword_switch '(' expr ')' stmt
4117/// | keyword_while '(' expr ')' stmt
4118/// | keyword_do stmt while '(' expr ')' ';'
4119/// | keyword_for '(' (decl | expr? ';') expr? ';' expr? ')' stmt
4120/// | keyword_goto (IDENTIFIER | ('*' expr)) ';'
4121/// | keyword_continue ';'
4122/// | keyword_break ';'
4123/// | keyword_return expr? ';'
4124/// | assembly ';'
4125/// | expr? ';'
4126fn stmt(p: *Parser) Error!NodeIndex {
4127 if (try p.labeledStmt()) |some| return some;
4128 if (try p.compoundStmt(false, null)) |some| return some;
4129 if (p.eatToken(.keyword_if)) |_| {
4130 const l_paren = try p.expectToken(.l_paren);
4131 const cond_tok = p.tok_i;
4132 var cond = try p.expr();
4133 try cond.expect(p);
4134 try cond.lvalConversion(p);
4135 try cond.usualUnaryConversion(p, cond_tok);
4136 if (!cond.ty.isScalar())
4137 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4138 try cond.saveValue(p);
4139 try p.expectClosing(l_paren, .r_paren);
4140
4141 const then = try p.stmt();
4142 const @"else" = if (p.eatToken(.keyword_else)) |_| try p.stmt() else .none;
4143
4144 if (then != .none and @"else" != .none)
4145 return try p.addNode(.{
4146 .tag = .if_then_else_stmt,
4147 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then, @"else" })).start } },
4148 })
4149 else
4150 return try p.addNode(.{
4151 .tag = .if_then_stmt,
4152 .data = .{ .bin = .{ .lhs = cond.node, .rhs = then } },
4153 });
4154 }
4155 if (p.eatToken(.keyword_switch)) |_| {
4156 const l_paren = try p.expectToken(.l_paren);
4157 const cond_tok = p.tok_i;
4158 var cond = try p.expr();
4159 try cond.expect(p);
4160 try cond.lvalConversion(p);
4161 try cond.usualUnaryConversion(p, cond_tok);
4162
4163 if (!cond.ty.isInt())
4164 try p.errStr(.statement_int, l_paren + 1, try p.typeStr(cond.ty));
4165 try cond.saveValue(p);
4166 try p.expectClosing(l_paren, .r_paren);
4167
4168 const old_switch = p.@"switch";
4169 var @"switch" = Switch{
4170 .ranges = std.ArrayList(Switch.Range).init(p.gpa),
4171 .ty = cond.ty,
4172 .comp = p.comp,
4173 };
4174 p.@"switch" = &@"switch";
4175 defer {
4176 @"switch".ranges.deinit();
4177 p.@"switch" = old_switch;
4178 }
4179
4180 const body = try p.stmt();
4181
4182 return try p.addNode(.{
4183 .tag = .switch_stmt,
4184 .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
4185 });
4186 }
4187 if (p.eatToken(.keyword_while)) |_| {
4188 const l_paren = try p.expectToken(.l_paren);
4189 const cond_tok = p.tok_i;
4190 var cond = try p.expr();
4191 try cond.expect(p);
4192 try cond.lvalConversion(p);
4193 try cond.usualUnaryConversion(p, cond_tok);
4194 if (!cond.ty.isScalar())
4195 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4196 try cond.saveValue(p);
4197 try p.expectClosing(l_paren, .r_paren);
4198
4199 const body = body: {
4200 const old_loop = p.in_loop;
4201 p.in_loop = true;
4202 defer p.in_loop = old_loop;
4203 break :body try p.stmt();
4204 };
4205
4206 return try p.addNode(.{
4207 .tag = .while_stmt,
4208 .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
4209 });
4210 }
4211 if (p.eatToken(.keyword_do)) |_| {
4212 const body = body: {
4213 const old_loop = p.in_loop;
4214 p.in_loop = true;
4215 defer p.in_loop = old_loop;
4216 break :body try p.stmt();
4217 };
4218
4219 _ = try p.expectToken(.keyword_while);
4220 const l_paren = try p.expectToken(.l_paren);
4221 const cond_tok = p.tok_i;
4222 var cond = try p.expr();
4223 try cond.expect(p);
4224 try cond.lvalConversion(p);
4225 try cond.usualUnaryConversion(p, cond_tok);
4226
4227 if (!cond.ty.isScalar())
4228 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4229 try cond.saveValue(p);
4230 try p.expectClosing(l_paren, .r_paren);
4231
4232 _ = try p.expectToken(.semicolon);
4233 return try p.addNode(.{
4234 .tag = .do_while_stmt,
4235 .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } },
4236 });
4237 }
4238 if (p.eatToken(.keyword_for)) |_| {
4239 try p.syms.pushScope(p);
4240 defer p.syms.popScope();
4241 const decl_buf_top = p.decl_buf.items.len;
4242 defer p.decl_buf.items.len = decl_buf_top;
4243
4244 const l_paren = try p.expectToken(.l_paren);
4245 const got_decl = try p.decl();
4246
4247 // for (init
4248 const init_start = p.tok_i;
4249 var err_start = p.comp.diagnostics.list.items.len;
4250 var init = if (!got_decl) try p.expr() else Result{};
4251 try init.saveValue(p);
4252 try init.maybeWarnUnused(p, init_start, err_start);
4253 if (!got_decl) _ = try p.expectToken(.semicolon);
4254
4255 // for (init; cond
4256 const cond_tok = p.tok_i;
4257 var cond = try p.expr();
4258 if (cond.node != .none) {
4259 try cond.lvalConversion(p);
4260 try cond.usualUnaryConversion(p, cond_tok);
4261 if (!cond.ty.isScalar())
4262 try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty));
4263 }
4264 try cond.saveValue(p);
4265 _ = try p.expectToken(.semicolon);
4266
4267 // for (init; cond; incr
4268 const incr_start = p.tok_i;
4269 err_start = p.comp.diagnostics.list.items.len;
4270 var incr = try p.expr();
4271 try incr.maybeWarnUnused(p, incr_start, err_start);
4272 try incr.saveValue(p);
4273 try p.expectClosing(l_paren, .r_paren);
4274
4275 const body = body: {
4276 const old_loop = p.in_loop;
4277 p.in_loop = true;
4278 defer p.in_loop = old_loop;
4279 break :body try p.stmt();
4280 };
4281
4282 if (got_decl) {
4283 const start = (try p.addList(p.decl_buf.items[decl_buf_top..])).start;
4284 const end = (try p.addList(&.{ cond.node, incr.node, body })).end;
4285
4286 return try p.addNode(.{
4287 .tag = .for_decl_stmt,
4288 .data = .{ .range = .{ .start = start, .end = end } },
4289 });
4290 } else if (init.node == .none and cond.node == .none and incr.node == .none) {
4291 return try p.addNode(.{
4292 .tag = .forever_stmt,
4293 .data = .{ .un = body },
4294 });
4295 } else return try p.addNode(.{ .tag = .for_stmt, .data = .{ .if3 = .{
4296 .cond = body,
4297 .body = (try p.addList(&.{ init.node, cond.node, incr.node })).start,
4298 } } });
4299 }
4300 if (p.eatToken(.keyword_goto)) |goto_tok| {
4301 if (p.eatToken(.asterisk)) |_| {
4302 const expr_tok = p.tok_i;
4303 var e = try p.expr();
4304 try e.expect(p);
4305 try e.lvalConversion(p);
4306 p.computed_goto_tok = p.computed_goto_tok orelse goto_tok;
4307 if (!e.ty.isPtr()) {
4308 const elem_ty = try p.arena.create(Type);
4309 elem_ty.* = .{ .specifier = .void, .qual = .{ .@"const" = true } };
4310 const result_ty = Type{
4311 .specifier = .pointer,
4312 .data = .{ .sub_type = elem_ty },
4313 };
4314 if (!e.ty.isInt()) {
4315 try p.errStr(.incompatible_arg, expr_tok, try p.typePairStrExtra(e.ty, " to parameter of incompatible type ", result_ty));
4316 return error.ParsingFailed;
4317 }
4318 if (e.val.isZero(p.comp)) {
4319 try e.nullCast(p, result_ty);
4320 } else {
4321 try p.errStr(.implicit_int_to_ptr, expr_tok, try p.typePairStrExtra(e.ty, " to ", result_ty));
4322 try e.ptrCast(p, result_ty);
4323 }
4324 }
4325
4326 try e.un(p, .computed_goto_stmt);
4327 _ = try p.expectToken(.semicolon);
4328 return e.node;
4329 }
4330 const name_tok = try p.expectIdentifier();
4331 const str = p.tokSlice(name_tok);
4332 if (p.findLabel(str) == null) {
4333 try p.labels.append(.{ .unresolved_goto = name_tok });
4334 }
4335 _ = try p.expectToken(.semicolon);
4336 return try p.addNode(.{
4337 .tag = .goto_stmt,
4338 .data = .{ .decl_ref = name_tok },
4339 });
4340 }
4341 if (p.eatToken(.keyword_continue)) |cont| {
4342 if (!p.in_loop) try p.errTok(.continue_not_in_loop, cont);
4343 _ = try p.expectToken(.semicolon);
4344 return try p.addNode(.{ .tag = .continue_stmt, .data = undefined });
4345 }
4346 if (p.eatToken(.keyword_break)) |br| {
4347 if (!p.in_loop and p.@"switch" == null) try p.errTok(.break_not_in_loop_or_switch, br);
4348 _ = try p.expectToken(.semicolon);
4349 return try p.addNode(.{ .tag = .break_stmt, .data = undefined });
4350 }
4351 if (try p.returnStmt()) |some| return some;
4352 if (try p.assembly(.stmt)) |some| return some;
4353
4354 const expr_start = p.tok_i;
4355 const err_start = p.comp.diagnostics.list.items.len;
4356
4357 const e = try p.expr();
4358 if (e.node != .none) {
4359 _ = try p.expectToken(.semicolon);
4360 try e.maybeWarnUnused(p, expr_start, err_start);
4361 return e.node;
4362 }
4363
4364 const attr_buf_top = p.attr_buf.len;
4365 defer p.attr_buf.len = attr_buf_top;
4366 try p.attributeSpecifier();
4367
4368 if (p.eatToken(.semicolon)) |_| {
4369 var null_node: Tree.Node = .{ .tag = .null_stmt, .data = undefined };
4370 null_node.ty = try Attribute.applyStatementAttributes(p, null_node.ty, expr_start, attr_buf_top);
4371 return p.addNode(null_node);
4372 }
4373
4374 try p.err(.expected_stmt);
4375 return error.ParsingFailed;
4376}
4377
4378/// labeledStmt
4379/// : IDENTIFIER ':' stmt
4380/// | keyword_case integerConstExpr ':' stmt
4381/// | keyword_default ':' stmt
4382fn labeledStmt(p: *Parser) Error!?NodeIndex {
4383 if ((p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) and p.tok_ids[p.tok_i + 1] == .colon) {
4384 const name_tok = try p.expectIdentifier();
4385 const str = p.tokSlice(name_tok);
4386 if (p.findLabel(str)) |some| {
4387 try p.errStr(.duplicate_label, name_tok, str);
4388 try p.errStr(.previous_label, some, str);
4389 } else {
4390 p.label_count += 1;
4391 try p.labels.append(.{ .label = name_tok });
4392 var i: usize = 0;
4393 while (i < p.labels.items.len) {
4394 if (p.labels.items[i] == .unresolved_goto and
4395 mem.eql(u8, p.tokSlice(p.labels.items[i].unresolved_goto), str))
4396 {
4397 _ = p.labels.swapRemove(i);
4398 } else i += 1;
4399 }
4400 }
4401
4402 p.tok_i += 1;
4403 const attr_buf_top = p.attr_buf.len;
4404 defer p.attr_buf.len = attr_buf_top;
4405 try p.attributeSpecifier();
4406
4407 var labeled_stmt = Tree.Node{
4408 .tag = .labeled_stmt,
4409 .data = .{ .decl = .{ .name = name_tok, .node = try p.labelableStmt() } },
4410 };
4411 labeled_stmt.ty = try Attribute.applyLabelAttributes(p, labeled_stmt.ty, attr_buf_top);
4412 return try p.addNode(labeled_stmt);
4413 } else if (p.eatToken(.keyword_case)) |case| {
4414 const first_item = try p.integerConstExpr(.gnu_folding_extension);
4415 const ellipsis = p.tok_i;
4416 const second_item = if (p.eatToken(.ellipsis) != null) blk: {
4417 try p.errTok(.gnu_switch_range, ellipsis);
4418 break :blk try p.integerConstExpr(.gnu_folding_extension);
4419 } else null;
4420 _ = try p.expectToken(.colon);
4421
4422 if (p.@"switch") |some| check: {
4423 if (some.ty.hasIncompleteSize()) break :check; // error already reported for incomplete size
4424
4425 const first = first_item.val;
4426 const last = if (second_item) |second| second.val else first;
4427 if (first.opt_ref == .none) {
4428 try p.errTok(.case_val_unavailable, case + 1);
4429 break :check;
4430 } else if (last.opt_ref == .none) {
4431 try p.errTok(.case_val_unavailable, ellipsis + 1);
4432 break :check;
4433 } else if (last.compare(.lt, first, p.comp)) {
4434 try p.errTok(.empty_case_range, case + 1);
4435 break :check;
4436 }
4437
4438 // TODO cast to target type
4439 const prev = (try some.add(first, last, case + 1)) orelse break :check;
4440
4441 // TODO check which value was already handled
4442 try p.errStr(.duplicate_switch_case, case + 1, try first_item.str(p));
4443 try p.errTok(.previous_case, prev.tok);
4444 } else {
4445 try p.errStr(.case_not_in_switch, case, "case");
4446 }
4447
4448 const s = try p.labelableStmt();
4449 if (second_item) |some| return try p.addNode(.{
4450 .tag = .case_range_stmt,
4451 .data = .{ .if3 = .{ .cond = s, .body = (try p.addList(&.{ first_item.node, some.node })).start } },
4452 }) else return try p.addNode(.{
4453 .tag = .case_stmt,
4454 .data = .{ .bin = .{ .lhs = first_item.node, .rhs = s } },
4455 });
4456 } else if (p.eatToken(.keyword_default)) |default| {
4457 _ = try p.expectToken(.colon);
4458 const s = try p.labelableStmt();
4459 const node = try p.addNode(.{
4460 .tag = .default_stmt,
4461 .data = .{ .un = s },
4462 });
4463 const @"switch" = p.@"switch" orelse {
4464 try p.errStr(.case_not_in_switch, default, "default");
4465 return node;
4466 };
4467 if (@"switch".default) |previous| {
4468 try p.errTok(.multiple_default, default);
4469 try p.errTok(.previous_case, previous);
4470 } else {
4471 @"switch".default = default;
4472 }
4473 return node;
4474 } else return null;
4475}
4476
4477fn labelableStmt(p: *Parser) Error!NodeIndex {
4478 if (p.tok_ids[p.tok_i] == .r_brace) {
4479 try p.err(.label_compound_end);
4480 return p.addNode(.{ .tag = .null_stmt, .data = undefined });
4481 }
4482 return p.stmt();
4483}
4484
4485const StmtExprState = struct {
4486 last_expr_tok: TokenIndex = 0,
4487 last_expr_res: Result = .{ .ty = .{ .specifier = .void } },
4488};
4489
4490/// compoundStmt : '{' ( decl | keyword_extension decl | staticAssert | stmt)* '}'
4491fn compoundStmt(p: *Parser, is_fn_body: bool, stmt_expr_state: ?*StmtExprState) Error!?NodeIndex {
4492 const l_brace = p.eatToken(.l_brace) orelse return null;
4493
4494 const decl_buf_top = p.decl_buf.items.len;
4495 defer p.decl_buf.items.len = decl_buf_top;
4496
4497 // the parameters of a function are in the same scope as the body
4498 if (!is_fn_body) try p.syms.pushScope(p);
4499 defer if (!is_fn_body) p.syms.popScope();
4500
4501 var noreturn_index: ?TokenIndex = null;
4502 var noreturn_label_count: u32 = 0;
4503
4504 while (p.eatToken(.r_brace) == null) : (_ = try p.pragma()) {
4505 if (stmt_expr_state) |state| state.* = .{};
4506 if (try p.parseOrNextStmt(staticAssert, l_brace)) continue;
4507 if (try p.parseOrNextStmt(decl, l_brace)) continue;
4508 if (p.eatToken(.keyword_extension)) |ext| {
4509 const saved_extension = p.extension_suppressed;
4510 defer p.extension_suppressed = saved_extension;
4511 p.extension_suppressed = true;
4512
4513 if (try p.parseOrNextStmt(decl, l_brace)) continue;
4514 p.tok_i = ext;
4515 }
4516 const stmt_tok = p.tok_i;
4517 const s = p.stmt() catch |er| switch (er) {
4518 error.ParsingFailed => {
4519 try p.nextStmt(l_brace);
4520 continue;
4521 },
4522 else => |e| return e,
4523 };
4524 if (s == .none) continue;
4525 if (stmt_expr_state) |state| {
4526 state.* = .{
4527 .last_expr_tok = stmt_tok,
4528 .last_expr_res = .{
4529 .node = s,
4530 .ty = p.nodes.items(.ty)[@intFromEnum(s)],
4531 },
4532 };
4533 }
4534 try p.decl_buf.append(s);
4535
4536 if (noreturn_index == null and p.nodeIsNoreturn(s) == .yes) {
4537 noreturn_index = p.tok_i;
4538 noreturn_label_count = p.label_count;
4539 }
4540 switch (p.nodes.items(.tag)[@intFromEnum(s)]) {
4541 .case_stmt, .default_stmt, .labeled_stmt => noreturn_index = null,
4542 else => {},
4543 }
4544 }
4545
4546 if (noreturn_index) |some| {
4547 // if new labels were defined we cannot be certain that the code is unreachable
4548 if (some != p.tok_i - 1 and noreturn_label_count == p.label_count) try p.errTok(.unreachable_code, some);
4549 }
4550 if (is_fn_body) {
4551 const last_noreturn = if (p.decl_buf.items.len == decl_buf_top)
4552 .no
4553 else
4554 p.nodeIsNoreturn(p.decl_buf.items[p.decl_buf.items.len - 1]);
4555
4556 if (last_noreturn != .yes) {
4557 const ret_ty = p.func.ty.?.returnType();
4558 var return_zero = false;
4559 if (last_noreturn == .no and !ret_ty.is(.void) and !ret_ty.isFunc() and !ret_ty.isArray()) {
4560 const func_name = p.tokSlice(p.func.name);
4561 const interned_name = try StrInt.intern(p.comp, func_name);
4562 if (interned_name == p.string_ids.main_id and ret_ty.is(.int)) {
4563 return_zero = true;
4564 } else {
4565 try p.errStr(.func_does_not_return, p.tok_i - 1, func_name);
4566 }
4567 }
4568 try p.decl_buf.append(try p.addNode(.{ .tag = .implicit_return, .ty = p.func.ty.?.returnType(), .data = .{ .return_zero = return_zero } }));
4569 }
4570 if (p.func.ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
4571 if (p.func.pretty_ident) |some| try p.decl_buf.insert(decl_buf_top, some.node);
4572 }
4573
4574 var node: Tree.Node = .{
4575 .tag = .compound_stmt_two,
4576 .data = .{ .bin = .{ .lhs = .none, .rhs = .none } },
4577 };
4578 const statements = p.decl_buf.items[decl_buf_top..];
4579 switch (statements.len) {
4580 0 => {},
4581 1 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = .none } },
4582 2 => node.data = .{ .bin = .{ .lhs = statements[0], .rhs = statements[1] } },
4583 else => {
4584 node.tag = .compound_stmt;
4585 node.data = .{ .range = try p.addList(statements) };
4586 },
4587 }
4588 return try p.addNode(node);
4589}
4590
4591const NoreturnKind = enum { no, yes, complex };
4592
4593fn nodeIsNoreturn(p: *Parser, node: NodeIndex) NoreturnKind {
4594 switch (p.nodes.items(.tag)[@intFromEnum(node)]) {
4595 .break_stmt, .continue_stmt, .return_stmt => return .yes,
4596 .if_then_else_stmt => {
4597 const data = p.data.items[p.nodes.items(.data)[@intFromEnum(node)].if3.body..];
4598 const then_type = p.nodeIsNoreturn(data[0]);
4599 const else_type = p.nodeIsNoreturn(data[1]);
4600 if (then_type == .complex or else_type == .complex) return .complex;
4601 if (then_type == .yes and else_type == .yes) return .yes;
4602 return .no;
4603 },
4604 .compound_stmt_two => {
4605 const data = p.nodes.items(.data)[@intFromEnum(node)];
4606 if (data.bin.rhs != .none) return p.nodeIsNoreturn(data.bin.rhs);
4607 if (data.bin.lhs != .none) return p.nodeIsNoreturn(data.bin.lhs);
4608 return .no;
4609 },
4610 .compound_stmt => {
4611 const data = p.nodes.items(.data)[@intFromEnum(node)];
4612 return p.nodeIsNoreturn(p.data.items[data.range.end - 1]);
4613 },
4614 .labeled_stmt => {
4615 const data = p.nodes.items(.data)[@intFromEnum(node)];
4616 return p.nodeIsNoreturn(data.decl.node);
4617 },
4618 .switch_stmt => {
4619 const data = p.nodes.items(.data)[@intFromEnum(node)];
4620 if (data.bin.rhs == .none) return .complex;
4621 if (p.nodeIsNoreturn(data.bin.rhs) == .yes) return .yes;
4622 return .complex;
4623 },
4624 else => return .no,
4625 }
4626}
4627
4628fn parseOrNextStmt(p: *Parser, comptime func: fn (*Parser) Error!bool, l_brace: TokenIndex) !bool {
4629 return func(p) catch |er| switch (er) {
4630 error.ParsingFailed => {
4631 try p.nextStmt(l_brace);
4632 return true;
4633 },
4634 else => |e| return e,
4635 };
4636}
4637
4638fn nextStmt(p: *Parser, l_brace: TokenIndex) !void {
4639 var parens: u32 = 0;
4640 while (p.tok_i < p.tok_ids.len) : (p.tok_i += 1) {
4641 switch (p.tok_ids[p.tok_i]) {
4642 .l_paren, .l_brace, .l_bracket => parens += 1,
4643 .r_paren, .r_bracket => if (parens != 0) {
4644 parens -= 1;
4645 },
4646 .r_brace => if (parens == 0)
4647 return
4648 else {
4649 parens -= 1;
4650 },
4651 .semicolon => if (parens == 0) {
4652 p.tok_i += 1;
4653 return;
4654 },
4655 .keyword_for,
4656 .keyword_while,
4657 .keyword_do,
4658 .keyword_if,
4659 .keyword_goto,
4660 .keyword_switch,
4661 .keyword_case,
4662 .keyword_default,
4663 .keyword_continue,
4664 .keyword_break,
4665 .keyword_return,
4666 .keyword_typedef,
4667 .keyword_extern,
4668 .keyword_static,
4669 .keyword_auto,
4670 .keyword_register,
4671 .keyword_thread_local,
4672 .keyword_c23_thread_local,
4673 .keyword_inline,
4674 .keyword_inline1,
4675 .keyword_inline2,
4676 .keyword_noreturn,
4677 .keyword_void,
4678 .keyword_bool,
4679 .keyword_c23_bool,
4680 .keyword_char,
4681 .keyword_short,
4682 .keyword_int,
4683 .keyword_long,
4684 .keyword_signed,
4685 .keyword_unsigned,
4686 .keyword_float,
4687 .keyword_double,
4688 .keyword_complex,
4689 .keyword_atomic,
4690 .keyword_enum,
4691 .keyword_struct,
4692 .keyword_union,
4693 .keyword_alignas,
4694 .keyword_c23_alignas,
4695 .keyword_typeof,
4696 .keyword_typeof1,
4697 .keyword_typeof2,
4698 .keyword_typeof_unqual,
4699 .keyword_extension,
4700 => if (parens == 0) return,
4701 .keyword_pragma => p.skipToPragmaSentinel(),
4702 else => {},
4703 }
4704 }
4705 p.tok_i -= 1; // So we can consume EOF
4706 try p.expectClosing(l_brace, .r_brace);
4707 unreachable;
4708}
4709
4710fn returnStmt(p: *Parser) Error!?NodeIndex {
4711 const ret_tok = p.eatToken(.keyword_return) orelse return null;
4712
4713 const e_tok = p.tok_i;
4714 var e = try p.expr();
4715 _ = try p.expectToken(.semicolon);
4716 const ret_ty = p.func.ty.?.returnType();
4717
4718 if (p.func.ty.?.hasAttribute(.noreturn)) {
4719 try p.errStr(.invalid_noreturn, e_tok, p.tokSlice(p.func.name));
4720 }
4721
4722 if (e.node == .none) {
4723 if (!ret_ty.is(.void)) try p.errStr(.func_should_return, ret_tok, p.tokSlice(p.func.name));
4724 return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
4725 } else if (ret_ty.is(.void)) {
4726 try p.errStr(.void_func_returns_value, e_tok, p.tokSlice(p.func.name));
4727 return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
4728 }
4729
4730 try e.lvalConversion(p);
4731 try e.coerce(p, ret_ty, e_tok, .ret);
4732
4733 try e.saveValue(p);
4734 return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node } });
4735}
4736
4737// ====== expressions ======
4738
4739pub fn macroExpr(p: *Parser) Compilation.Error!bool {
4740 const res = p.condExpr() catch |e| switch (e) {
4741 error.OutOfMemory => return error.OutOfMemory,
4742 error.FatalError => return error.FatalError,
4743 error.ParsingFailed => return false,
4744 };
4745 if (res.val.opt_ref == .none) {
4746 try p.errTok(.expected_expr, p.tok_i);
4747 return false;
4748 }
4749 return res.val.toBool(p.comp);
4750}
4751
4752const CallExpr = union(enum) {
4753 standard: NodeIndex,
4754 builtin: struct {
4755 node: NodeIndex,
4756 tag: Builtin.Tag,
4757 },
4758
4759 fn init(p: *Parser, call_node: NodeIndex, func_node: NodeIndex) CallExpr {
4760 if (p.getNode(call_node, .builtin_call_expr_one)) |node| {
4761 const data = p.nodes.items(.data)[@intFromEnum(node)];
4762 const name = p.tokSlice(data.decl.name);
4763 const builtin_ty = p.comp.builtins.lookup(name);
4764 return .{ .builtin = .{ .node = node, .tag = builtin_ty.builtin.tag } };
4765 }
4766 return .{ .standard = func_node };
4767 }
4768
4769 fn shouldPerformLvalConversion(self: CallExpr, arg_idx: u32) bool {
4770 return switch (self) {
4771 .standard => true,
4772 .builtin => |builtin| switch (builtin.tag) {
4773 Builtin.tagFromName("__builtin_va_start").?,
4774 Builtin.tagFromName("__va_start").?,
4775 Builtin.tagFromName("va_start").?,
4776 => arg_idx != 1,
4777 else => true,
4778 },
4779 };
4780 }
4781
4782 fn shouldPromoteVarArg(self: CallExpr, arg_idx: u32) bool {
4783 return switch (self) {
4784 .standard => true,
4785 .builtin => |builtin| switch (builtin.tag) {
4786 Builtin.tagFromName("__builtin_va_start").?,
4787 Builtin.tagFromName("__va_start").?,
4788 Builtin.tagFromName("va_start").?,
4789 => arg_idx != 1,
4790 Builtin.tagFromName("__builtin_complex").? => false,
4791 else => true,
4792 },
4793 };
4794 }
4795
4796 fn shouldCoerceArg(self: CallExpr, arg_idx: u32) bool {
4797 _ = self;
4798 _ = arg_idx;
4799 return true;
4800 }
4801
4802 fn checkVarArg(self: CallExpr, p: *Parser, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32) !void {
4803 if (self == .standard) return;
4804
4805 const builtin_tok = p.nodes.items(.data)[@intFromEnum(self.builtin.node)].decl.name;
4806 switch (self.builtin.tag) {
4807 Builtin.tagFromName("__builtin_va_start").?,
4808 Builtin.tagFromName("__va_start").?,
4809 Builtin.tagFromName("va_start").?,
4810 => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx),
4811 Builtin.tagFromName("__builtin_complex").? => return p.checkComplexArg(builtin_tok, first_after, param_tok, arg, arg_idx),
4812 else => {},
4813 }
4814 }
4815
4816 /// Some functions cannot be expressed as standard C prototypes. For example `__builtin_complex` requires
4817 /// two arguments of the same real floating point type (e.g. two doubles or two floats). These functions are
4818 /// encoded as varargs functions with custom typechecking. Since varargs functions do not have a fixed number
4819 /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for
4820 /// these custom-typechecked functions.
4821 fn paramCountOverride(self: CallExpr) ?u32 {
4822 @setEvalBranchQuota(10_000);
4823 return switch (self) {
4824 .standard => null,
4825 .builtin => |builtin| switch (builtin.tag) {
4826 Builtin.tagFromName("__builtin_complex").? => 2,
4827
4828 Builtin.tagFromName("__atomic_fetch_add").?,
4829 Builtin.tagFromName("__atomic_fetch_sub").?,
4830 Builtin.tagFromName("__atomic_fetch_and").?,
4831 Builtin.tagFromName("__atomic_fetch_xor").?,
4832 Builtin.tagFromName("__atomic_fetch_or").?,
4833 Builtin.tagFromName("__atomic_fetch_nand").?,
4834 => 3,
4835
4836 Builtin.tagFromName("__atomic_compare_exchange").?,
4837 Builtin.tagFromName("__atomic_compare_exchange_n").?,
4838 => 6,
4839 else => null,
4840 },
4841 };
4842 }
4843
4844 fn returnType(self: CallExpr, p: *Parser, callable_ty: Type) Type {
4845 return switch (self) {
4846 .standard => callable_ty.returnType(),
4847 .builtin => |builtin| switch (builtin.tag) {
4848 Builtin.tagFromName("__atomic_fetch_add").?,
4849 Builtin.tagFromName("__atomic_fetch_sub").?,
4850 Builtin.tagFromName("__atomic_fetch_and").?,
4851 Builtin.tagFromName("__atomic_fetch_xor").?,
4852 Builtin.tagFromName("__atomic_fetch_or").?,
4853 Builtin.tagFromName("__atomic_fetch_nand").?,
4854 => {
4855 if (p.list_buf.items.len < 2) return Type.invalid; // not enough arguments; already an error
4856 const second_param = p.list_buf.items[p.list_buf.items.len - 2];
4857 return p.nodes.items(.ty)[@intFromEnum(second_param)];
4858 },
4859 Builtin.tagFromName("__builtin_complex").? => {
4860 if (p.list_buf.items.len < 1) return Type.invalid; // not enough arguments; already an error
4861 const last_param = p.list_buf.items[p.list_buf.items.len - 1];
4862 return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex();
4863 },
4864 Builtin.tagFromName("__atomic_compare_exchange").?,
4865 Builtin.tagFromName("__atomic_compare_exchange_n").?,
4866 => .{ .specifier = .bool },
4867 else => callable_ty.returnType(),
4868 },
4869 };
4870 }
4871
4872 fn finish(self: CallExpr, p: *Parser, ty: Type, list_buf_top: usize, arg_count: u32) Error!Result {
4873 const ret_ty = self.returnType(p, ty);
4874 switch (self) {
4875 .standard => |func_node| {
4876 var call_node: Tree.Node = .{
4877 .tag = .call_expr_one,
4878 .ty = ret_ty,
4879 .data = .{ .bin = .{ .lhs = func_node, .rhs = .none } },
4880 };
4881 const args = p.list_buf.items[list_buf_top..];
4882 switch (arg_count) {
4883 0 => {},
4884 1 => call_node.data.bin.rhs = args[1], // args[0] == func.node
4885 else => {
4886 call_node.tag = .call_expr;
4887 call_node.data = .{ .range = try p.addList(args) };
4888 },
4889 }
4890 return Result{ .node = try p.addNode(call_node), .ty = ret_ty };
4891 },
4892 .builtin => |builtin| {
4893 const index = @intFromEnum(builtin.node);
4894 var call_node = p.nodes.get(index);
4895 defer p.nodes.set(index, call_node);
4896 call_node.ty = ret_ty;
4897 const args = p.list_buf.items[list_buf_top..];
4898 switch (arg_count) {
4899 0 => {},
4900 1 => call_node.data.decl.node = args[1], // args[0] == func.node
4901 else => {
4902 call_node.tag = .builtin_call_expr;
4903 args[0] = @enumFromInt(call_node.data.decl.name);
4904 call_node.data = .{ .range = try p.addList(args) };
4905 },
4906 }
4907 return Result{ .node = builtin.node, .ty = ret_ty };
4908 },
4909 }
4910 }
4911};
4912
4913pub const Result = struct {
4914 node: NodeIndex = .none,
4915 ty: Type = .{ .specifier = .int },
4916 val: Value = .{},
4917
4918 pub fn str(res: Result, p: *Parser) ![]const u8 {
4919 switch (res.val.opt_ref) {
4920 .none => return "(none)",
4921 .null => return "nullptr_t",
4922 else => {},
4923 }
4924 const strings_top = p.strings.items.len;
4925 defer p.strings.items.len = strings_top;
4926
4927 try res.val.print(res.ty, p.comp, p.strings.writer());
4928 return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
4929 }
4930
4931 fn expect(res: Result, p: *Parser) Error!void {
4932 if (p.in_macro) {
4933 if (res.val.opt_ref == .none) {
4934 try p.errTok(.expected_expr, p.tok_i);
4935 return error.ParsingFailed;
4936 }
4937 return;
4938 }
4939 if (res.node == .none) {
4940 try p.errTok(.expected_expr, p.tok_i);
4941 return error.ParsingFailed;
4942 }
4943 }
4944
4945 fn empty(res: Result, p: *Parser) bool {
4946 if (p.in_macro) return res.val.opt_ref == .none;
4947 return res.node == .none;
4948 }
4949
4950 fn maybeWarnUnused(res: Result, p: *Parser, expr_start: TokenIndex, err_start: usize) Error!void {
4951 if (res.ty.is(.void) or res.node == .none) return;
4952 // don't warn about unused result if the expression contained errors besides other unused results
4953 for (p.comp.diagnostics.list.items[err_start..]) |err_item| {
4954 if (err_item.tag != .unused_value) return;
4955 }
4956 var cur_node = res.node;
4957 while (true) switch (p.nodes.items(.tag)[@intFromEnum(cur_node)]) {
4958 .invalid, // So that we don't need to check for node == 0
4959 .assign_expr,
4960 .mul_assign_expr,
4961 .div_assign_expr,
4962 .mod_assign_expr,
4963 .add_assign_expr,
4964 .sub_assign_expr,
4965 .shl_assign_expr,
4966 .shr_assign_expr,
4967 .bit_and_assign_expr,
4968 .bit_xor_assign_expr,
4969 .bit_or_assign_expr,
4970 .pre_inc_expr,
4971 .pre_dec_expr,
4972 .post_inc_expr,
4973 .post_dec_expr,
4974 => return,
4975 .call_expr_one => {
4976 const fn_ptr = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.lhs;
4977 const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
4978 if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
4979 if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
4980 return;
4981 },
4982 .call_expr => {
4983 const fn_ptr = p.data.items[p.nodes.items(.data)[@intFromEnum(cur_node)].range.start];
4984 const fn_ty = p.nodes.items(.ty)[@intFromEnum(fn_ptr)].elemType();
4985 if (fn_ty.hasAttribute(.nodiscard)) try p.errStr(.nodiscard_unused, expr_start, "TODO get name");
4986 if (fn_ty.hasAttribute(.warn_unused_result)) try p.errStr(.warn_unused_result, expr_start, "TODO get name");
4987 return;
4988 },
4989 .stmt_expr => {
4990 const body = p.nodes.items(.data)[@intFromEnum(cur_node)].un;
4991 switch (p.nodes.items(.tag)[@intFromEnum(body)]) {
4992 .compound_stmt_two => {
4993 const body_stmt = p.nodes.items(.data)[@intFromEnum(body)].bin;
4994 cur_node = if (body_stmt.rhs != .none) body_stmt.rhs else body_stmt.lhs;
4995 },
4996 .compound_stmt => {
4997 const data = p.nodes.items(.data)[@intFromEnum(body)];
4998 cur_node = p.data.items[data.range.end - 1];
4999 },
5000 else => unreachable,
5001 }
5002 },
5003 .comma_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.rhs,
5004 .paren_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].un,
5005 else => break,
5006 };
5007 try p.errTok(.unused_value, expr_start);
5008 }
5009
5010 fn boolRes(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
5011 if (lhs.val.opt_ref == .null) {
5012 lhs.val = Value.zero;
5013 }
5014 if (lhs.ty.specifier != .invalid) {
5015 lhs.ty = Type.int;
5016 }
5017 return lhs.bin(p, tag, rhs);
5018 }
5019
5020 fn bin(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result) !void {
5021 lhs.node = try p.addNode(.{
5022 .tag = tag,
5023 .ty = lhs.ty,
5024 .data = .{ .bin = .{ .lhs = lhs.node, .rhs = rhs.node } },
5025 });
5026 }
5027
5028 fn un(operand: *Result, p: *Parser, tag: Tree.Tag) Error!void {
5029 operand.node = try p.addNode(.{
5030 .tag = tag,
5031 .ty = operand.ty,
5032 .data = .{ .un = operand.node },
5033 });
5034 }
5035
5036 fn implicitCast(operand: *Result, p: *Parser, kind: Tree.CastKind) Error!void {
5037 operand.node = try p.addNode(.{
5038 .tag = .implicit_cast,
5039 .ty = operand.ty,
5040 .data = .{ .cast = .{ .operand = operand.node, .kind = kind } },
5041 });
5042 }
5043
5044 fn adjustCondExprPtrs(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) !bool {
5045 assert(a.ty.isPtr() and b.ty.isPtr());
5046
5047 const a_elem = a.ty.elemType();
5048 const b_elem = b.ty.elemType();
5049 if (a_elem.eql(b_elem, p.comp, true)) return true;
5050
5051 var adjusted_elem_ty = try p.arena.create(Type);
5052 adjusted_elem_ty.* = a_elem;
5053
5054 const has_void_star_branch = a.ty.isVoidStar() or b.ty.isVoidStar();
5055 const only_quals_differ = a_elem.eql(b_elem, p.comp, false);
5056 const pointers_compatible = only_quals_differ or has_void_star_branch;
5057
5058 if (!pointers_compatible or has_void_star_branch) {
5059 if (!pointers_compatible) {
5060 try p.errStr(.pointer_mismatch, tok, try p.typePairStrExtra(a.ty, " and ", b.ty));
5061 }
5062 adjusted_elem_ty.* = .{ .specifier = .void };
5063 }
5064 if (pointers_compatible) {
5065 adjusted_elem_ty.qual = a_elem.qual.mergeCV(b_elem.qual);
5066 }
5067 if (!adjusted_elem_ty.eql(a_elem, p.comp, true)) {
5068 a.ty = .{
5069 .data = .{ .sub_type = adjusted_elem_ty },
5070 .specifier = .pointer,
5071 };
5072 try a.implicitCast(p, .bitcast);
5073 }
5074 if (!adjusted_elem_ty.eql(b_elem, p.comp, true)) {
5075 b.ty = .{
5076 .data = .{ .sub_type = adjusted_elem_ty },
5077 .specifier = .pointer,
5078 };
5079 try b.implicitCast(p, .bitcast);
5080 }
5081 return true;
5082 }
5083
5084 /// Adjust types for binary operation, returns true if the result can and should be evaluated.
5085 fn adjustTypes(a: *Result, tok: TokenIndex, b: *Result, p: *Parser, kind: enum {
5086 integer,
5087 arithmetic,
5088 boolean_logic,
5089 relational,
5090 equality,
5091 conditional,
5092 add,
5093 sub,
5094 }) !bool {
5095 if (b.ty.specifier == .invalid) {
5096 try a.saveValue(p);
5097 a.ty = Type.invalid;
5098 }
5099 if (a.ty.specifier == .invalid) {
5100 return false;
5101 }
5102 try a.lvalConversion(p);
5103 try b.lvalConversion(p);
5104
5105 const a_vec = a.ty.is(.vector);
5106 const b_vec = b.ty.is(.vector);
5107 if (a_vec and b_vec) {
5108 if (a.ty.eql(b.ty, p.comp, false)) {
5109 return a.shouldEval(b, p);
5110 }
5111 return a.invalidBinTy(tok, b, p);
5112 } else if (a_vec) {
5113 if (b.coerceExtra(p, a.ty.elemType(), tok, .test_coerce)) {
5114 try b.saveValue(p);
5115 try b.implicitCast(p, .vector_splat);
5116 return a.shouldEval(b, p);
5117 } else |er| switch (er) {
5118 error.CoercionFailed => return a.invalidBinTy(tok, b, p),
5119 else => |e| return e,
5120 }
5121 } else if (b_vec) {
5122 if (a.coerceExtra(p, b.ty.elemType(), tok, .test_coerce)) {
5123 try a.saveValue(p);
5124 try a.implicitCast(p, .vector_splat);
5125 return a.shouldEval(b, p);
5126 } else |er| switch (er) {
5127 error.CoercionFailed => return a.invalidBinTy(tok, b, p),
5128 else => |e| return e,
5129 }
5130 }
5131
5132 const a_int = a.ty.isInt();
5133 const b_int = b.ty.isInt();
5134 if (a_int and b_int) {
5135 try a.usualArithmeticConversion(b, p, tok);
5136 return a.shouldEval(b, p);
5137 }
5138 if (kind == .integer) return a.invalidBinTy(tok, b, p);
5139
5140 const a_float = a.ty.isFloat();
5141 const b_float = b.ty.isFloat();
5142 const a_arithmetic = a_int or a_float;
5143 const b_arithmetic = b_int or b_float;
5144 if (a_arithmetic and b_arithmetic) {
5145 // <, <=, >, >= only work on real types
5146 if (kind == .relational and (!a.ty.isReal() or !b.ty.isReal()))
5147 return a.invalidBinTy(tok, b, p);
5148
5149 try a.usualArithmeticConversion(b, p, tok);
5150 return a.shouldEval(b, p);
5151 }
5152 if (kind == .arithmetic) return a.invalidBinTy(tok, b, p);
5153
5154 const a_nullptr = a.ty.is(.nullptr_t);
5155 const b_nullptr = b.ty.is(.nullptr_t);
5156 const a_ptr = a.ty.isPtr();
5157 const b_ptr = b.ty.isPtr();
5158 const a_scalar = a_arithmetic or a_ptr;
5159 const b_scalar = b_arithmetic or b_ptr;
5160 switch (kind) {
5161 .boolean_logic => {
5162 if (!(a_scalar or a_nullptr) or !(b_scalar or b_nullptr)) return a.invalidBinTy(tok, b, p);
5163
5164 // Do integer promotions but nothing else
5165 if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
5166 if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
5167 return a.shouldEval(b, p);
5168 },
5169 .relational, .equality => {
5170 if (kind == .equality and (a_nullptr or b_nullptr)) {
5171 if (a_nullptr and b_nullptr) return a.shouldEval(b, p);
5172 const nullptr_res = if (a_nullptr) a else b;
5173 const other_res = if (a_nullptr) b else a;
5174 if (other_res.ty.isPtr()) {
5175 try nullptr_res.nullCast(p, other_res.ty);
5176 return other_res.shouldEval(nullptr_res, p);
5177 } else if (other_res.val.isZero(p.comp)) {
5178 other_res.val = Value.null;
5179 try other_res.nullCast(p, nullptr_res.ty);
5180 return other_res.shouldEval(nullptr_res, p);
5181 }
5182 return a.invalidBinTy(tok, b, p);
5183 }
5184 // comparisons between floats and pointes not allowed
5185 if (!a_scalar or !b_scalar or (a_float and b_ptr) or (b_float and a_ptr))
5186 return a.invalidBinTy(tok, b, p);
5187
5188 if ((a_int or b_int) and !(a.val.isZero(p.comp) or b.val.isZero(p.comp))) {
5189 try p.errStr(.comparison_ptr_int, tok, try p.typePairStr(a.ty, b.ty));
5190 } else if (a_ptr and b_ptr) {
5191 if (!a.ty.isVoidStar() and !b.ty.isVoidStar() and !a.ty.eql(b.ty, p.comp, false))
5192 try p.errStr(.comparison_distinct_ptr, tok, try p.typePairStr(a.ty, b.ty));
5193 } else if (a_ptr) {
5194 try b.ptrCast(p, a.ty);
5195 } else {
5196 assert(b_ptr);
5197 try a.ptrCast(p, b.ty);
5198 }
5199
5200 return a.shouldEval(b, p);
5201 },
5202 .conditional => {
5203 // doesn't matter what we return here, as the result is ignored
5204 if (a.ty.is(.void) or b.ty.is(.void)) {
5205 try a.toVoid(p);
5206 try b.toVoid(p);
5207 return true;
5208 }
5209 if (a_nullptr and b_nullptr) return true;
5210 if ((a_ptr and b_int) or (a_int and b_ptr)) {
5211 if (a.val.isZero(p.comp) or b.val.isZero(p.comp)) {
5212 try a.nullCast(p, b.ty);
5213 try b.nullCast(p, a.ty);
5214 return true;
5215 }
5216 const int_ty = if (a_int) a else b;
5217 const ptr_ty = if (a_ptr) a else b;
5218 try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(int_ty.ty, " to ", ptr_ty.ty));
5219 try int_ty.ptrCast(p, ptr_ty.ty);
5220
5221 return true;
5222 }
5223 if (a_ptr and b_ptr) return a.adjustCondExprPtrs(tok, b, p);
5224 if ((a_ptr and b_nullptr) or (a_nullptr and b_ptr)) {
5225 const nullptr_res = if (a_nullptr) a else b;
5226 const ptr_res = if (a_nullptr) b else a;
5227 try nullptr_res.nullCast(p, ptr_res.ty);
5228 return true;
5229 }
5230 if (a.ty.isRecord() and b.ty.isRecord() and a.ty.eql(b.ty, p.comp, false)) {
5231 return true;
5232 }
5233 return a.invalidBinTy(tok, b, p);
5234 },
5235 .add => {
5236 // if both aren't arithmetic one should be pointer and the other an integer
5237 if (a_ptr == b_ptr or a_int == b_int) return a.invalidBinTy(tok, b, p);
5238
5239 // Do integer promotions but nothing else
5240 if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok);
5241 if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
5242
5243 // The result type is the type of the pointer operand
5244 if (a_int) a.ty = b.ty else b.ty = a.ty;
5245 return a.shouldEval(b, p);
5246 },
5247 .sub => {
5248 // if both aren't arithmetic then either both should be pointers or just a
5249 if (!a_ptr or !(b_ptr or b_int)) return a.invalidBinTy(tok, b, p);
5250
5251 if (a_ptr and b_ptr) {
5252 if (!a.ty.eql(b.ty, p.comp, false)) try p.errStr(.incompatible_pointers, tok, try p.typePairStr(a.ty, b.ty));
5253 a.ty = p.comp.types.ptrdiff;
5254 }
5255
5256 // Do integer promotion on b if needed
5257 if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok);
5258 return a.shouldEval(b, p);
5259 },
5260 else => return a.invalidBinTy(tok, b, p),
5261 }
5262 }
5263
5264 fn lvalConversion(res: *Result, p: *Parser) Error!void {
5265 if (res.ty.isFunc()) {
5266 const elem_ty = try p.arena.create(Type);
5267 elem_ty.* = res.ty;
5268 res.ty.specifier = .pointer;
5269 res.ty.data = .{ .sub_type = elem_ty };
5270 try res.implicitCast(p, .function_to_pointer);
5271 } else if (res.ty.isArray()) {
5272 res.val = .{};
5273 res.ty.decayArray();
5274 try res.implicitCast(p, .array_to_pointer);
5275 } else if (!p.in_macro and p.tmpTree().isLval(res.node)) {
5276 res.ty.qual = .{};
5277 try res.implicitCast(p, .lval_to_rval);
5278 }
5279 }
5280
5281 fn boolCast(res: *Result, p: *Parser, bool_ty: Type, tok: TokenIndex) Error!void {
5282 if (res.ty.isArray()) {
5283 if (res.val.is(.bytes, p.comp)) {
5284 try p.errStr(.string_literal_to_bool, tok, try p.typePairStrExtra(res.ty, " to ", bool_ty));
5285 } else {
5286 try p.errStr(.array_address_to_bool, tok, p.tokSlice(tok));
5287 }
5288 try res.lvalConversion(p);
5289 res.val = Value.one;
5290 res.ty = bool_ty;
5291 try res.implicitCast(p, .pointer_to_bool);
5292 } else if (res.ty.isPtr()) {
5293 res.val.boolCast(p.comp);
5294 res.ty = bool_ty;
5295 try res.implicitCast(p, .pointer_to_bool);
5296 } else if (res.ty.isInt() and !res.ty.is(.bool)) {
5297 res.val.boolCast(p.comp);
5298 res.ty = bool_ty;
5299 try res.implicitCast(p, .int_to_bool);
5300 } else if (res.ty.isFloat()) {
5301 const old_value = res.val;
5302 const value_change_kind = try res.val.floatToInt(bool_ty, p.comp);
5303 try res.floatToIntWarning(p, bool_ty, old_value, value_change_kind, tok);
5304 if (!res.ty.isReal()) {
5305 res.ty = res.ty.makeReal();
5306 try res.implicitCast(p, .complex_float_to_real);
5307 }
5308 res.ty = bool_ty;
5309 try res.implicitCast(p, .float_to_bool);
5310 }
5311 }
5312
5313 fn intCast(res: *Result, p: *Parser, int_ty: Type, tok: TokenIndex) Error!void {
5314 if (int_ty.hasIncompleteSize()) return error.ParsingFailed; // Diagnostic already issued
5315 if (res.ty.is(.bool)) {
5316 res.ty = int_ty.makeReal();
5317 try res.implicitCast(p, .bool_to_int);
5318 if (!int_ty.isReal()) {
5319 res.ty = int_ty;
5320 try res.implicitCast(p, .real_to_complex_int);
5321 }
5322 } else if (res.ty.isPtr()) {
5323 res.ty = int_ty.makeReal();
5324 try res.implicitCast(p, .pointer_to_int);
5325 if (!int_ty.isReal()) {
5326 res.ty = int_ty;
5327 try res.implicitCast(p, .real_to_complex_int);
5328 }
5329 } else if (res.ty.isFloat()) {
5330 const old_value = res.val;
5331 const value_change_kind = try res.val.floatToInt(int_ty, p.comp);
5332 try res.floatToIntWarning(p, int_ty, old_value, value_change_kind, tok);
5333 const old_real = res.ty.isReal();
5334 const new_real = int_ty.isReal();
5335 if (old_real and new_real) {
5336 res.ty = int_ty;
5337 try res.implicitCast(p, .float_to_int);
5338 } else if (old_real) {
5339 res.ty = int_ty.makeReal();
5340 try res.implicitCast(p, .float_to_int);
5341 res.ty = int_ty;
5342 try res.implicitCast(p, .real_to_complex_int);
5343 } else if (new_real) {
5344 res.ty = res.ty.makeReal();
5345 try res.implicitCast(p, .complex_float_to_real);
5346 res.ty = int_ty;
5347 try res.implicitCast(p, .float_to_int);
5348 } else {
5349 res.ty = int_ty;
5350 try res.implicitCast(p, .complex_float_to_complex_int);
5351 }
5352 } else if (!res.ty.eql(int_ty, p.comp, true)) {
5353 try res.val.intCast(int_ty, p.comp);
5354 const old_real = res.ty.isReal();
5355 const new_real = int_ty.isReal();
5356 if (old_real and new_real) {
5357 res.ty = int_ty;
5358 try res.implicitCast(p, .int_cast);
5359 } else if (old_real) {
5360 const real_int_ty = int_ty.makeReal();
5361 if (!res.ty.eql(real_int_ty, p.comp, false)) {
5362 res.ty = real_int_ty;
5363 try res.implicitCast(p, .int_cast);
5364 }
5365 res.ty = int_ty;
5366 try res.implicitCast(p, .real_to_complex_int);
5367 } else if (new_real) {
5368 res.ty = res.ty.makeReal();
5369 try res.implicitCast(p, .complex_int_to_real);
5370 res.ty = int_ty;
5371 try res.implicitCast(p, .int_cast);
5372 } else {
5373 res.ty = int_ty;
5374 try res.implicitCast(p, .complex_int_cast);
5375 }
5376 }
5377 }
5378
5379 fn floatToIntWarning(res: *Result, p: *Parser, int_ty: Type, old_value: Value, change_kind: Value.FloatToIntChangeKind, tok: TokenIndex) !void {
5380 switch (change_kind) {
5381 .none => return p.errStr(.float_to_int, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
5382 .out_of_range => return p.errStr(.float_out_of_range, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
5383 .overflow => return p.errStr(.float_overflow_conversion, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)),
5384 .nonzero_to_zero => return p.errStr(.float_zero_conversion, tok, try p.floatValueChangedStr(res, old_value, int_ty)),
5385 .value_changed => return p.errStr(.float_value_changed, tok, try p.floatValueChangedStr(res, old_value, int_ty)),
5386 }
5387 }
5388
5389 fn floatCast(res: *Result, p: *Parser, float_ty: Type) Error!void {
5390 if (res.ty.is(.bool)) {
5391 try res.val.intToFloat(float_ty, p.comp);
5392 res.ty = float_ty.makeReal();
5393 try res.implicitCast(p, .bool_to_float);
5394 if (!float_ty.isReal()) {
5395 res.ty = float_ty;
5396 try res.implicitCast(p, .real_to_complex_float);
5397 }
5398 } else if (res.ty.isInt()) {
5399 try res.val.intToFloat(float_ty, p.comp);
5400 const old_real = res.ty.isReal();
5401 const new_real = float_ty.isReal();
5402 if (old_real and new_real) {
5403 res.ty = float_ty;
5404 try res.implicitCast(p, .int_to_float);
5405 } else if (old_real) {
5406 res.ty = float_ty.makeReal();
5407 try res.implicitCast(p, .int_to_float);
5408 res.ty = float_ty;
5409 try res.implicitCast(p, .real_to_complex_float);
5410 } else if (new_real) {
5411 res.ty = res.ty.makeReal();
5412 try res.implicitCast(p, .complex_int_to_real);
5413 res.ty = float_ty;
5414 try res.implicitCast(p, .int_to_float);
5415 } else {
5416 res.ty = float_ty;
5417 try res.implicitCast(p, .complex_int_to_complex_float);
5418 }
5419 } else if (!res.ty.eql(float_ty, p.comp, true)) {
5420 try res.val.floatCast(float_ty, p.comp);
5421 const old_real = res.ty.isReal();
5422 const new_real = float_ty.isReal();
5423 if (old_real and new_real) {
5424 res.ty = float_ty;
5425 try res.implicitCast(p, .float_cast);
5426 } else if (old_real) {
5427 if (res.ty.floatRank() != float_ty.floatRank()) {
5428 res.ty = float_ty.makeReal();
5429 try res.implicitCast(p, .float_cast);
5430 }
5431 res.ty = float_ty;
5432 try res.implicitCast(p, .real_to_complex_float);
5433 } else if (new_real) {
5434 res.ty = res.ty.makeReal();
5435 try res.implicitCast(p, .complex_float_to_real);
5436 if (res.ty.floatRank() != float_ty.floatRank()) {
5437 res.ty = float_ty;
5438 try res.implicitCast(p, .float_cast);
5439 }
5440 } else {
5441 res.ty = float_ty;
5442 try res.implicitCast(p, .complex_float_cast);
5443 }
5444 }
5445 }
5446
5447 /// Converts a bool or integer to a pointer
5448 fn ptrCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
5449 if (res.ty.is(.bool)) {
5450 res.ty = ptr_ty;
5451 try res.implicitCast(p, .bool_to_pointer);
5452 } else if (res.ty.isInt()) {
5453 try res.val.intCast(ptr_ty, p.comp);
5454 res.ty = ptr_ty;
5455 try res.implicitCast(p, .int_to_pointer);
5456 }
5457 }
5458
5459 /// Convert pointer to one with a different child type
5460 fn ptrChildTypeCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
5461 res.ty = ptr_ty;
5462 return res.implicitCast(p, .bitcast);
5463 }
5464
5465 fn toVoid(res: *Result, p: *Parser) Error!void {
5466 if (!res.ty.is(.void)) {
5467 res.ty = .{ .specifier = .void };
5468 try res.implicitCast(p, .to_void);
5469 }
5470 }
5471
5472 fn nullCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void {
5473 if (!res.ty.is(.nullptr_t) and !res.val.isZero(p.comp)) return;
5474 res.ty = ptr_ty;
5475 try res.implicitCast(p, .null_to_pointer);
5476 }
5477
5478 fn usualUnaryConversion(res: *Result, p: *Parser, tok: TokenIndex) Error!void {
5479 if (res.ty.isFloat()) fp_eval: {
5480 const eval_method = p.comp.langopts.fp_eval_method orelse break :fp_eval;
5481 switch (eval_method) {
5482 .source => {},
5483 .indeterminate => unreachable,
5484 .double => {
5485 if (res.ty.floatRank() < (Type{ .specifier = .double }).floatRank()) {
5486 const spec: Type.Specifier = if (res.ty.isReal()) .double else .complex_double;
5487 return res.floatCast(p, .{ .specifier = spec });
5488 }
5489 },
5490 .extended => {
5491 if (res.ty.floatRank() < (Type{ .specifier = .long_double }).floatRank()) {
5492 const spec: Type.Specifier = if (res.ty.isReal()) .long_double else .complex_long_double;
5493 return res.floatCast(p, .{ .specifier = spec });
5494 }
5495 },
5496 }
5497 }
5498
5499 if (res.ty.is(.fp16) and !p.comp.langopts.use_native_half_type) {
5500 return res.floatCast(p, .{ .specifier = .float });
5501 }
5502 if (res.ty.isInt()) {
5503 if (p.tmpTree().bitfieldWidth(res.node, true)) |width| {
5504 if (res.ty.bitfieldPromotion(p.comp, width)) |promotion_ty| {
5505 return res.intCast(p, promotion_ty, tok);
5506 }
5507 }
5508 return res.intCast(p, res.ty.integerPromotion(p.comp), tok);
5509 }
5510 }
5511
5512 fn usualArithmeticConversion(a: *Result, b: *Result, p: *Parser, tok: TokenIndex) Error!void {
5513 try a.usualUnaryConversion(p, tok);
5514 try b.usualUnaryConversion(p, tok);
5515
5516 // if either is a float cast to that type
5517 if (a.ty.isFloat() or b.ty.isFloat()) {
5518 const float_types = [7][2]Type.Specifier{
5519 .{ .complex_long_double, .long_double },
5520 .{ .complex_float128, .float128 },
5521 .{ .complex_float80, .float80 },
5522 .{ .complex_double, .double },
5523 .{ .complex_float, .float },
5524 // No `_Complex __fp16` type
5525 .{ .invalid, .fp16 },
5526 // No `_Complex _Float16`
5527 .{ .invalid, .float16 },
5528 };
5529 const a_spec = a.ty.canonicalize(.standard).specifier;
5530 const b_spec = b.ty.canonicalize(.standard).specifier;
5531 if (p.comp.target.c_type_bit_size(.longdouble) == 128) {
5532 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
5533 }
5534 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[1])) return;
5535 if (p.comp.target.c_type_bit_size(.longdouble) == 80) {
5536 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
5537 }
5538 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[2])) return;
5539 if (p.comp.target.c_type_bit_size(.longdouble) == 64) {
5540 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return;
5541 }
5542 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[3])) return;
5543 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[4])) return;
5544 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[5])) return;
5545 if (try a.floatConversion(b, a_spec, b_spec, p, float_types[6])) return;
5546 }
5547
5548 if (a.ty.eql(b.ty, p.comp, true)) {
5549 // cast to promoted type
5550 try a.intCast(p, a.ty, tok);
5551 try b.intCast(p, b.ty, tok);
5552 return;
5553 }
5554
5555 const target = a.ty.integerConversion(b.ty, p.comp);
5556 if (!target.isReal()) {
5557 try a.saveValue(p);
5558 try b.saveValue(p);
5559 }
5560 try a.intCast(p, target, tok);
5561 try b.intCast(p, target, tok);
5562 }
5563
5564 fn floatConversion(a: *Result, b: *Result, a_spec: Type.Specifier, b_spec: Type.Specifier, p: *Parser, pair: [2]Type.Specifier) !bool {
5565 if (a_spec == pair[0] or a_spec == pair[1] or
5566 b_spec == pair[0] or b_spec == pair[1])
5567 {
5568 const both_real = a.ty.isReal() and b.ty.isReal();
5569 const res_spec = pair[@intFromBool(both_real)];
5570 const ty = Type{ .specifier = res_spec };
5571 try a.floatCast(p, ty);
5572 try b.floatCast(p, ty);
5573 return true;
5574 }
5575 return false;
5576 }
5577
5578 fn invalidBinTy(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) Error!bool {
5579 try p.errStr(.invalid_bin_types, tok, try p.typePairStr(a.ty, b.ty));
5580 a.val = .{};
5581 b.val = .{};
5582 a.ty = Type.invalid;
5583 return false;
5584 }
5585
5586 fn shouldEval(a: *Result, b: *Result, p: *Parser) Error!bool {
5587 if (p.no_eval) return false;
5588 if (a.val.opt_ref != .none and b.val.opt_ref != .none)
5589 return true;
5590
5591 try a.saveValue(p);
5592 try b.saveValue(p);
5593 return p.no_eval;
5594 }
5595
5596 /// Saves value and replaces it with `.unavailable`.
5597 fn saveValue(res: *Result, p: *Parser) !void {
5598 assert(!p.in_macro);
5599 if (res.val.opt_ref == .none or res.val.opt_ref == .null) return;
5600 if (!p.in_macro) try p.value_map.put(res.node, res.val);
5601 res.val = .{};
5602 }
5603
5604 fn castType(res: *Result, p: *Parser, to: Type, operand_tok: TokenIndex, l_paren: TokenIndex) !void {
5605 var cast_kind: Tree.CastKind = undefined;
5606
5607 if (to.is(.void)) {
5608 // everything can cast to void
5609 cast_kind = .to_void;
5610 res.val = .{};
5611 } else if (to.is(.nullptr_t)) {
5612 if (res.ty.is(.nullptr_t)) {
5613 cast_kind = .no_op;
5614 } else {
5615 try p.errStr(.invalid_object_cast, l_paren, try p.typePairStrExtra(res.ty, " to ", to));
5616 return error.ParsingFailed;
5617 }
5618 } else if (res.ty.is(.nullptr_t)) {
5619 if (to.is(.bool)) {
5620 try res.nullCast(p, res.ty);
5621 res.val.boolCast(p.comp);
5622 res.ty = .{ .specifier = .bool };
5623 try res.implicitCast(p, .pointer_to_bool);
5624 try res.saveValue(p);
5625 } else if (to.isPtr()) {
5626 try res.nullCast(p, to);
5627 } else {
5628 try p.errStr(.invalid_object_cast, l_paren, try p.typePairStrExtra(res.ty, " to ", to));
5629 return error.ParsingFailed;
5630 }
5631 cast_kind = .no_op;
5632 } else if (res.val.isZero(p.comp) and to.isPtr()) {
5633 cast_kind = .null_to_pointer;
5634 } else if (to.isScalar()) cast: {
5635 const old_float = res.ty.isFloat();
5636 const new_float = to.isFloat();
5637
5638 if (new_float and res.ty.isPtr()) {
5639 try p.errStr(.invalid_cast_to_float, l_paren, try p.typeStr(to));
5640 return error.ParsingFailed;
5641 } else if (old_float and to.isPtr()) {
5642 try p.errStr(.invalid_cast_to_pointer, l_paren, try p.typeStr(res.ty));
5643 return error.ParsingFailed;
5644 }
5645 const old_real = res.ty.isReal();
5646 const new_real = to.isReal();
5647
5648 if (to.eql(res.ty, p.comp, false)) {
5649 cast_kind = .no_op;
5650 } else if (to.is(.bool)) {
5651 if (res.ty.isPtr()) {
5652 cast_kind = .pointer_to_bool;
5653 } else if (res.ty.isInt()) {
5654 if (!old_real) {
5655 res.ty = res.ty.makeReal();
5656 try res.implicitCast(p, .complex_int_to_real);
5657 }
5658 cast_kind = .int_to_bool;
5659 } else if (old_float) {
5660 if (!old_real) {
5661 res.ty = res.ty.makeReal();
5662 try res.implicitCast(p, .complex_float_to_real);
5663 }
5664 cast_kind = .float_to_bool;
5665 }
5666 } else if (to.isInt()) {
5667 if (res.ty.is(.bool)) {
5668 if (!new_real) {
5669 res.ty = to.makeReal();
5670 try res.implicitCast(p, .bool_to_int);
5671 cast_kind = .real_to_complex_int;
5672 } else {
5673 cast_kind = .bool_to_int;
5674 }
5675 } else if (res.ty.isInt()) {
5676 if (old_real and new_real) {
5677 cast_kind = .int_cast;
5678 } else if (old_real) {
5679 res.ty = to.makeReal();
5680 try res.implicitCast(p, .int_cast);
5681 cast_kind = .real_to_complex_int;
5682 } else if (new_real) {
5683 res.ty = res.ty.makeReal();
5684 try res.implicitCast(p, .complex_int_to_real);
5685 cast_kind = .int_cast;
5686 } else {
5687 cast_kind = .complex_int_cast;
5688 }
5689 } else if (res.ty.isPtr()) {
5690 if (!new_real) {
5691 res.ty = to.makeReal();
5692 try res.implicitCast(p, .pointer_to_int);
5693 cast_kind = .real_to_complex_int;
5694 } else {
5695 cast_kind = .pointer_to_int;
5696 }
5697 } else if (old_real and new_real) {
5698 cast_kind = .float_to_int;
5699 } else if (old_real) {
5700 res.ty = to.makeReal();
5701 try res.implicitCast(p, .float_to_int);
5702 cast_kind = .real_to_complex_int;
5703 } else if (new_real) {
5704 res.ty = res.ty.makeReal();
5705 try res.implicitCast(p, .complex_float_to_real);
5706 cast_kind = .float_to_int;
5707 } else {
5708 cast_kind = .complex_float_to_complex_int;
5709 }
5710 } else if (to.isPtr()) {
5711 if (res.ty.isArray())
5712 cast_kind = .array_to_pointer
5713 else if (res.ty.isPtr())
5714 cast_kind = .bitcast
5715 else if (res.ty.isFunc())
5716 cast_kind = .function_to_pointer
5717 else if (res.ty.is(.bool))
5718 cast_kind = .bool_to_pointer
5719 else if (res.ty.isInt()) {
5720 if (!old_real) {
5721 res.ty = res.ty.makeReal();
5722 try res.implicitCast(p, .complex_int_to_real);
5723 }
5724 cast_kind = .int_to_pointer;
5725 } else {
5726 try p.errStr(.cond_expr_type, operand_tok, try p.typeStr(res.ty));
5727 return error.ParsingFailed;
5728 }
5729 } else if (new_float) {
5730 if (res.ty.is(.bool)) {
5731 if (!new_real) {
5732 res.ty = to.makeReal();
5733 try res.implicitCast(p, .bool_to_float);
5734 cast_kind = .real_to_complex_float;
5735 } else {
5736 cast_kind = .bool_to_float;
5737 }
5738 } else if (res.ty.isInt()) {
5739 if (old_real and new_real) {
5740 cast_kind = .int_to_float;
5741 } else if (old_real) {
5742 res.ty = to.makeReal();
5743 try res.implicitCast(p, .int_to_float);
5744 cast_kind = .real_to_complex_float;
5745 } else if (new_real) {
5746 res.ty = res.ty.makeReal();
5747 try res.implicitCast(p, .complex_int_to_real);
5748 cast_kind = .int_to_float;
5749 } else {
5750 cast_kind = .complex_int_to_complex_float;
5751 }
5752 } else if (old_real and new_real) {
5753 cast_kind = .float_cast;
5754 } else if (old_real) {
5755 res.ty = to.makeReal();
5756 try res.implicitCast(p, .float_cast);
5757 cast_kind = .real_to_complex_float;
5758 } else if (new_real) {
5759 res.ty = res.ty.makeReal();
5760 try res.implicitCast(p, .complex_float_to_real);
5761 cast_kind = .float_cast;
5762 } else {
5763 cast_kind = .complex_float_cast;
5764 }
5765 }
5766 if (res.val.opt_ref == .none) break :cast;
5767
5768 const old_int = res.ty.isInt() or res.ty.isPtr();
5769 const new_int = to.isInt() or to.isPtr();
5770 if (to.is(.bool)) {
5771 res.val.boolCast(p.comp);
5772 } else if (old_float and new_int) {
5773 // Explicit cast, no conversion warning
5774 _ = try res.val.floatToInt(to, p.comp);
5775 } else if (new_float and old_int) {
5776 try res.val.intToFloat(to, p.comp);
5777 } else if (new_float and old_float) {
5778 try res.val.floatCast(to, p.comp);
5779 } else if (old_int and new_int) {
5780 if (to.hasIncompleteSize()) {
5781 try p.errStr(.cast_to_incomplete_type, l_paren, try p.typeStr(to));
5782 return error.ParsingFailed;
5783 }
5784 try res.val.intCast(to, p.comp);
5785 }
5786 } else if (to.get(.@"union")) |union_ty| {
5787 if (union_ty.data.record.hasFieldOfType(res.ty, p.comp)) {
5788 cast_kind = .union_cast;
5789 try p.errTok(.gnu_union_cast, l_paren);
5790 } else {
5791 if (union_ty.data.record.isIncomplete()) {
5792 try p.errStr(.cast_to_incomplete_type, l_paren, try p.typeStr(to));
5793 } else {
5794 try p.errStr(.invalid_union_cast, l_paren, try p.typeStr(res.ty));
5795 }
5796 return error.ParsingFailed;
5797 }
5798 } else {
5799 if (to.is(.auto_type)) {
5800 try p.errTok(.invalid_cast_to_auto_type, l_paren);
5801 } else {
5802 try p.errStr(.invalid_cast_type, l_paren, try p.typeStr(to));
5803 }
5804 return error.ParsingFailed;
5805 }
5806 if (to.anyQual()) try p.errStr(.qual_cast, l_paren, try p.typeStr(to));
5807 if (to.isInt() and res.ty.isPtr() and to.sizeCompare(res.ty, p.comp) == .lt) {
5808 try p.errStr(.cast_to_smaller_int, l_paren, try p.typePairStrExtra(to, " from ", res.ty));
5809 }
5810 res.ty = to;
5811 res.ty.qual = .{};
5812 res.node = try p.addNode(.{
5813 .tag = .explicit_cast,
5814 .ty = res.ty,
5815 .data = .{ .cast = .{ .operand = res.node, .kind = cast_kind } },
5816 });
5817 }
5818
5819 fn intFitsInType(res: Result, p: *Parser, ty: Type) !bool {
5820 const max_int = try Value.int(ty.maxInt(p.comp), p.comp);
5821 const min_int = try Value.int(ty.minInt(p.comp), p.comp);
5822 return res.val.compare(.lte, max_int, p.comp) and
5823 (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, min_int, p.comp));
5824 }
5825
5826 const CoerceContext = union(enum) {
5827 assign,
5828 init,
5829 ret,
5830 arg: TokenIndex,
5831 test_coerce,
5832
5833 fn note(c: CoerceContext, p: *Parser) !void {
5834 switch (c) {
5835 .arg => |tok| try p.errTok(.parameter_here, tok),
5836 .test_coerce => unreachable,
5837 else => {},
5838 }
5839 }
5840
5841 fn typePairStr(c: CoerceContext, p: *Parser, dest_ty: Type, src_ty: Type) ![]const u8 {
5842 switch (c) {
5843 .assign, .init => return p.typePairStrExtra(dest_ty, " from incompatible type ", src_ty),
5844 .ret => return p.typePairStrExtra(src_ty, " from a function with incompatible result type ", dest_ty),
5845 .arg => return p.typePairStrExtra(src_ty, " to parameter of incompatible type ", dest_ty),
5846 .test_coerce => unreachable,
5847 }
5848 }
5849 };
5850
5851 /// Perform assignment-like coercion to `dest_ty`.
5852 fn coerce(res: *Result, p: *Parser, dest_ty: Type, tok: TokenIndex, c: CoerceContext) Error!void {
5853 if (res.ty.specifier == .invalid or dest_ty.specifier == .invalid) {
5854 res.ty = Type.invalid;
5855 return;
5856 }
5857 return res.coerceExtra(p, dest_ty, tok, c) catch |er| switch (er) {
5858 error.CoercionFailed => unreachable,
5859 else => |e| return e,
5860 };
5861 }
5862
5863 fn coerceExtra(
5864 res: *Result,
5865 p: *Parser,
5866 dest_ty: Type,
5867 tok: TokenIndex,
5868 c: CoerceContext,
5869 ) (Error || error{CoercionFailed})!void {
5870 // Subject of the coercion does not need to be qualified.
5871 var unqual_ty = dest_ty.canonicalize(.standard);
5872 unqual_ty.qual = .{};
5873 if (unqual_ty.is(.nullptr_t)) {
5874 if (res.ty.is(.nullptr_t)) return;
5875 } else if (unqual_ty.is(.bool)) {
5876 if (res.ty.isScalar() and !res.ty.is(.nullptr_t)) {
5877 // this is ridiculous but it's what clang does
5878 try res.boolCast(p, unqual_ty, tok);
5879 return;
5880 }
5881 } else if (unqual_ty.isInt()) {
5882 if (res.ty.isInt() or res.ty.isFloat()) {
5883 try res.intCast(p, unqual_ty, tok);
5884 return;
5885 } else if (res.ty.isPtr()) {
5886 if (c == .test_coerce) return error.CoercionFailed;
5887 try p.errStr(.implicit_ptr_to_int, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
5888 try c.note(p);
5889 try res.intCast(p, unqual_ty, tok);
5890 return;
5891 }
5892 } else if (unqual_ty.isFloat()) {
5893 if (res.ty.isInt() or res.ty.isFloat()) {
5894 try res.floatCast(p, unqual_ty);
5895 return;
5896 }
5897 } else if (unqual_ty.isPtr()) {
5898 if (res.ty.is(.nullptr_t) or res.val.isZero(p.comp)) {
5899 try res.nullCast(p, dest_ty);
5900 return;
5901 } else if (res.ty.isInt() and res.ty.isReal()) {
5902 if (c == .test_coerce) return error.CoercionFailed;
5903 try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty));
5904 try c.note(p);
5905 try res.ptrCast(p, unqual_ty);
5906 return;
5907 } else if (res.ty.isVoidStar() or unqual_ty.eql(res.ty, p.comp, true)) {
5908 return; // ok
5909 } else if (unqual_ty.isVoidStar() and res.ty.isPtr() or (res.ty.isInt() and res.ty.isReal())) {
5910 return; // ok
5911 } else if (unqual_ty.eql(res.ty, p.comp, false)) {
5912 if (!unqual_ty.elemType().qual.hasQuals(res.ty.elemType().qual)) {
5913 try p.errStr(switch (c) {
5914 .assign => .ptr_assign_discards_quals,
5915 .init => .ptr_init_discards_quals,
5916 .ret => .ptr_ret_discards_quals,
5917 .arg => .ptr_arg_discards_quals,
5918 .test_coerce => return error.CoercionFailed,
5919 }, tok, try c.typePairStr(p, dest_ty, res.ty));
5920 }
5921 try res.ptrCast(p, unqual_ty);
5922 return;
5923 } else if (res.ty.isPtr()) {
5924 const different_sign_only = unqual_ty.elemType().sameRankDifferentSign(res.ty.elemType(), p.comp);
5925 try p.errStr(switch (c) {
5926 .assign => ([2]Diagnostics.Tag{ .incompatible_ptr_assign, .incompatible_ptr_assign_sign })[@intFromBool(different_sign_only)],
5927 .init => ([2]Diagnostics.Tag{ .incompatible_ptr_init, .incompatible_ptr_init_sign })[@intFromBool(different_sign_only)],
5928 .ret => ([2]Diagnostics.Tag{ .incompatible_return, .incompatible_return_sign })[@intFromBool(different_sign_only)],
5929 .arg => ([2]Diagnostics.Tag{ .incompatible_ptr_arg, .incompatible_ptr_arg_sign })[@intFromBool(different_sign_only)],
5930 .test_coerce => return error.CoercionFailed,
5931 }, tok, try c.typePairStr(p, dest_ty, res.ty));
5932 try c.note(p);
5933 try res.ptrChildTypeCast(p, unqual_ty);
5934 return;
5935 }
5936 } else if (unqual_ty.isRecord()) {
5937 if (unqual_ty.eql(res.ty, p.comp, false)) {
5938 return; // ok
5939 }
5940
5941 if (c == .arg) if (unqual_ty.get(.@"union")) |union_ty| {
5942 if (dest_ty.hasAttribute(.transparent_union)) transparent_union: {
5943 res.coerceExtra(p, union_ty.data.record.fields[0].ty, tok, .test_coerce) catch |er| switch (er) {
5944 error.CoercionFailed => break :transparent_union,
5945 else => |e| return e,
5946 };
5947 res.node = try p.addNode(.{
5948 .tag = .union_init_expr,
5949 .ty = dest_ty,
5950 .data = .{ .union_init = .{ .field_index = 0, .node = res.node } },
5951 });
5952 res.ty = dest_ty;
5953 return;
5954 }
5955 };
5956 } else if (unqual_ty.is(.vector)) {
5957 if (unqual_ty.eql(res.ty, p.comp, false)) {
5958 return; // ok
5959 }
5960 } else {
5961 if (c == .assign and (unqual_ty.isArray() or unqual_ty.isFunc())) {
5962 try p.errTok(.not_assignable, tok);
5963 return;
5964 } else if (c == .test_coerce) {
5965 return error.CoercionFailed;
5966 }
5967 // This case should not be possible and an error should have already been emitted but we
5968 // might still have attempted to parse further so return error.ParsingFailed here to stop.
5969 return error.ParsingFailed;
5970 }
5971
5972 try p.errStr(switch (c) {
5973 .assign => .incompatible_assign,
5974 .init => .incompatible_init,
5975 .ret => .incompatible_return,
5976 .arg => .incompatible_arg,
5977 .test_coerce => return error.CoercionFailed,
5978 }, tok, try c.typePairStr(p, dest_ty, res.ty));
5979 try c.note(p);
5980 }
5981};
5982
5983/// expr : assignExpr (',' assignExpr)*
5984fn expr(p: *Parser) Error!Result {
5985 var expr_start = p.tok_i;
5986 var err_start = p.comp.diagnostics.list.items.len;
5987 var lhs = try p.assignExpr();
5988 if (p.tok_ids[p.tok_i] == .comma) try lhs.expect(p);
5989 while (p.eatToken(.comma)) |_| {
5990 try lhs.maybeWarnUnused(p, expr_start, err_start);
5991 expr_start = p.tok_i;
5992 err_start = p.comp.diagnostics.list.items.len;
5993
5994 var rhs = try p.assignExpr();
5995 try rhs.expect(p);
5996 try rhs.lvalConversion(p);
5997 lhs.val = rhs.val;
5998 lhs.ty = rhs.ty;
5999 try lhs.bin(p, .comma_expr, rhs);
6000 }
6001 return lhs;
6002}
6003
6004fn tokToTag(p: *Parser, tok: TokenIndex) Tree.Tag {
6005 return switch (p.tok_ids[tok]) {
6006 .equal => .assign_expr,
6007 .asterisk_equal => .mul_assign_expr,
6008 .slash_equal => .div_assign_expr,
6009 .percent_equal => .mod_assign_expr,
6010 .plus_equal => .add_assign_expr,
6011 .minus_equal => .sub_assign_expr,
6012 .angle_bracket_angle_bracket_left_equal => .shl_assign_expr,
6013 .angle_bracket_angle_bracket_right_equal => .shr_assign_expr,
6014 .ampersand_equal => .bit_and_assign_expr,
6015 .caret_equal => .bit_xor_assign_expr,
6016 .pipe_equal => .bit_or_assign_expr,
6017 .equal_equal => .equal_expr,
6018 .bang_equal => .not_equal_expr,
6019 .angle_bracket_left => .less_than_expr,
6020 .angle_bracket_left_equal => .less_than_equal_expr,
6021 .angle_bracket_right => .greater_than_expr,
6022 .angle_bracket_right_equal => .greater_than_equal_expr,
6023 .angle_bracket_angle_bracket_left => .shl_expr,
6024 .angle_bracket_angle_bracket_right => .shr_expr,
6025 .plus => .add_expr,
6026 .minus => .sub_expr,
6027 .asterisk => .mul_expr,
6028 .slash => .div_expr,
6029 .percent => .mod_expr,
6030 else => unreachable,
6031 };
6032}
6033
6034/// assignExpr
6035/// : condExpr
6036/// | unExpr ('=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=') assignExpr
6037fn assignExpr(p: *Parser) Error!Result {
6038 var lhs = try p.condExpr();
6039 if (lhs.empty(p)) return lhs;
6040
6041 const tok = p.tok_i;
6042 const eq = p.eatToken(.equal);
6043 const mul = eq orelse p.eatToken(.asterisk_equal);
6044 const div = mul orelse p.eatToken(.slash_equal);
6045 const mod = div orelse p.eatToken(.percent_equal);
6046 const add = mod orelse p.eatToken(.plus_equal);
6047 const sub = add orelse p.eatToken(.minus_equal);
6048 const shl = sub orelse p.eatToken(.angle_bracket_angle_bracket_left_equal);
6049 const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right_equal);
6050 const bit_and = shr orelse p.eatToken(.ampersand_equal);
6051 const bit_xor = bit_and orelse p.eatToken(.caret_equal);
6052 const bit_or = bit_xor orelse p.eatToken(.pipe_equal);
6053
6054 const tag = p.tokToTag(bit_or orelse return lhs);
6055 var rhs = try p.assignExpr();
6056 try rhs.expect(p);
6057 try rhs.lvalConversion(p);
6058
6059 var is_const: bool = undefined;
6060 if (!p.tmpTree().isLvalExtra(lhs.node, &is_const) or is_const) {
6061 try p.errTok(.not_assignable, tok);
6062 return error.ParsingFailed;
6063 }
6064
6065 // adjustTypes will do do lvalue conversion but we do not want that
6066 var lhs_copy = lhs;
6067 switch (tag) {
6068 .assign_expr => {}, // handle plain assignment separately
6069 .mul_assign_expr,
6070 .div_assign_expr,
6071 .mod_assign_expr,
6072 => {
6073 if (rhs.val.isZero(p.comp) and lhs.ty.isInt() and rhs.ty.isInt()) {
6074 switch (tag) {
6075 .div_assign_expr => try p.errStr(.division_by_zero, div.?, "division"),
6076 .mod_assign_expr => try p.errStr(.division_by_zero, mod.?, "remainder"),
6077 else => {},
6078 }
6079 }
6080 _ = try lhs_copy.adjustTypes(tok, &rhs, p, if (tag == .mod_assign_expr) .integer else .arithmetic);
6081 try lhs.bin(p, tag, rhs);
6082 return lhs;
6083 },
6084 .sub_assign_expr,
6085 .add_assign_expr,
6086 => {
6087 if (lhs.ty.isPtr() and rhs.ty.isInt()) {
6088 try rhs.ptrCast(p, lhs.ty);
6089 } else {
6090 _ = try lhs_copy.adjustTypes(tok, &rhs, p, .arithmetic);
6091 }
6092 try lhs.bin(p, tag, rhs);
6093 return lhs;
6094 },
6095 .shl_assign_expr,
6096 .shr_assign_expr,
6097 .bit_and_assign_expr,
6098 .bit_xor_assign_expr,
6099 .bit_or_assign_expr,
6100 => {
6101 _ = try lhs_copy.adjustTypes(tok, &rhs, p, .integer);
6102 try lhs.bin(p, tag, rhs);
6103 return lhs;
6104 },
6105 else => unreachable,
6106 }
6107
6108 try rhs.coerce(p, lhs.ty, tok, .assign);
6109
6110 try lhs.bin(p, tag, rhs);
6111 return lhs;
6112}
6113
6114/// Returns a parse error if the expression is not an integer constant
6115/// integerConstExpr : constExpr
6116fn integerConstExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
6117 const start = p.tok_i;
6118 const res = try p.constExpr(decl_folding);
6119 if (!res.ty.isInt() and res.ty.specifier != .invalid) {
6120 try p.errTok(.expected_integer_constant_expr, start);
6121 return error.ParsingFailed;
6122 }
6123 return res;
6124}
6125
6126/// Caller is responsible for issuing a diagnostic if result is invalid/unavailable
6127/// constExpr : condExpr
6128fn constExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result {
6129 const const_decl_folding = p.const_decl_folding;
6130 defer p.const_decl_folding = const_decl_folding;
6131 p.const_decl_folding = decl_folding;
6132
6133 const res = try p.condExpr();
6134 try res.expect(p);
6135
6136 if (res.ty.specifier == .invalid or res.val.opt_ref == .none) return res;
6137
6138 // saveValue sets val to unavailable
6139 var copy = res;
6140 try copy.saveValue(p);
6141 return res;
6142}
6143
6144/// condExpr : lorExpr ('?' expression? ':' condExpr)?
6145fn condExpr(p: *Parser) Error!Result {
6146 const cond_tok = p.tok_i;
6147 var cond = try p.lorExpr();
6148 if (cond.empty(p) or p.eatToken(.question_mark) == null) return cond;
6149 try cond.lvalConversion(p);
6150 const saved_eval = p.no_eval;
6151
6152 if (!cond.ty.isScalar()) {
6153 try p.errStr(.cond_expr_type, cond_tok, try p.typeStr(cond.ty));
6154 return error.ParsingFailed;
6155 }
6156
6157 // Prepare for possible binary conditional expression.
6158 const maybe_colon = p.eatToken(.colon);
6159
6160 // Depending on the value of the condition, avoid evaluating unreachable branches.
6161 var then_expr = blk: {
6162 defer p.no_eval = saved_eval;
6163 if (cond.val.opt_ref != .none and !cond.val.toBool(p.comp)) p.no_eval = true;
6164 break :blk try p.expr();
6165 };
6166 try then_expr.expect(p);
6167
6168 // If we saw a colon then this is a binary conditional expression.
6169 if (maybe_colon) |colon| {
6170 var cond_then = cond;
6171 cond_then.node = try p.addNode(.{ .tag = .cond_dummy_expr, .ty = cond.ty, .data = .{ .un = cond.node } });
6172 _ = try cond_then.adjustTypes(colon, &then_expr, p, .conditional);
6173 cond.ty = then_expr.ty;
6174 cond.node = try p.addNode(.{
6175 .tag = .binary_cond_expr,
6176 .ty = cond.ty,
6177 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ cond_then.node, then_expr.node })).start } },
6178 });
6179 return cond;
6180 }
6181
6182 const colon = try p.expectToken(.colon);
6183 var else_expr = blk: {
6184 defer p.no_eval = saved_eval;
6185 if (cond.val.opt_ref != .none and cond.val.toBool(p.comp)) p.no_eval = true;
6186 break :blk try p.condExpr();
6187 };
6188 try else_expr.expect(p);
6189
6190 _ = try then_expr.adjustTypes(colon, &else_expr, p, .conditional);
6191
6192 if (cond.val.opt_ref != .none) {
6193 cond.val = if (cond.val.toBool(p.comp)) then_expr.val else else_expr.val;
6194 } else {
6195 try then_expr.saveValue(p);
6196 try else_expr.saveValue(p);
6197 }
6198 cond.ty = then_expr.ty;
6199 cond.node = try p.addNode(.{
6200 .tag = .cond_expr,
6201 .ty = cond.ty,
6202 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
6203 });
6204 return cond;
6205}
6206
6207/// lorExpr : landExpr ('||' landExpr)*
6208fn lorExpr(p: *Parser) Error!Result {
6209 var lhs = try p.landExpr();
6210 if (lhs.empty(p)) return lhs;
6211 const saved_eval = p.no_eval;
6212 defer p.no_eval = saved_eval;
6213
6214 while (p.eatToken(.pipe_pipe)) |tok| {
6215 if (lhs.val.opt_ref != .none and lhs.val.toBool(p.comp)) p.no_eval = true;
6216 var rhs = try p.landExpr();
6217 try rhs.expect(p);
6218
6219 if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
6220 const res = lhs.val.toBool(p.comp) or rhs.val.toBool(p.comp);
6221 lhs.val = Value.fromBool(res);
6222 }
6223 try lhs.boolRes(p, .bool_or_expr, rhs);
6224 }
6225 return lhs;
6226}
6227
6228/// landExpr : orExpr ('&&' orExpr)*
6229fn landExpr(p: *Parser) Error!Result {
6230 var lhs = try p.orExpr();
6231 if (lhs.empty(p)) return lhs;
6232 const saved_eval = p.no_eval;
6233 defer p.no_eval = saved_eval;
6234
6235 while (p.eatToken(.ampersand_ampersand)) |tok| {
6236 if (lhs.val.opt_ref != .none and !lhs.val.toBool(p.comp)) p.no_eval = true;
6237 var rhs = try p.orExpr();
6238 try rhs.expect(p);
6239
6240 if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) {
6241 const res = lhs.val.toBool(p.comp) and rhs.val.toBool(p.comp);
6242 lhs.val = Value.fromBool(res);
6243 }
6244 try lhs.boolRes(p, .bool_and_expr, rhs);
6245 }
6246 return lhs;
6247}
6248
6249/// orExpr : xorExpr ('|' xorExpr)*
6250fn orExpr(p: *Parser) Error!Result {
6251 var lhs = try p.xorExpr();
6252 if (lhs.empty(p)) return lhs;
6253 while (p.eatToken(.pipe)) |tok| {
6254 var rhs = try p.xorExpr();
6255 try rhs.expect(p);
6256
6257 if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
6258 lhs.val = try lhs.val.bitOr(rhs.val, p.comp);
6259 }
6260 try lhs.bin(p, .bit_or_expr, rhs);
6261 }
6262 return lhs;
6263}
6264
6265/// xorExpr : andExpr ('^' andExpr)*
6266fn xorExpr(p: *Parser) Error!Result {
6267 var lhs = try p.andExpr();
6268 if (lhs.empty(p)) return lhs;
6269 while (p.eatToken(.caret)) |tok| {
6270 var rhs = try p.andExpr();
6271 try rhs.expect(p);
6272
6273 if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
6274 lhs.val = try lhs.val.bitXor(rhs.val, p.comp);
6275 }
6276 try lhs.bin(p, .bit_xor_expr, rhs);
6277 }
6278 return lhs;
6279}
6280
6281/// andExpr : eqExpr ('&' eqExpr)*
6282fn andExpr(p: *Parser) Error!Result {
6283 var lhs = try p.eqExpr();
6284 if (lhs.empty(p)) return lhs;
6285 while (p.eatToken(.ampersand)) |tok| {
6286 var rhs = try p.eqExpr();
6287 try rhs.expect(p);
6288
6289 if (try lhs.adjustTypes(tok, &rhs, p, .integer)) {
6290 lhs.val = try lhs.val.bitAnd(rhs.val, p.comp);
6291 }
6292 try lhs.bin(p, .bit_and_expr, rhs);
6293 }
6294 return lhs;
6295}
6296
6297/// eqExpr : compExpr (('==' | '!=') compExpr)*
6298fn eqExpr(p: *Parser) Error!Result {
6299 var lhs = try p.compExpr();
6300 if (lhs.empty(p)) return lhs;
6301 while (true) {
6302 const eq = p.eatToken(.equal_equal);
6303 const ne = eq orelse p.eatToken(.bang_equal);
6304 const tag = p.tokToTag(ne orelse break);
6305 var rhs = try p.compExpr();
6306 try rhs.expect(p);
6307
6308 if (try lhs.adjustTypes(ne.?, &rhs, p, .equality)) {
6309 const op: std.math.CompareOperator = if (tag == .equal_expr) .eq else .neq;
6310 const res = lhs.val.compare(op, rhs.val, p.comp);
6311 lhs.val = Value.fromBool(res);
6312 }
6313 try lhs.boolRes(p, tag, rhs);
6314 }
6315 return lhs;
6316}
6317
6318/// compExpr : shiftExpr (('<' | '<=' | '>' | '>=') shiftExpr)*
6319fn compExpr(p: *Parser) Error!Result {
6320 var lhs = try p.shiftExpr();
6321 if (lhs.empty(p)) return lhs;
6322 while (true) {
6323 const lt = p.eatToken(.angle_bracket_left);
6324 const le = lt orelse p.eatToken(.angle_bracket_left_equal);
6325 const gt = le orelse p.eatToken(.angle_bracket_right);
6326 const ge = gt orelse p.eatToken(.angle_bracket_right_equal);
6327 const tag = p.tokToTag(ge orelse break);
6328 var rhs = try p.shiftExpr();
6329 try rhs.expect(p);
6330
6331 if (try lhs.adjustTypes(ge.?, &rhs, p, .relational)) {
6332 const op: std.math.CompareOperator = switch (tag) {
6333 .less_than_expr => .lt,
6334 .less_than_equal_expr => .lte,
6335 .greater_than_expr => .gt,
6336 .greater_than_equal_expr => .gte,
6337 else => unreachable,
6338 };
6339 const res = lhs.val.compare(op, rhs.val, p.comp);
6340 lhs.val = Value.fromBool(res);
6341 }
6342 try lhs.boolRes(p, tag, rhs);
6343 }
6344 return lhs;
6345}
6346
6347/// shiftExpr : addExpr (('<<' | '>>') addExpr)*
6348fn shiftExpr(p: *Parser) Error!Result {
6349 var lhs = try p.addExpr();
6350 if (lhs.empty(p)) return lhs;
6351 while (true) {
6352 const shl = p.eatToken(.angle_bracket_angle_bracket_left);
6353 const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right);
6354 const tag = p.tokToTag(shr orelse break);
6355 var rhs = try p.addExpr();
6356 try rhs.expect(p);
6357
6358 if (try lhs.adjustTypes(shr.?, &rhs, p, .integer)) {
6359 if (shl != null) {
6360 if (try lhs.val.shl(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(shl.?, lhs);
6361 } else {
6362 lhs.val = try lhs.val.shr(rhs.val, lhs.ty, p.comp);
6363 }
6364 }
6365 try lhs.bin(p, tag, rhs);
6366 }
6367 return lhs;
6368}
6369
6370/// addExpr : mulExpr (('+' | '-') mulExpr)*
6371fn addExpr(p: *Parser) Error!Result {
6372 var lhs = try p.mulExpr();
6373 if (lhs.empty(p)) return lhs;
6374 while (true) {
6375 const plus = p.eatToken(.plus);
6376 const minus = plus orelse p.eatToken(.minus);
6377 const tag = p.tokToTag(minus orelse break);
6378 var rhs = try p.mulExpr();
6379 try rhs.expect(p);
6380
6381 const lhs_ty = lhs.ty;
6382 if (try lhs.adjustTypes(minus.?, &rhs, p, if (plus != null) .add else .sub)) {
6383 if (plus != null) {
6384 if (try lhs.val.add(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(plus.?, lhs);
6385 } else {
6386 if (try lhs.val.sub(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(minus.?, lhs);
6387 }
6388 }
6389 if (lhs.ty.specifier != .invalid and lhs_ty.isPtr() and !lhs_ty.isVoidStar() and lhs_ty.elemType().hasIncompleteSize()) {
6390 try p.errStr(.ptr_arithmetic_incomplete, minus.?, try p.typeStr(lhs_ty.elemType()));
6391 lhs.ty = Type.invalid;
6392 }
6393 try lhs.bin(p, tag, rhs);
6394 }
6395 return lhs;
6396}
6397
6398/// mulExpr : castExpr (('*' | '/' | '%') castExpr)*´
6399fn mulExpr(p: *Parser) Error!Result {
6400 var lhs = try p.castExpr();
6401 if (lhs.empty(p)) return lhs;
6402 while (true) {
6403 const mul = p.eatToken(.asterisk);
6404 const div = mul orelse p.eatToken(.slash);
6405 const percent = div orelse p.eatToken(.percent);
6406 const tag = p.tokToTag(percent orelse break);
6407 var rhs = try p.castExpr();
6408 try rhs.expect(p);
6409
6410 if (rhs.val.isZero(p.comp) and mul == null and !p.no_eval and lhs.ty.isInt() and rhs.ty.isInt()) {
6411 const err_tag: Diagnostics.Tag = if (p.in_macro) .division_by_zero_macro else .division_by_zero;
6412 lhs.val = .{};
6413 if (div != null) {
6414 try p.errStr(err_tag, div.?, "division");
6415 } else {
6416 try p.errStr(err_tag, percent.?, "remainder");
6417 }
6418 if (p.in_macro) return error.ParsingFailed;
6419 }
6420
6421 if (try lhs.adjustTypes(percent.?, &rhs, p, if (tag == .mod_expr) .integer else .arithmetic)) {
6422 if (mul != null) {
6423 if (try lhs.val.mul(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs);
6424 } else if (div != null) {
6425 if (try lhs.val.div(lhs.val, rhs.val, lhs.ty, p.comp)) try p.errOverflow(mul.?, lhs);
6426 } else {
6427 var res = try Value.rem(lhs.val, rhs.val, lhs.ty, p.comp);
6428 if (res.opt_ref == .none) {
6429 if (p.in_macro) {
6430 // match clang behavior by defining invalid remainder to be zero in macros
6431 res = Value.zero;
6432 } else {
6433 try lhs.saveValue(p);
6434 try rhs.saveValue(p);
6435 }
6436 }
6437 lhs.val = res;
6438 }
6439 }
6440
6441 try lhs.bin(p, tag, rhs);
6442 }
6443 return lhs;
6444}
6445
6446/// This will always be the last message, if present
6447fn removeUnusedWarningForTok(p: *Parser, last_expr_tok: TokenIndex) void {
6448 if (last_expr_tok == 0) return;
6449 if (p.comp.diagnostics.list.items.len == 0) return;
6450
6451 const last_expr_loc = p.pp.tokens.items(.loc)[last_expr_tok];
6452 const last_msg = p.comp.diagnostics.list.items[p.comp.diagnostics.list.items.len - 1];
6453
6454 if (last_msg.tag == .unused_value and last_msg.loc.eql(last_expr_loc)) {
6455 p.comp.diagnostics.list.items.len = p.comp.diagnostics.list.items.len - 1;
6456 }
6457}
6458
6459/// castExpr
6460/// : '(' compoundStmt ')'
6461/// | '(' typeName ')' castExpr
6462/// | '(' typeName ')' '{' initializerItems '}'
6463/// | __builtin_choose_expr '(' integerConstExpr ',' assignExpr ',' assignExpr ')'
6464/// | __builtin_va_arg '(' assignExpr ',' typeName ')'
6465/// | __builtin_offsetof '(' typeName ',' offsetofMemberDesignator ')'
6466/// | __builtin_bitoffsetof '(' typeName ',' offsetofMemberDesignator ')'
6467/// | unExpr
6468fn castExpr(p: *Parser) Error!Result {
6469 if (p.eatToken(.l_paren)) |l_paren| cast_expr: {
6470 if (p.tok_ids[p.tok_i] == .l_brace) {
6471 try p.err(.gnu_statement_expression);
6472 if (p.func.ty == null) {
6473 try p.err(.stmt_expr_not_allowed_file_scope);
6474 return error.ParsingFailed;
6475 }
6476 var stmt_expr_state: StmtExprState = .{};
6477 const body_node = (try p.compoundStmt(false, &stmt_expr_state)).?; // compoundStmt only returns null if .l_brace isn't the first token
6478 p.removeUnusedWarningForTok(stmt_expr_state.last_expr_tok);
6479
6480 var res = Result{
6481 .node = body_node,
6482 .ty = stmt_expr_state.last_expr_res.ty,
6483 .val = stmt_expr_state.last_expr_res.val,
6484 };
6485 try p.expectClosing(l_paren, .r_paren);
6486 try res.un(p, .stmt_expr);
6487 return res;
6488 }
6489 const ty = (try p.typeName()) orelse {
6490 p.tok_i -= 1;
6491 break :cast_expr;
6492 };
6493 try p.expectClosing(l_paren, .r_paren);
6494
6495 if (p.tok_ids[p.tok_i] == .l_brace) {
6496 // Compound literal; handled in unExpr
6497 p.tok_i = l_paren;
6498 break :cast_expr;
6499 }
6500
6501 const operand_tok = p.tok_i;
6502 var operand = try p.castExpr();
6503 try operand.expect(p);
6504 try operand.lvalConversion(p);
6505 try operand.castType(p, ty, operand_tok, l_paren);
6506 return operand;
6507 }
6508 switch (p.tok_ids[p.tok_i]) {
6509 .builtin_choose_expr => return p.builtinChooseExpr(),
6510 .builtin_va_arg => return p.builtinVaArg(),
6511 .builtin_offsetof => return p.builtinOffsetof(false),
6512 .builtin_bitoffsetof => return p.builtinOffsetof(true),
6513 .builtin_types_compatible_p => return p.typesCompatible(),
6514 // TODO: other special-cased builtins
6515 else => {},
6516 }
6517 return p.unExpr();
6518}
6519
6520fn typesCompatible(p: *Parser) Error!Result {
6521 p.tok_i += 1;
6522 const l_paren = try p.expectToken(.l_paren);
6523
6524 const first = (try p.typeName()) orelse {
6525 try p.err(.expected_type);
6526 p.skipTo(.r_paren);
6527 return error.ParsingFailed;
6528 };
6529 const lhs = try p.addNode(.{ .tag = .invalid, .ty = first, .data = undefined });
6530 _ = try p.expectToken(.comma);
6531
6532 const second = (try p.typeName()) orelse {
6533 try p.err(.expected_type);
6534 p.skipTo(.r_paren);
6535 return error.ParsingFailed;
6536 };
6537 const rhs = try p.addNode(.{ .tag = .invalid, .ty = second, .data = undefined });
6538
6539 try p.expectClosing(l_paren, .r_paren);
6540
6541 var first_unqual = first.canonicalize(.standard);
6542 first_unqual.qual.@"const" = false;
6543 first_unqual.qual.@"volatile" = false;
6544 var second_unqual = second.canonicalize(.standard);
6545 second_unqual.qual.@"const" = false;
6546 second_unqual.qual.@"volatile" = false;
6547
6548 const compatible = first_unqual.eql(second_unqual, p.comp, true);
6549
6550 const res = Result{
6551 .val = Value.fromBool(compatible),
6552 .node = try p.addNode(.{ .tag = .builtin_types_compatible_p, .ty = Type.int, .data = .{ .bin = .{
6553 .lhs = lhs,
6554 .rhs = rhs,
6555 } } }),
6556 };
6557 try p.value_map.put(res.node, res.val);
6558 return res;
6559}
6560
6561fn builtinChooseExpr(p: *Parser) Error!Result {
6562 p.tok_i += 1;
6563 const l_paren = try p.expectToken(.l_paren);
6564 const cond_tok = p.tok_i;
6565 var cond = try p.integerConstExpr(.no_const_decl_folding);
6566 if (cond.val.opt_ref == .none) {
6567 try p.errTok(.builtin_choose_cond, cond_tok);
6568 return error.ParsingFailed;
6569 }
6570
6571 _ = try p.expectToken(.comma);
6572
6573 var then_expr = if (cond.val.toBool(p.comp)) try p.assignExpr() else try p.parseNoEval(assignExpr);
6574 try then_expr.expect(p);
6575
6576 _ = try p.expectToken(.comma);
6577
6578 var else_expr = if (!cond.val.toBool(p.comp)) try p.assignExpr() else try p.parseNoEval(assignExpr);
6579 try else_expr.expect(p);
6580
6581 try p.expectClosing(l_paren, .r_paren);
6582
6583 if (cond.val.toBool(p.comp)) {
6584 cond.val = then_expr.val;
6585 cond.ty = then_expr.ty;
6586 } else {
6587 cond.val = else_expr.val;
6588 cond.ty = else_expr.ty;
6589 }
6590 cond.node = try p.addNode(.{
6591 .tag = .builtin_choose_expr,
6592 .ty = cond.ty,
6593 .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } },
6594 });
6595 return cond;
6596}
6597
6598fn builtinVaArg(p: *Parser) Error!Result {
6599 const builtin_tok = p.tok_i;
6600 p.tok_i += 1;
6601
6602 const l_paren = try p.expectToken(.l_paren);
6603 const va_list_tok = p.tok_i;
6604 var va_list = try p.assignExpr();
6605 try va_list.expect(p);
6606 try va_list.lvalConversion(p);
6607
6608 _ = try p.expectToken(.comma);
6609
6610 const ty = (try p.typeName()) orelse {
6611 try p.err(.expected_type);
6612 return error.ParsingFailed;
6613 };
6614 try p.expectClosing(l_paren, .r_paren);
6615
6616 if (!va_list.ty.eql(p.comp.types.va_list, p.comp, true)) {
6617 try p.errStr(.incompatible_va_arg, va_list_tok, try p.typeStr(va_list.ty));
6618 return error.ParsingFailed;
6619 }
6620
6621 return Result{ .ty = ty, .node = try p.addNode(.{
6622 .tag = .special_builtin_call_one,
6623 .ty = ty,
6624 .data = .{ .decl = .{ .name = builtin_tok, .node = va_list.node } },
6625 }) };
6626}
6627
6628fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result {
6629 const builtin_tok = p.tok_i;
6630 p.tok_i += 1;
6631
6632 const l_paren = try p.expectToken(.l_paren);
6633 const ty_tok = p.tok_i;
6634
6635 const ty = (try p.typeName()) orelse {
6636 try p.err(.expected_type);
6637 p.skipTo(.r_paren);
6638 return error.ParsingFailed;
6639 };
6640
6641 if (!ty.isRecord()) {
6642 try p.errStr(.offsetof_ty, ty_tok, try p.typeStr(ty));
6643 p.skipTo(.r_paren);
6644 return error.ParsingFailed;
6645 } else if (ty.hasIncompleteSize()) {
6646 try p.errStr(.offsetof_incomplete, ty_tok, try p.typeStr(ty));
6647 p.skipTo(.r_paren);
6648 return error.ParsingFailed;
6649 }
6650
6651 _ = try p.expectToken(.comma);
6652
6653 const offsetof_expr = try p.offsetofMemberDesignator(ty, want_bits);
6654
6655 try p.expectClosing(l_paren, .r_paren);
6656
6657 return Result{
6658 .ty = p.comp.types.size,
6659 .val = offsetof_expr.val,
6660 .node = try p.addNode(.{
6661 .tag = .special_builtin_call_one,
6662 .ty = p.comp.types.size,
6663 .data = .{ .decl = .{ .name = builtin_tok, .node = offsetof_expr.node } },
6664 }),
6665 };
6666}
6667
6668/// offsetofMemberDesignator: IDENTIFIER ('.' IDENTIFIER | '[' expr ']' )*
6669fn offsetofMemberDesignator(p: *Parser, base_ty: Type, want_bits: bool) Error!Result {
6670 errdefer p.skipTo(.r_paren);
6671 const base_field_name_tok = try p.expectIdentifier();
6672 const base_field_name = try StrInt.intern(p.comp, p.tokSlice(base_field_name_tok));
6673 try p.validateFieldAccess(base_ty, base_ty, base_field_name_tok, base_field_name);
6674 const base_node = try p.addNode(.{ .tag = .default_init_expr, .ty = base_ty, .data = undefined });
6675
6676 var cur_offset: u64 = 0;
6677 const base_record_ty = base_ty.canonicalize(.standard);
6678 var lhs = try p.fieldAccessExtra(base_node, base_record_ty, base_field_name, false, &cur_offset);
6679
6680 var total_offset = cur_offset;
6681 while (true) switch (p.tok_ids[p.tok_i]) {
6682 .period => {
6683 p.tok_i += 1;
6684 const field_name_tok = try p.expectIdentifier();
6685 const field_name = try StrInt.intern(p.comp, p.tokSlice(field_name_tok));
6686
6687 if (!lhs.ty.isRecord()) {
6688 try p.errStr(.offsetof_ty, field_name_tok, try p.typeStr(lhs.ty));
6689 return error.ParsingFailed;
6690 }
6691 try p.validateFieldAccess(lhs.ty, lhs.ty, field_name_tok, field_name);
6692 const record_ty = lhs.ty.canonicalize(.standard);
6693 lhs = try p.fieldAccessExtra(lhs.node, record_ty, field_name, false, &cur_offset);
6694 total_offset += cur_offset;
6695 },
6696 .l_bracket => {
6697 const l_bracket_tok = p.tok_i;
6698 p.tok_i += 1;
6699 var index = try p.expr();
6700 try index.expect(p);
6701 _ = try p.expectClosing(l_bracket_tok, .r_bracket);
6702
6703 if (!lhs.ty.isArray()) {
6704 try p.errStr(.offsetof_array, l_bracket_tok, try p.typeStr(lhs.ty));
6705 return error.ParsingFailed;
6706 }
6707 var ptr = lhs;
6708 try ptr.lvalConversion(p);
6709 try index.lvalConversion(p);
6710
6711 if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket_tok);
6712 try p.checkArrayBounds(index, lhs, l_bracket_tok);
6713
6714 try index.saveValue(p);
6715 try ptr.bin(p, .array_access_expr, index);
6716 lhs = ptr;
6717 },
6718 else => break,
6719 };
6720 const val = try Value.int(if (want_bits) total_offset else total_offset / 8, p.comp);
6721 return Result{ .ty = base_ty, .val = val, .node = lhs.node };
6722}
6723
6724/// unExpr
6725/// : (compoundLiteral | primaryExpr) suffixExpr*
6726/// | '&&' IDENTIFIER
6727/// | ('&' | '*' | '+' | '-' | '~' | '!' | '++' | '--' | keyword_extension | keyword_imag | keyword_real) castExpr
6728/// | keyword_sizeof unExpr
6729/// | keyword_sizeof '(' typeName ')'
6730/// | keyword_alignof '(' typeName ')'
6731/// | keyword_c23_alignof '(' typeName ')'
6732fn unExpr(p: *Parser) Error!Result {
6733 const tok = p.tok_i;
6734 switch (p.tok_ids[tok]) {
6735 .ampersand_ampersand => {
6736 const address_tok = p.tok_i;
6737 p.tok_i += 1;
6738 const name_tok = try p.expectIdentifier();
6739 try p.errTok(.gnu_label_as_value, address_tok);
6740 p.contains_address_of_label = true;
6741
6742 const str = p.tokSlice(name_tok);
6743 if (p.findLabel(str) == null) {
6744 try p.labels.append(.{ .unresolved_goto = name_tok });
6745 }
6746 const elem_ty = try p.arena.create(Type);
6747 elem_ty.* = .{ .specifier = .void };
6748 const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } };
6749 return Result{
6750 .node = try p.addNode(.{
6751 .tag = .addr_of_label,
6752 .data = .{ .decl_ref = name_tok },
6753 .ty = result_ty,
6754 }),
6755 .ty = result_ty,
6756 };
6757 },
6758 .ampersand => {
6759 if (p.in_macro) {
6760 try p.err(.invalid_preproc_operator);
6761 return error.ParsingFailed;
6762 }
6763 p.tok_i += 1;
6764 var operand = try p.castExpr();
6765 try operand.expect(p);
6766
6767 const tree = p.tmpTree();
6768 if (p.getNode(operand.node, .member_access_expr) orelse
6769 p.getNode(operand.node, .member_access_ptr_expr)) |member_node|
6770 {
6771 if (tree.isBitfield(member_node)) try p.errTok(.addr_of_bitfield, tok);
6772 }
6773 if (!tree.isLval(operand.node)) {
6774 try p.errTok(.addr_of_rvalue, tok);
6775 }
6776 if (operand.ty.qual.register) try p.errTok(.addr_of_register, tok);
6777
6778 const elem_ty = try p.arena.create(Type);
6779 elem_ty.* = operand.ty;
6780 operand.ty = Type{
6781 .specifier = .pointer,
6782 .data = .{ .sub_type = elem_ty },
6783 };
6784 try operand.saveValue(p);
6785 try operand.un(p, .addr_of_expr);
6786 return operand;
6787 },
6788 .asterisk => {
6789 const asterisk_loc = p.tok_i;
6790 p.tok_i += 1;
6791 var operand = try p.castExpr();
6792 try operand.expect(p);
6793
6794 if (operand.ty.isArray() or operand.ty.isPtr() or operand.ty.isFunc()) {
6795 try operand.lvalConversion(p);
6796 operand.ty = operand.ty.elemType();
6797 } else {
6798 try p.errTok(.indirection_ptr, tok);
6799 }
6800 if (operand.ty.hasIncompleteSize() and !operand.ty.is(.void)) {
6801 try p.errStr(.deref_incomplete_ty_ptr, asterisk_loc, try p.typeStr(operand.ty));
6802 }
6803 operand.ty.qual = .{};
6804 try operand.un(p, .deref_expr);
6805 return operand;
6806 },
6807 .plus => {
6808 p.tok_i += 1;
6809
6810 var operand = try p.castExpr();
6811 try operand.expect(p);
6812 try operand.lvalConversion(p);
6813 if (!operand.ty.isInt() and !operand.ty.isFloat())
6814 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6815
6816 try operand.usualUnaryConversion(p, tok);
6817
6818 return operand;
6819 },
6820 .minus => {
6821 p.tok_i += 1;
6822
6823 var operand = try p.castExpr();
6824 try operand.expect(p);
6825 try operand.lvalConversion(p);
6826 if (!operand.ty.isInt() and !operand.ty.isFloat())
6827 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6828
6829 try operand.usualUnaryConversion(p, tok);
6830 if (operand.val.is(.int, p.comp)) {
6831 _ = try operand.val.sub(Value.zero, operand.val, operand.ty, p.comp);
6832 } else {
6833 operand.val = .{};
6834 }
6835 try operand.un(p, .negate_expr);
6836 return operand;
6837 },
6838 .plus_plus => {
6839 p.tok_i += 1;
6840
6841 var operand = try p.castExpr();
6842 try operand.expect(p);
6843 if (!operand.ty.isScalar())
6844 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6845 if (operand.ty.isComplex())
6846 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
6847
6848 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
6849 try p.errTok(.not_assignable, tok);
6850 return error.ParsingFailed;
6851 }
6852 try operand.usualUnaryConversion(p, tok);
6853
6854 if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) {
6855 if (try operand.val.add(operand.val, Value.one, operand.ty, p.comp))
6856 try p.errOverflow(tok, operand);
6857 } else {
6858 operand.val = .{};
6859 }
6860
6861 try operand.un(p, .pre_inc_expr);
6862 return operand;
6863 },
6864 .minus_minus => {
6865 p.tok_i += 1;
6866
6867 var operand = try p.castExpr();
6868 try operand.expect(p);
6869 if (!operand.ty.isScalar())
6870 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6871 if (operand.ty.isComplex())
6872 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
6873
6874 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
6875 try p.errTok(.not_assignable, tok);
6876 return error.ParsingFailed;
6877 }
6878 try operand.usualUnaryConversion(p, tok);
6879
6880 if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) {
6881 if (try operand.val.sub(operand.val, Value.one, operand.ty, p.comp))
6882 try p.errOverflow(tok, operand);
6883 } else {
6884 operand.val = .{};
6885 }
6886
6887 try operand.un(p, .pre_dec_expr);
6888 return operand;
6889 },
6890 .tilde => {
6891 p.tok_i += 1;
6892
6893 var operand = try p.castExpr();
6894 try operand.expect(p);
6895 try operand.lvalConversion(p);
6896 try operand.usualUnaryConversion(p, tok);
6897 if (operand.ty.isInt()) {
6898 if (operand.val.is(.int, p.comp)) {
6899 operand.val = try operand.val.bitNot(operand.ty, p.comp);
6900 }
6901 } else {
6902 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6903 operand.val = .{};
6904 }
6905 try operand.un(p, .bit_not_expr);
6906 return operand;
6907 },
6908 .bang => {
6909 p.tok_i += 1;
6910
6911 var operand = try p.castExpr();
6912 try operand.expect(p);
6913 try operand.lvalConversion(p);
6914 if (!operand.ty.isScalar())
6915 try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty));
6916
6917 try operand.usualUnaryConversion(p, tok);
6918 if (operand.val.is(.int, p.comp)) {
6919 operand.val = Value.fromBool(!operand.val.toBool(p.comp));
6920 } else if (operand.val.opt_ref == .null) {
6921 operand.val = Value.one;
6922 } else {
6923 if (operand.ty.isDecayed()) {
6924 operand.val = Value.zero;
6925 } else {
6926 operand.val = .{};
6927 }
6928 }
6929 operand.ty = .{ .specifier = .int };
6930 try operand.un(p, .bool_not_expr);
6931 return operand;
6932 },
6933 .keyword_sizeof => {
6934 p.tok_i += 1;
6935 const expected_paren = p.tok_i;
6936 var res = Result{};
6937 if (try p.typeName()) |ty| {
6938 res.ty = ty;
6939 try p.errTok(.expected_parens_around_typename, expected_paren);
6940 } else if (p.eatToken(.l_paren)) |l_paren| {
6941 if (try p.typeName()) |ty| {
6942 res.ty = ty;
6943 try p.expectClosing(l_paren, .r_paren);
6944 } else {
6945 p.tok_i = expected_paren;
6946 res = try p.parseNoEval(unExpr);
6947 }
6948 } else {
6949 res = try p.parseNoEval(unExpr);
6950 }
6951
6952 if (res.ty.is(.void)) {
6953 try p.errStr(.pointer_arith_void, tok, "sizeof");
6954 } else if (res.ty.isDecayed()) {
6955 const array_ty = res.ty.originalTypeOfDecayedArray();
6956 const err_str = try p.typePairStrExtra(res.ty, " instead of ", array_ty);
6957 try p.errStr(.sizeof_array_arg, tok, err_str);
6958 }
6959 if (res.ty.sizeof(p.comp)) |size| {
6960 if (size == 0) {
6961 try p.errTok(.sizeof_returns_zero, tok);
6962 }
6963 res.val = try Value.int(size, p.comp);
6964 res.ty = p.comp.types.size;
6965 } else {
6966 res.val = .{};
6967 if (res.ty.hasIncompleteSize()) {
6968 try p.errStr(.invalid_sizeof, expected_paren - 1, try p.typeStr(res.ty));
6969 res.ty = Type.invalid;
6970 } else {
6971 res.ty = p.comp.types.size;
6972 }
6973 }
6974 try res.un(p, .sizeof_expr);
6975 return res;
6976 },
6977 .keyword_alignof,
6978 .keyword_alignof1,
6979 .keyword_alignof2,
6980 .keyword_c23_alignof,
6981 => {
6982 p.tok_i += 1;
6983 const expected_paren = p.tok_i;
6984 var res = Result{};
6985 if (try p.typeName()) |ty| {
6986 res.ty = ty;
6987 try p.errTok(.expected_parens_around_typename, expected_paren);
6988 } else if (p.eatToken(.l_paren)) |l_paren| {
6989 if (try p.typeName()) |ty| {
6990 res.ty = ty;
6991 try p.expectClosing(l_paren, .r_paren);
6992 } else {
6993 p.tok_i = expected_paren;
6994 res = try p.parseNoEval(unExpr);
6995 try p.errTok(.alignof_expr, expected_paren);
6996 }
6997 } else {
6998 res = try p.parseNoEval(unExpr);
6999 try p.errTok(.alignof_expr, expected_paren);
7000 }
7001
7002 if (res.ty.is(.void)) {
7003 try p.errStr(.pointer_arith_void, tok, "alignof");
7004 }
7005 if (res.ty.alignable()) {
7006 res.val = try Value.int(res.ty.alignof(p.comp), p.comp);
7007 res.ty = p.comp.types.size;
7008 } else {
7009 try p.errStr(.invalid_alignof, expected_paren, try p.typeStr(res.ty));
7010 res.ty = Type.invalid;
7011 }
7012 try res.un(p, .alignof_expr);
7013 return res;
7014 },
7015 .keyword_extension => {
7016 p.tok_i += 1;
7017 const saved_extension = p.extension_suppressed;
7018 defer p.extension_suppressed = saved_extension;
7019 p.extension_suppressed = true;
7020
7021 var child = try p.castExpr();
7022 try child.expect(p);
7023 return child;
7024 },
7025 .keyword_imag1, .keyword_imag2 => {
7026 const imag_tok = p.tok_i;
7027 p.tok_i += 1;
7028
7029 var operand = try p.castExpr();
7030 try operand.expect(p);
7031 try operand.lvalConversion(p);
7032 if (!operand.ty.isInt() and !operand.ty.isFloat()) {
7033 try p.errStr(.invalid_imag, imag_tok, try p.typeStr(operand.ty));
7034 }
7035 if (operand.ty.isReal()) {
7036 switch (p.comp.langopts.emulate) {
7037 .msvc => {}, // Doesn't support `_Complex` or `__imag` in the first place
7038 .gcc => operand.val = Value.zero,
7039 .clang => {
7040 if (operand.val.is(.int, p.comp)) {
7041 operand.val = Value.zero;
7042 } else {
7043 operand.val = .{};
7044 }
7045 },
7046 }
7047 }
7048 // convert _Complex T to T
7049 operand.ty = operand.ty.makeReal();
7050 try operand.un(p, .imag_expr);
7051 return operand;
7052 },
7053 .keyword_real1, .keyword_real2 => {
7054 const real_tok = p.tok_i;
7055 p.tok_i += 1;
7056
7057 var operand = try p.castExpr();
7058 try operand.expect(p);
7059 try operand.lvalConversion(p);
7060 if (!operand.ty.isInt() and !operand.ty.isFloat()) {
7061 try p.errStr(.invalid_real, real_tok, try p.typeStr(operand.ty));
7062 }
7063 // convert _Complex T to T
7064 operand.ty = operand.ty.makeReal();
7065 try operand.un(p, .real_expr);
7066 return operand;
7067 },
7068 else => {
7069 var lhs = try p.compoundLiteral();
7070 if (lhs.empty(p)) {
7071 lhs = try p.primaryExpr();
7072 if (lhs.empty(p)) return lhs;
7073 }
7074 while (true) {
7075 const suffix = try p.suffixExpr(lhs);
7076 if (suffix.empty(p)) break;
7077 lhs = suffix;
7078 }
7079 return lhs;
7080 },
7081 }
7082}
7083
7084/// compoundLiteral
7085/// : '(' storageClassSpec* type_name ')' '{' initializer_list '}'
7086/// | '(' storageClassSpec* type_name ')' '{' initializer_list ',' '}'
7087fn compoundLiteral(p: *Parser) Error!Result {
7088 const l_paren = p.eatToken(.l_paren) orelse return Result{};
7089
7090 var d: DeclSpec = .{ .ty = .{ .specifier = undefined } };
7091 const any = if (p.comp.langopts.standard.atLeast(.c23))
7092 try p.storageClassSpec(&d)
7093 else
7094 false;
7095
7096 const tag: Tree.Tag = switch (d.storage_class) {
7097 .static => if (d.thread_local != null)
7098 .static_thread_local_compound_literal_expr
7099 else
7100 .static_compound_literal_expr,
7101 .register, .none => if (d.thread_local != null)
7102 .thread_local_compound_literal_expr
7103 else
7104 .compound_literal_expr,
7105 .auto, .@"extern", .typedef => |tok| blk: {
7106 try p.errStr(.invalid_compound_literal_storage_class, tok, @tagName(d.storage_class));
7107 d.storage_class = .none;
7108 break :blk if (d.thread_local != null)
7109 .thread_local_compound_literal_expr
7110 else
7111 .compound_literal_expr;
7112 },
7113 };
7114
7115 var ty = (try p.typeName()) orelse {
7116 p.tok_i = l_paren;
7117 if (any) {
7118 try p.err(.expected_type);
7119 return error.ParsingFailed;
7120 }
7121 return Result{};
7122 };
7123 if (d.storage_class == .register) ty.qual.register = true;
7124 try p.expectClosing(l_paren, .r_paren);
7125
7126 if (ty.isFunc()) {
7127 try p.err(.func_init);
7128 } else if (ty.is(.variable_len_array)) {
7129 try p.err(.vla_init);
7130 } else if (ty.hasIncompleteSize() and !ty.is(.incomplete_array)) {
7131 try p.errStr(.variable_incomplete_ty, p.tok_i, try p.typeStr(ty));
7132 return error.ParsingFailed;
7133 }
7134 var init_list_expr = try p.initializer(ty);
7135 if (d.constexpr) |_| {
7136 // TODO error if not constexpr
7137 }
7138 try init_list_expr.un(p, tag);
7139 return init_list_expr;
7140}
7141
7142/// suffixExpr
7143/// : '[' expr ']'
7144/// | '(' argumentExprList? ')'
7145/// | '.' IDENTIFIER
7146/// | '->' IDENTIFIER
7147/// | '++'
7148/// | '--'
7149/// argumentExprList : assignExpr (',' assignExpr)*
7150fn suffixExpr(p: *Parser, lhs: Result) Error!Result {
7151 assert(!lhs.empty(p));
7152 switch (p.tok_ids[p.tok_i]) {
7153 .l_paren => return p.callExpr(lhs),
7154 .plus_plus => {
7155 defer p.tok_i += 1;
7156
7157 var operand = lhs;
7158 if (!operand.ty.isScalar())
7159 try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
7160 if (operand.ty.isComplex())
7161 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
7162
7163 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
7164 try p.err(.not_assignable);
7165 return error.ParsingFailed;
7166 }
7167 try operand.usualUnaryConversion(p, p.tok_i);
7168
7169 try operand.un(p, .post_inc_expr);
7170 return operand;
7171 },
7172 .minus_minus => {
7173 defer p.tok_i += 1;
7174
7175 var operand = lhs;
7176 if (!operand.ty.isScalar())
7177 try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty));
7178 if (operand.ty.isComplex())
7179 try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty));
7180
7181 if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) {
7182 try p.err(.not_assignable);
7183 return error.ParsingFailed;
7184 }
7185 try operand.usualUnaryConversion(p, p.tok_i);
7186
7187 try operand.un(p, .post_dec_expr);
7188 return operand;
7189 },
7190 .l_bracket => {
7191 const l_bracket = p.tok_i;
7192 p.tok_i += 1;
7193 var index = try p.expr();
7194 try index.expect(p);
7195 try p.expectClosing(l_bracket, .r_bracket);
7196
7197 const array_before_conversion = lhs;
7198 const index_before_conversion = index;
7199 var ptr = lhs;
7200 try ptr.lvalConversion(p);
7201 try index.lvalConversion(p);
7202 if (ptr.ty.isPtr()) {
7203 ptr.ty = ptr.ty.elemType();
7204 if (!index.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
7205 try p.checkArrayBounds(index_before_conversion, array_before_conversion, l_bracket);
7206 } else if (index.ty.isPtr()) {
7207 index.ty = index.ty.elemType();
7208 if (!ptr.ty.isInt()) try p.errTok(.invalid_index, l_bracket);
7209 try p.checkArrayBounds(array_before_conversion, index_before_conversion, l_bracket);
7210 std.mem.swap(Result, &ptr, &index);
7211 } else {
7212 try p.errTok(.invalid_subscript, l_bracket);
7213 }
7214
7215 try ptr.saveValue(p);
7216 try index.saveValue(p);
7217 try ptr.bin(p, .array_access_expr, index);
7218 return ptr;
7219 },
7220 .period => {
7221 p.tok_i += 1;
7222 const name = try p.expectIdentifier();
7223 return p.fieldAccess(lhs, name, false);
7224 },
7225 .arrow => {
7226 p.tok_i += 1;
7227 const name = try p.expectIdentifier();
7228 if (lhs.ty.isArray()) {
7229 var copy = lhs;
7230 copy.ty.decayArray();
7231 try copy.implicitCast(p, .array_to_pointer);
7232 return p.fieldAccess(copy, name, true);
7233 }
7234 return p.fieldAccess(lhs, name, true);
7235 },
7236 else => return Result{},
7237 }
7238}
7239
7240fn fieldAccess(
7241 p: *Parser,
7242 lhs: Result,
7243 field_name_tok: TokenIndex,
7244 is_arrow: bool,
7245) !Result {
7246 const expr_ty = lhs.ty;
7247 const is_ptr = expr_ty.isPtr();
7248 const expr_base_ty = if (is_ptr) expr_ty.elemType() else expr_ty;
7249 const record_ty = expr_base_ty.canonicalize(.standard);
7250
7251 switch (record_ty.specifier) {
7252 .@"struct", .@"union" => {},
7253 else => {
7254 try p.errStr(.expected_record_ty, field_name_tok, try p.typeStr(expr_ty));
7255 return error.ParsingFailed;
7256 },
7257 }
7258 if (record_ty.hasIncompleteSize()) {
7259 try p.errStr(.deref_incomplete_ty_ptr, field_name_tok - 2, try p.typeStr(expr_base_ty));
7260 return error.ParsingFailed;
7261 }
7262 if (is_arrow and !is_ptr) try p.errStr(.member_expr_not_ptr, field_name_tok, try p.typeStr(expr_ty));
7263 if (!is_arrow and is_ptr) try p.errStr(.member_expr_ptr, field_name_tok, try p.typeStr(expr_ty));
7264
7265 const field_name = try StrInt.intern(p.comp, p.tokSlice(field_name_tok));
7266 try p.validateFieldAccess(record_ty, expr_ty, field_name_tok, field_name);
7267 var discard: u64 = 0;
7268 return p.fieldAccessExtra(lhs.node, record_ty, field_name, is_arrow, &discard);
7269}
7270
7271fn validateFieldAccess(p: *Parser, record_ty: Type, expr_ty: Type, field_name_tok: TokenIndex, field_name: StringId) Error!void {
7272 if (record_ty.hasField(field_name)) return;
7273
7274 p.strings.items.len = 0;
7275
7276 try p.strings.writer().print("'{s}' in '", .{p.tokSlice(field_name_tok)});
7277 const mapper = p.comp.string_interner.getSlowTypeMapper();
7278 try expr_ty.print(mapper, p.comp.langopts, p.strings.writer());
7279 try p.strings.append('\'');
7280
7281 const duped = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items);
7282 try p.errStr(.no_such_member, field_name_tok, duped);
7283 return error.ParsingFailed;
7284}
7285
7286fn fieldAccessExtra(p: *Parser, lhs: NodeIndex, record_ty: Type, field_name: StringId, is_arrow: bool, offset_bits: *u64) Error!Result {
7287 for (record_ty.data.record.fields, 0..) |f, i| {
7288 if (f.isAnonymousRecord()) {
7289 if (!f.ty.hasField(field_name)) continue;
7290 const inner = try p.addNode(.{
7291 .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
7292 .ty = f.ty,
7293 .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
7294 });
7295 const ret = p.fieldAccessExtra(inner, f.ty, field_name, false, offset_bits);
7296 offset_bits.* = f.layout.offset_bits;
7297 return ret;
7298 }
7299 if (field_name == f.name) {
7300 offset_bits.* = f.layout.offset_bits;
7301 return Result{
7302 .ty = f.ty,
7303 .node = try p.addNode(.{
7304 .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr,
7305 .ty = f.ty,
7306 .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } },
7307 }),
7308 };
7309 }
7310 }
7311 // We already checked that this container has a field by the name.
7312 unreachable;
7313}
7314
7315fn checkVaStartArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
7316 assert(idx != 0);
7317 if (idx > 1) {
7318 try p.errTok(.closing_paren, first_after);
7319 return error.ParsingFailed;
7320 }
7321
7322 var func_ty = p.func.ty orelse {
7323 try p.errTok(.va_start_not_in_func, builtin_tok);
7324 return;
7325 };
7326 const func_params = func_ty.params();
7327 if (func_ty.specifier != .var_args_func or func_params.len == 0) {
7328 return p.errTok(.va_start_fixed_args, builtin_tok);
7329 }
7330 const last_param_name = func_params[func_params.len - 1].name;
7331 const decl_ref = p.getNode(arg.node, .decl_ref_expr);
7332 if (decl_ref == null or last_param_name != try StrInt.intern(p.comp, p.tokSlice(p.nodes.items(.data)[@intFromEnum(decl_ref.?)].decl_ref))) {
7333 try p.errTok(.va_start_not_last_param, param_tok);
7334 }
7335}
7336
7337fn checkComplexArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
7338 _ = builtin_tok;
7339 _ = first_after;
7340 if (idx <= 1 and !arg.ty.isFloat()) {
7341 try p.errStr(.not_floating_type, param_tok, try p.typeStr(arg.ty));
7342 } else if (idx == 1) {
7343 const prev_idx = p.list_buf.items[p.list_buf.items.len - 1];
7344 const prev_ty = p.nodes.items(.ty)[@intFromEnum(prev_idx)];
7345 if (!prev_ty.eql(arg.ty, p.comp, false)) {
7346 try p.errStr(.argument_types_differ, param_tok, try p.typePairStrExtra(prev_ty, " vs ", arg.ty));
7347 }
7348 }
7349}
7350
7351fn callExpr(p: *Parser, lhs: Result) Error!Result {
7352 const l_paren = p.tok_i;
7353 p.tok_i += 1;
7354 const ty = lhs.ty.isCallable() orelse {
7355 try p.errStr(.not_callable, l_paren, try p.typeStr(lhs.ty));
7356 return error.ParsingFailed;
7357 };
7358 const params = ty.params();
7359 var func = lhs;
7360 try func.lvalConversion(p);
7361
7362 const list_buf_top = p.list_buf.items.len;
7363 defer p.list_buf.items.len = list_buf_top;
7364 try p.list_buf.append(func.node);
7365 var arg_count: u32 = 0;
7366 var first_after = l_paren;
7367
7368 const call_expr = CallExpr.init(p, lhs.node, func.node);
7369
7370 while (p.eatToken(.r_paren) == null) {
7371 const param_tok = p.tok_i;
7372 if (arg_count == params.len) first_after = p.tok_i;
7373 var arg = try p.assignExpr();
7374 try arg.expect(p);
7375
7376 if (call_expr.shouldPerformLvalConversion(arg_count)) {
7377 try arg.lvalConversion(p);
7378 }
7379 if (arg.ty.hasIncompleteSize() and !arg.ty.is(.void)) return error.ParsingFailed;
7380
7381 if (arg_count >= params.len) {
7382 if (call_expr.shouldPromoteVarArg(arg_count)) {
7383 if (arg.ty.isInt()) try arg.intCast(p, arg.ty.integerPromotion(p.comp), param_tok);
7384 if (arg.ty.is(.float)) try arg.floatCast(p, .{ .specifier = .double });
7385 }
7386 try call_expr.checkVarArg(p, first_after, param_tok, &arg, arg_count);
7387 try arg.saveValue(p);
7388 try p.list_buf.append(arg.node);
7389 arg_count += 1;
7390
7391 _ = p.eatToken(.comma) orelse {
7392 try p.expectClosing(l_paren, .r_paren);
7393 break;
7394 };
7395 continue;
7396 }
7397 const p_ty = params[arg_count].ty;
7398 if (call_expr.shouldCoerceArg(arg_count)) {
7399 try arg.coerce(p, p_ty, param_tok, .{ .arg = params[arg_count].name_tok });
7400 }
7401 try arg.saveValue(p);
7402 try p.list_buf.append(arg.node);
7403 arg_count += 1;
7404
7405 _ = p.eatToken(.comma) orelse {
7406 try p.expectClosing(l_paren, .r_paren);
7407 break;
7408 };
7409 }
7410
7411 const actual: u32 = @intCast(arg_count);
7412 const extra = Diagnostics.Message.Extra{ .arguments = .{
7413 .expected = @intCast(params.len),
7414 .actual = actual,
7415 } };
7416 if (call_expr.paramCountOverride()) |expected| {
7417 if (expected != actual) {
7418 try p.errExtra(.expected_arguments, first_after, .{ .arguments = .{ .expected = expected, .actual = actual } });
7419 }
7420 } else if (ty.is(.func) and params.len != arg_count) {
7421 try p.errExtra(.expected_arguments, first_after, extra);
7422 } else if (ty.is(.old_style_func) and params.len != arg_count) {
7423 if (params.len == 0)
7424 try p.errTok(.passing_args_to_kr, first_after)
7425 else
7426 try p.errExtra(.expected_arguments_old, first_after, extra);
7427 } else if (ty.is(.var_args_func) and arg_count < params.len) {
7428 try p.errExtra(.expected_at_least_arguments, first_after, extra);
7429 }
7430
7431 return call_expr.finish(p, ty, list_buf_top, arg_count);
7432}
7433
7434fn checkArrayBounds(p: *Parser, index: Result, array: Result, tok: TokenIndex) !void {
7435 if (index.val.opt_ref == .none) return;
7436
7437 const array_len = array.ty.arrayLen() orelse return;
7438 if (array_len == 0) return;
7439
7440 if (array_len == 1) {
7441 if (p.getNode(array.node, .member_access_expr) orelse p.getNode(array.node, .member_access_ptr_expr)) |node| {
7442 const data = p.nodes.items(.data)[@intFromEnum(node)];
7443 var lhs = p.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
7444 if (lhs.get(.pointer)) |ptr| {
7445 lhs = ptr.data.sub_type.*;
7446 }
7447 if (lhs.is(.@"struct")) {
7448 const record = lhs.getRecord().?;
7449 if (data.member.index + 1 == record.fields.len) {
7450 if (!index.val.isZero(p.comp)) {
7451 try p.errStr(.old_style_flexible_struct, tok, try index.str(p));
7452 }
7453 return;
7454 }
7455 }
7456 }
7457 }
7458 const index_int = index.val.toInt(u64, p.comp) orelse std.math.maxInt(u64);
7459 if (index.ty.isUnsignedInt(p.comp)) {
7460 if (index_int >= array_len) {
7461 try p.errStr(.array_after, tok, try index.str(p));
7462 }
7463 } else {
7464 if (index.val.compare(.lt, Value.zero, p.comp)) {
7465 try p.errStr(.array_before, tok, try index.str(p));
7466 } else if (index_int >= array_len) {
7467 try p.errStr(.array_after, tok, try index.str(p));
7468 }
7469 }
7470}
7471
7472/// primaryExpr
7473/// : IDENTIFIER
7474/// | keyword_true
7475/// | keyword_false
7476/// | keyword_nullptr
7477/// | INTEGER_LITERAL
7478/// | FLOAT_LITERAL
7479/// | IMAGINARY_LITERAL
7480/// | CHAR_LITERAL
7481/// | STRING_LITERAL
7482/// | '(' expr ')'
7483/// | genericSelection
7484fn primaryExpr(p: *Parser) Error!Result {
7485 if (p.eatToken(.l_paren)) |l_paren| {
7486 var e = try p.expr();
7487 try e.expect(p);
7488 try p.expectClosing(l_paren, .r_paren);
7489 try e.un(p, .paren_expr);
7490 return e;
7491 }
7492 switch (p.tok_ids[p.tok_i]) {
7493 .identifier, .extended_identifier => {
7494 const name_tok = try p.expectIdentifier();
7495 const name = p.tokSlice(name_tok);
7496 const interned_name = try StrInt.intern(p.comp, name);
7497 if (p.syms.findSymbol(interned_name)) |sym| {
7498 try p.checkDeprecatedUnavailable(sym.ty, name_tok, sym.tok);
7499 if (sym.kind == .constexpr) {
7500 return Result{
7501 .val = sym.val,
7502 .ty = sym.ty,
7503 .node = try p.addNode(.{
7504 .tag = .decl_ref_expr,
7505 .ty = sym.ty,
7506 .data = .{ .decl_ref = name_tok },
7507 }),
7508 };
7509 }
7510 if (sym.val.is(.int, p.comp)) {
7511 switch (p.const_decl_folding) {
7512 .gnu_folding_extension => try p.errTok(.const_decl_folded, name_tok),
7513 .gnu_vla_folding_extension => try p.errTok(.const_decl_folded_vla, name_tok),
7514 else => {},
7515 }
7516 }
7517 return Result{
7518 .val = if (p.const_decl_folding == .no_const_decl_folding and sym.kind != .enumeration) Value{} else sym.val,
7519 .ty = sym.ty,
7520 .node = try p.addNode(.{
7521 .tag = if (sym.kind == .enumeration) .enumeration_ref else .decl_ref_expr,
7522 .ty = sym.ty,
7523 .data = .{ .decl_ref = name_tok },
7524 }),
7525 };
7526 }
7527 if (try p.comp.builtins.getOrCreate(p.comp, name, p.arena)) |some| {
7528 for (p.tok_ids[p.tok_i..]) |id| switch (id) {
7529 .r_paren => {}, // closing grouped expr
7530 .l_paren => break, // beginning of a call
7531 else => {
7532 try p.errTok(.builtin_must_be_called, name_tok);
7533 return error.ParsingFailed;
7534 },
7535 };
7536 if (some.builtin.properties.header != .none) {
7537 try p.errStr(.implicit_builtin, name_tok, name);
7538 try p.errExtra(.implicit_builtin_header_note, name_tok, .{ .builtin_with_header = .{
7539 .builtin = some.builtin.tag,
7540 .header = some.builtin.properties.header,
7541 } });
7542 }
7543
7544 return Result{
7545 .ty = some.ty,
7546 .node = try p.addNode(.{
7547 .tag = .builtin_call_expr_one,
7548 .ty = some.ty,
7549 .data = .{ .decl = .{ .name = name_tok, .node = .none } },
7550 }),
7551 };
7552 }
7553 if (p.tok_ids[p.tok_i] == .l_paren and !p.comp.langopts.standard.atLeast(.c23)) {
7554 // allow implicitly declaring functions before C99 like `puts("foo")`
7555 if (mem.startsWith(u8, name, "__builtin_"))
7556 try p.errStr(.unknown_builtin, name_tok, name)
7557 else
7558 try p.errStr(.implicit_func_decl, name_tok, name);
7559
7560 const func_ty = try p.arena.create(Type.Func);
7561 func_ty.* = .{ .return_type = .{ .specifier = .int }, .params = &.{} };
7562 const ty: Type = .{ .specifier = .old_style_func, .data = .{ .func = func_ty } };
7563 const node = try p.addNode(.{
7564 .ty = ty,
7565 .tag = .fn_proto,
7566 .data = .{ .decl = .{ .name = name_tok } },
7567 });
7568
7569 try p.decl_buf.append(node);
7570 try p.syms.declareSymbol(p, interned_name, ty, name_tok, node);
7571
7572 return Result{
7573 .ty = ty,
7574 .node = try p.addNode(.{
7575 .tag = .decl_ref_expr,
7576 .ty = ty,
7577 .data = .{ .decl_ref = name_tok },
7578 }),
7579 };
7580 }
7581 try p.errStr(.undeclared_identifier, name_tok, p.tokSlice(name_tok));
7582 return error.ParsingFailed;
7583 },
7584 .keyword_true, .keyword_false => |id| {
7585 p.tok_i += 1;
7586 const res = Result{
7587 .val = Value.fromBool(id == .keyword_true),
7588 .ty = .{ .specifier = .bool },
7589 .node = try p.addNode(.{ .tag = .bool_literal, .ty = .{ .specifier = .bool }, .data = undefined }),
7590 };
7591 std.debug.assert(!p.in_macro); // Should have been replaced with .one / .zero
7592 try p.value_map.put(res.node, res.val);
7593 return res;
7594 },
7595 .keyword_nullptr => {
7596 defer p.tok_i += 1;
7597 try p.errStr(.pre_c23_compat, p.tok_i, "'nullptr'");
7598 return Result{
7599 .val = Value.null,
7600 .ty = .{ .specifier = .nullptr_t },
7601 .node = try p.addNode(.{
7602 .tag = .nullptr_literal,
7603 .ty = .{ .specifier = .nullptr_t },
7604 .data = undefined,
7605 }),
7606 };
7607 },
7608 .macro_func, .macro_function => {
7609 defer p.tok_i += 1;
7610 var ty: Type = undefined;
7611 var tok = p.tok_i;
7612 if (p.func.ident) |some| {
7613 ty = some.ty;
7614 tok = p.nodes.items(.data)[@intFromEnum(some.node)].decl.name;
7615 } else if (p.func.ty) |_| {
7616 const strings_top = p.strings.items.len;
7617 defer p.strings.items.len = strings_top;
7618
7619 try p.strings.appendSlice(p.tokSlice(p.func.name));
7620 try p.strings.append(0);
7621 const predef = try p.makePredefinedIdentifier(strings_top);
7622 ty = predef.ty;
7623 p.func.ident = predef;
7624 } else {
7625 const strings_top = p.strings.items.len;
7626 defer p.strings.items.len = strings_top;
7627
7628 try p.strings.append(0);
7629 const predef = try p.makePredefinedIdentifier(strings_top);
7630 ty = predef.ty;
7631 p.func.ident = predef;
7632 try p.decl_buf.append(predef.node);
7633 }
7634 if (p.func.ty == null) try p.err(.predefined_top_level);
7635 return Result{
7636 .ty = ty,
7637 .node = try p.addNode(.{
7638 .tag = .decl_ref_expr,
7639 .ty = ty,
7640 .data = .{ .decl_ref = tok },
7641 }),
7642 };
7643 },
7644 .macro_pretty_func => {
7645 defer p.tok_i += 1;
7646 var ty: Type = undefined;
7647 if (p.func.pretty_ident) |some| {
7648 ty = some.ty;
7649 } else if (p.func.ty) |func_ty| {
7650 const strings_top = p.strings.items.len;
7651 defer p.strings.items.len = strings_top;
7652
7653 const mapper = p.comp.string_interner.getSlowTypeMapper();
7654 try Type.printNamed(func_ty, p.tokSlice(p.func.name), mapper, p.comp.langopts, p.strings.writer());
7655 try p.strings.append(0);
7656 const predef = try p.makePredefinedIdentifier(strings_top);
7657 ty = predef.ty;
7658 p.func.pretty_ident = predef;
7659 } else {
7660 const strings_top = p.strings.items.len;
7661 defer p.strings.items.len = strings_top;
7662
7663 try p.strings.appendSlice("top level\x00");
7664 const predef = try p.makePredefinedIdentifier(strings_top);
7665 ty = predef.ty;
7666 p.func.pretty_ident = predef;
7667 try p.decl_buf.append(predef.node);
7668 }
7669 if (p.func.ty == null) try p.err(.predefined_top_level);
7670 return Result{
7671 .ty = ty,
7672 .node = try p.addNode(.{
7673 .tag = .decl_ref_expr,
7674 .ty = ty,
7675 .data = .{ .decl_ref = p.tok_i },
7676 }),
7677 };
7678 },
7679 .string_literal,
7680 .string_literal_utf_16,
7681 .string_literal_utf_8,
7682 .string_literal_utf_32,
7683 .string_literal_wide,
7684 .unterminated_string_literal,
7685 => return p.stringLiteral(),
7686 .char_literal,
7687 .char_literal_utf_8,
7688 .char_literal_utf_16,
7689 .char_literal_utf_32,
7690 .char_literal_wide,
7691 .empty_char_literal,
7692 .unterminated_char_literal,
7693 => return p.charLiteral(),
7694 .zero => {
7695 p.tok_i += 1;
7696 var res: Result = .{ .val = Value.zero, .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
7697 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
7698 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7699 return res;
7700 },
7701 .one => {
7702 p.tok_i += 1;
7703 var res: Result = .{ .val = Value.one, .ty = if (p.in_macro) p.comp.types.intmax else Type.int };
7704 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
7705 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7706 return res;
7707 },
7708 .pp_num => return p.ppNum(),
7709 .embed_byte => {
7710 assert(!p.in_macro);
7711 const loc = p.pp.tokens.items(.loc)[p.tok_i];
7712 p.tok_i += 1;
7713 const buf = p.comp.getSource(.generated).buf[loc.byte_offset..];
7714 var byte: u8 = buf[0] - '0';
7715 for (buf[1..]) |c| {
7716 if (!std.ascii.isDigit(c)) break;
7717 byte *= 10;
7718 byte += c - '0';
7719 }
7720 var res: Result = .{ .val = try Value.int(byte, p.comp) };
7721 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
7722 try p.value_map.put(res.node, res.val);
7723 return res;
7724 },
7725 .keyword_generic => return p.genericSelection(),
7726 else => return Result{},
7727 }
7728}
7729
7730fn makePredefinedIdentifier(p: *Parser, strings_top: usize) !Result {
7731 const end: u32 = @intCast(p.strings.items.len);
7732 const elem_ty = .{ .specifier = .char, .qual = .{ .@"const" = true } };
7733 const arr_ty = try p.arena.create(Type.Array);
7734 arr_ty.* = .{ .elem = elem_ty, .len = end - strings_top };
7735 const ty: Type = .{ .specifier = .array, .data = .{ .array = arr_ty } };
7736
7737 const slice = p.strings.items[strings_top..];
7738 const val = try Value.intern(p.comp, .{ .bytes = slice });
7739
7740 const str_lit = try p.addNode(.{ .tag = .string_literal_expr, .ty = ty, .data = undefined });
7741 if (!p.in_macro) try p.value_map.put(str_lit, val);
7742
7743 return Result{ .ty = ty, .node = try p.addNode(.{
7744 .tag = .implicit_static_var,
7745 .ty = ty,
7746 .data = .{ .decl = .{ .name = p.tok_i, .node = str_lit } },
7747 }) };
7748}
7749
7750fn stringLiteral(p: *Parser) Error!Result {
7751 var string_end = p.tok_i;
7752 var string_kind: text_literal.Kind = .char;
7753 while (text_literal.Kind.classify(p.tok_ids[string_end], .string_literal)) |next| : (string_end += 1) {
7754 string_kind = string_kind.concat(next) catch {
7755 try p.errTok(.unsupported_str_cat, string_end);
7756 while (p.tok_ids[p.tok_i].isStringLiteral()) : (p.tok_i += 1) {}
7757 return error.ParsingFailed;
7758 };
7759 if (string_kind == .unterminated) {
7760 try p.errTok(.unterminated_string_literal_error, string_end);
7761 p.tok_i = string_end + 1;
7762 return error.ParsingFailed;
7763 }
7764 }
7765 assert(string_end > p.tok_i);
7766
7767 const char_width = string_kind.charUnitSize(p.comp);
7768
7769 const strings_top = p.strings.items.len;
7770 defer p.strings.items.len = strings_top;
7771
7772 while (p.tok_i < string_end) : (p.tok_i += 1) {
7773 const this_kind = text_literal.Kind.classify(p.tok_ids[p.tok_i], .string_literal).?;
7774 const slice = this_kind.contentSlice(p.tokSlice(p.tok_i));
7775 var char_literal_parser = text_literal.Parser.init(slice, this_kind, 0x10ffff, p.comp);
7776
7777 try p.strings.ensureUnusedCapacity((slice.len + 1) * @intFromEnum(char_width)); // +1 for null terminator
7778 while (char_literal_parser.next()) |item| switch (item) {
7779 .value => |v| {
7780 switch (char_width) {
7781 .@"1" => p.strings.appendAssumeCapacity(@intCast(v)),
7782 .@"2" => {
7783 const word: u16 = @intCast(v);
7784 p.strings.appendSliceAssumeCapacity(mem.asBytes(&word));
7785 },
7786 .@"4" => p.strings.appendSliceAssumeCapacity(mem.asBytes(&v)),
7787 }
7788 },
7789 .codepoint => |c| {
7790 switch (char_width) {
7791 .@"1" => {
7792 var buf: [4]u8 = undefined;
7793 const written = std.unicode.utf8Encode(c, &buf) catch unreachable;
7794 const encoded = buf[0..written];
7795 p.strings.appendSliceAssumeCapacity(encoded);
7796 },
7797 .@"2" => {
7798 var utf16_buf: [2]u16 = undefined;
7799 var utf8_buf: [4]u8 = undefined;
7800 const utf8_written = std.unicode.utf8Encode(c, &utf8_buf) catch unreachable;
7801 const utf16_written = std.unicode.utf8ToUtf16Le(&utf16_buf, utf8_buf[0..utf8_written]) catch unreachable;
7802 const bytes = std.mem.sliceAsBytes(utf16_buf[0..utf16_written]);
7803 p.strings.appendSliceAssumeCapacity(bytes);
7804 },
7805 .@"4" => {
7806 const val: u32 = c;
7807 p.strings.appendSliceAssumeCapacity(mem.asBytes(&val));
7808 },
7809 }
7810 },
7811 .improperly_encoded => |bytes| p.strings.appendSliceAssumeCapacity(bytes),
7812 .utf8_text => |view| {
7813 switch (char_width) {
7814 .@"1" => p.strings.appendSliceAssumeCapacity(view.bytes),
7815 .@"2" => {
7816 const capacity_slice: []align(@alignOf(u16)) u8 = @alignCast(p.strings.unusedCapacitySlice());
7817 const dest_len = std.mem.alignBackward(usize, capacity_slice.len, 2);
7818 const dest = std.mem.bytesAsSlice(u16, capacity_slice[0..dest_len]);
7819 const words_written = std.unicode.utf8ToUtf16Le(dest, view.bytes) catch unreachable;
7820 p.strings.resize(p.strings.items.len + words_written * 2) catch unreachable;
7821 },
7822 .@"4" => {
7823 var it = view.iterator();
7824 while (it.nextCodepoint()) |codepoint| {
7825 const val: u32 = codepoint;
7826 p.strings.appendSliceAssumeCapacity(mem.asBytes(&val));
7827 }
7828 },
7829 }
7830 },
7831 };
7832 for (char_literal_parser.errors()) |item| {
7833 try p.errExtra(item.tag, p.tok_i, item.extra);
7834 }
7835 }
7836 p.strings.appendNTimesAssumeCapacity(0, @intFromEnum(char_width));
7837 const slice = p.strings.items[strings_top..];
7838
7839 // TODO this won't do anything if there is a cache hit
7840 const interned_align = mem.alignForward(
7841 usize,
7842 p.comp.interner.strings.items.len,
7843 string_kind.internalStorageAlignment(p.comp),
7844 );
7845 try p.comp.interner.strings.resize(p.gpa, interned_align);
7846
7847 const val = try Value.intern(p.comp, .{ .bytes = slice });
7848
7849 const arr_ty = try p.arena.create(Type.Array);
7850 arr_ty.* = .{ .elem = string_kind.elementType(p.comp), .len = @divExact(slice.len, @intFromEnum(char_width)) };
7851 var res: Result = .{
7852 .ty = .{
7853 .specifier = .array,
7854 .data = .{ .array = arr_ty },
7855 },
7856 .val = val,
7857 };
7858 res.node = try p.addNode(.{ .tag = .string_literal_expr, .ty = res.ty, .data = undefined });
7859 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7860 return res;
7861}
7862
7863fn charLiteral(p: *Parser) Error!Result {
7864 defer p.tok_i += 1;
7865 const tok_id = p.tok_ids[p.tok_i];
7866 const char_kind = text_literal.Kind.classify(tok_id, .char_literal) orelse {
7867 if (tok_id == .empty_char_literal) {
7868 try p.err(.empty_char_literal_error);
7869 } else if (tok_id == .unterminated_char_literal) {
7870 try p.err(.unterminated_char_literal_error);
7871 } else unreachable;
7872 return .{
7873 .ty = Type.int,
7874 .val = Value.zero,
7875 .node = try p.addNode(.{ .tag = .char_literal, .ty = Type.int, .data = undefined }),
7876 };
7877 };
7878 if (char_kind == .utf_8) try p.err(.u8_char_lit);
7879 var val: u32 = 0;
7880
7881 const slice = char_kind.contentSlice(p.tokSlice(p.tok_i));
7882
7883 if (slice.len == 1 and std.ascii.isASCII(slice[0])) {
7884 // fast path: single unescaped ASCII char
7885 val = slice[0];
7886 } else {
7887 const max_codepoint = char_kind.maxCodepoint(p.comp);
7888 var char_literal_parser = text_literal.Parser.init(slice, char_kind, max_codepoint, p.comp);
7889
7890 const max_chars_expected = 4;
7891 var stack_fallback = std.heap.stackFallback(max_chars_expected * @sizeOf(u32), p.comp.gpa);
7892 var chars = std.ArrayList(u32).initCapacity(stack_fallback.get(), max_chars_expected) catch unreachable; // stack allocation already succeeded
7893 defer chars.deinit();
7894
7895 while (char_literal_parser.next()) |item| switch (item) {
7896 .value => |v| try chars.append(v),
7897 .codepoint => |c| try chars.append(c),
7898 .improperly_encoded => |s| {
7899 try chars.ensureUnusedCapacity(s.len);
7900 for (s) |c| chars.appendAssumeCapacity(c);
7901 },
7902 .utf8_text => |view| {
7903 var it = view.iterator();
7904 var max_codepoint_seen: u21 = 0;
7905 try chars.ensureUnusedCapacity(view.bytes.len);
7906 while (it.nextCodepoint()) |c| {
7907 max_codepoint_seen = @max(max_codepoint_seen, c);
7908 chars.appendAssumeCapacity(c);
7909 }
7910 if (max_codepoint_seen > max_codepoint) {
7911 char_literal_parser.err(.char_too_large, .{ .none = {} });
7912 }
7913 },
7914 };
7915
7916 const is_multichar = chars.items.len > 1;
7917 if (is_multichar) {
7918 if (char_kind == .char and chars.items.len == 4) {
7919 char_literal_parser.warn(.four_char_char_literal, .{ .none = {} });
7920 } else if (char_kind == .char) {
7921 char_literal_parser.warn(.multichar_literal_warning, .{ .none = {} });
7922 } else {
7923 const kind = switch (char_kind) {
7924 .wide => "wide",
7925 .utf_8, .utf_16, .utf_32 => "Unicode",
7926 else => unreachable,
7927 };
7928 char_literal_parser.err(.invalid_multichar_literal, .{ .str = kind });
7929 }
7930 }
7931
7932 var multichar_overflow = false;
7933 if (char_kind == .char and is_multichar) {
7934 for (chars.items) |item| {
7935 val, const overflowed = @shlWithOverflow(val, 8);
7936 multichar_overflow = multichar_overflow or overflowed != 0;
7937 val += @as(u8, @truncate(item));
7938 }
7939 } else if (chars.items.len > 0) {
7940 val = chars.items[chars.items.len - 1];
7941 }
7942
7943 if (multichar_overflow) {
7944 char_literal_parser.err(.char_lit_too_wide, .{ .none = {} });
7945 }
7946
7947 for (char_literal_parser.errors()) |item| {
7948 try p.errExtra(item.tag, p.tok_i, item.extra);
7949 }
7950 }
7951
7952 const ty = char_kind.charLiteralType(p.comp);
7953 // This is the type the literal will have if we're in a macro; macros always operate on intmax_t/uintmax_t values
7954 const macro_ty = if (ty.isUnsignedInt(p.comp) or (char_kind == .char and p.comp.getCharSignedness() == .unsigned))
7955 p.comp.types.intmax.makeIntegerUnsigned()
7956 else
7957 p.comp.types.intmax;
7958
7959 const res = Result{
7960 .ty = if (p.in_macro) macro_ty else ty,
7961 .val = try Value.int(val, p.comp),
7962 .node = try p.addNode(.{ .tag = .char_literal, .ty = ty, .data = undefined }),
7963 };
7964 if (!p.in_macro) try p.value_map.put(res.node, res.val);
7965 return res;
7966}
7967
7968fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
7969 const ty = Type{ .specifier = switch (suffix) {
7970 .None, .I => .double,
7971 .F, .IF => .float,
7972 .F16 => .float16,
7973 .L, .IL => .long_double,
7974 .W, .IW => .float80,
7975 .Q, .IQ, .F128, .IF128 => .float128,
7976 else => unreachable,
7977 } };
7978 const val = try Value.intern(p.comp, key: {
7979 try p.strings.ensureUnusedCapacity(buf.len);
7980
7981 const strings_top = p.strings.items.len;
7982 defer p.strings.items.len = strings_top;
7983 for (buf) |c| {
7984 if (c != '\'') p.strings.appendAssumeCapacity(c);
7985 }
7986
7987 const float = std.fmt.parseFloat(f128, p.strings.items[strings_top..]) catch unreachable;
7988 const bits = ty.bitSizeof(p.comp).?;
7989 break :key switch (bits) {
7990 16 => .{ .float = .{ .f16 = @floatCast(float) } },
7991 32 => .{ .float = .{ .f32 = @floatCast(float) } },
7992 64 => .{ .float = .{ .f64 = @floatCast(float) } },
7993 80 => .{ .float = .{ .f80 = @floatCast(float) } },
7994 128 => .{ .float = .{ .f128 = @floatCast(float) } },
7995 else => unreachable,
7996 };
7997 });
7998 var res = Result{
7999 .ty = ty,
8000 .node = try p.addNode(.{ .tag = .float_literal, .ty = ty, .data = undefined }),
8001 .val = val,
8002 };
8003 if (suffix.isImaginary()) {
8004 try p.err(.gnu_imaginary_constant);
8005 res.ty = .{ .specifier = switch (suffix) {
8006 .I => .complex_double,
8007 .IF => .complex_float,
8008 .IL => .complex_long_double,
8009 .IW => .complex_float80,
8010 .IQ, .IF128 => .complex_float128,
8011 else => unreachable,
8012 } };
8013 res.val = .{}; // TODO add complex values
8014 try res.un(p, .imaginary_literal);
8015 }
8016 return res;
8017}
8018
8019fn getIntegerPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
8020 if (buf[0] == '.') return "";
8021
8022 if (!prefix.digitAllowed(buf[0])) {
8023 switch (prefix) {
8024 .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
8025 .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(buf[0]) }),
8026 .hex => try p.errStr(.invalid_int_suffix, tok_i, buf),
8027 .decimal => unreachable,
8028 }
8029 return error.ParsingFailed;
8030 }
8031
8032 for (buf, 0..) |c, idx| {
8033 if (idx == 0) continue;
8034 switch (c) {
8035 '.' => return buf[0..idx],
8036 'p', 'P' => return if (prefix == .hex) buf[0..idx] else {
8037 try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]);
8038 return error.ParsingFailed;
8039 },
8040 'e', 'E' => {
8041 switch (prefix) {
8042 .hex => continue,
8043 .decimal => return buf[0..idx],
8044 .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
8045 .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
8046 }
8047 return error.ParsingFailed;
8048 },
8049 '0'...'9', 'a'...'d', 'A'...'D', 'f', 'F' => {
8050 if (!prefix.digitAllowed(c)) {
8051 switch (prefix) {
8052 .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }),
8053 .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }),
8054 .decimal, .hex => try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]),
8055 }
8056 return error.ParsingFailed;
8057 }
8058 },
8059 '\'' => {},
8060 else => return buf[0..idx],
8061 }
8062 }
8063 return buf;
8064}
8065
8066fn fixedSizeInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
8067 var val: u64 = 0;
8068 var overflow = false;
8069 for (buf) |c| {
8070 const digit: u64 = switch (c) {
8071 '0'...'9' => c - '0',
8072 'A'...'Z' => c - 'A' + 10,
8073 'a'...'z' => c - 'a' + 10,
8074 '\'' => continue,
8075 else => unreachable,
8076 };
8077
8078 if (val != 0) {
8079 const product, const overflowed = @mulWithOverflow(val, base);
8080 if (overflowed != 0) {
8081 overflow = true;
8082 }
8083 val = product;
8084 }
8085 const sum, const overflowed = @addWithOverflow(val, digit);
8086 if (overflowed != 0) overflow = true;
8087 val = sum;
8088 }
8089 var res: Result = .{ .val = try Value.int(val, p.comp) };
8090 if (overflow) {
8091 try p.errTok(.int_literal_too_big, tok_i);
8092 res.ty = .{ .specifier = .ulong_long };
8093 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
8094 if (!p.in_macro) try p.value_map.put(res.node, res.val);
8095 return res;
8096 }
8097 if (suffix.isSignedInteger()) {
8098 if (val > p.comp.types.intmax.maxInt(p.comp)) {
8099 try p.errTok(.implicitly_unsigned_literal, tok_i);
8100 }
8101 }
8102
8103 const signed_specs = .{ .int, .long, .long_long };
8104 const unsigned_specs = .{ .uint, .ulong, .ulong_long };
8105 const signed_oct_hex_specs = .{ .int, .uint, .long, .ulong, .long_long, .ulong_long };
8106 const specs: []const Type.Specifier = if (suffix.signedness() == .unsigned)
8107 &unsigned_specs
8108 else if (base == 10)
8109 &signed_specs
8110 else
8111 &signed_oct_hex_specs;
8112
8113 const suffix_ty: Type = .{ .specifier = switch (suffix) {
8114 .None, .I => .int,
8115 .U, .IU => .uint,
8116 .UL, .IUL => .ulong,
8117 .ULL, .IULL => .ulong_long,
8118 .L, .IL => .long,
8119 .LL, .ILL => .long_long,
8120 else => unreachable,
8121 } };
8122
8123 for (specs) |spec| {
8124 res.ty = Type{ .specifier = spec };
8125 if (res.ty.compareIntegerRanks(suffix_ty, p.comp).compare(.lt)) continue;
8126 const max_int = res.ty.maxInt(p.comp);
8127 if (val <= max_int) break;
8128 } else {
8129 res.ty = .{ .specifier = .ulong_long };
8130 }
8131
8132 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
8133 if (!p.in_macro) try p.value_map.put(res.node, res.val);
8134 return res;
8135}
8136
8137fn parseInt(p: *Parser, prefix: NumberPrefix, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result {
8138 if (prefix == .binary) {
8139 try p.errTok(.binary_integer_literal, tok_i);
8140 }
8141 const base = @intFromEnum(prefix);
8142 var res = if (suffix.isBitInt())
8143 try p.bitInt(base, buf, suffix, tok_i)
8144 else
8145 try p.fixedSizeInt(base, buf, suffix, tok_i);
8146
8147 if (suffix.isImaginary()) {
8148 try p.errTok(.gnu_imaginary_constant, tok_i);
8149 res.ty = res.ty.makeComplex();
8150 res.val = .{};
8151 try res.un(p, .imaginary_literal);
8152 }
8153 return res;
8154}
8155
8156fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) Error!Result {
8157 try p.errStr(.pre_c23_compat, tok_i, "'_BitInt' suffix for literals");
8158 try p.errTok(.bitint_suffix, tok_i);
8159
8160 var managed = try big.int.Managed.init(p.gpa);
8161 defer managed.deinit();
8162
8163 {
8164 try p.strings.ensureUnusedCapacity(buf.len);
8165
8166 const strings_top = p.strings.items.len;
8167 defer p.strings.items.len = strings_top;
8168 for (buf) |c| {
8169 if (c != '\'') p.strings.appendAssumeCapacity(c);
8170 }
8171
8172 managed.setString(base, p.strings.items[strings_top..]) catch |e| switch (e) {
8173 error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16
8174 error.InvalidCharacter => unreachable, // digits validated by Tokenizer
8175 else => |er| return er,
8176 };
8177 }
8178 const c = managed.toConst();
8179 const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: {
8180 // Literal `0` requires at least 1 bit
8181 const count = @max(1, c.bitCountTwosComp());
8182 // The wb suffix results in a _BitInt that includes space for the sign bit even if the
8183 // value of the constant is positive or was specified in hexadecimal or octal notation.
8184 const sign_bits = @intFromBool(suffix.isSignedInteger());
8185 const bits_needed = count + sign_bits;
8186 if (bits_needed > Compilation.bit_int_max_bits) {
8187 const specifier: Type.Builder.Specifier = switch (suffix) {
8188 .WB => .{ .bit_int = 0 },
8189 .UWB => .{ .ubit_int = 0 },
8190 .IWB => .{ .complex_bit_int = 0 },
8191 .IUWB => .{ .complex_ubit_int = 0 },
8192 else => unreachable,
8193 };
8194 try p.errStr(.bit_int_too_big, tok_i, specifier.str(p.comp.langopts).?);
8195 return error.ParsingFailed;
8196 }
8197 break :blk @intCast(bits_needed);
8198 };
8199
8200 var res: Result = .{
8201 .val = try Value.intern(p.comp, .{ .int = .{ .big_int = c } }),
8202 .ty = .{
8203 .specifier = .bit_int,
8204 .data = .{ .int = .{ .bits = bits_needed, .signedness = suffix.signedness() } },
8205 },
8206 };
8207 res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined });
8208 if (!p.in_macro) try p.value_map.put(res.node, res.val);
8209 return res;
8210}
8211
8212fn getFracPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
8213 if (buf.len == 0 or buf[0] != '.') return "";
8214 assert(prefix != .octal);
8215 if (prefix == .binary) {
8216 try p.errStr(.invalid_int_suffix, tok_i, buf);
8217 return error.ParsingFailed;
8218 }
8219 for (buf, 0..) |c, idx| {
8220 if (idx == 0) continue;
8221 if (c == '\'') continue;
8222 if (!prefix.digitAllowed(c)) return buf[0..idx];
8223 }
8224 return buf;
8225}
8226
8227fn getExponent(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 {
8228 if (buf.len == 0) return "";
8229
8230 switch (buf[0]) {
8231 'e', 'E' => assert(prefix == .decimal),
8232 'p', 'P' => if (prefix != .hex) {
8233 try p.errStr(.invalid_float_suffix, tok_i, buf);
8234 return error.ParsingFailed;
8235 },
8236 else => return "",
8237 }
8238 const end = for (buf, 0..) |c, idx| {
8239 if (idx == 0) continue;
8240 if (idx == 1 and (c == '+' or c == '-')) continue;
8241 switch (c) {
8242 '0'...'9' => {},
8243 '\'' => continue,
8244 else => break idx,
8245 }
8246 } else buf.len;
8247 const exponent = buf[0..end];
8248 if (std.mem.indexOfAny(u8, exponent, "0123456789") == null) {
8249 try p.errTok(.exponent_has_no_digits, tok_i);
8250 return error.ParsingFailed;
8251 }
8252 return exponent;
8253}
8254
8255/// Using an explicit `tok_i` parameter instead of `p.tok_i` makes it easier
8256/// to parse numbers in pragma handlers.
8257pub fn parseNumberToken(p: *Parser, tok_i: TokenIndex) !Result {
8258 const buf = p.tokSlice(tok_i);
8259 const prefix = NumberPrefix.fromString(buf);
8260 const after_prefix = buf[prefix.stringLen()..];
8261
8262 const int_part = try p.getIntegerPart(after_prefix, prefix, tok_i);
8263
8264 const after_int = after_prefix[int_part.len..];
8265
8266 const frac = try p.getFracPart(after_int, prefix, tok_i);
8267 const after_frac = after_int[frac.len..];
8268
8269 const exponent = try p.getExponent(after_frac, prefix, tok_i);
8270 const suffix_str = after_frac[exponent.len..];
8271 const is_float = (exponent.len > 0 or frac.len > 0);
8272 const suffix = NumberSuffix.fromString(suffix_str, if (is_float) .float else .int) orelse {
8273 if (is_float) {
8274 try p.errStr(.invalid_float_suffix, tok_i, suffix_str);
8275 } else {
8276 try p.errStr(.invalid_int_suffix, tok_i, suffix_str);
8277 }
8278 return error.ParsingFailed;
8279 };
8280
8281 if (is_float) {
8282 assert(prefix == .hex or prefix == .decimal);
8283 if (prefix == .hex and exponent.len == 0) {
8284 try p.errTok(.hex_floating_constant_requires_exponent, tok_i);
8285 return error.ParsingFailed;
8286 }
8287 const number = buf[0 .. buf.len - suffix_str.len];
8288 return p.parseFloat(number, suffix);
8289 } else {
8290 return p.parseInt(prefix, int_part, suffix, tok_i);
8291 }
8292}
8293
8294fn ppNum(p: *Parser) Error!Result {
8295 defer p.tok_i += 1;
8296 var res = try p.parseNumberToken(p.tok_i);
8297 if (p.in_macro) {
8298 if (res.ty.isFloat() or !res.ty.isReal()) {
8299 try p.errTok(.float_literal_in_pp_expr, p.tok_i);
8300 return error.ParsingFailed;
8301 }
8302 res.ty = if (res.ty.isUnsignedInt(p.comp)) p.comp.types.intmax.makeIntegerUnsigned() else p.comp.types.intmax;
8303 } else if (res.val.opt_ref != .none) {
8304 // TODO add complex values
8305 try p.value_map.put(res.node, res.val);
8306 }
8307 return res;
8308}
8309
8310/// Run a parser function but do not evaluate the result
8311fn parseNoEval(p: *Parser, comptime func: fn (*Parser) Error!Result) Error!Result {
8312 const no_eval = p.no_eval;
8313 defer p.no_eval = no_eval;
8314 p.no_eval = true;
8315 const parsed = try func(p);
8316 try parsed.expect(p);
8317 return parsed;
8318}
8319
8320/// genericSelection : keyword_generic '(' assignExpr ',' genericAssoc (',' genericAssoc)* ')'
8321/// genericAssoc
8322/// : typeName ':' assignExpr
8323/// | keyword_default ':' assignExpr
8324fn genericSelection(p: *Parser) Error!Result {
8325 p.tok_i += 1;
8326 const l_paren = try p.expectToken(.l_paren);
8327 const controlling_tok = p.tok_i;
8328 const controlling = try p.parseNoEval(assignExpr);
8329 _ = try p.expectToken(.comma);
8330 var controlling_ty = controlling.ty;
8331 if (controlling_ty.isArray()) controlling_ty.decayArray();
8332
8333 const list_buf_top = p.list_buf.items.len;
8334 defer p.list_buf.items.len = list_buf_top;
8335 try p.list_buf.append(controlling.node);
8336
8337 // Use decl_buf to store the token indexes of previous cases
8338 const decl_buf_top = p.decl_buf.items.len;
8339 defer p.decl_buf.items.len = decl_buf_top;
8340
8341 var default_tok: ?TokenIndex = null;
8342 var default: Result = undefined;
8343 var chosen_tok: TokenIndex = undefined;
8344 var chosen: Result = .{};
8345 while (true) {
8346 const start = p.tok_i;
8347 if (try p.typeName()) |ty| blk: {
8348 if (ty.isArray()) {
8349 try p.errTok(.generic_array_type, start);
8350 } else if (ty.isFunc()) {
8351 try p.errTok(.generic_func_type, start);
8352 } else if (ty.anyQual()) {
8353 try p.errTok(.generic_qual_type, start);
8354 }
8355 _ = try p.expectToken(.colon);
8356 const node = try p.assignExpr();
8357 try node.expect(p);
8358
8359 if (ty.eql(controlling_ty, p.comp, false)) {
8360 if (chosen.node == .none) {
8361 chosen = node;
8362 chosen_tok = start;
8363 break :blk;
8364 }
8365 try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
8366 try p.errStr(.generic_duplicate_here, chosen_tok, try p.typeStr(ty));
8367 }
8368 for (p.list_buf.items[list_buf_top + 1 ..], p.decl_buf.items[decl_buf_top..]) |item, prev_tok| {
8369 const prev_ty = p.nodes.items(.ty)[@intFromEnum(item)];
8370 if (prev_ty.eql(ty, p.comp, true)) {
8371 try p.errStr(.generic_duplicate, start, try p.typeStr(ty));
8372 try p.errStr(.generic_duplicate_here, @intFromEnum(prev_tok), try p.typeStr(ty));
8373 }
8374 }
8375 try p.list_buf.append(try p.addNode(.{
8376 .tag = .generic_association_expr,
8377 .ty = ty,
8378 .data = .{ .un = node.node },
8379 }));
8380 try p.decl_buf.append(@enumFromInt(start));
8381 } else if (p.eatToken(.keyword_default)) |tok| {
8382 if (default_tok) |prev| {
8383 try p.errTok(.generic_duplicate_default, tok);
8384 try p.errTok(.previous_case, prev);
8385 }
8386 default_tok = tok;
8387 _ = try p.expectToken(.colon);
8388 default = try p.assignExpr();
8389 try default.expect(p);
8390 } else {
8391 if (p.list_buf.items.len == list_buf_top + 1) {
8392 try p.err(.expected_type);
8393 return error.ParsingFailed;
8394 }
8395 break;
8396 }
8397 if (p.eatToken(.comma) == null) break;
8398 }
8399 try p.expectClosing(l_paren, .r_paren);
8400
8401 if (chosen.node == .none) {
8402 if (default_tok != null) {
8403 try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
8404 .tag = .generic_default_expr,
8405 .data = .{ .un = default.node },
8406 }));
8407 chosen = default;
8408 } else {
8409 try p.errStr(.generic_no_match, controlling_tok, try p.typeStr(controlling_ty));
8410 return error.ParsingFailed;
8411 }
8412 } else {
8413 try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{
8414 .tag = .generic_association_expr,
8415 .data = .{ .un = chosen.node },
8416 }));
8417 if (default_tok != null) {
8418 try p.list_buf.append(try p.addNode(.{
8419 .tag = .generic_default_expr,
8420 .data = .{ .un = chosen.node },
8421 }));
8422 }
8423 }
8424
8425 var generic_node: Tree.Node = .{
8426 .tag = .generic_expr_one,
8427 .ty = chosen.ty,
8428 .data = .{ .bin = .{ .lhs = controlling.node, .rhs = chosen.node } },
8429 };
8430 const associations = p.list_buf.items[list_buf_top..];
8431 if (associations.len > 2) { // associations[0] == controlling.node
8432 generic_node.tag = .generic_expr;
8433 generic_node.data = .{ .range = try p.addList(associations) };
8434 }
8435 chosen.node = try p.addNode(generic_node);
8436 return chosen;
8437}
lib/compiler/aro/aro/Pragma.zig created+83
......@@ -0,0 +1,83 @@
1const std = @import("std");
2const Compilation = @import("Compilation.zig");
3const Preprocessor = @import("Preprocessor.zig");
4const Parser = @import("Parser.zig");
5const TokenIndex = @import("Tree.zig").TokenIndex;
6
7pub const Error = Compilation.Error || error{ UnknownPragma, StopPreprocessing };
8
9const Pragma = @This();
10
11/// Called during Preprocessor.init
12beforePreprocess: ?*const fn (*Pragma, *Compilation) void = null,
13
14/// Called at the beginning of Parser.parse
15beforeParse: ?*const fn (*Pragma, *Compilation) void = null,
16
17/// Called at the end of Parser.parse if a Tree was successfully parsed
18afterParse: ?*const fn (*Pragma, *Compilation) void = null,
19
20/// Called during Compilation.deinit
21deinit: *const fn (*Pragma, *Compilation) void,
22
23/// Called whenever the preprocessor encounters this pragma. `start_idx` is the index
24/// within `pp.tokens` of the pragma name token. The pragma end is indicated by a
25/// .nl token (which may be generated if the source ends with a pragma with no newline)
26/// As an example, given the following line:
27/// #pragma GCC diagnostic error "-Wnewline-eof" \n
28/// Then pp.tokens.get(start_idx) will return the `GCC` token.
29/// Return error.UnknownPragma to emit an `unknown_pragma` diagnostic
30/// Return error.StopPreprocessing to stop preprocessing the current file (see once.zig)
31preprocessorHandler: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) Error!void = null,
32
33/// Called during token pretty-printing (`-E` option). If this returns true, the pragma will
34/// be printed; otherwise it will be omitted. start_idx is the index of the pragma name token
35preserveTokens: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) bool = null,
36
37/// Same as preprocessorHandler except called during parsing
38/// The parser's `p.tok_i` field must not be changed
39parserHandler: ?*const fn (*Pragma, *Parser, start_idx: TokenIndex) Compilation.Error!void = null,
40
41pub fn pasteTokens(pp: *Preprocessor, start_idx: TokenIndex) ![]const u8 {
42 if (pp.tokens.get(start_idx).id == .nl) return error.ExpectedStringLiteral;
43
44 const char_top = pp.char_buf.items.len;
45 defer pp.char_buf.items.len = char_top;
46 var i: usize = 0;
47 var lparen_count: u32 = 0;
48 var rparen_count: u32 = 0;
49 while (true) : (i += 1) {
50 const tok = pp.tokens.get(start_idx + i);
51 if (tok.id == .nl) break;
52 switch (tok.id) {
53 .l_paren => {
54 if (lparen_count != i) return error.ExpectedStringLiteral;
55 lparen_count += 1;
56 },
57 .r_paren => rparen_count += 1,
58 .string_literal => {
59 if (rparen_count != 0) return error.ExpectedStringLiteral;
60 const str = pp.expandedSlice(tok);
61 try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
62 },
63 else => return error.ExpectedStringLiteral,
64 }
65 }
66 if (lparen_count != rparen_count) return error.ExpectedStringLiteral;
67 return pp.char_buf.items[char_top..];
68}
69
70pub fn shouldPreserveTokens(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
71 if (self.preserveTokens) |func| return func(self, pp, start_idx);
72 return false;
73}
74
75pub fn preprocessorCB(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Error!void {
76 if (self.preprocessorHandler) |func| return func(self, pp, start_idx);
77}
78
79pub fn parserCB(self: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
80 const tok_index = p.tok_i;
81 defer std.debug.assert(tok_index == p.tok_i);
82 if (self.parserHandler) |func| return func(self, p, start_idx);
83}
lib/compiler/aro/aro/Preprocessor.zig created+3421
......@@ -0,0 +1,3421 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const assert = std.debug.assert;
5const Compilation = @import("Compilation.zig");
6const Error = Compilation.Error;
7const Source = @import("Source.zig");
8const Tokenizer = @import("Tokenizer.zig");
9const RawToken = Tokenizer.Token;
10const Parser = @import("Parser.zig");
11const Diagnostics = @import("Diagnostics.zig");
12const Token = @import("Tree.zig").Token;
13const Attribute = @import("Attribute.zig");
14const features = @import("features.zig");
15
16const DefineMap = std.StringHashMapUnmanaged(Macro);
17const RawTokenList = std.ArrayList(RawToken);
18const max_include_depth = 200;
19
20/// Errors that can be returned when expanding a macro.
21/// error.UnknownPragma can occur within Preprocessor.pragma() but
22/// it is handled there and doesn't escape that function
23const MacroError = Error || error{StopPreprocessing};
24
25const Macro = struct {
26 /// Parameters of the function type macro
27 params: []const []const u8,
28
29 /// Token constituting the macro body
30 tokens: []const RawToken,
31
32 /// If the function type macro has variable number of arguments
33 var_args: bool,
34
35 /// Is a function type macro
36 is_func: bool,
37
38 /// Is a predefined macro
39 is_builtin: bool = false,
40
41 /// Location of macro in the source
42 loc: Source.Location,
43 start: u32,
44 end: u32,
45
46 fn eql(a: Macro, b: Macro, pp: *Preprocessor) bool {
47 if (a.tokens.len != b.tokens.len) return false;
48 if (a.is_builtin != b.is_builtin) return false;
49 for (a.tokens, b.tokens) |a_tok, b_tok| if (!tokEql(pp, a_tok, b_tok)) return false;
50
51 if (a.is_func and b.is_func) {
52 if (a.var_args != b.var_args) return false;
53 if (a.params.len != b.params.len) return false;
54 for (a.params, b.params) |a_param, b_param| if (!mem.eql(u8, a_param, b_param)) return false;
55 }
56
57 return true;
58 }
59
60 fn tokEql(pp: *Preprocessor, a: RawToken, b: RawToken) bool {
61 return mem.eql(u8, pp.tokSlice(a), pp.tokSlice(b));
62 }
63};
64
65const Preprocessor = @This();
66
67comp: *Compilation,
68gpa: mem.Allocator,
69arena: std.heap.ArenaAllocator,
70defines: DefineMap = .{},
71tokens: Token.List = .{},
72token_buf: RawTokenList,
73char_buf: std.ArrayList(u8),
74/// Counter that is incremented each time preprocess() is called
75/// Can be used to distinguish multiple preprocessings of the same file
76preprocess_count: u32 = 0,
77generated_line: u32 = 1,
78add_expansion_nl: u32 = 0,
79include_depth: u8 = 0,
80counter: u32 = 0,
81expansion_source_loc: Source.Location = undefined,
82poisoned_identifiers: std.StringHashMap(void),
83/// Map from Source.Id to macro name in the `#ifndef` condition which guards the source, if any
84include_guards: std.AutoHashMapUnmanaged(Source.Id, []const u8) = .{},
85
86/// Memory is retained to avoid allocation on every single token.
87top_expansion_buf: ExpandBuf,
88
89/// Dump current state to stderr.
90verbose: bool = false,
91preserve_whitespace: bool = false,
92
93/// linemarker tokens. Must be .none unless in -E mode (parser does not handle linemarkers)
94linemarkers: Linemarkers = .none,
95
96pub const parse = Parser.parse;
97
98pub const Linemarkers = enum {
99 /// No linemarker tokens. Required setting if parser will run
100 none,
101 /// #line <num> "filename"
102 line_directives,
103 /// # <num> "filename" flags
104 numeric_directives,
105};
106
107pub fn init(comp: *Compilation) Preprocessor {
108 const pp = Preprocessor{
109 .comp = comp,
110 .gpa = comp.gpa,
111 .arena = std.heap.ArenaAllocator.init(comp.gpa),
112 .token_buf = RawTokenList.init(comp.gpa),
113 .char_buf = std.ArrayList(u8).init(comp.gpa),
114 .poisoned_identifiers = std.StringHashMap(void).init(comp.gpa),
115 .top_expansion_buf = ExpandBuf.init(comp.gpa),
116 };
117 comp.pragmaEvent(.before_preprocess);
118 return pp;
119}
120
121/// Initialize Preprocessor with builtin macros.
122pub fn initDefault(comp: *Compilation) !Preprocessor {
123 var pp = init(comp);
124 errdefer pp.deinit();
125 try pp.addBuiltinMacros();
126 return pp;
127}
128
129const builtin_macros = struct {
130 const args = [1][]const u8{"X"};
131
132 const has_attribute = [1]RawToken{.{
133 .id = .macro_param_has_attribute,
134 .source = .generated,
135 }};
136 const has_c_attribute = [1]RawToken{.{
137 .id = .macro_param_has_c_attribute,
138 .source = .generated,
139 }};
140 const has_declspec_attribute = [1]RawToken{.{
141 .id = .macro_param_has_declspec_attribute,
142 .source = .generated,
143 }};
144 const has_warning = [1]RawToken{.{
145 .id = .macro_param_has_warning,
146 .source = .generated,
147 }};
148 const has_feature = [1]RawToken{.{
149 .id = .macro_param_has_feature,
150 .source = .generated,
151 }};
152 const has_extension = [1]RawToken{.{
153 .id = .macro_param_has_extension,
154 .source = .generated,
155 }};
156 const has_builtin = [1]RawToken{.{
157 .id = .macro_param_has_builtin,
158 .source = .generated,
159 }};
160 const has_include = [1]RawToken{.{
161 .id = .macro_param_has_include,
162 .source = .generated,
163 }};
164 const has_include_next = [1]RawToken{.{
165 .id = .macro_param_has_include_next,
166 .source = .generated,
167 }};
168 const has_embed = [1]RawToken{.{
169 .id = .macro_param_has_embed,
170 .source = .generated,
171 }};
172
173 const is_identifier = [1]RawToken{.{
174 .id = .macro_param_is_identifier,
175 .source = .generated,
176 }};
177
178 const pragma_operator = [1]RawToken{.{
179 .id = .macro_param_pragma_operator,
180 .source = .generated,
181 }};
182
183 const file = [1]RawToken{.{
184 .id = .macro_file,
185 .source = .generated,
186 }};
187 const line = [1]RawToken{.{
188 .id = .macro_line,
189 .source = .generated,
190 }};
191 const counter = [1]RawToken{.{
192 .id = .macro_counter,
193 .source = .generated,
194 }};
195};
196
197fn addBuiltinMacro(pp: *Preprocessor, name: []const u8, is_func: bool, tokens: []const RawToken) !void {
198 try pp.defines.putNoClobber(pp.gpa, name, .{
199 .params = &builtin_macros.args,
200 .tokens = tokens,
201 .var_args = false,
202 .is_func = is_func,
203 .loc = .{ .id = .generated },
204 .start = 0,
205 .end = 0,
206 .is_builtin = true,
207 });
208}
209
210pub fn addBuiltinMacros(pp: *Preprocessor) !void {
211 try pp.addBuiltinMacro("__has_attribute", true, &builtin_macros.has_attribute);
212 try pp.addBuiltinMacro("__has_c_attribute", true, &builtin_macros.has_c_attribute);
213 try pp.addBuiltinMacro("__has_declspec_attribute", true, &builtin_macros.has_declspec_attribute);
214 try pp.addBuiltinMacro("__has_warning", true, &builtin_macros.has_warning);
215 try pp.addBuiltinMacro("__has_feature", true, &builtin_macros.has_feature);
216 try pp.addBuiltinMacro("__has_extension", true, &builtin_macros.has_extension);
217 try pp.addBuiltinMacro("__has_builtin", true, &builtin_macros.has_builtin);
218 try pp.addBuiltinMacro("__has_include", true, &builtin_macros.has_include);
219 try pp.addBuiltinMacro("__has_include_next", true, &builtin_macros.has_include_next);
220 try pp.addBuiltinMacro("__has_embed", true, &builtin_macros.has_embed);
221 try pp.addBuiltinMacro("__is_identifier", true, &builtin_macros.is_identifier);
222 try pp.addBuiltinMacro("_Pragma", true, &builtin_macros.pragma_operator);
223
224 try pp.addBuiltinMacro("__FILE__", false, &builtin_macros.file);
225 try pp.addBuiltinMacro("__LINE__", false, &builtin_macros.line);
226 try pp.addBuiltinMacro("__COUNTER__", false, &builtin_macros.counter);
227}
228
229pub fn deinit(pp: *Preprocessor) void {
230 pp.defines.deinit(pp.gpa);
231 for (pp.tokens.items(.expansion_locs)) |loc| Token.free(loc, pp.gpa);
232 pp.tokens.deinit(pp.gpa);
233 pp.arena.deinit();
234 pp.token_buf.deinit();
235 pp.char_buf.deinit();
236 pp.poisoned_identifiers.deinit();
237 pp.include_guards.deinit(pp.gpa);
238 pp.top_expansion_buf.deinit();
239}
240
241/// Preprocess a compilation unit of sources into a parsable list of tokens.
242pub fn preprocessSources(pp: *Preprocessor, sources: []const Source) Error!void {
243 assert(sources.len > 1);
244 const first = sources[0];
245 try pp.addIncludeStart(first);
246 for (sources[1..]) |header| {
247 try pp.addIncludeStart(header);
248 _ = try pp.preprocess(header);
249 }
250 try pp.addIncludeResume(first.id, 0, 0);
251 const eof = try pp.preprocess(first);
252 try pp.tokens.append(pp.comp.gpa, eof);
253}
254
255/// Preprocess a source file, returns eof token.
256pub fn preprocess(pp: *Preprocessor, source: Source) Error!Token {
257 const eof = pp.preprocessExtra(source) catch |er| switch (er) {
258 // This cannot occur in the main file and is handled in `include`.
259 error.StopPreprocessing => unreachable,
260 else => |e| return e,
261 };
262 try eof.checkMsEof(source, pp.comp);
263 return eof;
264}
265
266/// Tokenize a file without any preprocessing, returns eof token.
267pub fn tokenize(pp: *Preprocessor, source: Source) Error!Token {
268 assert(pp.linemarkers == .none);
269 assert(pp.preserve_whitespace == false);
270 var tokenizer = Tokenizer{
271 .buf = source.buf,
272 .comp = pp.comp,
273 .source = source.id,
274 };
275
276 // Estimate how many new tokens this source will contain.
277 const estimated_token_count = source.buf.len / 8;
278 try pp.tokens.ensureTotalCapacity(pp.gpa, pp.tokens.len + estimated_token_count);
279
280 while (true) {
281 const tok = tokenizer.next();
282 if (tok.id == .eof) return tokFromRaw(tok);
283 try pp.tokens.append(pp.gpa, tokFromRaw(tok));
284 }
285}
286
287pub fn addIncludeStart(pp: *Preprocessor, source: Source) !void {
288 if (pp.linemarkers == .none) return;
289 try pp.tokens.append(pp.gpa, .{ .id = .include_start, .loc = .{
290 .id = source.id,
291 .byte_offset = std.math.maxInt(u32),
292 .line = 0,
293 } });
294}
295
296pub fn addIncludeResume(pp: *Preprocessor, source: Source.Id, offset: u32, line: u32) !void {
297 if (pp.linemarkers == .none) return;
298 try pp.tokens.append(pp.gpa, .{ .id = .include_resume, .loc = .{
299 .id = source,
300 .byte_offset = offset,
301 .line = line,
302 } });
303}
304
305fn invalidTokenDiagnostic(tok_id: Token.Id) Diagnostics.Tag {
306 return switch (tok_id) {
307 .unterminated_string_literal => .unterminated_string_literal_warning,
308 .empty_char_literal => .empty_char_literal_warning,
309 .unterminated_char_literal => .unterminated_char_literal_warning,
310 else => unreachable,
311 };
312}
313
314/// Return the name of the #ifndef guard macro that starts a source, if any.
315fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 {
316 var tokenizer = Tokenizer{
317 .buf = source.buf,
318 .langopts = pp.comp.langopts,
319 .source = source.id,
320 };
321 var hash = tokenizer.nextNoWS();
322 while (hash.id == .nl) hash = tokenizer.nextNoWS();
323 if (hash.id != .hash) return null;
324 const ifndef = tokenizer.nextNoWS();
325 if (ifndef.id != .keyword_ifndef) return null;
326 const guard = tokenizer.nextNoWS();
327 if (guard.id != .identifier) return null;
328 return pp.tokSlice(guard);
329}
330
331fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token {
332 var guard_name = pp.findIncludeGuard(source);
333
334 pp.preprocess_count += 1;
335 var tokenizer = Tokenizer{
336 .buf = source.buf,
337 .langopts = pp.comp.langopts,
338 .source = source.id,
339 };
340
341 // Estimate how many new tokens this source will contain.
342 const estimated_token_count = source.buf.len / 8;
343 try pp.tokens.ensureTotalCapacity(pp.gpa, pp.tokens.len + estimated_token_count);
344
345 var if_level: u8 = 0;
346 var if_kind = std.PackedIntArray(u2, 256).init([1]u2{0} ** 256);
347 const until_else = 0;
348 const until_endif = 1;
349 const until_endif_seen_else = 2;
350
351 var start_of_line = true;
352 while (true) {
353 var tok = tokenizer.next();
354 switch (tok.id) {
355 .hash => if (!start_of_line) try pp.tokens.append(pp.gpa, tokFromRaw(tok)) else {
356 const directive = tokenizer.nextNoWS();
357 switch (directive.id) {
358 .keyword_error, .keyword_warning => {
359 // #error tokens..
360 pp.top_expansion_buf.items.len = 0;
361 const char_top = pp.char_buf.items.len;
362 defer pp.char_buf.items.len = char_top;
363
364 while (true) {
365 tok = tokenizer.next();
366 if (tok.id == .nl or tok.id == .eof) break;
367 if (tok.id == .whitespace) tok.id = .macro_ws;
368 try pp.top_expansion_buf.append(tokFromRaw(tok));
369 }
370 try pp.stringify(pp.top_expansion_buf.items);
371 const slice = pp.char_buf.items[char_top + 1 .. pp.char_buf.items.len - 2];
372 const duped = try pp.comp.diagnostics.arena.allocator().dupe(u8, slice);
373
374 try pp.comp.addDiagnostic(.{
375 .tag = if (directive.id == .keyword_error) .error_directive else .warning_directive,
376 .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
377 .extra = .{ .str = duped },
378 }, &.{});
379 },
380 .keyword_if => {
381 const sum, const overflowed = @addWithOverflow(if_level, 1);
382 if (overflowed != 0)
383 return pp.fatal(directive, "too many #if nestings", .{});
384 if_level = sum;
385
386 if (try pp.expr(&tokenizer)) {
387 if_kind.set(if_level, until_endif);
388 if (pp.verbose) {
389 pp.verboseLog(directive, "entering then branch of #if", .{});
390 }
391 } else {
392 if_kind.set(if_level, until_else);
393 try pp.skip(&tokenizer, .until_else);
394 if (pp.verbose) {
395 pp.verboseLog(directive, "entering else branch of #if", .{});
396 }
397 }
398 },
399 .keyword_ifdef => {
400 const sum, const overflowed = @addWithOverflow(if_level, 1);
401 if (overflowed != 0)
402 return pp.fatal(directive, "too many #if nestings", .{});
403 if_level = sum;
404
405 const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
406 try pp.expectNl(&tokenizer);
407 if (pp.defines.get(macro_name) != null) {
408 if_kind.set(if_level, until_endif);
409 if (pp.verbose) {
410 pp.verboseLog(directive, "entering then branch of #ifdef", .{});
411 }
412 } else {
413 if_kind.set(if_level, until_else);
414 try pp.skip(&tokenizer, .until_else);
415 if (pp.verbose) {
416 pp.verboseLog(directive, "entering else branch of #ifdef", .{});
417 }
418 }
419 },
420 .keyword_ifndef => {
421 const sum, const overflowed = @addWithOverflow(if_level, 1);
422 if (overflowed != 0)
423 return pp.fatal(directive, "too many #if nestings", .{});
424 if_level = sum;
425
426 const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
427 try pp.expectNl(&tokenizer);
428 if (pp.defines.get(macro_name) == null) {
429 if_kind.set(if_level, until_endif);
430 } else {
431 if_kind.set(if_level, until_else);
432 try pp.skip(&tokenizer, .until_else);
433 }
434 },
435 .keyword_elif => {
436 if (if_level == 0) {
437 try pp.err(directive, .elif_without_if);
438 if_level += 1;
439 if_kind.set(if_level, until_else);
440 } else if (if_level == 1) {
441 guard_name = null;
442 }
443 switch (if_kind.get(if_level)) {
444 until_else => if (try pp.expr(&tokenizer)) {
445 if_kind.set(if_level, until_endif);
446 if (pp.verbose) {
447 pp.verboseLog(directive, "entering then branch of #elif", .{});
448 }
449 } else {
450 try pp.skip(&tokenizer, .until_else);
451 if (pp.verbose) {
452 pp.verboseLog(directive, "entering else branch of #elif", .{});
453 }
454 },
455 until_endif => try pp.skip(&tokenizer, .until_endif),
456 until_endif_seen_else => {
457 try pp.err(directive, .elif_after_else);
458 skipToNl(&tokenizer);
459 },
460 else => unreachable,
461 }
462 },
463 .keyword_elifdef => {
464 if (if_level == 0) {
465 try pp.err(directive, .elifdef_without_if);
466 if_level += 1;
467 if_kind.set(if_level, until_else);
468 } else if (if_level == 1) {
469 guard_name = null;
470 }
471 switch (if_kind.get(if_level)) {
472 until_else => {
473 const macro_name = try pp.expectMacroName(&tokenizer);
474 if (macro_name == null) {
475 if_kind.set(if_level, until_else);
476 try pp.skip(&tokenizer, .until_else);
477 if (pp.verbose) {
478 pp.verboseLog(directive, "entering else branch of #elifdef", .{});
479 }
480 } else {
481 try pp.expectNl(&tokenizer);
482 if (pp.defines.get(macro_name.?) != null) {
483 if_kind.set(if_level, until_endif);
484 if (pp.verbose) {
485 pp.verboseLog(directive, "entering then branch of #elifdef", .{});
486 }
487 } else {
488 if_kind.set(if_level, until_else);
489 try pp.skip(&tokenizer, .until_else);
490 if (pp.verbose) {
491 pp.verboseLog(directive, "entering else branch of #elifdef", .{});
492 }
493 }
494 }
495 },
496 until_endif => try pp.skip(&tokenizer, .until_endif),
497 until_endif_seen_else => {
498 try pp.err(directive, .elifdef_after_else);
499 skipToNl(&tokenizer);
500 },
501 else => unreachable,
502 }
503 },
504 .keyword_elifndef => {
505 if (if_level == 0) {
506 try pp.err(directive, .elifdef_without_if);
507 if_level += 1;
508 if_kind.set(if_level, until_else);
509 } else if (if_level == 1) {
510 guard_name = null;
511 }
512 switch (if_kind.get(if_level)) {
513 until_else => {
514 const macro_name = try pp.expectMacroName(&tokenizer);
515 if (macro_name == null) {
516 if_kind.set(if_level, until_else);
517 try pp.skip(&tokenizer, .until_else);
518 if (pp.verbose) {
519 pp.verboseLog(directive, "entering else branch of #elifndef", .{});
520 }
521 } else {
522 try pp.expectNl(&tokenizer);
523 if (pp.defines.get(macro_name.?) == null) {
524 if_kind.set(if_level, until_endif);
525 if (pp.verbose) {
526 pp.verboseLog(directive, "entering then branch of #elifndef", .{});
527 }
528 } else {
529 if_kind.set(if_level, until_else);
530 try pp.skip(&tokenizer, .until_else);
531 if (pp.verbose) {
532 pp.verboseLog(directive, "entering else branch of #elifndef", .{});
533 }
534 }
535 }
536 },
537 until_endif => try pp.skip(&tokenizer, .until_endif),
538 until_endif_seen_else => {
539 try pp.err(directive, .elifdef_after_else);
540 skipToNl(&tokenizer);
541 },
542 else => unreachable,
543 }
544 },
545 .keyword_else => {
546 try pp.expectNl(&tokenizer);
547 if (if_level == 0) {
548 try pp.err(directive, .else_without_if);
549 continue;
550 } else if (if_level == 1) {
551 guard_name = null;
552 }
553 switch (if_kind.get(if_level)) {
554 until_else => {
555 if_kind.set(if_level, until_endif_seen_else);
556 if (pp.verbose) {
557 pp.verboseLog(directive, "#else branch here", .{});
558 }
559 },
560 until_endif => try pp.skip(&tokenizer, .until_endif_seen_else),
561 until_endif_seen_else => {
562 try pp.err(directive, .else_after_else);
563 skipToNl(&tokenizer);
564 },
565 else => unreachable,
566 }
567 },
568 .keyword_endif => {
569 try pp.expectNl(&tokenizer);
570 if (if_level == 0) {
571 guard_name = null;
572 try pp.err(directive, .endif_without_if);
573 continue;
574 } else if (if_level == 1) {
575 const saved_tokenizer = tokenizer;
576 defer tokenizer = saved_tokenizer;
577
578 var next = tokenizer.nextNoWS();
579 while (next.id == .nl) : (next = tokenizer.nextNoWS()) {}
580 if (next.id != .eof) guard_name = null;
581 }
582 if_level -= 1;
583 },
584 .keyword_define => try pp.define(&tokenizer),
585 .keyword_undef => {
586 const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue;
587
588 _ = pp.defines.remove(macro_name);
589 try pp.expectNl(&tokenizer);
590 },
591 .keyword_include => {
592 try pp.include(&tokenizer, .first);
593 continue;
594 },
595 .keyword_include_next => {
596 try pp.comp.addDiagnostic(.{
597 .tag = .include_next,
598 .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
599 }, &.{});
600 if (pp.include_depth == 0) {
601 try pp.comp.addDiagnostic(.{
602 .tag = .include_next_outside_header,
603 .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line },
604 }, &.{});
605 try pp.include(&tokenizer, .first);
606 } else {
607 try pp.include(&tokenizer, .next);
608 }
609 },
610 .keyword_embed => try pp.embed(&tokenizer),
611 .keyword_pragma => {
612 try pp.pragma(&tokenizer, directive, null, &.{});
613 continue;
614 },
615 .keyword_line => {
616 // #line number "file"
617 const digits = tokenizer.nextNoWS();
618 if (digits.id != .pp_num) try pp.err(digits, .line_simple_digit);
619 // TODO: validate that the pp_num token is solely digits
620
621 if (digits.id == .eof or digits.id == .nl) continue;
622 const name = tokenizer.nextNoWS();
623 if (name.id == .eof or name.id == .nl) continue;
624 if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
625 try pp.expectNl(&tokenizer);
626 },
627 .pp_num => {
628 // # number "file" flags
629 // TODO: validate that the pp_num token is solely digits
630 // if not, emit `GNU line marker directive requires a simple digit sequence`
631 const name = tokenizer.nextNoWS();
632 if (name.id == .eof or name.id == .nl) continue;
633 if (name.id != .string_literal) try pp.err(name, .line_invalid_filename);
634
635 const flag_1 = tokenizer.nextNoWS();
636 if (flag_1.id == .eof or flag_1.id == .nl) continue;
637 const flag_2 = tokenizer.nextNoWS();
638 if (flag_2.id == .eof or flag_2.id == .nl) continue;
639 const flag_3 = tokenizer.nextNoWS();
640 if (flag_3.id == .eof or flag_3.id == .nl) continue;
641 const flag_4 = tokenizer.nextNoWS();
642 if (flag_4.id == .eof or flag_4.id == .nl) continue;
643 try pp.expectNl(&tokenizer);
644 },
645 .nl => {},
646 .eof => {
647 if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
648 return tokFromRaw(directive);
649 },
650 else => {
651 try pp.err(tok, .invalid_preprocessing_directive);
652 skipToNl(&tokenizer);
653 },
654 }
655 if (pp.preserve_whitespace) {
656 tok.id = .nl;
657 try pp.tokens.append(pp.gpa, tokFromRaw(tok));
658 }
659 },
660 .whitespace => if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok)),
661 .nl => {
662 start_of_line = true;
663 if (pp.preserve_whitespace) try pp.tokens.append(pp.gpa, tokFromRaw(tok));
664 },
665 .eof => {
666 if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive);
667 // The following check needs to occur here and not at the top of the function
668 // because a pragma may change the level during preprocessing
669 if (source.buf.len > 0 and source.buf[source.buf.len - 1] != '\n') {
670 try pp.err(tok, .newline_eof);
671 }
672 if (guard_name) |name| {
673 if (try pp.include_guards.fetchPut(pp.gpa, source.id, name)) |prev| {
674 assert(mem.eql(u8, name, prev.value));
675 }
676 }
677 return tokFromRaw(tok);
678 },
679 .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| {
680 start_of_line = false;
681 try pp.err(tok, invalidTokenDiagnostic(tag));
682 try pp.expandMacro(&tokenizer, tok);
683 },
684 .unterminated_comment => try pp.err(tok, .unterminated_comment),
685 else => {
686 if (tok.id.isMacroIdentifier() and pp.poisoned_identifiers.get(pp.tokSlice(tok)) != null) {
687 try pp.err(tok, .poisoned_identifier);
688 }
689 // Add the token to the buffer doing any necessary expansions.
690 start_of_line = false;
691 try pp.expandMacro(&tokenizer, tok);
692 },
693 }
694 }
695}
696
697/// Get raw token source string.
698/// Returned slice is invalidated when comp.generated_buf is updated.
699pub fn tokSlice(pp: *Preprocessor, token: RawToken) []const u8 {
700 if (token.id.lexeme()) |some| return some;
701 const source = pp.comp.getSource(token.source);
702 return source.buf[token.start..token.end];
703}
704
705/// Convert a token from the Tokenizer into a token used by the parser.
706fn tokFromRaw(raw: RawToken) Token {
707 return .{
708 .id = raw.id,
709 .loc = .{
710 .id = raw.source,
711 .byte_offset = raw.start,
712 .line = raw.line,
713 },
714 };
715}
716
717fn err(pp: *Preprocessor, raw: RawToken, tag: Diagnostics.Tag) !void {
718 try pp.comp.addDiagnostic(.{
719 .tag = tag,
720 .loc = .{
721 .id = raw.source,
722 .byte_offset = raw.start,
723 .line = raw.line,
724 },
725 }, &.{});
726}
727
728fn errStr(pp: *Preprocessor, tok: Token, tag: Diagnostics.Tag, str: []const u8) !void {
729 try pp.comp.addDiagnostic(.{
730 .tag = tag,
731 .loc = tok.loc,
732 .extra = .{ .str = str },
733 }, tok.expansionSlice());
734}
735
736fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) Compilation.Error {
737 try pp.comp.diagnostics.list.append(pp.gpa, .{
738 .tag = .cli_error,
739 .kind = .@"fatal error",
740 .extra = .{ .str = try std.fmt.allocPrint(pp.comp.diagnostics.arena.allocator(), fmt, args) },
741 .loc = .{
742 .id = raw.source,
743 .byte_offset = raw.start,
744 .line = raw.line,
745 },
746 });
747 return error.FatalError;
748}
749
750fn fatalNotFound(pp: *Preprocessor, tok: Token, filename: []const u8) Compilation.Error {
751 const old = pp.comp.diagnostics.fatal_errors;
752 pp.comp.diagnostics.fatal_errors = true;
753 defer pp.comp.diagnostics.fatal_errors = old;
754
755 try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ .tag = .cli_error, .loc = tok.loc, .extra = .{
756 .str = try std.fmt.allocPrint(pp.comp.diagnostics.arena.allocator(), "'{s}' not found", .{filename}),
757 } }, tok.expansionSlice(), false);
758 unreachable; // addExtra should've returned FatalError
759}
760
761fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void {
762 const source = pp.comp.getSource(raw.source);
763 const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start });
764
765 const stderr = std.io.getStdErr().writer();
766 var buf_writer = std.io.bufferedWriter(stderr);
767 const writer = buf_writer.writer();
768 defer buf_writer.flush() catch {};
769 writer.print("{s}:{d}:{d}: ", .{ source.path, line_col.line_no, line_col.col }) catch return;
770 writer.print(fmt, args) catch return;
771 writer.writeByte('\n') catch return;
772 writer.writeAll(line_col.line) catch return;
773 writer.writeByte('\n') catch return;
774}
775
776/// Consume next token, error if it is not an identifier.
777fn expectMacroName(pp: *Preprocessor, tokenizer: *Tokenizer) Error!?[]const u8 {
778 const macro_name = tokenizer.nextNoWS();
779 if (!macro_name.id.isMacroIdentifier()) {
780 try pp.err(macro_name, .macro_name_missing);
781 skipToNl(tokenizer);
782 return null;
783 }
784 return pp.tokSlice(macro_name);
785}
786
787/// Skip until after a newline, error if extra tokens before it.
788fn expectNl(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
789 var sent_err = false;
790 while (true) {
791 const tok = tokenizer.next();
792 if (tok.id == .nl or tok.id == .eof) return;
793 if (tok.id == .whitespace) continue;
794 if (!sent_err) {
795 sent_err = true;
796 try pp.err(tok, .extra_tokens_directive_end);
797 }
798 }
799}
800
801/// Consume all tokens until a newline and parse the result into a boolean.
802fn expr(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!bool {
803 const start = pp.tokens.len;
804 defer {
805 for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
806 pp.tokens.len = start;
807 }
808
809 pp.top_expansion_buf.items.len = 0;
810 const eof = while (true) {
811 const tok = tokenizer.next();
812 switch (tok.id) {
813 .nl, .eof => break tok,
814 .whitespace => if (pp.top_expansion_buf.items.len == 0) continue,
815 else => {},
816 }
817 try pp.top_expansion_buf.append(tokFromRaw(tok));
818 } else unreachable;
819 if (pp.top_expansion_buf.items.len != 0) {
820 pp.expansion_source_loc = pp.top_expansion_buf.items[0].loc;
821 try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, pp.top_expansion_buf.items.len, false, .expr);
822 }
823 for (pp.top_expansion_buf.items) |tok| {
824 if (tok.id == .macro_ws) continue;
825 if (!tok.id.validPreprocessorExprStart()) {
826 try pp.comp.addDiagnostic(.{
827 .tag = .invalid_preproc_expr_start,
828 .loc = tok.loc,
829 }, tok.expansionSlice());
830 return false;
831 }
832 break;
833 } else {
834 try pp.err(eof, .expected_value_in_expr);
835 return false;
836 }
837
838 // validate the tokens in the expression
839 try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
840 var i: usize = 0;
841 const items = pp.top_expansion_buf.items;
842 while (i < items.len) : (i += 1) {
843 var tok = items[i];
844 switch (tok.id) {
845 .string_literal,
846 .string_literal_utf_16,
847 .string_literal_utf_8,
848 .string_literal_utf_32,
849 .string_literal_wide,
850 => {
851 try pp.comp.addDiagnostic(.{
852 .tag = .string_literal_in_pp_expr,
853 .loc = tok.loc,
854 }, tok.expansionSlice());
855 return false;
856 },
857 .plus_plus,
858 .minus_minus,
859 .plus_equal,
860 .minus_equal,
861 .asterisk_equal,
862 .slash_equal,
863 .percent_equal,
864 .angle_bracket_angle_bracket_left_equal,
865 .angle_bracket_angle_bracket_right_equal,
866 .ampersand_equal,
867 .caret_equal,
868 .pipe_equal,
869 .l_bracket,
870 .r_bracket,
871 .l_brace,
872 .r_brace,
873 .ellipsis,
874 .semicolon,
875 .hash,
876 .hash_hash,
877 .equal,
878 .arrow,
879 .period,
880 => {
881 try pp.comp.addDiagnostic(.{
882 .tag = .invalid_preproc_operator,
883 .loc = tok.loc,
884 }, tok.expansionSlice());
885 return false;
886 },
887 .macro_ws, .whitespace => continue,
888 .keyword_false => tok.id = .zero,
889 .keyword_true => tok.id = .one,
890 else => if (tok.id.isMacroIdentifier()) {
891 if (tok.id == .keyword_defined) {
892 const tokens_consumed = try pp.handleKeywordDefined(&tok, items[i + 1 ..], eof);
893 i += tokens_consumed;
894 } else {
895 try pp.errStr(tok, .undefined_macro, pp.expandedSlice(tok));
896
897 if (i + 1 < pp.top_expansion_buf.items.len and
898 pp.top_expansion_buf.items[i + 1].id == .l_paren)
899 {
900 try pp.errStr(tok, .fn_macro_undefined, pp.expandedSlice(tok));
901 return false;
902 }
903
904 tok.id = .zero; // undefined macro
905 }
906 },
907 }
908 pp.tokens.appendAssumeCapacity(tok);
909 }
910 try pp.tokens.append(pp.gpa, .{
911 .id = .eof,
912 .loc = tokFromRaw(eof).loc,
913 });
914
915 // Actually parse it.
916 var parser = Parser{
917 .pp = pp,
918 .comp = pp.comp,
919 .gpa = pp.gpa,
920 .tok_ids = pp.tokens.items(.id),
921 .tok_i = @intCast(start),
922 .arena = pp.arena.allocator(),
923 .in_macro = true,
924 .strings = std.ArrayList(u8).init(pp.comp.gpa),
925
926 .data = undefined,
927 .value_map = undefined,
928 .labels = undefined,
929 .decl_buf = undefined,
930 .list_buf = undefined,
931 .param_buf = undefined,
932 .enum_buf = undefined,
933 .record_buf = undefined,
934 .attr_buf = undefined,
935 .field_attr_buf = undefined,
936 .string_ids = undefined,
937 };
938 defer parser.strings.deinit();
939 return parser.macroExpr();
940}
941
942/// Turns macro_tok from .keyword_defined into .zero or .one depending on whether the argument is defined
943/// Returns the number of tokens consumed
944fn handleKeywordDefined(pp: *Preprocessor, macro_tok: *Token, tokens: []const Token, eof: RawToken) !usize {
945 std.debug.assert(macro_tok.id == .keyword_defined);
946 var it = TokenIterator.init(tokens);
947 const first = it.nextNoWS() orelse {
948 try pp.err(eof, .macro_name_missing);
949 return it.i;
950 };
951 switch (first.id) {
952 .l_paren => {},
953 else => {
954 if (!first.id.isMacroIdentifier()) {
955 try pp.errStr(first, .macro_name_must_be_identifier, pp.expandedSlice(first));
956 }
957 macro_tok.id = if (pp.defines.contains(pp.expandedSlice(first))) .one else .zero;
958 return it.i;
959 },
960 }
961 const second = it.nextNoWS() orelse {
962 try pp.err(eof, .macro_name_missing);
963 return it.i;
964 };
965 if (!second.id.isMacroIdentifier()) {
966 try pp.comp.addDiagnostic(.{
967 .tag = .macro_name_must_be_identifier,
968 .loc = second.loc,
969 }, second.expansionSlice());
970 return it.i;
971 }
972 macro_tok.id = if (pp.defines.contains(pp.expandedSlice(second))) .one else .zero;
973
974 const last = it.nextNoWS();
975 if (last == null or last.?.id != .r_paren) {
976 const tok = last orelse tokFromRaw(eof);
977 try pp.comp.addDiagnostic(.{
978 .tag = .closing_paren,
979 .loc = tok.loc,
980 }, tok.expansionSlice());
981 try pp.comp.addDiagnostic(.{
982 .tag = .to_match_paren,
983 .loc = first.loc,
984 }, first.expansionSlice());
985 }
986
987 return it.i;
988}
989
990/// Skip until #else #elif #endif, return last directive token id.
991/// Also skips nested #if ... #endifs.
992fn skip(
993 pp: *Preprocessor,
994 tokenizer: *Tokenizer,
995 cont: enum { until_else, until_endif, until_endif_seen_else },
996) Error!void {
997 var ifs_seen: u32 = 0;
998 var line_start = true;
999 while (tokenizer.index < tokenizer.buf.len) {
1000 if (line_start) {
1001 const saved_tokenizer = tokenizer.*;
1002 const hash = tokenizer.nextNoWS();
1003 if (hash.id == .nl) continue;
1004 line_start = false;
1005 if (hash.id != .hash) continue;
1006 const directive = tokenizer.nextNoWS();
1007 switch (directive.id) {
1008 .keyword_else => {
1009 if (ifs_seen != 0) continue;
1010 if (cont == .until_endif_seen_else) {
1011 try pp.err(directive, .else_after_else);
1012 continue;
1013 }
1014 tokenizer.* = saved_tokenizer;
1015 return;
1016 },
1017 .keyword_elif => {
1018 if (ifs_seen != 0 or cont == .until_endif) continue;
1019 if (cont == .until_endif_seen_else) {
1020 try pp.err(directive, .elif_after_else);
1021 continue;
1022 }
1023 tokenizer.* = saved_tokenizer;
1024 return;
1025 },
1026 .keyword_elifdef => {
1027 if (ifs_seen != 0 or cont == .until_endif) continue;
1028 if (cont == .until_endif_seen_else) {
1029 try pp.err(directive, .elifdef_after_else);
1030 continue;
1031 }
1032 tokenizer.* = saved_tokenizer;
1033 return;
1034 },
1035 .keyword_elifndef => {
1036 if (ifs_seen != 0 or cont == .until_endif) continue;
1037 if (cont == .until_endif_seen_else) {
1038 try pp.err(directive, .elifndef_after_else);
1039 continue;
1040 }
1041 tokenizer.* = saved_tokenizer;
1042 return;
1043 },
1044 .keyword_endif => {
1045 if (ifs_seen == 0) {
1046 tokenizer.* = saved_tokenizer;
1047 return;
1048 }
1049 ifs_seen -= 1;
1050 },
1051 .keyword_if, .keyword_ifdef, .keyword_ifndef => ifs_seen += 1,
1052 else => {},
1053 }
1054 } else if (tokenizer.buf[tokenizer.index] == '\n') {
1055 line_start = true;
1056 tokenizer.index += 1;
1057 tokenizer.line += 1;
1058 if (pp.preserve_whitespace) {
1059 try pp.tokens.append(pp.gpa, .{ .id = .nl, .loc = .{
1060 .id = tokenizer.source,
1061 .line = tokenizer.line,
1062 } });
1063 }
1064 } else {
1065 line_start = false;
1066 tokenizer.index += 1;
1067 }
1068 } else {
1069 const eof = tokenizer.next();
1070 return pp.err(eof, .unterminated_conditional_directive);
1071 }
1072}
1073
1074// Skip until newline, ignore other tokens.
1075fn skipToNl(tokenizer: *Tokenizer) void {
1076 while (true) {
1077 const tok = tokenizer.next();
1078 if (tok.id == .nl or tok.id == .eof) return;
1079 }
1080}
1081
1082const ExpandBuf = std.ArrayList(Token);
1083fn removePlacemarkers(buf: *ExpandBuf) void {
1084 var i: usize = buf.items.len -% 1;
1085 while (i < buf.items.len) : (i -%= 1) {
1086 if (buf.items[i].id == .placemarker) {
1087 const placemarker = buf.orderedRemove(i);
1088 Token.free(placemarker.expansion_locs, buf.allocator);
1089 }
1090 }
1091}
1092
1093const MacroArguments = std.ArrayList([]const Token);
1094fn deinitMacroArguments(allocator: Allocator, args: *const MacroArguments) void {
1095 for (args.items) |item| {
1096 for (item) |tok| Token.free(tok.expansion_locs, allocator);
1097 allocator.free(item);
1098 }
1099 args.deinit();
1100}
1101
1102fn expandObjMacro(pp: *Preprocessor, simple_macro: *const Macro) Error!ExpandBuf {
1103 var buf = ExpandBuf.init(pp.gpa);
1104 errdefer buf.deinit();
1105 try buf.ensureTotalCapacity(simple_macro.tokens.len);
1106
1107 // Add all of the simple_macros tokens to the new buffer handling any concats.
1108 var i: usize = 0;
1109 while (i < simple_macro.tokens.len) : (i += 1) {
1110 const raw = simple_macro.tokens[i];
1111 const tok = tokFromRaw(raw);
1112 switch (raw.id) {
1113 .hash_hash => {
1114 var rhs = tokFromRaw(simple_macro.tokens[i + 1]);
1115 i += 1;
1116 while (true) {
1117 if (rhs.id == .whitespace) {
1118 rhs = tokFromRaw(simple_macro.tokens[i + 1]);
1119 i += 1;
1120 } else if (rhs.id == .comment and !pp.comp.langopts.preserve_comments_in_macros) {
1121 rhs = tokFromRaw(simple_macro.tokens[i + 1]);
1122 i += 1;
1123 } else break;
1124 }
1125 try pp.pasteTokens(&buf, &.{rhs});
1126 },
1127 .whitespace => if (pp.preserve_whitespace) buf.appendAssumeCapacity(tok),
1128 .macro_file => {
1129 const start = pp.comp.generated_buf.items.len;
1130 const source = pp.comp.getSource(pp.expansion_source_loc.id);
1131 const w = pp.comp.generated_buf.writer(pp.gpa);
1132 try w.print("\"{s}\"\n", .{source.path});
1133
1134 buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .string_literal, tok));
1135 },
1136 .macro_line => {
1137 const start = pp.comp.generated_buf.items.len;
1138 const source = pp.comp.getSource(pp.expansion_source_loc.id);
1139 const w = pp.comp.generated_buf.writer(pp.gpa);
1140 try w.print("{d}\n", .{source.physicalLine(pp.expansion_source_loc)});
1141
1142 buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
1143 },
1144 .macro_counter => {
1145 defer pp.counter += 1;
1146 const start = pp.comp.generated_buf.items.len;
1147 const w = pp.comp.generated_buf.writer(pp.gpa);
1148 try w.print("{d}\n", .{pp.counter});
1149
1150 buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok));
1151 },
1152 else => buf.appendAssumeCapacity(tok),
1153 }
1154 }
1155
1156 return buf;
1157}
1158
1159/// Join a possibly-parenthesized series of string literal tokens into a single string without
1160/// leading or trailing quotes. The returned slice is invalidated if pp.char_buf changes.
1161/// Returns error.ExpectedStringLiteral if parentheses are not balanced, a non-string-literal
1162/// is encountered, or if no string literals are encountered
1163/// TODO: destringize (replace all '\\' with a single `\` and all '\"' with a '"')
1164fn pasteStringsUnsafe(pp: *Preprocessor, toks: []const Token) ![]const u8 {
1165 const char_top = pp.char_buf.items.len;
1166 defer pp.char_buf.items.len = char_top;
1167 var unwrapped = toks;
1168 if (toks.len >= 2 and toks[0].id == .l_paren and toks[toks.len - 1].id == .r_paren) {
1169 unwrapped = toks[1 .. toks.len - 1];
1170 }
1171 if (unwrapped.len == 0) return error.ExpectedStringLiteral;
1172
1173 for (unwrapped) |tok| {
1174 if (tok.id == .macro_ws) continue;
1175 if (tok.id != .string_literal) return error.ExpectedStringLiteral;
1176 const str = pp.expandedSlice(tok);
1177 try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
1178 }
1179 return pp.char_buf.items[char_top..];
1180}
1181
1182/// Handle the _Pragma operator (implemented as a builtin macro)
1183fn pragmaOperator(pp: *Preprocessor, arg_tok: Token, operator_loc: Source.Location) !void {
1184 const arg_slice = pp.expandedSlice(arg_tok);
1185 const content = arg_slice[1 .. arg_slice.len - 1];
1186 const directive = "#pragma ";
1187
1188 pp.char_buf.clearRetainingCapacity();
1189 const total_len = directive.len + content.len + 1; // destringify can never grow the string, + 1 for newline
1190 try pp.char_buf.ensureUnusedCapacity(total_len);
1191 pp.char_buf.appendSliceAssumeCapacity(directive);
1192 pp.destringify(content);
1193 pp.char_buf.appendAssumeCapacity('\n');
1194
1195 const start = pp.comp.generated_buf.items.len;
1196 try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items);
1197 var tmp_tokenizer = Tokenizer{
1198 .buf = pp.comp.generated_buf.items,
1199 .langopts = pp.comp.langopts,
1200 .index = @intCast(start),
1201 .source = .generated,
1202 .line = pp.generated_line,
1203 };
1204 pp.generated_line += 1;
1205 const hash_tok = tmp_tokenizer.next();
1206 assert(hash_tok.id == .hash);
1207 const pragma_tok = tmp_tokenizer.next();
1208 assert(pragma_tok.id == .keyword_pragma);
1209 try pp.pragma(&tmp_tokenizer, pragma_tok, operator_loc, arg_tok.expansionSlice());
1210}
1211
1212/// Inverts the output of the preprocessor stringify (#) operation
1213/// (except all whitespace is condensed to a single space)
1214/// writes output to pp.char_buf; assumes capacity is sufficient
1215/// backslash backslash -> backslash
1216/// backslash doublequote -> doublequote
1217/// All other characters remain the same
1218fn destringify(pp: *Preprocessor, str: []const u8) void {
1219 var state: enum { start, backslash_seen } = .start;
1220 for (str) |c| {
1221 switch (c) {
1222 '\\' => {
1223 if (state == .backslash_seen) pp.char_buf.appendAssumeCapacity(c);
1224 state = if (state == .start) .backslash_seen else .start;
1225 },
1226 else => {
1227 if (state == .backslash_seen and c != '"') pp.char_buf.appendAssumeCapacity('\\');
1228 pp.char_buf.appendAssumeCapacity(c);
1229 state = .start;
1230 },
1231 }
1232 }
1233}
1234
1235/// Stringify `tokens` into pp.char_buf.
1236/// See https://gcc.gnu.org/onlinedocs/gcc-11.2.0/cpp/Stringizing.html#Stringizing
1237fn stringify(pp: *Preprocessor, tokens: []const Token) !void {
1238 try pp.char_buf.append('"');
1239 var ws_state: enum { start, need, not_needed } = .start;
1240 for (tokens) |tok| {
1241 if (tok.id == .macro_ws) {
1242 if (ws_state == .start) continue;
1243 ws_state = .need;
1244 continue;
1245 }
1246 if (ws_state == .need) try pp.char_buf.append(' ');
1247 ws_state = .not_needed;
1248
1249 // backslashes not inside strings are not escaped
1250 const is_str = switch (tok.id) {
1251 .string_literal,
1252 .string_literal_utf_16,
1253 .string_literal_utf_8,
1254 .string_literal_utf_32,
1255 .string_literal_wide,
1256 .char_literal,
1257 .char_literal_utf_16,
1258 .char_literal_utf_32,
1259 .char_literal_wide,
1260 => true,
1261 else => false,
1262 };
1263
1264 for (pp.expandedSlice(tok)) |c| {
1265 if (c == '"')
1266 try pp.char_buf.appendSlice("\\\"")
1267 else if (c == '\\' and is_str)
1268 try pp.char_buf.appendSlice("\\\\")
1269 else
1270 try pp.char_buf.append(c);
1271 }
1272 }
1273 if (pp.char_buf.items[pp.char_buf.items.len - 1] == '\\') {
1274 const tok = tokens[tokens.len - 1];
1275 try pp.comp.addDiagnostic(.{
1276 .tag = .invalid_pp_stringify_escape,
1277 .loc = tok.loc,
1278 }, tok.expansionSlice());
1279 pp.char_buf.items.len -= 1;
1280 }
1281 try pp.char_buf.appendSlice("\"\n");
1282}
1283
1284fn reconstructIncludeString(pp: *Preprocessor, param_toks: []const Token, embed_args: ?*[]const Token) !?[]const u8 {
1285 const char_top = pp.char_buf.items.len;
1286 defer pp.char_buf.items.len = char_top;
1287
1288 // Trim leading/trailing whitespace
1289 var begin: usize = 0;
1290 var end: usize = param_toks.len;
1291 while (begin < end and param_toks[begin].id == .macro_ws) : (begin += 1) {}
1292 while (end > begin and param_toks[end - 1].id == .macro_ws) : (end -= 1) {}
1293 const params = param_toks[begin..end];
1294
1295 if (params.len == 0) {
1296 try pp.comp.addDiagnostic(.{
1297 .tag = .expected_filename,
1298 .loc = param_toks[0].loc,
1299 }, param_toks[0].expansionSlice());
1300 return null;
1301 }
1302 // no string pasting
1303 if (embed_args == null and params[0].id == .string_literal and params.len > 1) {
1304 try pp.comp.addDiagnostic(.{
1305 .tag = .closing_paren,
1306 .loc = params[1].loc,
1307 }, params[1].expansionSlice());
1308 return null;
1309 }
1310
1311 for (params, 0..) |tok, i| {
1312 const str = pp.expandedSliceExtra(tok, .preserve_macro_ws);
1313 try pp.char_buf.appendSlice(str);
1314 if (embed_args) |some| {
1315 if ((i == 0 and tok.id == .string_literal) or tok.id == .angle_bracket_right) {
1316 some.* = params[i + 1 ..];
1317 break;
1318 }
1319 }
1320 }
1321
1322 const include_str = pp.char_buf.items[char_top..];
1323 if (include_str.len < 3) {
1324 try pp.comp.addDiagnostic(.{
1325 .tag = .empty_filename,
1326 .loc = params[0].loc,
1327 }, params[0].expansionSlice());
1328 return null;
1329 }
1330
1331 switch (include_str[0]) {
1332 '<' => {
1333 if (include_str[include_str.len - 1] != '>') {
1334 // Ugly hack to find out where the '>' should go, since we don't have the closing ')' location
1335 const start = params[0].loc;
1336 try pp.comp.addDiagnostic(.{
1337 .tag = .header_str_closing,
1338 .loc = .{ .id = start.id, .byte_offset = start.byte_offset + @as(u32, @intCast(include_str.len)) + 1, .line = start.line },
1339 }, params[0].expansionSlice());
1340 try pp.comp.addDiagnostic(.{
1341 .tag = .header_str_match,
1342 .loc = params[0].loc,
1343 }, params[0].expansionSlice());
1344 return null;
1345 }
1346 return include_str;
1347 },
1348 '"' => return include_str,
1349 else => {
1350 try pp.comp.addDiagnostic(.{
1351 .tag = .expected_filename,
1352 .loc = params[0].loc,
1353 }, params[0].expansionSlice());
1354 return null;
1355 },
1356 }
1357}
1358
1359fn handleBuiltinMacro(pp: *Preprocessor, builtin: RawToken.Id, param_toks: []const Token, src_loc: Source.Location) Error!bool {
1360 switch (builtin) {
1361 .macro_param_has_attribute,
1362 .macro_param_has_declspec_attribute,
1363 .macro_param_has_feature,
1364 .macro_param_has_extension,
1365 .macro_param_has_builtin,
1366 => {
1367 var invalid: ?Token = null;
1368 var identifier: ?Token = null;
1369 for (param_toks) |tok| {
1370 if (tok.id == .macro_ws) continue;
1371 if (tok.id == .comment) continue;
1372 if (!tok.id.isMacroIdentifier()) {
1373 invalid = tok;
1374 break;
1375 }
1376 if (identifier) |_| invalid = tok else identifier = tok;
1377 }
1378 if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
1379 if (invalid) |some| {
1380 try pp.comp.addDiagnostic(
1381 .{ .tag = .feature_check_requires_identifier, .loc = some.loc },
1382 some.expansionSlice(),
1383 );
1384 return false;
1385 }
1386
1387 const ident_str = pp.expandedSlice(identifier.?);
1388 return switch (builtin) {
1389 .macro_param_has_attribute => Attribute.fromString(.gnu, null, ident_str) != null,
1390 .macro_param_has_declspec_attribute => {
1391 return if (pp.comp.langopts.declspec_attrs)
1392 Attribute.fromString(.declspec, null, ident_str) != null
1393 else
1394 false;
1395 },
1396 .macro_param_has_feature => features.hasFeature(pp.comp, ident_str),
1397 .macro_param_has_extension => features.hasExtension(pp.comp, ident_str),
1398 .macro_param_has_builtin => pp.comp.hasBuiltin(ident_str),
1399 else => unreachable,
1400 };
1401 },
1402 .macro_param_has_warning => {
1403 const actual_param = pp.pasteStringsUnsafe(param_toks) catch |er| switch (er) {
1404 error.ExpectedStringLiteral => {
1405 try pp.errStr(param_toks[0], .expected_str_literal_in, "__has_warning");
1406 return false;
1407 },
1408 else => |e| return e,
1409 };
1410 if (!mem.startsWith(u8, actual_param, "-W")) {
1411 try pp.errStr(param_toks[0], .malformed_warning_check, "__has_warning");
1412 return false;
1413 }
1414 const warning_name = actual_param[2..];
1415 return Diagnostics.warningExists(warning_name);
1416 },
1417 .macro_param_is_identifier => {
1418 var invalid: ?Token = null;
1419 var identifier: ?Token = null;
1420 for (param_toks) |tok| switch (tok.id) {
1421 .macro_ws => continue,
1422 .comment => continue,
1423 else => {
1424 if (identifier) |_| invalid = tok else identifier = tok;
1425 },
1426 };
1427 if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc };
1428 if (invalid) |some| {
1429 try pp.comp.addDiagnostic(.{
1430 .tag = .missing_tok_builtin,
1431 .loc = some.loc,
1432 .extra = .{ .tok_id_expected = .r_paren },
1433 }, some.expansionSlice());
1434 return false;
1435 }
1436
1437 const id = identifier.?.id;
1438 return id == .identifier or id == .extended_identifier;
1439 },
1440 .macro_param_has_include, .macro_param_has_include_next => {
1441 const include_str = (try pp.reconstructIncludeString(param_toks, null)) orelse return false;
1442 const include_type: Compilation.IncludeType = switch (include_str[0]) {
1443 '"' => .quotes,
1444 '<' => .angle_brackets,
1445 else => unreachable,
1446 };
1447 const filename = include_str[1 .. include_str.len - 1];
1448 if (builtin == .macro_param_has_include or pp.include_depth == 0) {
1449 if (builtin == .macro_param_has_include_next) {
1450 try pp.comp.addDiagnostic(.{
1451 .tag = .include_next_outside_header,
1452 .loc = src_loc,
1453 }, &.{});
1454 }
1455 return pp.comp.hasInclude(filename, src_loc.id, include_type, .first);
1456 }
1457 return pp.comp.hasInclude(filename, src_loc.id, include_type, .next);
1458 },
1459 else => unreachable,
1460 }
1461}
1462
1463fn expandFuncMacro(
1464 pp: *Preprocessor,
1465 loc: Source.Location,
1466 func_macro: *const Macro,
1467 args: *const MacroArguments,
1468 expanded_args: *const MacroArguments,
1469) MacroError!ExpandBuf {
1470 var buf = ExpandBuf.init(pp.gpa);
1471 try buf.ensureTotalCapacity(func_macro.tokens.len);
1472 errdefer buf.deinit();
1473
1474 var expanded_variable_arguments = ExpandBuf.init(pp.gpa);
1475 defer expanded_variable_arguments.deinit();
1476 var variable_arguments = ExpandBuf.init(pp.gpa);
1477 defer variable_arguments.deinit();
1478
1479 if (func_macro.var_args) {
1480 var i: usize = func_macro.params.len;
1481 while (i < expanded_args.items.len) : (i += 1) {
1482 try variable_arguments.appendSlice(args.items[i]);
1483 try expanded_variable_arguments.appendSlice(expanded_args.items[i]);
1484 if (i != expanded_args.items.len - 1) {
1485 const comma = Token{ .id = .comma, .loc = .{ .id = .generated } };
1486 try variable_arguments.append(comma);
1487 try expanded_variable_arguments.append(comma);
1488 }
1489 }
1490 }
1491
1492 // token concatenation and expansion phase
1493 var tok_i: usize = 0;
1494 while (tok_i < func_macro.tokens.len) : (tok_i += 1) {
1495 const raw = func_macro.tokens[tok_i];
1496 switch (raw.id) {
1497 .hash_hash => while (tok_i + 1 < func_macro.tokens.len) {
1498 const raw_next = func_macro.tokens[tok_i + 1];
1499 tok_i += 1;
1500
1501 var va_opt_buf = ExpandBuf.init(pp.gpa);
1502 defer va_opt_buf.deinit();
1503
1504 const next = switch (raw_next.id) {
1505 .macro_ws => continue,
1506 .hash_hash => continue,
1507 .comment => if (!pp.comp.langopts.preserve_comments_in_macros)
1508 continue
1509 else
1510 &[1]Token{tokFromRaw(raw_next)},
1511 .macro_param, .macro_param_no_expand => if (args.items[raw_next.end].len > 0)
1512 args.items[raw_next.end]
1513 else
1514 &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })},
1515 .keyword_va_args => variable_arguments.items,
1516 .keyword_va_opt => blk: {
1517 try pp.expandVaOpt(&va_opt_buf, raw_next, variable_arguments.items.len != 0);
1518 if (va_opt_buf.items.len == 0) break;
1519 break :blk va_opt_buf.items;
1520 },
1521 else => &[1]Token{tokFromRaw(raw_next)},
1522 };
1523
1524 try pp.pasteTokens(&buf, next);
1525 if (next.len != 0) break;
1526 },
1527 .macro_param_no_expand => {
1528 const slice = if (args.items[raw.end].len > 0)
1529 args.items[raw.end]
1530 else
1531 &[1]Token{tokFromRaw(.{ .id = .placemarker, .source = .generated })};
1532 const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
1533 try bufCopyTokens(&buf, slice, &.{raw_loc});
1534 },
1535 .macro_param => {
1536 const arg = expanded_args.items[raw.end];
1537 const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
1538 try bufCopyTokens(&buf, arg, &.{raw_loc});
1539 },
1540 .keyword_va_args => {
1541 const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line };
1542 try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
1543 },
1544 .keyword_va_opt => {
1545 try pp.expandVaOpt(&buf, raw, variable_arguments.items.len != 0);
1546 },
1547 .stringify_param, .stringify_va_args => {
1548 const arg = if (raw.id == .stringify_va_args)
1549 variable_arguments.items
1550 else
1551 args.items[raw.end];
1552
1553 pp.char_buf.clearRetainingCapacity();
1554 try pp.stringify(arg);
1555
1556 const start = pp.comp.generated_buf.items.len;
1557 try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items);
1558
1559 try buf.append(try pp.makeGeneratedToken(start, .string_literal, tokFromRaw(raw)));
1560 },
1561 .macro_param_has_attribute,
1562 .macro_param_has_declspec_attribute,
1563 .macro_param_has_warning,
1564 .macro_param_has_feature,
1565 .macro_param_has_extension,
1566 .macro_param_has_builtin,
1567 .macro_param_has_include,
1568 .macro_param_has_include_next,
1569 .macro_param_is_identifier,
1570 => {
1571 const arg = expanded_args.items[0];
1572 const result = if (arg.len == 0) blk: {
1573 const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
1574 try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
1575 break :blk false;
1576 } else try pp.handleBuiltinMacro(raw.id, arg, loc);
1577 const start = pp.comp.generated_buf.items.len;
1578 const w = pp.comp.generated_buf.writer(pp.gpa);
1579 try w.print("{}\n", .{@intFromBool(result)});
1580 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1581 },
1582 .macro_param_has_c_attribute => {
1583 const arg = expanded_args.items[0];
1584 const not_found = "0\n";
1585 const result = if (arg.len == 0) blk: {
1586 const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
1587 try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
1588 break :blk not_found;
1589 } else res: {
1590 var invalid: ?Token = null;
1591 var vendor_ident: ?Token = null;
1592 var colon_colon: ?Token = null;
1593 var attr_ident: ?Token = null;
1594 for (arg) |tok| {
1595 if (tok.id == .macro_ws) continue;
1596 if (tok.id == .comment) continue;
1597 if (tok.id == .colon_colon) {
1598 if (colon_colon != null or attr_ident == null) {
1599 invalid = tok;
1600 break;
1601 }
1602 vendor_ident = attr_ident;
1603 attr_ident = null;
1604 colon_colon = tok;
1605 continue;
1606 }
1607 if (!tok.id.isMacroIdentifier()) {
1608 invalid = tok;
1609 break;
1610 }
1611 if (attr_ident) |_| {
1612 invalid = tok;
1613 break;
1614 } else attr_ident = tok;
1615 }
1616 if (vendor_ident != null and attr_ident == null) {
1617 invalid = vendor_ident;
1618 } else if (attr_ident == null and invalid == null) {
1619 invalid = .{ .id = .eof, .loc = loc };
1620 }
1621 if (invalid) |some| {
1622 try pp.comp.addDiagnostic(
1623 .{ .tag = .feature_check_requires_identifier, .loc = some.loc },
1624 some.expansionSlice(),
1625 );
1626 break :res not_found;
1627 }
1628 if (vendor_ident) |some| {
1629 const vendor_str = pp.expandedSlice(some);
1630 const attr_str = pp.expandedSlice(attr_ident.?);
1631 const exists = Attribute.fromString(.gnu, vendor_str, attr_str) != null;
1632
1633 const start = pp.comp.generated_buf.items.len;
1634 try pp.comp.generated_buf.appendSlice(pp.gpa, if (exists) "1\n" else "0\n");
1635 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1636 continue;
1637 }
1638 if (!pp.comp.langopts.standard.atLeast(.c23)) break :res not_found;
1639
1640 const attrs = std.ComptimeStringMap([]const u8, .{
1641 .{ "deprecated", "201904L\n" },
1642 .{ "fallthrough", "201904L\n" },
1643 .{ "maybe_unused", "201904L\n" },
1644 .{ "nodiscard", "202003L\n" },
1645 .{ "noreturn", "202202L\n" },
1646 .{ "_Noreturn", "202202L\n" },
1647 .{ "unsequenced", "202207L\n" },
1648 .{ "reproducible", "202207L\n" },
1649 });
1650
1651 const attr_str = Attribute.normalize(pp.expandedSlice(attr_ident.?));
1652 break :res attrs.get(attr_str) orelse not_found;
1653 };
1654 const start = pp.comp.generated_buf.items.len;
1655 try pp.comp.generated_buf.appendSlice(pp.gpa, result);
1656 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1657 },
1658 .macro_param_has_embed => {
1659 const arg = expanded_args.items[0];
1660 const not_found = "0\n";
1661 const result = if (arg.len == 0) blk: {
1662 const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } };
1663 try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = loc, .extra = extra }, &.{});
1664 break :blk not_found;
1665 } else res: {
1666 var embed_args: []const Token = &.{};
1667 const include_str = (try pp.reconstructIncludeString(arg, &embed_args)) orelse
1668 break :res not_found;
1669
1670 var prev = tokFromRaw(raw);
1671 prev.id = .eof;
1672 var it: struct {
1673 i: u32 = 0,
1674 slice: []const Token,
1675 prev: Token,
1676 fn next(it: *@This()) Token {
1677 while (it.i < it.slice.len) switch (it.slice[it.i].id) {
1678 .macro_ws, .whitespace => it.i += 1,
1679 else => break,
1680 } else return it.prev;
1681 defer it.i += 1;
1682 it.prev = it.slice[it.i];
1683 it.prev.id = .eof;
1684 return it.slice[it.i];
1685 }
1686 } = .{ .slice = embed_args, .prev = prev };
1687
1688 while (true) {
1689 const param_first = it.next();
1690 if (param_first.id == .eof) break;
1691 if (param_first.id != .identifier) {
1692 try pp.comp.addDiagnostic(
1693 .{ .tag = .malformed_embed_param, .loc = param_first.loc },
1694 param_first.expansionSlice(),
1695 );
1696 continue;
1697 }
1698
1699 const char_top = pp.char_buf.items.len;
1700 defer pp.char_buf.items.len = char_top;
1701
1702 const maybe_colon = it.next();
1703 const param = switch (maybe_colon.id) {
1704 .colon_colon => blk: {
1705 // vendor::param
1706 const param = it.next();
1707 if (param.id != .identifier) {
1708 try pp.comp.addDiagnostic(
1709 .{ .tag = .malformed_embed_param, .loc = param.loc },
1710 param.expansionSlice(),
1711 );
1712 continue;
1713 }
1714 const l_paren = it.next();
1715 if (l_paren.id != .l_paren) {
1716 try pp.comp.addDiagnostic(
1717 .{ .tag = .malformed_embed_param, .loc = l_paren.loc },
1718 l_paren.expansionSlice(),
1719 );
1720 continue;
1721 }
1722 break :blk "doesn't exist";
1723 },
1724 .l_paren => Attribute.normalize(pp.expandedSlice(param_first)),
1725 else => {
1726 try pp.comp.addDiagnostic(
1727 .{ .tag = .malformed_embed_param, .loc = maybe_colon.loc },
1728 maybe_colon.expansionSlice(),
1729 );
1730 continue;
1731 },
1732 };
1733
1734 var arg_count: u32 = 0;
1735 var first_arg: Token = undefined;
1736 while (true) {
1737 const next = it.next();
1738 if (next.id == .eof) {
1739 try pp.comp.addDiagnostic(
1740 .{ .tag = .malformed_embed_limit, .loc = param_first.loc },
1741 param_first.expansionSlice(),
1742 );
1743 break;
1744 }
1745 if (next.id == .r_paren) break;
1746 arg_count += 1;
1747 if (arg_count == 1) first_arg = next;
1748 }
1749
1750 if (std.mem.eql(u8, param, "limit")) {
1751 if (arg_count != 1) {
1752 try pp.comp.addDiagnostic(
1753 .{ .tag = .malformed_embed_limit, .loc = param_first.loc },
1754 param_first.expansionSlice(),
1755 );
1756 continue;
1757 }
1758 if (first_arg.id != .pp_num) {
1759 try pp.comp.addDiagnostic(
1760 .{ .tag = .malformed_embed_limit, .loc = param_first.loc },
1761 param_first.expansionSlice(),
1762 );
1763 continue;
1764 }
1765 _ = std.fmt.parseInt(u32, pp.expandedSlice(first_arg), 10) catch {
1766 break :res not_found;
1767 };
1768 } else if (!std.mem.eql(u8, param, "prefix") and !std.mem.eql(u8, param, "suffix") and
1769 !std.mem.eql(u8, param, "if_empty"))
1770 {
1771 break :res not_found;
1772 }
1773 }
1774
1775 const include_type: Compilation.IncludeType = switch (include_str[0]) {
1776 '"' => .quotes,
1777 '<' => .angle_brackets,
1778 else => unreachable,
1779 };
1780 const filename = include_str[1 .. include_str.len - 1];
1781 const contents = (try pp.comp.findEmbed(filename, arg[0].loc.id, include_type, 1)) orelse
1782 break :res not_found;
1783
1784 defer pp.comp.gpa.free(contents);
1785 break :res if (contents.len != 0) "1\n" else "2\n";
1786 };
1787 const start = pp.comp.generated_buf.items.len;
1788 try pp.comp.generated_buf.appendSlice(pp.comp.gpa, result);
1789 try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw)));
1790 },
1791 .macro_param_pragma_operator => {
1792 const param_toks = expanded_args.items[0];
1793 // Clang and GCC require exactly one token (so, no parentheses or string pasting)
1794 // even though their error messages indicate otherwise. Ours is slightly more
1795 // descriptive.
1796 var invalid: ?Token = null;
1797 var string: ?Token = null;
1798 for (param_toks) |tok| switch (tok.id) {
1799 .string_literal => {
1800 if (string) |_| invalid = tok else string = tok;
1801 },
1802 .macro_ws => continue,
1803 .comment => continue,
1804 else => {
1805 invalid = tok;
1806 break;
1807 },
1808 };
1809 if (string == null and invalid == null) invalid = .{ .loc = loc, .id = .eof };
1810 if (invalid) |some| try pp.comp.addDiagnostic(
1811 .{ .tag = .pragma_operator_string_literal, .loc = some.loc },
1812 some.expansionSlice(),
1813 ) else try pp.pragmaOperator(string.?, loc);
1814 },
1815 .comma => {
1816 if (tok_i + 2 < func_macro.tokens.len and func_macro.tokens[tok_i + 1].id == .hash_hash) {
1817 const hash_hash = func_macro.tokens[tok_i + 1];
1818 var maybe_va_args = func_macro.tokens[tok_i + 2];
1819 var consumed: usize = 2;
1820 if (maybe_va_args.id == .macro_ws and tok_i + 3 < func_macro.tokens.len) {
1821 consumed = 3;
1822 maybe_va_args = func_macro.tokens[tok_i + 3];
1823 }
1824 if (maybe_va_args.id == .keyword_va_args) {
1825 // GNU extension: `, ##__VA_ARGS__` deletes the comma if __VA_ARGS__ is empty
1826 tok_i += consumed;
1827 if (func_macro.params.len == expanded_args.items.len) {
1828 // Empty __VA_ARGS__, drop the comma
1829 try pp.err(hash_hash, .comma_deletion_va_args);
1830 } else if (func_macro.params.len == 0 and expanded_args.items.len == 1 and expanded_args.items[0].len == 0) {
1831 // Ambiguous whether this is "empty __VA_ARGS__" or "__VA_ARGS__ omitted"
1832 if (pp.comp.langopts.standard.isGNU()) {
1833 // GNU standard, drop the comma
1834 try pp.err(hash_hash, .comma_deletion_va_args);
1835 } else {
1836 // C standard, retain the comma
1837 try buf.append(tokFromRaw(raw));
1838 }
1839 } else {
1840 try buf.append(tokFromRaw(raw));
1841 if (expanded_variable_arguments.items.len > 0 or variable_arguments.items.len == func_macro.params.len) {
1842 try pp.err(hash_hash, .comma_deletion_va_args);
1843 }
1844 const raw_loc = Source.Location{
1845 .id = maybe_va_args.source,
1846 .byte_offset = maybe_va_args.start,
1847 .line = maybe_va_args.line,
1848 };
1849 try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc});
1850 }
1851 continue;
1852 }
1853 }
1854 // Regular comma, no token pasting with __VA_ARGS__
1855 try buf.append(tokFromRaw(raw));
1856 },
1857 else => try buf.append(tokFromRaw(raw)),
1858 }
1859 }
1860 removePlacemarkers(&buf);
1861
1862 return buf;
1863}
1864
1865fn expandVaOpt(
1866 pp: *Preprocessor,
1867 buf: *ExpandBuf,
1868 raw: RawToken,
1869 should_expand: bool,
1870) !void {
1871 if (!should_expand) return;
1872
1873 const source = pp.comp.getSource(raw.source);
1874 var tokenizer: Tokenizer = .{
1875 .buf = source.buf,
1876 .index = raw.start,
1877 .source = raw.source,
1878 .langopts = pp.comp.langopts,
1879 .line = raw.line,
1880 };
1881 while (tokenizer.index < raw.end) {
1882 const tok = tokenizer.next();
1883 try buf.append(tokFromRaw(tok));
1884 }
1885}
1886
1887fn shouldExpand(tok: Token, macro: *Macro) bool {
1888 if (tok.loc.id == macro.loc.id and
1889 tok.loc.byte_offset >= macro.start and
1890 tok.loc.byte_offset <= macro.end)
1891 return false;
1892 for (tok.expansionSlice()) |loc| {
1893 if (loc.id == macro.loc.id and
1894 loc.byte_offset >= macro.start and
1895 loc.byte_offset <= macro.end)
1896 return false;
1897 }
1898 if (tok.flags.expansion_disabled) return false;
1899
1900 return true;
1901}
1902
1903fn bufCopyTokens(buf: *ExpandBuf, tokens: []const Token, src: []const Source.Location) !void {
1904 try buf.ensureUnusedCapacity(tokens.len);
1905 for (tokens) |tok| {
1906 var copy = try tok.dupe(buf.allocator);
1907 errdefer Token.free(copy.expansion_locs, buf.allocator);
1908 try copy.addExpansionLocation(buf.allocator, src);
1909 buf.appendAssumeCapacity(copy);
1910 }
1911}
1912
1913fn nextBufToken(
1914 pp: *Preprocessor,
1915 tokenizer: *Tokenizer,
1916 buf: *ExpandBuf,
1917 start_idx: *usize,
1918 end_idx: *usize,
1919 extend_buf: bool,
1920) Error!Token {
1921 start_idx.* += 1;
1922 if (start_idx.* == buf.items.len and start_idx.* >= end_idx.*) {
1923 if (extend_buf) {
1924 const raw_tok = tokenizer.next();
1925 if (raw_tok.id.isMacroIdentifier() and
1926 pp.poisoned_identifiers.get(pp.tokSlice(raw_tok)) != null)
1927 try pp.err(raw_tok, .poisoned_identifier);
1928
1929 if (raw_tok.id == .nl) pp.add_expansion_nl += 1;
1930
1931 const new_tok = tokFromRaw(raw_tok);
1932 end_idx.* += 1;
1933 try buf.append(new_tok);
1934 return new_tok;
1935 } else {
1936 return Token{ .id = .eof, .loc = .{ .id = .generated } };
1937 }
1938 } else {
1939 return buf.items[start_idx.*];
1940 }
1941}
1942
1943fn collectMacroFuncArguments(
1944 pp: *Preprocessor,
1945 tokenizer: *Tokenizer,
1946 buf: *ExpandBuf,
1947 start_idx: *usize,
1948 end_idx: *usize,
1949 extend_buf: bool,
1950 is_builtin: bool,
1951) !MacroArguments {
1952 const name_tok = buf.items[start_idx.*];
1953 const saved_tokenizer = tokenizer.*;
1954 const old_end = end_idx.*;
1955
1956 while (true) {
1957 const tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
1958 switch (tok.id) {
1959 .nl, .whitespace, .macro_ws => {},
1960 .l_paren => break,
1961 else => {
1962 if (is_builtin) {
1963 try pp.errStr(name_tok, .missing_lparen_after_builtin, pp.expandedSlice(name_tok));
1964 }
1965 // Not a macro function call, go over normal identifier, rewind
1966 tokenizer.* = saved_tokenizer;
1967 end_idx.* = old_end;
1968 return error.MissingLParen;
1969 },
1970 }
1971 }
1972
1973 // collect the arguments.
1974 var parens: u32 = 0;
1975 var args = MacroArguments.init(pp.gpa);
1976 errdefer deinitMacroArguments(pp.gpa, &args);
1977 var curArgument = std.ArrayList(Token).init(pp.gpa);
1978 defer curArgument.deinit();
1979 while (true) {
1980 var tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf);
1981 tok.flags.is_macro_arg = true;
1982 switch (tok.id) {
1983 .comma => {
1984 if (parens == 0) {
1985 const owned = try curArgument.toOwnedSlice();
1986 errdefer pp.gpa.free(owned);
1987 try args.append(owned);
1988 } else {
1989 const duped = try tok.dupe(pp.gpa);
1990 errdefer Token.free(duped.expansion_locs, pp.gpa);
1991 try curArgument.append(duped);
1992 }
1993 },
1994 .l_paren => {
1995 const duped = try tok.dupe(pp.gpa);
1996 errdefer Token.free(duped.expansion_locs, pp.gpa);
1997 try curArgument.append(duped);
1998 parens += 1;
1999 },
2000 .r_paren => {
2001 if (parens == 0) {
2002 const owned = try curArgument.toOwnedSlice();
2003 errdefer pp.gpa.free(owned);
2004 try args.append(owned);
2005 break;
2006 } else {
2007 const duped = try tok.dupe(pp.gpa);
2008 errdefer Token.free(duped.expansion_locs, pp.gpa);
2009 try curArgument.append(duped);
2010 parens -= 1;
2011 }
2012 },
2013 .eof => {
2014 {
2015 const owned = try curArgument.toOwnedSlice();
2016 errdefer pp.gpa.free(owned);
2017 try args.append(owned);
2018 }
2019 tokenizer.* = saved_tokenizer;
2020 try pp.comp.addDiagnostic(
2021 .{ .tag = .unterminated_macro_arg_list, .loc = name_tok.loc },
2022 name_tok.expansionSlice(),
2023 );
2024 return error.Unterminated;
2025 },
2026 .nl, .whitespace => {
2027 try curArgument.append(.{ .id = .macro_ws, .loc = tok.loc });
2028 },
2029 else => {
2030 const duped = try tok.dupe(pp.gpa);
2031 errdefer Token.free(duped.expansion_locs, pp.gpa);
2032 try curArgument.append(duped);
2033 },
2034 }
2035 }
2036
2037 return args;
2038}
2039
2040fn removeExpandedTokens(pp: *Preprocessor, buf: *ExpandBuf, start: usize, len: usize, moving_end_idx: *usize) !void {
2041 for (buf.items[start .. start + len]) |tok| Token.free(tok.expansion_locs, pp.gpa);
2042 try buf.replaceRange(start, len, &.{});
2043 moving_end_idx.* -|= len;
2044}
2045
2046/// The behavior of `defined` depends on whether we are in a preprocessor
2047/// expression context (#if or #elif) or not.
2048/// In a non-expression context it's just an identifier. Within a preprocessor
2049/// expression it is a unary operator or one-argument function.
2050const EvalContext = enum {
2051 expr,
2052 non_expr,
2053};
2054
2055/// Helper for safely iterating over a slice of tokens while skipping whitespace
2056const TokenIterator = struct {
2057 toks: []const Token,
2058 i: usize,
2059
2060 fn init(toks: []const Token) TokenIterator {
2061 return .{ .toks = toks, .i = 0 };
2062 }
2063
2064 fn nextNoWS(self: *TokenIterator) ?Token {
2065 while (self.i < self.toks.len) : (self.i += 1) {
2066 const tok = self.toks[self.i];
2067 if (tok.id == .whitespace or tok.id == .macro_ws) continue;
2068
2069 self.i += 1;
2070 return tok;
2071 }
2072 return null;
2073 }
2074};
2075
2076fn expandMacroExhaustive(
2077 pp: *Preprocessor,
2078 tokenizer: *Tokenizer,
2079 buf: *ExpandBuf,
2080 start_idx: usize,
2081 end_idx: usize,
2082 extend_buf: bool,
2083 eval_ctx: EvalContext,
2084) MacroError!void {
2085 var moving_end_idx = end_idx;
2086 var advance_index: usize = 0;
2087 // rescan loop
2088 var do_rescan = true;
2089 while (do_rescan) {
2090 do_rescan = false;
2091 // expansion loop
2092 var idx: usize = start_idx + advance_index;
2093 while (idx < moving_end_idx) {
2094 const macro_tok = buf.items[idx];
2095 if (macro_tok.id == .keyword_defined and eval_ctx == .expr) {
2096 idx += 1;
2097 var it = TokenIterator.init(buf.items[idx..moving_end_idx]);
2098 if (it.nextNoWS()) |tok| {
2099 switch (tok.id) {
2100 .l_paren => {
2101 _ = it.nextNoWS(); // eat (what should be) identifier
2102 _ = it.nextNoWS(); // eat (what should be) r paren
2103 },
2104 .identifier, .extended_identifier => {},
2105 else => {},
2106 }
2107 }
2108 idx += it.i;
2109 continue;
2110 }
2111 const macro_entry = pp.defines.getPtr(pp.expandedSlice(macro_tok));
2112 if (macro_entry == null or !shouldExpand(buf.items[idx], macro_entry.?)) {
2113 idx += 1;
2114 continue;
2115 }
2116 if (macro_entry) |macro| macro_handler: {
2117 if (macro.is_func) {
2118 var macro_scan_idx = idx;
2119 // to be saved in case this doesn't turn out to be a call
2120 const args = pp.collectMacroFuncArguments(
2121 tokenizer,
2122 buf,
2123 &macro_scan_idx,
2124 &moving_end_idx,
2125 extend_buf,
2126 macro.is_builtin,
2127 ) catch |er| switch (er) {
2128 error.MissingLParen => {
2129 if (!buf.items[idx].flags.is_macro_arg) buf.items[idx].flags.expansion_disabled = true;
2130 idx += 1;
2131 break :macro_handler;
2132 },
2133 error.Unterminated => {
2134 if (pp.comp.langopts.emulate == .gcc) idx += 1;
2135 try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx, &moving_end_idx);
2136 break :macro_handler;
2137 },
2138 else => |e| return e,
2139 };
2140 defer {
2141 for (args.items) |item| {
2142 pp.gpa.free(item);
2143 }
2144 args.deinit();
2145 }
2146
2147 var args_count: u32 = @intCast(args.items.len);
2148 // if the macro has zero arguments g() args_count is still 1
2149 // an empty token list g() and a whitespace-only token list g( )
2150 // counts as zero arguments for the purposes of argument-count validation
2151 if (args_count == 1 and macro.params.len == 0) {
2152 for (args.items[0]) |tok| {
2153 if (tok.id != .macro_ws) break;
2154 } else {
2155 args_count = 0;
2156 }
2157 }
2158
2159 // Validate argument count.
2160 const extra = Diagnostics.Message.Extra{
2161 .arguments = .{ .expected = @intCast(macro.params.len), .actual = args_count },
2162 };
2163 if (macro.var_args and args_count < macro.params.len) {
2164 try pp.comp.addDiagnostic(
2165 .{ .tag = .expected_at_least_arguments, .loc = buf.items[idx].loc, .extra = extra },
2166 buf.items[idx].expansionSlice(),
2167 );
2168 idx += 1;
2169 try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
2170 continue;
2171 }
2172 if (!macro.var_args and args_count != macro.params.len) {
2173 try pp.comp.addDiagnostic(
2174 .{ .tag = .expected_arguments, .loc = buf.items[idx].loc, .extra = extra },
2175 buf.items[idx].expansionSlice(),
2176 );
2177 idx += 1;
2178 try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx);
2179 continue;
2180 }
2181 var expanded_args = MacroArguments.init(pp.gpa);
2182 defer deinitMacroArguments(pp.gpa, &expanded_args);
2183 try expanded_args.ensureTotalCapacity(args.items.len);
2184 for (args.items) |arg| {
2185 var expand_buf = ExpandBuf.init(pp.gpa);
2186 errdefer expand_buf.deinit();
2187 try expand_buf.appendSlice(arg);
2188
2189 try pp.expandMacroExhaustive(tokenizer, &expand_buf, 0, expand_buf.items.len, false, eval_ctx);
2190
2191 expanded_args.appendAssumeCapacity(try expand_buf.toOwnedSlice());
2192 }
2193
2194 var res = try pp.expandFuncMacro(macro_tok.loc, macro, &args, &expanded_args);
2195 defer res.deinit();
2196 const tokens_added = res.items.len;
2197
2198 const macro_expansion_locs = macro_tok.expansionSlice();
2199 for (res.items) |*tok| {
2200 try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
2201 try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
2202 }
2203
2204 const tokens_removed = macro_scan_idx - idx + 1;
2205 for (buf.items[idx .. idx + tokens_removed]) |tok| Token.free(tok.expansion_locs, pp.gpa);
2206 try buf.replaceRange(idx, tokens_removed, res.items);
2207
2208 moving_end_idx += tokens_added;
2209 // Overflow here means that we encountered an unterminated argument list
2210 // while expanding the body of this macro.
2211 moving_end_idx -|= tokens_removed;
2212 idx += tokens_added;
2213 do_rescan = true;
2214 } else {
2215 const res = try pp.expandObjMacro(macro);
2216 defer res.deinit();
2217
2218 const macro_expansion_locs = macro_tok.expansionSlice();
2219 var increment_idx_by = res.items.len;
2220 for (res.items, 0..) |*tok, i| {
2221 tok.flags.is_macro_arg = macro_tok.flags.is_macro_arg;
2222 try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc});
2223 try tok.addExpansionLocation(pp.gpa, macro_expansion_locs);
2224 if (tok.id == .keyword_defined and eval_ctx == .expr) {
2225 try pp.comp.addDiagnostic(.{
2226 .tag = .expansion_to_defined,
2227 .loc = tok.loc,
2228 }, tok.expansionSlice());
2229 }
2230
2231 if (i < increment_idx_by and (tok.id == .keyword_defined or pp.defines.contains(pp.expandedSlice(tok.*)))) {
2232 increment_idx_by = i;
2233 }
2234 }
2235
2236 Token.free(buf.items[idx].expansion_locs, pp.gpa);
2237 try buf.replaceRange(idx, 1, res.items);
2238 idx += increment_idx_by;
2239 moving_end_idx = moving_end_idx + res.items.len - 1;
2240 do_rescan = true;
2241 }
2242 }
2243 if (idx - start_idx == advance_index + 1 and !do_rescan) {
2244 advance_index += 1;
2245 }
2246 } // end of replacement phase
2247 }
2248 // end of scanning phase
2249
2250 // trim excess buffer
2251 for (buf.items[moving_end_idx..]) |item| {
2252 Token.free(item.expansion_locs, pp.gpa);
2253 }
2254 buf.items.len = moving_end_idx;
2255}
2256
2257/// Try to expand a macro after a possible candidate has been read from the `tokenizer`
2258/// into the `raw` token passed as argument
2259fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroError!void {
2260 var source_tok = tokFromRaw(raw);
2261 if (!raw.id.isMacroIdentifier()) {
2262 source_tok.id.simplifyMacroKeyword();
2263 return pp.tokens.append(pp.gpa, source_tok);
2264 }
2265 pp.top_expansion_buf.items.len = 0;
2266 try pp.top_expansion_buf.append(source_tok);
2267 pp.expansion_source_loc = source_tok.loc;
2268
2269 try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr);
2270 try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.top_expansion_buf.items.len);
2271 for (pp.top_expansion_buf.items) |*tok| {
2272 if (tok.id == .macro_ws and !pp.preserve_whitespace) {
2273 Token.free(tok.expansion_locs, pp.gpa);
2274 continue;
2275 }
2276 if (tok.id == .comment and !pp.comp.langopts.preserve_comments_in_macros) {
2277 Token.free(tok.expansion_locs, pp.gpa);
2278 continue;
2279 }
2280 tok.id.simplifyMacroKeywordExtra(true);
2281 pp.tokens.appendAssumeCapacity(tok.*);
2282 }
2283 if (pp.preserve_whitespace) {
2284 try pp.tokens.ensureUnusedCapacity(pp.gpa, pp.add_expansion_nl);
2285 while (pp.add_expansion_nl > 0) : (pp.add_expansion_nl -= 1) {
2286 pp.tokens.appendAssumeCapacity(.{ .id = .nl, .loc = .{
2287 .id = tokenizer.source,
2288 .line = tokenizer.line,
2289 } });
2290 }
2291 }
2292}
2293
2294fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 {
2295 if (tok.id.lexeme()) |some| {
2296 if (!tok.id.allowsDigraphs(pp.comp.langopts) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some;
2297 }
2298 var tmp_tokenizer = Tokenizer{
2299 .buf = pp.comp.getSource(tok.loc.id).buf,
2300 .langopts = pp.comp.langopts,
2301 .index = tok.loc.byte_offset,
2302 .source = .generated,
2303 };
2304 if (tok.id == .macro_string) {
2305 while (true) : (tmp_tokenizer.index += 1) {
2306 if (tmp_tokenizer.buf[tmp_tokenizer.index] == '>') break;
2307 }
2308 return tmp_tokenizer.buf[tok.loc.byte_offset .. tmp_tokenizer.index + 1];
2309 }
2310 const res = tmp_tokenizer.next();
2311 return tmp_tokenizer.buf[res.start..res.end];
2312}
2313
2314/// Get expanded token source string.
2315pub fn expandedSlice(pp: *Preprocessor, tok: Token) []const u8 {
2316 return pp.expandedSliceExtra(tok, .single_macro_ws);
2317}
2318
2319/// Concat two tokens and add the result to pp.generated
2320fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token) Error!void {
2321 const lhs = while (lhs_toks.popOrNull()) |lhs| {
2322 if ((pp.comp.langopts.preserve_comments_in_macros and lhs.id == .comment) or
2323 (lhs.id != .macro_ws and lhs.id != .comment))
2324 break lhs;
2325
2326 Token.free(lhs.expansion_locs, pp.gpa);
2327 } else {
2328 return bufCopyTokens(lhs_toks, rhs_toks, &.{});
2329 };
2330
2331 var rhs_rest: u32 = 1;
2332 const rhs = for (rhs_toks) |rhs| {
2333 if ((pp.comp.langopts.preserve_comments_in_macros and rhs.id == .comment) or
2334 (rhs.id != .macro_ws and rhs.id != .comment))
2335 break rhs;
2336
2337 rhs_rest += 1;
2338 } else {
2339 return lhs_toks.appendAssumeCapacity(lhs);
2340 };
2341 defer Token.free(lhs.expansion_locs, pp.gpa);
2342
2343 const start = pp.comp.generated_buf.items.len;
2344 const end = start + pp.expandedSlice(lhs).len + pp.expandedSlice(rhs).len;
2345 try pp.comp.generated_buf.ensureTotalCapacity(pp.gpa, end + 1); // +1 for a newline
2346 // We cannot use the same slices here since they might be invalidated by `ensureCapacity`
2347 pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(lhs));
2348 pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(rhs));
2349 pp.comp.generated_buf.appendAssumeCapacity('\n');
2350
2351 // Try to tokenize the result.
2352 var tmp_tokenizer = Tokenizer{
2353 .buf = pp.comp.generated_buf.items,
2354 .langopts = pp.comp.langopts,
2355 .index = @intCast(start),
2356 .source = .generated,
2357 };
2358 const pasted_token = tmp_tokenizer.nextNoWSComments();
2359 const next = tmp_tokenizer.nextNoWSComments();
2360 const pasted_id = if (lhs.id == .placemarker and rhs.id == .placemarker)
2361 .placemarker
2362 else
2363 pasted_token.id;
2364 try lhs_toks.append(try pp.makeGeneratedToken(start, pasted_id, lhs));
2365
2366 if (next.id != .nl and next.id != .eof) {
2367 try pp.errStr(
2368 lhs,
2369 .pasting_formed_invalid,
2370 try pp.comp.diagnostics.arena.allocator().dupe(u8, pp.comp.generated_buf.items[start..end]),
2371 );
2372 try lhs_toks.append(tokFromRaw(next));
2373 }
2374
2375 try bufCopyTokens(lhs_toks, rhs_toks[rhs_rest..], &.{});
2376}
2377
2378fn makeGeneratedToken(pp: *Preprocessor, start: usize, id: Token.Id, source: Token) !Token {
2379 var pasted_token = Token{ .id = id, .loc = .{
2380 .id = .generated,
2381 .byte_offset = @intCast(start),
2382 .line = pp.generated_line,
2383 } };
2384 pp.generated_line += 1;
2385 try pasted_token.addExpansionLocation(pp.gpa, &.{source.loc});
2386 try pasted_token.addExpansionLocation(pp.gpa, source.expansionSlice());
2387 return pasted_token;
2388}
2389
2390/// Defines a new macro and warns if it is a duplicate
2391fn defineMacro(pp: *Preprocessor, name_tok: RawToken, macro: Macro) Error!void {
2392 const name_str = pp.tokSlice(name_tok);
2393 const gop = try pp.defines.getOrPut(pp.gpa, name_str);
2394 if (gop.found_existing and !gop.value_ptr.eql(macro, pp)) {
2395 const tag: Diagnostics.Tag = if (gop.value_ptr.is_builtin) .builtin_macro_redefined else .macro_redefined;
2396 const start = pp.comp.diagnostics.list.items.len;
2397 try pp.comp.addDiagnostic(.{
2398 .tag = tag,
2399 .loc = .{ .id = name_tok.source, .byte_offset = name_tok.start, .line = name_tok.line },
2400 .extra = .{ .str = name_str },
2401 }, &.{});
2402 if (!gop.value_ptr.is_builtin and pp.comp.diagnostics.list.items.len != start) {
2403 try pp.comp.addDiagnostic(.{
2404 .tag = .previous_definition,
2405 .loc = gop.value_ptr.loc,
2406 }, &.{});
2407 }
2408 }
2409 if (pp.verbose) {
2410 pp.verboseLog(name_tok, "macro {s} defined", .{name_str});
2411 }
2412 gop.value_ptr.* = macro;
2413}
2414
2415/// Handle a #define directive.
2416fn define(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void {
2417 // Get macro name and validate it.
2418 const macro_name = tokenizer.nextNoWS();
2419 if (macro_name.id == .keyword_defined) {
2420 try pp.err(macro_name, .defined_as_macro_name);
2421 return skipToNl(tokenizer);
2422 }
2423 if (!macro_name.id.isMacroIdentifier()) {
2424 try pp.err(macro_name, .macro_name_must_be_identifier);
2425 return skipToNl(tokenizer);
2426 }
2427 var macro_name_token_id = macro_name.id;
2428 macro_name_token_id.simplifyMacroKeyword();
2429 switch (macro_name_token_id) {
2430 .identifier, .extended_identifier => {},
2431 else => if (macro_name_token_id.isMacroIdentifier()) {
2432 try pp.err(macro_name, .keyword_macro);
2433 },
2434 }
2435
2436 // Check for function macros and empty defines.
2437 var first = tokenizer.next();
2438 switch (first.id) {
2439 .nl, .eof => return pp.defineMacro(macro_name, .{
2440 .params = &.{},
2441 .tokens = &.{},
2442 .var_args = false,
2443 .loc = tokFromRaw(macro_name).loc,
2444 .start = 0,
2445 .end = 0,
2446 .is_func = false,
2447 }),
2448 .whitespace => first = tokenizer.next(),
2449 .l_paren => return pp.defineFn(tokenizer, macro_name, first),
2450 else => try pp.err(first, .whitespace_after_macro_name),
2451 }
2452 if (first.id == .hash_hash) {
2453 try pp.err(first, .hash_hash_at_start);
2454 return skipToNl(tokenizer);
2455 }
2456 first.id.simplifyMacroKeyword();
2457
2458 pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
2459
2460 var need_ws = false;
2461 // Collect the token body and validate any ## found.
2462 var tok = first;
2463 const end_index = while (true) {
2464 tok.id.simplifyMacroKeyword();
2465 switch (tok.id) {
2466 .hash_hash => {
2467 const next = tokenizer.nextNoWSComments();
2468 switch (next.id) {
2469 .nl, .eof => {
2470 try pp.err(tok, .hash_hash_at_end);
2471 return;
2472 },
2473 .hash_hash => {
2474 try pp.err(next, .hash_hash_at_end);
2475 return;
2476 },
2477 else => {},
2478 }
2479 try pp.token_buf.append(tok);
2480 try pp.token_buf.append(next);
2481 },
2482 .nl, .eof => break tok.start,
2483 .comment => if (pp.comp.langopts.preserve_comments_in_macros) {
2484 if (need_ws) {
2485 need_ws = false;
2486 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2487 }
2488 try pp.token_buf.append(tok);
2489 },
2490 .whitespace => need_ws = true,
2491 .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| {
2492 try pp.err(tok, invalidTokenDiagnostic(tag));
2493 try pp.token_buf.append(tok);
2494 },
2495 .unterminated_comment => try pp.err(tok, .unterminated_comment),
2496 else => {
2497 if (tok.id != .whitespace and need_ws) {
2498 need_ws = false;
2499 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2500 }
2501 try pp.token_buf.append(tok);
2502 },
2503 }
2504 tok = tokenizer.next();
2505 } else unreachable;
2506
2507 const list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
2508 try pp.defineMacro(macro_name, .{
2509 .loc = tokFromRaw(macro_name).loc,
2510 .start = first.start,
2511 .end = end_index,
2512 .tokens = list,
2513 .params = undefined,
2514 .is_func = false,
2515 .var_args = false,
2516 });
2517}
2518
2519/// Handle a function like #define directive.
2520fn defineFn(pp: *Preprocessor, tokenizer: *Tokenizer, macro_name: RawToken, l_paren: RawToken) Error!void {
2521 assert(macro_name.id.isMacroIdentifier());
2522 var params = std.ArrayList([]const u8).init(pp.gpa);
2523 defer params.deinit();
2524
2525 // Parse the parameter list.
2526 var gnu_var_args: []const u8 = "";
2527 var var_args = false;
2528 const start_index = while (true) {
2529 var tok = tokenizer.nextNoWS();
2530 if (tok.id == .r_paren) break tok.end;
2531 if (tok.id == .eof) return pp.err(tok, .unterminated_macro_param_list);
2532 if (tok.id == .ellipsis) {
2533 var_args = true;
2534 const r_paren = tokenizer.nextNoWS();
2535 if (r_paren.id != .r_paren) {
2536 try pp.err(r_paren, .missing_paren_param_list);
2537 try pp.err(l_paren, .to_match_paren);
2538 return skipToNl(tokenizer);
2539 }
2540 break r_paren.end;
2541 }
2542 if (!tok.id.isMacroIdentifier()) {
2543 try pp.err(tok, .invalid_token_param_list);
2544 return skipToNl(tokenizer);
2545 }
2546
2547 try params.append(pp.tokSlice(tok));
2548
2549 tok = tokenizer.nextNoWS();
2550 if (tok.id == .ellipsis) {
2551 try pp.err(tok, .gnu_va_macro);
2552 gnu_var_args = params.pop();
2553 const r_paren = tokenizer.nextNoWS();
2554 if (r_paren.id != .r_paren) {
2555 try pp.err(r_paren, .missing_paren_param_list);
2556 try pp.err(l_paren, .to_match_paren);
2557 return skipToNl(tokenizer);
2558 }
2559 break r_paren.end;
2560 } else if (tok.id == .r_paren) {
2561 break tok.end;
2562 } else if (tok.id != .comma) {
2563 try pp.err(tok, .expected_comma_param_list);
2564 return skipToNl(tokenizer);
2565 }
2566 } else unreachable;
2567
2568 var need_ws = false;
2569 // Collect the body tokens and validate # and ##'s found.
2570 pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time.
2571 const end_index = tok_loop: while (true) {
2572 var tok = tokenizer.next();
2573 switch (tok.id) {
2574 .nl, .eof => break tok.start,
2575 .whitespace => need_ws = pp.token_buf.items.len != 0,
2576 .comment => if (!pp.comp.langopts.preserve_comments_in_macros) continue else {
2577 if (need_ws) {
2578 need_ws = false;
2579 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2580 }
2581 try pp.token_buf.append(tok);
2582 },
2583 .hash => {
2584 if (tok.id != .whitespace and need_ws) {
2585 need_ws = false;
2586 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2587 }
2588 const param = tokenizer.nextNoWS();
2589 blk: {
2590 if (var_args and param.id == .keyword_va_args) {
2591 tok.id = .stringify_va_args;
2592 try pp.token_buf.append(tok);
2593 continue :tok_loop;
2594 }
2595 if (!param.id.isMacroIdentifier()) break :blk;
2596 const s = pp.tokSlice(param);
2597 if (mem.eql(u8, s, gnu_var_args)) {
2598 tok.id = .stringify_va_args;
2599 try pp.token_buf.append(tok);
2600 continue :tok_loop;
2601 }
2602 for (params.items, 0..) |p, i| {
2603 if (mem.eql(u8, p, s)) {
2604 tok.id = .stringify_param;
2605 tok.end = @intCast(i);
2606 try pp.token_buf.append(tok);
2607 continue :tok_loop;
2608 }
2609 }
2610 }
2611 try pp.err(param, .hash_not_followed_param);
2612 return skipToNl(tokenizer);
2613 },
2614 .hash_hash => {
2615 need_ws = false;
2616 // if ## appears at the beginning, the token buf is still empty
2617 // in this case, error out
2618 if (pp.token_buf.items.len == 0) {
2619 try pp.err(tok, .hash_hash_at_start);
2620 return skipToNl(tokenizer);
2621 }
2622 const saved_tokenizer = tokenizer.*;
2623 const next = tokenizer.nextNoWSComments();
2624 if (next.id == .nl or next.id == .eof) {
2625 try pp.err(tok, .hash_hash_at_end);
2626 return;
2627 }
2628 tokenizer.* = saved_tokenizer;
2629 // convert the previous token to .macro_param_no_expand if it was .macro_param
2630 if (pp.token_buf.items[pp.token_buf.items.len - 1].id == .macro_param) {
2631 pp.token_buf.items[pp.token_buf.items.len - 1].id = .macro_param_no_expand;
2632 }
2633 try pp.token_buf.append(tok);
2634 },
2635 .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| {
2636 try pp.err(tok, invalidTokenDiagnostic(tag));
2637 try pp.token_buf.append(tok);
2638 },
2639 .unterminated_comment => try pp.err(tok, .unterminated_comment),
2640 else => {
2641 if (tok.id != .whitespace and need_ws) {
2642 need_ws = false;
2643 try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated });
2644 }
2645 if (var_args and tok.id == .keyword_va_args) {
2646 // do nothing
2647 } else if (var_args and tok.id == .keyword_va_opt) {
2648 const opt_l_paren = tokenizer.next();
2649 if (opt_l_paren.id != .l_paren) {
2650 try pp.err(opt_l_paren, .va_opt_lparen);
2651 return skipToNl(tokenizer);
2652 }
2653 tok.start = opt_l_paren.end;
2654
2655 var parens: u32 = 0;
2656 while (true) {
2657 const opt_tok = tokenizer.next();
2658 switch (opt_tok.id) {
2659 .l_paren => parens += 1,
2660 .r_paren => if (parens == 0) {
2661 break;
2662 } else {
2663 parens -= 1;
2664 },
2665 .nl, .eof => {
2666 try pp.err(opt_tok, .va_opt_rparen);
2667 try pp.err(opt_l_paren, .to_match_paren);
2668 return skipToNl(tokenizer);
2669 },
2670 .whitespace => {},
2671 else => tok.end = opt_tok.end,
2672 }
2673 }
2674 } else if (tok.id.isMacroIdentifier()) {
2675 tok.id.simplifyMacroKeyword();
2676 const s = pp.tokSlice(tok);
2677 if (mem.eql(u8, gnu_var_args, s)) {
2678 tok.id = .keyword_va_args;
2679 } else for (params.items, 0..) |param, i| {
2680 if (mem.eql(u8, param, s)) {
2681 // NOTE: it doesn't matter to assign .macro_param_no_expand
2682 // here in case a ## was the previous token, because
2683 // ## processing will eat this token with the same semantics
2684 tok.id = .macro_param;
2685 tok.end = @intCast(i);
2686 break;
2687 }
2688 }
2689 }
2690 try pp.token_buf.append(tok);
2691 },
2692 }
2693 } else unreachable;
2694
2695 const param_list = try pp.arena.allocator().dupe([]const u8, params.items);
2696 const token_list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items);
2697 try pp.defineMacro(macro_name, .{
2698 .is_func = true,
2699 .params = param_list,
2700 .var_args = var_args or gnu_var_args.len != 0,
2701 .tokens = token_list,
2702 .loc = tokFromRaw(macro_name).loc,
2703 .start = start_index,
2704 .end = end_index,
2705 });
2706}
2707
2708/// Handle an #embed directive
2709/// embedDirective : ("FILENAME" | <FILENAME>) embedParam*
2710/// embedParam : IDENTIFIER (:: IDENTIFIER)? '(' <tokens> ')'
2711fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
2712 const first = tokenizer.nextNoWS();
2713 const filename_tok = pp.findIncludeFilenameToken(first, tokenizer, .ignore_trailing_tokens) catch |er| switch (er) {
2714 error.InvalidInclude => return,
2715 else => |e| return e,
2716 };
2717 defer Token.free(filename_tok.expansion_locs, pp.gpa);
2718
2719 // Check for empty filename.
2720 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
2721 if (tok_slice.len < 3) {
2722 try pp.err(first, .empty_filename);
2723 return;
2724 }
2725 const filename = tok_slice[1 .. tok_slice.len - 1];
2726 const include_type: Compilation.IncludeType = switch (filename_tok.id) {
2727 .string_literal => .quotes,
2728 .macro_string => .angle_brackets,
2729 else => unreachable,
2730 };
2731
2732 // Index into `token_buf`
2733 const Range = struct {
2734 start: u32,
2735 end: u32,
2736
2737 fn expand(opt_range: ?@This(), pp_: *Preprocessor, tokenizer_: *Tokenizer) !void {
2738 const range = opt_range orelse return;
2739 const slice = pp_.token_buf.items[range.start..range.end];
2740 for (slice) |tok| {
2741 try pp_.expandMacro(tokenizer_, tok);
2742 }
2743 }
2744 };
2745 pp.token_buf.items.len = 0;
2746
2747 var limit: ?u32 = null;
2748 var prefix: ?Range = null;
2749 var suffix: ?Range = null;
2750 var if_empty: ?Range = null;
2751 while (true) {
2752 const param_first = tokenizer.nextNoWS();
2753 switch (param_first.id) {
2754 .nl, .eof => break,
2755 .identifier => {},
2756 else => {
2757 try pp.err(param_first, .malformed_embed_param);
2758 continue;
2759 },
2760 }
2761
2762 const char_top = pp.char_buf.items.len;
2763 defer pp.char_buf.items.len = char_top;
2764
2765 const maybe_colon = tokenizer.colonColon();
2766 const param = switch (maybe_colon.id) {
2767 .colon_colon => blk: {
2768 // vendor::param
2769 const param = tokenizer.nextNoWS();
2770 if (param.id != .identifier) {
2771 try pp.err(param, .malformed_embed_param);
2772 continue;
2773 }
2774 const l_paren = tokenizer.nextNoWS();
2775 if (l_paren.id != .l_paren) {
2776 try pp.err(l_paren, .malformed_embed_param);
2777 continue;
2778 }
2779 try pp.char_buf.appendSlice(Attribute.normalize(pp.tokSlice(param_first)));
2780 try pp.char_buf.appendSlice("::");
2781 try pp.char_buf.appendSlice(Attribute.normalize(pp.tokSlice(param)));
2782 break :blk pp.char_buf.items;
2783 },
2784 .l_paren => Attribute.normalize(pp.tokSlice(param_first)),
2785 else => {
2786 try pp.err(maybe_colon, .malformed_embed_param);
2787 continue;
2788 },
2789 };
2790
2791 const start: u32 = @intCast(pp.token_buf.items.len);
2792 while (true) {
2793 const next = tokenizer.nextNoWS();
2794 if (next.id == .r_paren) break;
2795 if (next.id == .eof) {
2796 try pp.err(maybe_colon, .malformed_embed_param);
2797 break;
2798 }
2799 try pp.token_buf.append(next);
2800 }
2801 const end: u32 = @intCast(pp.token_buf.items.len);
2802
2803 if (std.mem.eql(u8, param, "limit")) {
2804 if (limit != null) {
2805 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "limit");
2806 continue;
2807 }
2808 if (start + 1 != end) {
2809 try pp.err(param_first, .malformed_embed_limit);
2810 continue;
2811 }
2812 const limit_tok = pp.token_buf.items[start];
2813 if (limit_tok.id != .pp_num) {
2814 try pp.err(param_first, .malformed_embed_limit);
2815 continue;
2816 }
2817 limit = std.fmt.parseInt(u32, pp.tokSlice(limit_tok), 10) catch {
2818 try pp.err(limit_tok, .malformed_embed_limit);
2819 continue;
2820 };
2821 pp.token_buf.items.len = start;
2822 } else if (std.mem.eql(u8, param, "prefix")) {
2823 if (prefix != null) {
2824 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "prefix");
2825 continue;
2826 }
2827 prefix = .{ .start = start, .end = end };
2828 } else if (std.mem.eql(u8, param, "suffix")) {
2829 if (suffix != null) {
2830 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "suffix");
2831 continue;
2832 }
2833 suffix = .{ .start = start, .end = end };
2834 } else if (std.mem.eql(u8, param, "if_empty")) {
2835 if (if_empty != null) {
2836 try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "if_empty");
2837 continue;
2838 }
2839 if_empty = .{ .start = start, .end = end };
2840 } else {
2841 try pp.errStr(
2842 tokFromRaw(param_first),
2843 .unsupported_embed_param,
2844 try pp.comp.diagnostics.arena.allocator().dupe(u8, param),
2845 );
2846 pp.token_buf.items.len = start;
2847 }
2848 }
2849
2850 const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type, limit)) orelse
2851 return pp.fatalNotFound(filename_tok, filename);
2852 defer pp.comp.gpa.free(embed_bytes);
2853
2854 try Range.expand(prefix, pp, tokenizer);
2855
2856 if (embed_bytes.len == 0) {
2857 try Range.expand(if_empty, pp, tokenizer);
2858 try Range.expand(suffix, pp, tokenizer);
2859 return;
2860 }
2861
2862 try pp.tokens.ensureUnusedCapacity(pp.comp.gpa, 2 * embed_bytes.len - 1); // N bytes and N-1 commas
2863
2864 // TODO: We currently only support systems with CHAR_BIT == 8
2865 // If the target's CHAR_BIT is not 8, we need to write out correctly-sized embed_bytes
2866 // and correctly account for the target's endianness
2867 const writer = pp.comp.generated_buf.writer(pp.gpa);
2868
2869 {
2870 const byte = embed_bytes[0];
2871 const start = pp.comp.generated_buf.items.len;
2872 try writer.print("{d}", .{byte});
2873 pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start, .embed_byte, filename_tok));
2874 }
2875
2876 for (embed_bytes[1..]) |byte| {
2877 const start = pp.comp.generated_buf.items.len;
2878 try writer.print(",{d}", .{byte});
2879 pp.tokens.appendAssumeCapacity(.{ .id = .comma, .loc = .{ .id = .generated, .byte_offset = @intCast(start) } });
2880 pp.tokens.appendAssumeCapacity(try pp.makeGeneratedToken(start + 1, .embed_byte, filename_tok));
2881 }
2882 try pp.comp.generated_buf.append(pp.gpa, '\n');
2883
2884 try Range.expand(suffix, pp, tokenizer);
2885}
2886
2887// Handle a #include directive.
2888fn include(pp: *Preprocessor, tokenizer: *Tokenizer, which: Compilation.WhichInclude) MacroError!void {
2889 const first = tokenizer.nextNoWS();
2890 const new_source = findIncludeSource(pp, tokenizer, first, which) catch |er| switch (er) {
2891 error.InvalidInclude => return,
2892 else => |e| return e,
2893 };
2894
2895 // Prevent stack overflow
2896 pp.include_depth += 1;
2897 defer pp.include_depth -= 1;
2898 if (pp.include_depth > max_include_depth) {
2899 try pp.comp.addDiagnostic(.{
2900 .tag = .too_many_includes,
2901 .loc = .{ .id = first.source, .byte_offset = first.start, .line = first.line },
2902 }, &.{});
2903 return error.StopPreprocessing;
2904 }
2905
2906 if (pp.include_guards.get(new_source.id)) |guard| {
2907 if (pp.defines.contains(guard)) return;
2908 }
2909
2910 if (pp.verbose) {
2911 pp.verboseLog(first, "include file {s}", .{new_source.path});
2912 }
2913
2914 const tokens_start = pp.tokens.len;
2915 try pp.addIncludeStart(new_source);
2916 const eof = pp.preprocessExtra(new_source) catch |er| switch (er) {
2917 error.StopPreprocessing => {
2918 for (pp.tokens.items(.expansion_locs)[tokens_start..]) |loc| Token.free(loc, pp.gpa);
2919 pp.tokens.len = tokens_start;
2920 return;
2921 },
2922 else => |e| return e,
2923 };
2924 try eof.checkMsEof(new_source, pp.comp);
2925 if (pp.preserve_whitespace and pp.tokens.items(.id)[pp.tokens.len - 1] != .nl) {
2926 try pp.tokens.append(pp.gpa, .{ .id = .nl, .loc = .{
2927 .id = tokenizer.source,
2928 .line = tokenizer.line,
2929 } });
2930 }
2931 if (pp.linemarkers == .none) return;
2932 var next = first;
2933 while (true) {
2934 var tmp = tokenizer.*;
2935 next = tmp.nextNoWS();
2936 if (next.id != .nl) break;
2937 tokenizer.* = tmp;
2938 }
2939 try pp.addIncludeResume(next.source, next.end, next.line);
2940}
2941
2942/// tokens that are part of a pragma directive can happen in 3 ways:
2943/// 1. directly in the text via `#pragma ...`
2944/// 2. Via a string literal argument to `_Pragma`
2945/// 3. Via a stringified macro argument which is used as an argument to `_Pragma`
2946/// operator_loc: Location of `_Pragma`; null if this is from #pragma
2947/// arg_locs: expansion locations of the argument to _Pragma. empty if #pragma or a raw string literal was used
2948fn makePragmaToken(pp: *Preprocessor, raw: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !Token {
2949 var tok = tokFromRaw(raw);
2950 if (operator_loc) |loc| {
2951 try tok.addExpansionLocation(pp.gpa, &.{loc});
2952 }
2953 try tok.addExpansionLocation(pp.gpa, arg_locs);
2954 return tok;
2955}
2956
2957/// Handle a pragma directive
2958fn pragma(pp: *Preprocessor, tokenizer: *Tokenizer, pragma_tok: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !void {
2959 const name_tok = tokenizer.nextNoWS();
2960 if (name_tok.id == .nl or name_tok.id == .eof) return;
2961
2962 const name = pp.tokSlice(name_tok);
2963 try pp.tokens.append(pp.gpa, try pp.makePragmaToken(pragma_tok, operator_loc, arg_locs));
2964 const pragma_start: u32 = @intCast(pp.tokens.len);
2965
2966 const pragma_name_tok = try pp.makePragmaToken(name_tok, operator_loc, arg_locs);
2967 try pp.tokens.append(pp.gpa, pragma_name_tok);
2968 while (true) {
2969 const next_tok = tokenizer.next();
2970 if (next_tok.id == .whitespace) continue;
2971 if (next_tok.id == .eof) {
2972 try pp.tokens.append(pp.gpa, .{
2973 .id = .nl,
2974 .loc = .{ .id = .generated },
2975 });
2976 break;
2977 }
2978 try pp.tokens.append(pp.gpa, try pp.makePragmaToken(next_tok, operator_loc, arg_locs));
2979 if (next_tok.id == .nl) break;
2980 }
2981 if (pp.comp.getPragma(name)) |prag| unknown: {
2982 return prag.preprocessorCB(pp, pragma_start) catch |er| switch (er) {
2983 error.UnknownPragma => break :unknown,
2984 else => |e| return e,
2985 };
2986 }
2987 return pp.comp.addDiagnostic(.{
2988 .tag = .unknown_pragma,
2989 .loc = pragma_name_tok.loc,
2990 }, pragma_name_tok.expansionSlice());
2991}
2992
2993fn findIncludeFilenameToken(
2994 pp: *Preprocessor,
2995 first_token: RawToken,
2996 tokenizer: *Tokenizer,
2997 trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof },
2998) !Token {
2999 var first = first_token;
3000
3001 if (first.id == .angle_bracket_left) to_end: {
3002 // The tokenizer does not handle <foo> include strings so do it here.
3003 while (tokenizer.index < tokenizer.buf.len) : (tokenizer.index += 1) {
3004 switch (tokenizer.buf[tokenizer.index]) {
3005 '>' => {
3006 tokenizer.index += 1;
3007 first.end = tokenizer.index;
3008 first.id = .macro_string;
3009 break :to_end;
3010 },
3011 '\n' => break,
3012 else => {},
3013 }
3014 }
3015 try pp.comp.addDiagnostic(.{
3016 .tag = .header_str_closing,
3017 .loc = .{ .id = first.source, .byte_offset = tokenizer.index, .line = first.line },
3018 }, &.{});
3019 try pp.err(first, .header_str_match);
3020 }
3021
3022 const source_tok = tokFromRaw(first);
3023 const filename_tok, const expanded_trailing = switch (source_tok.id) {
3024 .string_literal, .macro_string => .{ source_tok, false },
3025 else => expanded: {
3026 // Try to expand if the argument is a macro.
3027 pp.top_expansion_buf.items.len = 0;
3028 defer for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
3029 try pp.top_expansion_buf.append(source_tok);
3030 pp.expansion_source_loc = source_tok.loc;
3031
3032 try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr);
3033 var trailing_toks: []const Token = &.{};
3034 const include_str = (try pp.reconstructIncludeString(pp.top_expansion_buf.items, &trailing_toks)) orelse {
3035 try pp.err(first, .expected_filename);
3036 try pp.expectNl(tokenizer);
3037 return error.InvalidInclude;
3038 };
3039 const start = pp.comp.generated_buf.items.len;
3040 try pp.comp.generated_buf.appendSlice(pp.gpa, include_str);
3041
3042 break :expanded .{ try pp.makeGeneratedToken(start, switch (include_str[0]) {
3043 '"' => .string_literal,
3044 '<' => .macro_string,
3045 else => unreachable,
3046 }, pp.top_expansion_buf.items[0]), trailing_toks.len != 0 };
3047 },
3048 };
3049
3050 switch (trailing_token_behavior) {
3051 .expect_nl_eof => {
3052 // Error on extra tokens.
3053 const nl = tokenizer.nextNoWS();
3054 if ((nl.id != .nl and nl.id != .eof) or expanded_trailing) {
3055 skipToNl(tokenizer);
3056 try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{
3057 .tag = .extra_tokens_directive_end,
3058 .loc = filename_tok.loc,
3059 }, filename_tok.expansionSlice(), false);
3060 }
3061 },
3062 .ignore_trailing_tokens => if (expanded_trailing) {
3063 try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{
3064 .tag = .extra_tokens_directive_end,
3065 .loc = filename_tok.loc,
3066 }, filename_tok.expansionSlice(), false);
3067 },
3068 }
3069 return filename_tok;
3070}
3071
3072fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source {
3073 const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof);
3074 defer Token.free(filename_tok.expansion_locs, pp.gpa);
3075
3076 // Check for empty filename.
3077 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
3078 if (tok_slice.len < 3) {
3079 try pp.err(first, .empty_filename);
3080 return error.InvalidInclude;
3081 }
3082
3083 // Find the file.
3084 const filename = tok_slice[1 .. tok_slice.len - 1];
3085 const include_type: Compilation.IncludeType = switch (filename_tok.id) {
3086 .string_literal => .quotes,
3087 .macro_string => .angle_brackets,
3088 else => unreachable,
3089 };
3090
3091 return (try pp.comp.findInclude(filename, first, include_type, which)) orelse
3092 return pp.fatalNotFound(filename_tok, filename);
3093}
3094
3095fn printLinemarker(
3096 pp: *Preprocessor,
3097 w: anytype,
3098 line_no: u32,
3099 source: Source,
3100 start_resume: enum(u8) { start, @"resume", none },
3101) !void {
3102 try w.writeByte('#');
3103 if (pp.linemarkers == .line_directives) try w.writeAll("line");
3104 // line_no is 0 indexed
3105 try w.print(" {d} \"", .{line_no + 1});
3106 for (source.path) |byte| switch (byte) {
3107 '\n' => try w.writeAll("\\n"),
3108 '\r' => try w.writeAll("\\r"),
3109 '\t' => try w.writeAll("\\t"),
3110 '\\' => try w.writeAll("\\\\"),
3111 '"' => try w.writeAll("\\\""),
3112 ' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte),
3113 // Use hex escapes for any non-ASCII/unprintable characters.
3114 // This ensures that the parsed version of this string will end up
3115 // containing the same bytes as the input regardless of encoding.
3116 else => {
3117 try w.writeAll("\\x");
3118 try std.fmt.formatInt(byte, 16, .lower, .{ .width = 2, .fill = '0' }, w);
3119 },
3120 };
3121 try w.writeByte('"');
3122 if (pp.linemarkers == .numeric_directives) {
3123 switch (start_resume) {
3124 .none => {},
3125 .start => try w.writeAll(" 1"),
3126 .@"resume" => try w.writeAll(" 2"),
3127 }
3128 switch (source.kind) {
3129 .user => {},
3130 .system => try w.writeAll(" 3"),
3131 .extern_c_system => try w.writeAll(" 3 4"),
3132 }
3133 }
3134 try w.writeByte('\n');
3135}
3136
3137// After how many empty lines are needed to replace them with linemarkers.
3138const collapse_newlines = 8;
3139
3140/// Pretty print tokens and try to preserve whitespace.
3141pub fn prettyPrintTokens(pp: *Preprocessor, w: anytype) !void {
3142 const tok_ids = pp.tokens.items(.id);
3143
3144 var i: u32 = 0;
3145 var last_nl = true;
3146 outer: while (true) : (i += 1) {
3147 var cur: Token = pp.tokens.get(i);
3148 switch (cur.id) {
3149 .eof => {
3150 if (!last_nl) try w.writeByte('\n');
3151 return;
3152 },
3153 .nl => {
3154 var newlines: u32 = 0;
3155 for (tok_ids[i..], i..) |id, j| {
3156 if (id == .nl) {
3157 newlines += 1;
3158 } else if (id == .eof) {
3159 if (!last_nl) try w.writeByte('\n');
3160 return;
3161 } else if (id != .whitespace) {
3162 if (pp.linemarkers == .none) {
3163 if (newlines < 2) break;
3164 } else if (newlines < collapse_newlines) {
3165 break;
3166 }
3167
3168 i = @intCast((j - 1) - @intFromBool(tok_ids[j - 1] == .whitespace));
3169 if (!last_nl) try w.writeAll("\n");
3170 if (pp.linemarkers != .none) {
3171 const next = pp.tokens.get(i);
3172 const source = pp.comp.getSource(next.loc.id);
3173 const line_col = source.lineCol(next.loc);
3174 try pp.printLinemarker(w, line_col.line_no, source, .none);
3175 last_nl = true;
3176 }
3177 continue :outer;
3178 }
3179 }
3180 last_nl = true;
3181 try w.writeAll("\n");
3182 },
3183 .keyword_pragma => {
3184 const pragma_name = pp.expandedSlice(pp.tokens.get(i + 1));
3185 const end_idx = mem.indexOfScalarPos(Token.Id, tok_ids, i, .nl) orelse i + 1;
3186 const pragma_len = @as(u32, @intCast(end_idx)) - i;
3187
3188 if (pp.comp.getPragma(pragma_name)) |prag| {
3189 if (!prag.shouldPreserveTokens(pp, i + 1)) {
3190 try w.writeByte('\n');
3191 i += pragma_len;
3192 cur = pp.tokens.get(i);
3193 continue;
3194 }
3195 }
3196 try w.writeAll("#pragma");
3197 i += 1;
3198 while (true) : (i += 1) {
3199 cur = pp.tokens.get(i);
3200 if (cur.id == .nl) {
3201 try w.writeByte('\n');
3202 last_nl = true;
3203 break;
3204 }
3205 try w.writeByte(' ');
3206 const slice = pp.expandedSlice(cur);
3207 try w.writeAll(slice);
3208 }
3209 },
3210 .whitespace => {
3211 var slice = pp.expandedSlice(cur);
3212 while (mem.indexOfScalar(u8, slice, '\n')) |some| {
3213 if (pp.linemarkers != .none) try w.writeByte('\n');
3214 slice = slice[some + 1 ..];
3215 }
3216 for (slice) |_| try w.writeByte(' ');
3217 last_nl = false;
3218 },
3219 .include_start => {
3220 const source = pp.comp.getSource(cur.loc.id);
3221
3222 try pp.printLinemarker(w, 0, source, .start);
3223 last_nl = true;
3224 },
3225 .include_resume => {
3226 const source = pp.comp.getSource(cur.loc.id);
3227 const line_col = source.lineCol(cur.loc);
3228 if (!last_nl) try w.writeAll("\n");
3229
3230 try pp.printLinemarker(w, line_col.line_no, source, .@"resume");
3231 last_nl = true;
3232 },
3233 else => {
3234 const slice = pp.expandedSlice(cur);
3235 try w.writeAll(slice);
3236 last_nl = false;
3237 },
3238 }
3239 }
3240}
3241
3242test "Preserve pragma tokens sometimes" {
3243 const allocator = std.testing.allocator;
3244 const Test = struct {
3245 fn runPreprocessor(source_text: []const u8) ![]const u8 {
3246 var buf = std.ArrayList(u8).init(allocator);
3247 defer buf.deinit();
3248
3249 var comp = Compilation.init(allocator);
3250 defer comp.deinit();
3251
3252 try comp.addDefaultPragmaHandlers();
3253
3254 var pp = Preprocessor.init(&comp);
3255 defer pp.deinit();
3256
3257 pp.preserve_whitespace = true;
3258 assert(pp.linemarkers == .none);
3259
3260 const test_runner_macros = try comp.addSourceFromBuffer("<test_runner>", source_text);
3261 const eof = try pp.preprocess(test_runner_macros);
3262 try pp.tokens.append(pp.gpa, eof);
3263 try pp.prettyPrintTokens(buf.writer());
3264 return allocator.dupe(u8, buf.items);
3265 }
3266
3267 fn check(source_text: []const u8, expected: []const u8) !void {
3268 const output = try runPreprocessor(source_text);
3269 defer allocator.free(output);
3270
3271 try std.testing.expectEqualStrings(expected, output);
3272 }
3273 };
3274 const preserve_gcc_diagnostic =
3275 \\#pragma GCC diagnostic error "-Wnewline-eof"
3276 \\#pragma GCC warning error "-Wnewline-eof"
3277 \\int x;
3278 \\#pragma GCC ignored error "-Wnewline-eof"
3279 \\
3280 ;
3281 try Test.check(preserve_gcc_diagnostic, preserve_gcc_diagnostic);
3282
3283 const omit_once =
3284 \\#pragma once
3285 \\int x;
3286 \\#pragma once
3287 \\
3288 ;
3289 // TODO should only be one newline afterwards when emulating clang
3290 try Test.check(omit_once, "\nint x;\n\n");
3291
3292 const omit_poison =
3293 \\#pragma GCC poison foobar
3294 \\
3295 ;
3296 try Test.check(omit_poison, "\n");
3297}
3298
3299test "destringify" {
3300 const allocator = std.testing.allocator;
3301 const Test = struct {
3302 fn testDestringify(pp: *Preprocessor, stringified: []const u8, destringified: []const u8) !void {
3303 pp.char_buf.clearRetainingCapacity();
3304 try pp.char_buf.ensureUnusedCapacity(stringified.len);
3305 pp.destringify(stringified);
3306 try std.testing.expectEqualStrings(destringified, pp.char_buf.items);
3307 }
3308 };
3309 var comp = Compilation.init(allocator);
3310 defer comp.deinit();
3311 var pp = Preprocessor.init(&comp);
3312 defer pp.deinit();
3313
3314 try Test.testDestringify(&pp, "hello\tworld\n", "hello\tworld\n");
3315 try Test.testDestringify(&pp,
3316 \\ \"FOO BAR BAZ\"
3317 ,
3318 \\ "FOO BAR BAZ"
3319 );
3320 try Test.testDestringify(&pp,
3321 \\ \\t\\n
3322 \\
3323 ,
3324 \\ \t\n
3325 \\
3326 );
3327}
3328
3329test "Include guards" {
3330 const Test = struct {
3331 /// This is here so that when #elifdef / #elifndef are added we don't forget
3332 /// to test that they don't accidentally break include guard detection
3333 fn pairsWithIfndef(tok_id: RawToken.Id) bool {
3334 return switch (tok_id) {
3335 .keyword_elif,
3336 .keyword_elifdef,
3337 .keyword_elifndef,
3338 .keyword_else,
3339 => true,
3340
3341 .keyword_include,
3342 .keyword_include_next,
3343 .keyword_embed,
3344 .keyword_define,
3345 .keyword_defined,
3346 .keyword_undef,
3347 .keyword_ifdef,
3348 .keyword_ifndef,
3349 .keyword_error,
3350 .keyword_warning,
3351 .keyword_pragma,
3352 .keyword_line,
3353 .keyword_endif,
3354 => false,
3355 else => unreachable,
3356 };
3357 }
3358
3359 fn skippable(tok_id: RawToken.Id) bool {
3360 return switch (tok_id) {
3361 .keyword_defined, .keyword_va_args, .keyword_va_opt, .keyword_endif => true,
3362 else => false,
3363 };
3364 }
3365
3366 fn testIncludeGuard(allocator: std.mem.Allocator, comptime template: []const u8, tok_id: RawToken.Id, expected_guards: u32) !void {
3367 var comp = Compilation.init(allocator);
3368 defer comp.deinit();
3369 var pp = Preprocessor.init(&comp);
3370 defer pp.deinit();
3371
3372 const path = try std.fs.path.join(allocator, &.{ ".", "bar.h" });
3373 defer allocator.free(path);
3374
3375 _ = try comp.addSourceFromBuffer(path, "int bar = 5;\n");
3376
3377 var buf = std.ArrayList(u8).init(allocator);
3378 defer buf.deinit();
3379
3380 var writer = buf.writer();
3381 switch (tok_id) {
3382 .keyword_include, .keyword_include_next => try writer.print(template, .{ tok_id.lexeme().?, " \"bar.h\"" }),
3383 .keyword_define, .keyword_undef => try writer.print(template, .{ tok_id.lexeme().?, " BAR" }),
3384 .keyword_ifndef,
3385 .keyword_ifdef,
3386 .keyword_elifdef,
3387 .keyword_elifndef,
3388 => try writer.print(template, .{ tok_id.lexeme().?, " BAR\n#endif" }),
3389 else => try writer.print(template, .{ tok_id.lexeme().?, "" }),
3390 }
3391 const source = try comp.addSourceFromBuffer("test.h", buf.items);
3392 _ = try pp.preprocess(source);
3393
3394 try std.testing.expectEqual(expected_guards, pp.include_guards.count());
3395 }
3396 };
3397 const tags = std.meta.tags(RawToken.Id);
3398 for (tags) |tag| {
3399 if (Test.skippable(tag)) continue;
3400 var copy = tag;
3401 copy.simplifyMacroKeyword();
3402 if (copy != tag or tag == .keyword_else) {
3403 const inside_ifndef_template =
3404 \\//Leading comment (should be ignored)
3405 \\
3406 \\#ifndef FOO
3407 \\#{s}{s}
3408 \\#endif
3409 ;
3410 const expected_guards: u32 = if (Test.pairsWithIfndef(tag)) 0 else 1;
3411 try Test.testIncludeGuard(std.testing.allocator, inside_ifndef_template, tag, expected_guards);
3412
3413 const outside_ifndef_template =
3414 \\#ifndef FOO
3415 \\#endif
3416 \\#{s}{s}
3417 ;
3418 try Test.testIncludeGuard(std.testing.allocator, outside_ifndef_template, tag, 0);
3419 }
3420 }
3421}
lib/compiler/aro/aro/Source.zig created+127
......@@ -0,0 +1,127 @@
1const std = @import("std");
2
3pub const Id = enum(u32) {
4 unused = 0,
5 generated = 1,
6 _,
7};
8
9/// Classifies the file for line marker output in -E mode
10pub const Kind = enum {
11 /// regular file
12 user,
13 /// Included from a system include directory
14 system,
15 /// Included from an "implicit extern C" directory
16 extern_c_system,
17};
18
19pub const Location = struct {
20 id: Id = .unused,
21 byte_offset: u32 = 0,
22 line: u32 = 0,
23
24 pub fn eql(a: Location, b: Location) bool {
25 return a.id == b.id and a.byte_offset == b.byte_offset and a.line == b.line;
26 }
27};
28
29const Source = @This();
30
31path: []const u8,
32buf: []const u8,
33id: Id,
34/// each entry represents a byte position within `buf` where a backslash+newline was deleted
35/// from the original raw buffer. The same position can appear multiple times if multiple
36/// consecutive splices happened. Guaranteed to be non-decreasing
37splice_locs: []const u32,
38kind: Kind,
39
40/// Todo: binary search instead of scanning entire `splice_locs`.
41pub fn numSplicesBefore(source: Source, byte_offset: u32) u32 {
42 for (source.splice_locs, 0..) |splice_offset, i| {
43 if (splice_offset > byte_offset) return @intCast(i);
44 }
45 return @intCast(source.splice_locs.len);
46}
47
48/// Returns the actual line number (before newline splicing) of a Location
49/// This corresponds to what the user would actually see in their text editor
50pub fn physicalLine(source: Source, loc: Location) u32 {
51 return loc.line + source.numSplicesBefore(loc.byte_offset);
52}
53
54const LineCol = struct { line: []const u8, line_no: u32, col: u32, width: u32, end_with_splice: bool };
55
56pub fn lineCol(source: Source, loc: Location) LineCol {
57 var start: usize = 0;
58 // find the start of the line which is either a newline or a splice
59 if (std.mem.lastIndexOfScalar(u8, source.buf[0..loc.byte_offset], '\n')) |some| start = some + 1;
60 const splice_index: u32 = for (source.splice_locs, 0..) |splice_offset, i| {
61 if (splice_offset > start) {
62 if (splice_offset < loc.byte_offset) {
63 start = splice_offset;
64 break @as(u32, @intCast(i)) + 1;
65 }
66 break @intCast(i);
67 }
68 } else @intCast(source.splice_locs.len);
69 var i: usize = start;
70 var col: u32 = 1;
71 var width: u32 = 0;
72
73 while (i < loc.byte_offset) : (col += 1) { // TODO this is still incorrect, but better
74 const len = std.unicode.utf8ByteSequenceLength(source.buf[i]) catch {
75 i += 1;
76 continue;
77 };
78 const cp = std.unicode.utf8Decode(source.buf[i..][0..len]) catch {
79 i += 1;
80 continue;
81 };
82 width += codepointWidth(cp);
83 i += len;
84 }
85
86 // find the end of the line which is either a newline, EOF or a splice
87 var nl = source.buf.len;
88 var end_with_splice = false;
89 if (std.mem.indexOfScalar(u8, source.buf[start..], '\n')) |some| nl = some + start;
90 if (source.splice_locs.len > splice_index and nl > source.splice_locs[splice_index] and source.splice_locs[splice_index] > start) {
91 end_with_splice = true;
92 nl = source.splice_locs[splice_index];
93 }
94 return .{
95 .line = source.buf[start..nl],
96 .line_no = loc.line + splice_index,
97 .col = col,
98 .width = width,
99 .end_with_splice = end_with_splice,
100 };
101}
102
103fn codepointWidth(cp: u32) u32 {
104 return switch (cp) {
105 0x1100...0x115F,
106 0x2329,
107 0x232A,
108 0x2E80...0x303F,
109 0x3040...0x3247,
110 0x3250...0x4DBF,
111 0x4E00...0xA4C6,
112 0xA960...0xA97C,
113 0xAC00...0xD7A3,
114 0xF900...0xFAFF,
115 0xFE10...0xFE19,
116 0xFE30...0xFE6B,
117 0xFF01...0xFF60,
118 0xFFE0...0xFFE6,
119 0x1B000...0x1B001,
120 0x1F200...0x1F251,
121 0x20000...0x3FFFD,
122 0x1F300...0x1F5FF,
123 0x1F900...0x1F9FF,
124 => 2,
125 else => 1,
126 };
127}
lib/compiler/aro/aro/StringInterner.zig created+83
......@@ -0,0 +1,83 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("Compilation.zig");
4
5const StringToIdMap = std.StringHashMapUnmanaged(StringId);
6
7pub const StringId = enum(u32) {
8 empty,
9 _,
10};
11
12pub const TypeMapper = struct {
13 const LookupSpeed = enum {
14 fast,
15 slow,
16 };
17
18 data: union(LookupSpeed) {
19 fast: []const []const u8,
20 slow: *const StringToIdMap,
21 },
22
23 pub fn lookup(self: TypeMapper, string_id: StringInterner.StringId) []const u8 {
24 if (string_id == .empty) return "";
25 switch (self.data) {
26 .fast => |arr| return arr[@intFromEnum(string_id)],
27 .slow => |map| {
28 var it = map.iterator();
29 while (it.next()) |entry| {
30 if (entry.value_ptr.* == string_id) return entry.key_ptr.*;
31 }
32 unreachable;
33 },
34 }
35 }
36
37 pub fn deinit(self: TypeMapper, allocator: mem.Allocator) void {
38 switch (self.data) {
39 .slow => {},
40 .fast => |arr| allocator.free(arr),
41 }
42 }
43};
44
45const StringInterner = @This();
46
47string_table: StringToIdMap = .{},
48next_id: StringId = @enumFromInt(@intFromEnum(StringId.empty) + 1),
49
50pub fn deinit(self: *StringInterner, allocator: mem.Allocator) void {
51 self.string_table.deinit(allocator);
52}
53
54pub fn intern(comp: *Compilation, str: []const u8) !StringId {
55 return comp.string_interner.internExtra(comp.gpa, str);
56}
57
58pub fn internExtra(self: *StringInterner, allocator: mem.Allocator, str: []const u8) !StringId {
59 if (str.len == 0) return .empty;
60
61 const gop = try self.string_table.getOrPut(allocator, str);
62 if (gop.found_existing) return gop.value_ptr.*;
63
64 defer self.next_id = @enumFromInt(@intFromEnum(self.next_id) + 1);
65 gop.value_ptr.* = self.next_id;
66 return self.next_id;
67}
68
69/// deinit for the returned TypeMapper is a no-op and does not need to be called
70pub fn getSlowTypeMapper(self: *const StringInterner) TypeMapper {
71 return TypeMapper{ .data = .{ .slow = &self.string_table } };
72}
73
74/// Caller must call `deinit` on the returned TypeMapper
75pub fn getFastTypeMapper(self: *const StringInterner, allocator: mem.Allocator) !TypeMapper {
76 var strings = try allocator.alloc([]const u8, @intFromEnum(self.next_id));
77 var it = self.string_table.iterator();
78 strings[0] = "";
79 while (it.next()) |entry| {
80 strings[@intFromEnum(entry.value_ptr.*)] = entry.key_ptr.*;
81 }
82 return TypeMapper{ .data = .{ .fast = strings } };
83}
lib/compiler/aro/aro/SymbolStack.zig created+392
......@@ -0,0 +1,392 @@
1const std = @import("std");
2const mem = std.mem;
3const Allocator = mem.Allocator;
4const assert = std.debug.assert;
5const Tree = @import("Tree.zig");
6const Token = Tree.Token;
7const TokenIndex = Tree.TokenIndex;
8const NodeIndex = Tree.NodeIndex;
9const Type = @import("Type.zig");
10const Parser = @import("Parser.zig");
11const Value = @import("Value.zig");
12const StringId = @import("StringInterner.zig").StringId;
13
14const SymbolStack = @This();
15
16pub const Symbol = struct {
17 name: StringId,
18 ty: Type,
19 tok: TokenIndex,
20 node: NodeIndex = .none,
21 kind: Kind,
22 val: Value,
23};
24
25pub const Kind = enum {
26 typedef,
27 @"struct",
28 @"union",
29 @"enum",
30 decl,
31 def,
32 enumeration,
33 constexpr,
34};
35
36scopes: std.ArrayListUnmanaged(Scope) = .{},
37/// allocations from nested scopes are retained after popping; `active_len` is the number
38/// of currently-active items in `scopes`.
39active_len: usize = 0,
40
41const Scope = struct {
42 vars: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
43 tags: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
44
45 fn deinit(self: *Scope, allocator: Allocator) void {
46 self.vars.deinit(allocator);
47 self.tags.deinit(allocator);
48 }
49
50 fn clearRetainingCapacity(self: *Scope) void {
51 self.vars.clearRetainingCapacity();
52 self.tags.clearRetainingCapacity();
53 }
54};
55
56pub fn deinit(s: *SymbolStack, gpa: Allocator) void {
57 std.debug.assert(s.active_len == 0); // all scopes should have been popped
58 for (s.scopes.items) |*scope| {
59 scope.deinit(gpa);
60 }
61 s.scopes.deinit(gpa);
62 s.* = undefined;
63}
64
65pub fn pushScope(s: *SymbolStack, p: *Parser) !void {
66 if (s.active_len + 1 > s.scopes.items.len) {
67 try s.scopes.append(p.gpa, .{});
68 s.active_len = s.scopes.items.len;
69 } else {
70 s.scopes.items[s.active_len].clearRetainingCapacity();
71 s.active_len += 1;
72 }
73}
74
75pub fn popScope(s: *SymbolStack) void {
76 s.active_len -= 1;
77}
78
79pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol {
80 const prev = s.lookup(name, .vars) orelse s.lookup(name, .tags) orelse return null;
81 switch (prev.kind) {
82 .typedef => return prev,
83 .@"struct" => {
84 if (no_type_yet) return null;
85 try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));
86 return prev;
87 },
88 .@"union" => {
89 if (no_type_yet) return null;
90 try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));
91 return prev;
92 },
93 .@"enum" => {
94 if (no_type_yet) return null;
95 try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok));
96 return prev;
97 },
98 else => return null,
99 }
100}
101
102pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol {
103 return s.lookup(name, .vars);
104}
105
106pub fn findTag(
107 s: *SymbolStack,
108 p: *Parser,
109 name: StringId,
110 kind: Token.Id,
111 name_tok: TokenIndex,
112 next_tok_id: Token.Id,
113) !?Symbol {
114 // `tag Name;` should always result in a new type if in a new scope.
115 const prev = (if (next_tok_id == .semicolon) s.get(name, .tags) else s.lookup(name, .tags)) orelse return null;
116 switch (prev.kind) {
117 .@"enum" => if (kind == .keyword_enum) return prev,
118 .@"struct" => if (kind == .keyword_struct) return prev,
119 .@"union" => if (kind == .keyword_union) return prev,
120 else => unreachable,
121 }
122 if (s.get(name, .tags) == null) return null;
123 try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok));
124 try p.errTok(.previous_definition, prev.tok);
125 return null;
126}
127
128const ScopeKind = enum {
129 /// structs, enums, unions
130 tags,
131 /// everything else
132 vars,
133};
134
135/// Return the Symbol for `name` (or null if not found) in the innermost scope
136pub fn get(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol {
137 return switch (kind) {
138 .vars => s.scopes.items[s.active_len - 1].vars.get(name),
139 .tags => s.scopes.items[s.active_len - 1].tags.get(name),
140 };
141}
142
143/// Return the Symbol for `name` (or null if not found) in the nearest active scope,
144/// starting at the innermost.
145fn lookup(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol {
146 var i = s.active_len;
147 while (i > 0) {
148 i -= 1;
149 switch (kind) {
150 .vars => if (s.scopes.items[i].vars.get(name)) |sym| return sym,
151 .tags => if (s.scopes.items[i].tags.get(name)) |sym| return sym,
152 }
153 }
154 return null;
155}
156
157/// Define a symbol in the innermost scope. Does not issue diagnostics or check correctness
158/// with regard to the C standard.
159pub fn define(s: *SymbolStack, allocator: Allocator, symbol: Symbol) !void {
160 switch (symbol.kind) {
161 .constexpr, .def, .decl, .enumeration, .typedef => {
162 try s.scopes.items[s.active_len - 1].vars.put(allocator, symbol.name, symbol);
163 },
164 .@"struct", .@"union", .@"enum" => {
165 try s.scopes.items[s.active_len - 1].tags.put(allocator, symbol.name, symbol);
166 },
167 }
168}
169
170pub fn defineTypedef(
171 s: *SymbolStack,
172 p: *Parser,
173 name: StringId,
174 ty: Type,
175 tok: TokenIndex,
176 node: NodeIndex,
177) !void {
178 if (s.get(name, .vars)) |prev| {
179 switch (prev.kind) {
180 .typedef => {
181 if (!ty.eql(prev.ty, p.comp, true)) {
182 try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev.ty));
183 if (prev.tok != 0) try p.errTok(.previous_definition, prev.tok);
184 }
185 },
186 .enumeration, .decl, .def, .constexpr => {
187 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
188 try p.errTok(.previous_definition, prev.tok);
189 },
190 else => unreachable,
191 }
192 }
193 try s.define(p.gpa, .{
194 .kind = .typedef,
195 .name = name,
196 .tok = tok,
197 .ty = ty,
198 .node = node,
199 .val = .{},
200 });
201}
202
203pub fn defineSymbol(
204 s: *SymbolStack,
205 p: *Parser,
206 name: StringId,
207 ty: Type,
208 tok: TokenIndex,
209 node: NodeIndex,
210 val: Value,
211 constexpr: bool,
212) !void {
213 if (s.get(name, .vars)) |prev| {
214 switch (prev.kind) {
215 .enumeration => {
216 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
217 try p.errTok(.previous_definition, prev.tok);
218 },
219 .decl => {
220 if (!ty.eql(prev.ty, p.comp, true)) {
221 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
222 try p.errTok(.previous_definition, prev.tok);
223 }
224 },
225 .def, .constexpr => {
226 try p.errStr(.redefinition, tok, p.tokSlice(tok));
227 try p.errTok(.previous_definition, prev.tok);
228 },
229 .typedef => {
230 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
231 try p.errTok(.previous_definition, prev.tok);
232 },
233 else => unreachable,
234 }
235 }
236
237 try s.define(p.gpa, .{
238 .kind = if (constexpr) .constexpr else .def,
239 .name = name,
240 .tok = tok,
241 .ty = ty,
242 .node = node,
243 .val = val,
244 });
245}
246
247/// Get a pointer to the named symbol in the innermost scope.
248/// Asserts that a symbol with the name exists.
249pub fn getPtr(s: *SymbolStack, name: StringId, kind: ScopeKind) *Symbol {
250 return switch (kind) {
251 .tags => s.scopes.items[s.active_len - 1].tags.getPtr(name).?,
252 .vars => s.scopes.items[s.active_len - 1].vars.getPtr(name).?,
253 };
254}
255
256pub fn declareSymbol(
257 s: *SymbolStack,
258 p: *Parser,
259 name: StringId,
260 ty: Type,
261 tok: TokenIndex,
262 node: NodeIndex,
263) !void {
264 if (s.get(name, .vars)) |prev| {
265 switch (prev.kind) {
266 .enumeration => {
267 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
268 try p.errTok(.previous_definition, prev.tok);
269 },
270 .decl => {
271 if (!ty.eql(prev.ty, p.comp, true)) {
272 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
273 try p.errTok(.previous_definition, prev.tok);
274 }
275 },
276 .def, .constexpr => {
277 if (!ty.eql(prev.ty, p.comp, true)) {
278 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
279 try p.errTok(.previous_definition, prev.tok);
280 } else {
281 return;
282 }
283 },
284 .typedef => {
285 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
286 try p.errTok(.previous_definition, prev.tok);
287 },
288 else => unreachable,
289 }
290 }
291 try s.define(p.gpa, .{
292 .kind = .decl,
293 .name = name,
294 .tok = tok,
295 .ty = ty,
296 .node = node,
297 .val = .{},
298 });
299}
300
301pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void {
302 if (s.get(name, .vars)) |prev| {
303 switch (prev.kind) {
304 .enumeration, .decl, .def, .constexpr => {
305 try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok));
306 try p.errTok(.previous_definition, prev.tok);
307 },
308 .typedef => {
309 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
310 try p.errTok(.previous_definition, prev.tok);
311 },
312 else => unreachable,
313 }
314 }
315 if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
316 try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters");
317 }
318 try s.define(p.gpa, .{
319 .kind = .def,
320 .name = name,
321 .tok = tok,
322 .ty = ty,
323 .val = .{},
324 });
325}
326
327pub fn defineTag(
328 s: *SymbolStack,
329 p: *Parser,
330 name: StringId,
331 kind: Token.Id,
332 tok: TokenIndex,
333) !?Symbol {
334 const prev = s.get(name, .tags) orelse return null;
335 switch (prev.kind) {
336 .@"enum" => {
337 if (kind == .keyword_enum) return prev;
338 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
339 try p.errTok(.previous_definition, prev.tok);
340 return null;
341 },
342 .@"struct" => {
343 if (kind == .keyword_struct) return prev;
344 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
345 try p.errTok(.previous_definition, prev.tok);
346 return null;
347 },
348 .@"union" => {
349 if (kind == .keyword_union) return prev;
350 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
351 try p.errTok(.previous_definition, prev.tok);
352 return null;
353 },
354 else => unreachable,
355 }
356}
357
358pub fn defineEnumeration(
359 s: *SymbolStack,
360 p: *Parser,
361 name: StringId,
362 ty: Type,
363 tok: TokenIndex,
364 val: Value,
365) !void {
366 if (s.get(name, .vars)) |prev| {
367 switch (prev.kind) {
368 .enumeration => {
369 try p.errStr(.redefinition, tok, p.tokSlice(tok));
370 try p.errTok(.previous_definition, prev.tok);
371 return;
372 },
373 .decl, .def, .constexpr => {
374 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
375 try p.errTok(.previous_definition, prev.tok);
376 return;
377 },
378 .typedef => {
379 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
380 try p.errTok(.previous_definition, prev.tok);
381 },
382 else => unreachable,
383 }
384 }
385 try s.define(p.gpa, .{
386 .kind = .enumeration,
387 .name = name,
388 .tok = tok,
389 .ty = ty,
390 .val = val,
391 });
392}
lib/compiler/aro/aro/Tokenizer.zig created+2174
......@@ -0,0 +1,2174 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const Compilation = @import("Compilation.zig");
4const Source = @import("Source.zig");
5const LangOpts = @import("LangOpts.zig");
6
7pub const Token = struct {
8 id: Id,
9 source: Source.Id,
10 start: u32 = 0,
11 end: u32 = 0,
12 line: u32 = 0,
13
14 pub const Id = enum(u8) {
15 invalid,
16 nl,
17 whitespace,
18 eof,
19 /// identifier containing solely basic character set characters
20 identifier,
21 /// identifier with at least one extended character
22 extended_identifier,
23
24 // string literals with prefixes
25 string_literal,
26 string_literal_utf_16,
27 string_literal_utf_8,
28 string_literal_utf_32,
29 string_literal_wide,
30
31 /// Any string literal with an embedded newline or EOF
32 /// Always a parser error; by default just a warning from preprocessor
33 unterminated_string_literal,
34
35 // <foobar> only generated by preprocessor
36 macro_string,
37
38 // char literals with prefixes
39 char_literal,
40 char_literal_utf_8,
41 char_literal_utf_16,
42 char_literal_utf_32,
43 char_literal_wide,
44
45 /// Any character literal with nothing inside the quotes
46 /// Always a parser error; by default just a warning from preprocessor
47 empty_char_literal,
48
49 /// Any character literal with an embedded newline or EOF
50 /// Always a parser error; by default just a warning from preprocessor
51 unterminated_char_literal,
52
53 /// `/* */` style comment without a closing `*/` before EOF
54 unterminated_comment,
55
56 /// Integer literal tokens generated by preprocessor.
57 one,
58 zero,
59
60 bang,
61 bang_equal,
62 pipe,
63 pipe_pipe,
64 pipe_equal,
65 equal,
66 equal_equal,
67 l_paren,
68 r_paren,
69 l_brace,
70 r_brace,
71 l_bracket,
72 r_bracket,
73 period,
74 ellipsis,
75 caret,
76 caret_equal,
77 plus,
78 plus_plus,
79 plus_equal,
80 minus,
81 minus_minus,
82 minus_equal,
83 asterisk,
84 asterisk_equal,
85 percent,
86 percent_equal,
87 arrow,
88 colon,
89 colon_colon,
90 semicolon,
91 slash,
92 slash_equal,
93 comma,
94 ampersand,
95 ampersand_ampersand,
96 ampersand_equal,
97 question_mark,
98 angle_bracket_left,
99 angle_bracket_left_equal,
100 angle_bracket_angle_bracket_left,
101 angle_bracket_angle_bracket_left_equal,
102 angle_bracket_right,
103 angle_bracket_right_equal,
104 angle_bracket_angle_bracket_right,
105 angle_bracket_angle_bracket_right_equal,
106 tilde,
107 hash,
108 hash_hash,
109
110 /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
111 macro_param,
112 /// Special token to signal that the argument must be replaced without expansion (e.g. in concatenation)
113 macro_param_no_expand,
114 /// Special token to speed up preprocessing, `loc.end` will be an index to the param list.
115 stringify_param,
116 /// Same as stringify_param, but for var args
117 stringify_va_args,
118 /// Special macro whitespace, always equal to a single space
119 macro_ws,
120 /// Special token for implementing __has_attribute
121 macro_param_has_attribute,
122 /// Special token for implementing __has_c_attribute
123 macro_param_has_c_attribute,
124 /// Special token for implementing __has_declspec_attribute
125 macro_param_has_declspec_attribute,
126 /// Special token for implementing __has_warning
127 macro_param_has_warning,
128 /// Special token for implementing __has_feature
129 macro_param_has_feature,
130 /// Special token for implementing __has_extension
131 macro_param_has_extension,
132 /// Special token for implementing __has_builtin
133 macro_param_has_builtin,
134 /// Special token for implementing __has_include
135 macro_param_has_include,
136 /// Special token for implementing __has_include_next
137 macro_param_has_include_next,
138 /// Special token for implementing __has_embed
139 macro_param_has_embed,
140 /// Special token for implementing __is_identifier
141 macro_param_is_identifier,
142 /// Special token for implementing __FILE__
143 macro_file,
144 /// Special token for implementing __LINE__
145 macro_line,
146 /// Special token for implementing __COUNTER__
147 macro_counter,
148 /// Special token for implementing _Pragma
149 macro_param_pragma_operator,
150
151 /// Special identifier for implementing __func__
152 macro_func,
153 /// Special identifier for implementing __FUNCTION__
154 macro_function,
155 /// Special identifier for implementing __PRETTY_FUNCTION__
156 macro_pretty_func,
157
158 keyword_auto,
159 keyword_auto_type,
160 keyword_break,
161 keyword_case,
162 keyword_char,
163 keyword_const,
164 keyword_continue,
165 keyword_default,
166 keyword_do,
167 keyword_double,
168 keyword_else,
169 keyword_enum,
170 keyword_extern,
171 keyword_float,
172 keyword_for,
173 keyword_goto,
174 keyword_if,
175 keyword_int,
176 keyword_long,
177 keyword_register,
178 keyword_return,
179 keyword_short,
180 keyword_signed,
181 keyword_sizeof,
182 keyword_static,
183 keyword_struct,
184 keyword_switch,
185 keyword_typedef,
186 keyword_typeof1,
187 keyword_typeof2,
188 keyword_union,
189 keyword_unsigned,
190 keyword_void,
191 keyword_volatile,
192 keyword_while,
193
194 // ISO C99
195 keyword_bool,
196 keyword_complex,
197 keyword_imaginary,
198 keyword_inline,
199 keyword_restrict,
200
201 // ISO C11
202 keyword_alignas,
203 keyword_alignof,
204 keyword_atomic,
205 keyword_generic,
206 keyword_noreturn,
207 keyword_static_assert,
208 keyword_thread_local,
209
210 // ISO C23
211 keyword_bit_int,
212 keyword_c23_alignas,
213 keyword_c23_alignof,
214 keyword_c23_bool,
215 keyword_c23_static_assert,
216 keyword_c23_thread_local,
217 keyword_constexpr,
218 keyword_true,
219 keyword_false,
220 keyword_nullptr,
221 keyword_typeof_unqual,
222
223 // Preprocessor directives
224 keyword_include,
225 keyword_include_next,
226 keyword_embed,
227 keyword_define,
228 keyword_defined,
229 keyword_undef,
230 keyword_ifdef,
231 keyword_ifndef,
232 keyword_elif,
233 keyword_elifdef,
234 keyword_elifndef,
235 keyword_endif,
236 keyword_error,
237 keyword_warning,
238 keyword_pragma,
239 keyword_line,
240 keyword_va_args,
241 keyword_va_opt,
242
243 // gcc keywords
244 keyword_const1,
245 keyword_const2,
246 keyword_inline1,
247 keyword_inline2,
248 keyword_volatile1,
249 keyword_volatile2,
250 keyword_restrict1,
251 keyword_restrict2,
252 keyword_alignof1,
253 keyword_alignof2,
254 keyword_typeof,
255 keyword_attribute1,
256 keyword_attribute2,
257 keyword_extension,
258 keyword_asm,
259 keyword_asm1,
260 keyword_asm2,
261 keyword_float80,
262 /// _Float128
263 keyword_float128_1,
264 /// __float128
265 keyword_float128_2,
266 keyword_int128,
267 keyword_imag1,
268 keyword_imag2,
269 keyword_real1,
270 keyword_real2,
271 keyword_float16,
272
273 // clang keywords
274 keyword_fp16,
275
276 // ms keywords
277 keyword_declspec,
278 keyword_int64,
279 keyword_int64_2,
280 keyword_int32,
281 keyword_int32_2,
282 keyword_int16,
283 keyword_int16_2,
284 keyword_int8,
285 keyword_int8_2,
286 keyword_stdcall,
287 keyword_stdcall2,
288 keyword_thiscall,
289 keyword_thiscall2,
290 keyword_vectorcall,
291 keyword_vectorcall2,
292
293 // builtins that require special parsing
294 builtin_choose_expr,
295 builtin_va_arg,
296 builtin_offsetof,
297 builtin_bitoffsetof,
298 builtin_types_compatible_p,
299
300 /// Generated by #embed directive
301 /// Decimal value with no prefix or suffix
302 embed_byte,
303
304 /// preprocessor number
305 /// An optional period, followed by a digit 0-9, followed by any number of letters
306 /// digits, underscores, periods, and exponents (e+, e-, E+, E-, p+, p-, P+, P-)
307 pp_num,
308
309 /// preprocessor placemarker token
310 /// generated if `##` is used with a zero-token argument
311 /// removed after substitution, so the parser should never see this
312 /// See C99 6.10.3.3.2
313 placemarker,
314
315 /// Virtual linemarker token output from preprocessor to indicate start of a new include
316 include_start,
317
318 /// Virtual linemarker token output from preprocessor to indicate resuming a file after
319 /// completion of the preceding #include
320 include_resume,
321
322 /// A comment token if asked to preserve comments.
323 comment,
324
325 /// Return true if token is identifier or keyword.
326 pub fn isMacroIdentifier(id: Id) bool {
327 switch (id) {
328 .keyword_include,
329 .keyword_include_next,
330 .keyword_embed,
331 .keyword_define,
332 .keyword_defined,
333 .keyword_undef,
334 .keyword_ifdef,
335 .keyword_ifndef,
336 .keyword_elif,
337 .keyword_elifdef,
338 .keyword_elifndef,
339 .keyword_endif,
340 .keyword_error,
341 .keyword_warning,
342 .keyword_pragma,
343 .keyword_line,
344 .keyword_va_args,
345 .keyword_va_opt,
346 .macro_func,
347 .macro_function,
348 .macro_pretty_func,
349 .keyword_auto,
350 .keyword_auto_type,
351 .keyword_break,
352 .keyword_case,
353 .keyword_char,
354 .keyword_const,
355 .keyword_continue,
356 .keyword_default,
357 .keyword_do,
358 .keyword_double,
359 .keyword_else,
360 .keyword_enum,
361 .keyword_extern,
362 .keyword_float,
363 .keyword_for,
364 .keyword_goto,
365 .keyword_if,
366 .keyword_int,
367 .keyword_long,
368 .keyword_register,
369 .keyword_return,
370 .keyword_short,
371 .keyword_signed,
372 .keyword_sizeof,
373 .keyword_static,
374 .keyword_struct,
375 .keyword_switch,
376 .keyword_typedef,
377 .keyword_union,
378 .keyword_unsigned,
379 .keyword_void,
380 .keyword_volatile,
381 .keyword_while,
382 .keyword_bool,
383 .keyword_complex,
384 .keyword_imaginary,
385 .keyword_inline,
386 .keyword_restrict,
387 .keyword_alignas,
388 .keyword_alignof,
389 .keyword_atomic,
390 .keyword_generic,
391 .keyword_noreturn,
392 .keyword_static_assert,
393 .keyword_thread_local,
394 .identifier,
395 .extended_identifier,
396 .keyword_typeof,
397 .keyword_typeof1,
398 .keyword_typeof2,
399 .keyword_const1,
400 .keyword_const2,
401 .keyword_inline1,
402 .keyword_inline2,
403 .keyword_volatile1,
404 .keyword_volatile2,
405 .keyword_restrict1,
406 .keyword_restrict2,
407 .keyword_alignof1,
408 .keyword_alignof2,
409 .builtin_choose_expr,
410 .builtin_va_arg,
411 .builtin_offsetof,
412 .builtin_bitoffsetof,
413 .builtin_types_compatible_p,
414 .keyword_attribute1,
415 .keyword_attribute2,
416 .keyword_extension,
417 .keyword_asm,
418 .keyword_asm1,
419 .keyword_asm2,
420 .keyword_float80,
421 .keyword_float128_1,
422 .keyword_float128_2,
423 .keyword_int128,
424 .keyword_imag1,
425 .keyword_imag2,
426 .keyword_real1,
427 .keyword_real2,
428 .keyword_float16,
429 .keyword_fp16,
430 .keyword_declspec,
431 .keyword_int64,
432 .keyword_int64_2,
433 .keyword_int32,
434 .keyword_int32_2,
435 .keyword_int16,
436 .keyword_int16_2,
437 .keyword_int8,
438 .keyword_int8_2,
439 .keyword_stdcall,
440 .keyword_stdcall2,
441 .keyword_thiscall,
442 .keyword_thiscall2,
443 .keyword_vectorcall,
444 .keyword_vectorcall2,
445 .keyword_bit_int,
446 .keyword_c23_alignas,
447 .keyword_c23_alignof,
448 .keyword_c23_bool,
449 .keyword_c23_static_assert,
450 .keyword_c23_thread_local,
451 .keyword_constexpr,
452 .keyword_true,
453 .keyword_false,
454 .keyword_nullptr,
455 .keyword_typeof_unqual,
456 => return true,
457 else => return false,
458 }
459 }
460
461 /// Turn macro keywords into identifiers.
462 /// `keyword_defined` is special since it should only turn into an identifier if
463 /// we are *not* in an #if or #elif expression
464 pub fn simplifyMacroKeywordExtra(id: *Id, defined_to_identifier: bool) void {
465 switch (id.*) {
466 .keyword_include,
467 .keyword_include_next,
468 .keyword_embed,
469 .keyword_define,
470 .keyword_undef,
471 .keyword_ifdef,
472 .keyword_ifndef,
473 .keyword_elif,
474 .keyword_elifdef,
475 .keyword_elifndef,
476 .keyword_endif,
477 .keyword_error,
478 .keyword_warning,
479 .keyword_pragma,
480 .keyword_line,
481 .keyword_va_args,
482 .keyword_va_opt,
483 => id.* = .identifier,
484 .keyword_defined => if (defined_to_identifier) {
485 id.* = .identifier;
486 },
487 else => {},
488 }
489 }
490
491 pub fn simplifyMacroKeyword(id: *Id) void {
492 simplifyMacroKeywordExtra(id, false);
493 }
494
495 pub fn lexeme(id: Id) ?[]const u8 {
496 return switch (id) {
497 .include_start,
498 .include_resume,
499 => unreachable,
500
501 .unterminated_comment,
502 .invalid,
503 .identifier,
504 .extended_identifier,
505 .string_literal,
506 .string_literal_utf_16,
507 .string_literal_utf_8,
508 .string_literal_utf_32,
509 .string_literal_wide,
510 .unterminated_string_literal,
511 .unterminated_char_literal,
512 .empty_char_literal,
513 .char_literal,
514 .char_literal_utf_8,
515 .char_literal_utf_16,
516 .char_literal_utf_32,
517 .char_literal_wide,
518 .macro_string,
519 .whitespace,
520 .pp_num,
521 .embed_byte,
522 .comment,
523 => null,
524
525 .zero => "0",
526 .one => "1",
527
528 .nl,
529 .eof,
530 .macro_param,
531 .macro_param_no_expand,
532 .stringify_param,
533 .stringify_va_args,
534 .macro_param_has_attribute,
535 .macro_param_has_c_attribute,
536 .macro_param_has_declspec_attribute,
537 .macro_param_has_warning,
538 .macro_param_has_feature,
539 .macro_param_has_extension,
540 .macro_param_has_builtin,
541 .macro_param_has_include,
542 .macro_param_has_include_next,
543 .macro_param_has_embed,
544 .macro_param_is_identifier,
545 .macro_file,
546 .macro_line,
547 .macro_counter,
548 .macro_param_pragma_operator,
549 .placemarker,
550 => "",
551 .macro_ws => " ",
552
553 .macro_func => "__func__",
554 .macro_function => "__FUNCTION__",
555 .macro_pretty_func => "__PRETTY_FUNCTION__",
556
557 .bang => "!",
558 .bang_equal => "!=",
559 .pipe => "|",
560 .pipe_pipe => "||",
561 .pipe_equal => "|=",
562 .equal => "=",
563 .equal_equal => "==",
564 .l_paren => "(",
565 .r_paren => ")",
566 .l_brace => "{",
567 .r_brace => "}",
568 .l_bracket => "[",
569 .r_bracket => "]",
570 .period => ".",
571 .ellipsis => "...",
572 .caret => "^",
573 .caret_equal => "^=",
574 .plus => "+",
575 .plus_plus => "++",
576 .plus_equal => "+=",
577 .minus => "-",
578 .minus_minus => "--",
579 .minus_equal => "-=",
580 .asterisk => "*",
581 .asterisk_equal => "*=",
582 .percent => "%",
583 .percent_equal => "%=",
584 .arrow => "->",
585 .colon => ":",
586 .colon_colon => "::",
587 .semicolon => ";",
588 .slash => "/",
589 .slash_equal => "/=",
590 .comma => ",",
591 .ampersand => "&",
592 .ampersand_ampersand => "&&",
593 .ampersand_equal => "&=",
594 .question_mark => "?",
595 .angle_bracket_left => "<",
596 .angle_bracket_left_equal => "<=",
597 .angle_bracket_angle_bracket_left => "<<",
598 .angle_bracket_angle_bracket_left_equal => "<<=",
599 .angle_bracket_right => ">",
600 .angle_bracket_right_equal => ">=",
601 .angle_bracket_angle_bracket_right => ">>",
602 .angle_bracket_angle_bracket_right_equal => ">>=",
603 .tilde => "~",
604 .hash => "#",
605 .hash_hash => "##",
606
607 .keyword_auto => "auto",
608 .keyword_auto_type => "__auto_type",
609 .keyword_break => "break",
610 .keyword_case => "case",
611 .keyword_char => "char",
612 .keyword_const => "const",
613 .keyword_continue => "continue",
614 .keyword_default => "default",
615 .keyword_do => "do",
616 .keyword_double => "double",
617 .keyword_else => "else",
618 .keyword_enum => "enum",
619 .keyword_extern => "extern",
620 .keyword_float => "float",
621 .keyword_for => "for",
622 .keyword_goto => "goto",
623 .keyword_if => "if",
624 .keyword_int => "int",
625 .keyword_long => "long",
626 .keyword_register => "register",
627 .keyword_return => "return",
628 .keyword_short => "short",
629 .keyword_signed => "signed",
630 .keyword_sizeof => "sizeof",
631 .keyword_static => "static",
632 .keyword_struct => "struct",
633 .keyword_switch => "switch",
634 .keyword_typedef => "typedef",
635 .keyword_typeof => "typeof",
636 .keyword_union => "union",
637 .keyword_unsigned => "unsigned",
638 .keyword_void => "void",
639 .keyword_volatile => "volatile",
640 .keyword_while => "while",
641 .keyword_bool => "_Bool",
642 .keyword_complex => "_Complex",
643 .keyword_imaginary => "_Imaginary",
644 .keyword_inline => "inline",
645 .keyword_restrict => "restrict",
646 .keyword_alignas => "_Alignas",
647 .keyword_alignof => "_Alignof",
648 .keyword_atomic => "_Atomic",
649 .keyword_generic => "_Generic",
650 .keyword_noreturn => "_Noreturn",
651 .keyword_static_assert => "_Static_assert",
652 .keyword_thread_local => "_Thread_local",
653 .keyword_bit_int => "_BitInt",
654 .keyword_c23_alignas => "alignas",
655 .keyword_c23_alignof => "alignof",
656 .keyword_c23_bool => "bool",
657 .keyword_c23_static_assert => "static_assert",
658 .keyword_c23_thread_local => "thread_local",
659 .keyword_constexpr => "constexpr",
660 .keyword_true => "true",
661 .keyword_false => "false",
662 .keyword_nullptr => "nullptr",
663 .keyword_typeof_unqual => "typeof_unqual",
664 .keyword_include => "include",
665 .keyword_include_next => "include_next",
666 .keyword_embed => "embed",
667 .keyword_define => "define",
668 .keyword_defined => "defined",
669 .keyword_undef => "undef",
670 .keyword_ifdef => "ifdef",
671 .keyword_ifndef => "ifndef",
672 .keyword_elif => "elif",
673 .keyword_elifdef => "elifdef",
674 .keyword_elifndef => "elifndef",
675 .keyword_endif => "endif",
676 .keyword_error => "error",
677 .keyword_warning => "warning",
678 .keyword_pragma => "pragma",
679 .keyword_line => "line",
680 .keyword_va_args => "__VA_ARGS__",
681 .keyword_va_opt => "__VA_OPT__",
682 .keyword_const1 => "__const",
683 .keyword_const2 => "__const__",
684 .keyword_inline1 => "__inline",
685 .keyword_inline2 => "__inline__",
686 .keyword_volatile1 => "__volatile",
687 .keyword_volatile2 => "__volatile__",
688 .keyword_restrict1 => "__restrict",
689 .keyword_restrict2 => "__restrict__",
690 .keyword_alignof1 => "__alignof",
691 .keyword_alignof2 => "__alignof__",
692 .keyword_typeof1 => "__typeof",
693 .keyword_typeof2 => "__typeof__",
694 .builtin_choose_expr => "__builtin_choose_expr",
695 .builtin_va_arg => "__builtin_va_arg",
696 .builtin_offsetof => "__builtin_offsetof",
697 .builtin_bitoffsetof => "__builtin_bitoffsetof",
698 .builtin_types_compatible_p => "__builtin_types_compatible_p",
699 .keyword_attribute1 => "__attribute",
700 .keyword_attribute2 => "__attribute__",
701 .keyword_extension => "__extension__",
702 .keyword_asm => "asm",
703 .keyword_asm1 => "__asm",
704 .keyword_asm2 => "__asm__",
705 .keyword_float80 => "__float80",
706 .keyword_float128_1 => "_Float128",
707 .keyword_float128_2 => "__float128",
708 .keyword_int128 => "__int128",
709 .keyword_imag1 => "__imag",
710 .keyword_imag2 => "__imag__",
711 .keyword_real1 => "__real",
712 .keyword_real2 => "__real__",
713 .keyword_float16 => "_Float16",
714 .keyword_fp16 => "__fp16",
715 .keyword_declspec => "__declspec",
716 .keyword_int64 => "__int64",
717 .keyword_int64_2 => "_int64",
718 .keyword_int32 => "__int32",
719 .keyword_int32_2 => "_int32",
720 .keyword_int16 => "__int16",
721 .keyword_int16_2 => "_int16",
722 .keyword_int8 => "__int8",
723 .keyword_int8_2 => "_int8",
724 .keyword_stdcall => "__stdcall",
725 .keyword_stdcall2 => "_stdcall",
726 .keyword_thiscall => "__thiscall",
727 .keyword_thiscall2 => "_thiscall",
728 .keyword_vectorcall => "__vectorcall",
729 .keyword_vectorcall2 => "_vectorcall",
730 };
731 }
732
733 pub fn symbol(id: Id) []const u8 {
734 return switch (id) {
735 .macro_string, .invalid => unreachable,
736 .identifier,
737 .extended_identifier,
738 .macro_func,
739 .macro_function,
740 .macro_pretty_func,
741 .builtin_choose_expr,
742 .builtin_va_arg,
743 .builtin_offsetof,
744 .builtin_bitoffsetof,
745 .builtin_types_compatible_p,
746 => "an identifier",
747 .string_literal,
748 .string_literal_utf_16,
749 .string_literal_utf_8,
750 .string_literal_utf_32,
751 .string_literal_wide,
752 .unterminated_string_literal,
753 => "a string literal",
754 .char_literal,
755 .char_literal_utf_8,
756 .char_literal_utf_16,
757 .char_literal_utf_32,
758 .char_literal_wide,
759 .unterminated_char_literal,
760 .empty_char_literal,
761 => "a character literal",
762 .pp_num, .embed_byte => "A number",
763 else => id.lexeme().?,
764 };
765 }
766
767 /// tokens that can start an expression parsed by Preprocessor.expr
768 /// Note that eof, r_paren, and string literals cannot actually start a
769 /// preprocessor expression, but we include them here so that a nicer
770 /// error message can be generated by the parser.
771 pub fn validPreprocessorExprStart(id: Id) bool {
772 return switch (id) {
773 .eof,
774 .r_paren,
775 .string_literal,
776 .string_literal_utf_16,
777 .string_literal_utf_8,
778 .string_literal_utf_32,
779 .string_literal_wide,
780
781 .char_literal,
782 .char_literal_utf_8,
783 .char_literal_utf_16,
784 .char_literal_utf_32,
785 .char_literal_wide,
786 .l_paren,
787 .plus,
788 .minus,
789 .tilde,
790 .bang,
791 .identifier,
792 .extended_identifier,
793 .keyword_defined,
794 .one,
795 .zero,
796 .pp_num,
797 .keyword_true,
798 .keyword_false,
799 => true,
800 else => false,
801 };
802 }
803
804 pub fn allowsDigraphs(id: Id, langopts: LangOpts) bool {
805 return switch (id) {
806 .l_bracket,
807 .r_bracket,
808 .l_brace,
809 .r_brace,
810 .hash,
811 .hash_hash,
812 => langopts.hasDigraphs(),
813 else => false,
814 };
815 }
816
817 pub fn canOpenGCCAsmStmt(id: Id) bool {
818 return switch (id) {
819 .keyword_volatile, .keyword_volatile1, .keyword_volatile2, .keyword_inline, .keyword_inline1, .keyword_inline2, .keyword_goto, .l_paren => true,
820 else => false,
821 };
822 }
823
824 pub fn isStringLiteral(id: Id) bool {
825 return switch (id) {
826 .string_literal, .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32, .string_literal_wide => true,
827 else => false,
828 };
829 }
830 };
831
832 /// double underscore and underscore + capital letter identifiers
833 /// belong to the implementation namespace, so we always convert them
834 /// to keywords.
835 pub fn getTokenId(langopts: LangOpts, str: []const u8) Token.Id {
836 const kw = all_kws.get(str) orelse return .identifier;
837 const standard = langopts.standard;
838 return switch (kw) {
839 .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier,
840 .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier,
841 .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c23)) kw else .identifier,
842 .keyword_asm => if (standard.isGNU()) kw else .identifier,
843 .keyword_declspec => if (langopts.declspec_attrs) kw else .identifier,
844
845 .keyword_c23_alignas,
846 .keyword_c23_alignof,
847 .keyword_c23_bool,
848 .keyword_c23_static_assert,
849 .keyword_c23_thread_local,
850 .keyword_constexpr,
851 .keyword_true,
852 .keyword_false,
853 .keyword_nullptr,
854 .keyword_typeof_unqual,
855 .keyword_elifdef,
856 .keyword_elifndef,
857 => if (standard.atLeast(.c23)) kw else .identifier,
858
859 .keyword_int64,
860 .keyword_int64_2,
861 .keyword_int32,
862 .keyword_int32_2,
863 .keyword_int16,
864 .keyword_int16_2,
865 .keyword_int8,
866 .keyword_int8_2,
867 .keyword_stdcall2,
868 .keyword_thiscall2,
869 .keyword_vectorcall2,
870 => if (langopts.ms_extensions) kw else .identifier,
871 else => kw,
872 };
873 }
874
875 const all_kws = std.ComptimeStringMap(Id, .{
876 .{ "auto", auto: {
877 @setEvalBranchQuota(3000);
878 break :auto .keyword_auto;
879 } },
880 .{ "break", .keyword_break },
881 .{ "case", .keyword_case },
882 .{ "char", .keyword_char },
883 .{ "const", .keyword_const },
884 .{ "continue", .keyword_continue },
885 .{ "default", .keyword_default },
886 .{ "do", .keyword_do },
887 .{ "double", .keyword_double },
888 .{ "else", .keyword_else },
889 .{ "enum", .keyword_enum },
890 .{ "extern", .keyword_extern },
891 .{ "float", .keyword_float },
892 .{ "for", .keyword_for },
893 .{ "goto", .keyword_goto },
894 .{ "if", .keyword_if },
895 .{ "int", .keyword_int },
896 .{ "long", .keyword_long },
897 .{ "register", .keyword_register },
898 .{ "return", .keyword_return },
899 .{ "short", .keyword_short },
900 .{ "signed", .keyword_signed },
901 .{ "sizeof", .keyword_sizeof },
902 .{ "static", .keyword_static },
903 .{ "struct", .keyword_struct },
904 .{ "switch", .keyword_switch },
905 .{ "typedef", .keyword_typedef },
906 .{ "union", .keyword_union },
907 .{ "unsigned", .keyword_unsigned },
908 .{ "void", .keyword_void },
909 .{ "volatile", .keyword_volatile },
910 .{ "while", .keyword_while },
911 .{ "__typeof__", .keyword_typeof2 },
912 .{ "__typeof", .keyword_typeof1 },
913
914 // ISO C99
915 .{ "_Bool", .keyword_bool },
916 .{ "_Complex", .keyword_complex },
917 .{ "_Imaginary", .keyword_imaginary },
918 .{ "inline", .keyword_inline },
919 .{ "restrict", .keyword_restrict },
920
921 // ISO C11
922 .{ "_Alignas", .keyword_alignas },
923 .{ "_Alignof", .keyword_alignof },
924 .{ "_Atomic", .keyword_atomic },
925 .{ "_Generic", .keyword_generic },
926 .{ "_Noreturn", .keyword_noreturn },
927 .{ "_Static_assert", .keyword_static_assert },
928 .{ "_Thread_local", .keyword_thread_local },
929
930 // ISO C23
931 .{ "_BitInt", .keyword_bit_int },
932 .{ "alignas", .keyword_c23_alignas },
933 .{ "alignof", .keyword_c23_alignof },
934 .{ "bool", .keyword_c23_bool },
935 .{ "static_assert", .keyword_c23_static_assert },
936 .{ "thread_local", .keyword_c23_thread_local },
937 .{ "constexpr", .keyword_constexpr },
938 .{ "true", .keyword_true },
939 .{ "false", .keyword_false },
940 .{ "nullptr", .keyword_nullptr },
941 .{ "typeof_unqual", .keyword_typeof_unqual },
942
943 // Preprocessor directives
944 .{ "include", .keyword_include },
945 .{ "include_next", .keyword_include_next },
946 .{ "embed", .keyword_embed },
947 .{ "define", .keyword_define },
948 .{ "defined", .keyword_defined },
949 .{ "undef", .keyword_undef },
950 .{ "ifdef", .keyword_ifdef },
951 .{ "ifndef", .keyword_ifndef },
952 .{ "elif", .keyword_elif },
953 .{ "elifdef", .keyword_elifdef },
954 .{ "elifndef", .keyword_elifndef },
955 .{ "endif", .keyword_endif },
956 .{ "error", .keyword_error },
957 .{ "warning", .keyword_warning },
958 .{ "pragma", .keyword_pragma },
959 .{ "line", .keyword_line },
960 .{ "__VA_ARGS__", .keyword_va_args },
961 .{ "__VA_OPT__", .keyword_va_opt },
962 .{ "__func__", .macro_func },
963 .{ "__FUNCTION__", .macro_function },
964 .{ "__PRETTY_FUNCTION__", .macro_pretty_func },
965
966 // gcc keywords
967 .{ "__auto_type", .keyword_auto_type },
968 .{ "__const", .keyword_const1 },
969 .{ "__const__", .keyword_const2 },
970 .{ "__inline", .keyword_inline1 },
971 .{ "__inline__", .keyword_inline2 },
972 .{ "__volatile", .keyword_volatile1 },
973 .{ "__volatile__", .keyword_volatile2 },
974 .{ "__restrict", .keyword_restrict1 },
975 .{ "__restrict__", .keyword_restrict2 },
976 .{ "__alignof", .keyword_alignof1 },
977 .{ "__alignof__", .keyword_alignof2 },
978 .{ "typeof", .keyword_typeof },
979 .{ "__attribute", .keyword_attribute1 },
980 .{ "__attribute__", .keyword_attribute2 },
981 .{ "__extension__", .keyword_extension },
982 .{ "asm", .keyword_asm },
983 .{ "__asm", .keyword_asm1 },
984 .{ "__asm__", .keyword_asm2 },
985 .{ "__float80", .keyword_float80 },
986 .{ "_Float128", .keyword_float128_1 },
987 .{ "__float128", .keyword_float128_2 },
988 .{ "__int128", .keyword_int128 },
989 .{ "__imag", .keyword_imag1 },
990 .{ "__imag__", .keyword_imag2 },
991 .{ "__real", .keyword_real1 },
992 .{ "__real__", .keyword_real2 },
993 .{ "_Float16", .keyword_float16 },
994
995 // clang keywords
996 .{ "__fp16", .keyword_fp16 },
997
998 // ms keywords
999 .{ "__declspec", .keyword_declspec },
1000 .{ "__int64", .keyword_int64 },
1001 .{ "_int64", .keyword_int64_2 },
1002 .{ "__int32", .keyword_int32 },
1003 .{ "_int32", .keyword_int32_2 },
1004 .{ "__int16", .keyword_int16 },
1005 .{ "_int16", .keyword_int16_2 },
1006 .{ "__int8", .keyword_int8 },
1007 .{ "_int8", .keyword_int8_2 },
1008 .{ "__stdcall", .keyword_stdcall },
1009 .{ "_stdcall", .keyword_stdcall2 },
1010 .{ "__thiscall", .keyword_thiscall },
1011 .{ "_thiscall", .keyword_thiscall2 },
1012 .{ "__vectorcall", .keyword_vectorcall },
1013 .{ "_vectorcall", .keyword_vectorcall2 },
1014
1015 // builtins that require special parsing
1016 .{ "__builtin_choose_expr", .builtin_choose_expr },
1017 .{ "__builtin_va_arg", .builtin_va_arg },
1018 .{ "__builtin_offsetof", .builtin_offsetof },
1019 .{ "__builtin_bitoffsetof", .builtin_bitoffsetof },
1020 .{ "__builtin_types_compatible_p", .builtin_types_compatible_p },
1021 });
1022};
1023
1024const Tokenizer = @This();
1025
1026buf: []const u8,
1027index: u32 = 0,
1028source: Source.Id,
1029langopts: LangOpts,
1030line: u32 = 1,
1031
1032pub fn next(self: *Tokenizer) Token {
1033 var state: enum {
1034 start,
1035 whitespace,
1036 u,
1037 u8,
1038 U,
1039 L,
1040 string_literal,
1041 char_literal_start,
1042 char_literal,
1043 char_escape_sequence,
1044 string_escape_sequence,
1045 identifier,
1046 extended_identifier,
1047 equal,
1048 bang,
1049 pipe,
1050 colon,
1051 percent,
1052 asterisk,
1053 plus,
1054 angle_bracket_left,
1055 angle_bracket_angle_bracket_left,
1056 angle_bracket_right,
1057 angle_bracket_angle_bracket_right,
1058 caret,
1059 period,
1060 period2,
1061 minus,
1062 slash,
1063 ampersand,
1064 hash,
1065 hash_digraph,
1066 hash_hash_digraph_partial,
1067 line_comment,
1068 multi_line_comment,
1069 multi_line_comment_asterisk,
1070 multi_line_comment_done,
1071 pp_num,
1072 pp_num_exponent,
1073 pp_num_digit_separator,
1074 } = .start;
1075
1076 var start = self.index;
1077 var id: Token.Id = .eof;
1078
1079 while (self.index < self.buf.len) : (self.index += 1) {
1080 const c = self.buf[self.index];
1081 switch (state) {
1082 .start => switch (c) {
1083 '\n' => {
1084 id = .nl;
1085 self.index += 1;
1086 self.line += 1;
1087 break;
1088 },
1089 '"' => {
1090 id = .string_literal;
1091 state = .string_literal;
1092 },
1093 '\'' => {
1094 id = .char_literal;
1095 state = .char_literal_start;
1096 },
1097 'u' => state = .u,
1098 'U' => state = .U,
1099 'L' => state = .L,
1100 'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_' => state = .identifier,
1101 '=' => state = .equal,
1102 '!' => state = .bang,
1103 '|' => state = .pipe,
1104 '(' => {
1105 id = .l_paren;
1106 self.index += 1;
1107 break;
1108 },
1109 ')' => {
1110 id = .r_paren;
1111 self.index += 1;
1112 break;
1113 },
1114 '[' => {
1115 id = .l_bracket;
1116 self.index += 1;
1117 break;
1118 },
1119 ']' => {
1120 id = .r_bracket;
1121 self.index += 1;
1122 break;
1123 },
1124 ';' => {
1125 id = .semicolon;
1126 self.index += 1;
1127 break;
1128 },
1129 ',' => {
1130 id = .comma;
1131 self.index += 1;
1132 break;
1133 },
1134 '?' => {
1135 id = .question_mark;
1136 self.index += 1;
1137 break;
1138 },
1139 ':' => state = .colon,
1140 '%' => state = .percent,
1141 '*' => state = .asterisk,
1142 '+' => state = .plus,
1143 '<' => state = .angle_bracket_left,
1144 '>' => state = .angle_bracket_right,
1145 '^' => state = .caret,
1146 '{' => {
1147 id = .l_brace;
1148 self.index += 1;
1149 break;
1150 },
1151 '}' => {
1152 id = .r_brace;
1153 self.index += 1;
1154 break;
1155 },
1156 '~' => {
1157 id = .tilde;
1158 self.index += 1;
1159 break;
1160 },
1161 '.' => state = .period,
1162 '-' => state = .minus,
1163 '/' => state = .slash,
1164 '&' => state = .ampersand,
1165 '#' => state = .hash,
1166 '0'...'9' => state = .pp_num,
1167 '\t', '\x0B', '\x0C', ' ' => state = .whitespace,
1168 '$' => if (self.langopts.dollars_in_identifiers) {
1169 state = .extended_identifier;
1170 } else {
1171 id = .invalid;
1172 self.index += 1;
1173 break;
1174 },
1175 0x1A => if (self.langopts.ms_extensions) {
1176 id = .eof;
1177 break;
1178 } else {
1179 id = .invalid;
1180 self.index += 1;
1181 break;
1182 },
1183 0x80...0xFF => state = .extended_identifier,
1184 else => {
1185 id = .invalid;
1186 self.index += 1;
1187 break;
1188 },
1189 },
1190 .whitespace => switch (c) {
1191 '\t', '\x0B', '\x0C', ' ' => {},
1192 else => {
1193 id = .whitespace;
1194 break;
1195 },
1196 },
1197 .u => switch (c) {
1198 '8' => {
1199 state = .u8;
1200 },
1201 '\'' => {
1202 id = .char_literal_utf_16;
1203 state = .char_literal_start;
1204 },
1205 '\"' => {
1206 id = .string_literal_utf_16;
1207 state = .string_literal;
1208 },
1209 else => {
1210 self.index -= 1;
1211 state = .identifier;
1212 },
1213 },
1214 .u8 => switch (c) {
1215 '\"' => {
1216 id = .string_literal_utf_8;
1217 state = .string_literal;
1218 },
1219 '\'' => {
1220 id = .char_literal_utf_8;
1221 state = .char_literal_start;
1222 },
1223 else => {
1224 self.index -= 1;
1225 state = .identifier;
1226 },
1227 },
1228 .U => switch (c) {
1229 '\'' => {
1230 id = .char_literal_utf_32;
1231 state = .char_literal_start;
1232 },
1233 '\"' => {
1234 id = .string_literal_utf_32;
1235 state = .string_literal;
1236 },
1237 else => {
1238 self.index -= 1;
1239 state = .identifier;
1240 },
1241 },
1242 .L => switch (c) {
1243 '\'' => {
1244 id = .char_literal_wide;
1245 state = .char_literal_start;
1246 },
1247 '\"' => {
1248 id = .string_literal_wide;
1249 state = .string_literal;
1250 },
1251 else => {
1252 self.index -= 1;
1253 state = .identifier;
1254 },
1255 },
1256 .string_literal => switch (c) {
1257 '\\' => {
1258 state = .string_escape_sequence;
1259 },
1260 '"' => {
1261 self.index += 1;
1262 break;
1263 },
1264 '\n' => {
1265 id = .unterminated_string_literal;
1266 break;
1267 },
1268 '\r' => unreachable,
1269 else => {},
1270 },
1271 .char_literal_start => switch (c) {
1272 '\\' => {
1273 state = .char_escape_sequence;
1274 },
1275 '\'' => {
1276 id = .empty_char_literal;
1277 self.index += 1;
1278 break;
1279 },
1280 '\n' => {
1281 id = .unterminated_char_literal;
1282 break;
1283 },
1284 else => {
1285 state = .char_literal;
1286 },
1287 },
1288 .char_literal => switch (c) {
1289 '\\' => {
1290 state = .char_escape_sequence;
1291 },
1292 '\'' => {
1293 self.index += 1;
1294 break;
1295 },
1296 '\n' => {
1297 id = .unterminated_char_literal;
1298 break;
1299 },
1300 else => {},
1301 },
1302 .char_escape_sequence => switch (c) {
1303 '\r', '\n' => unreachable, // removed by line splicing
1304 else => state = .char_literal,
1305 },
1306 .string_escape_sequence => switch (c) {
1307 '\r', '\n' => unreachable, // removed by line splicing
1308 else => state = .string_literal,
1309 },
1310 .identifier, .extended_identifier => switch (c) {
1311 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
1312 '$' => if (self.langopts.dollars_in_identifiers) {
1313 state = .extended_identifier;
1314 } else {
1315 id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier;
1316 break;
1317 },
1318 0x80...0xFF => state = .extended_identifier,
1319 else => {
1320 id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier;
1321 break;
1322 },
1323 },
1324 .equal => switch (c) {
1325 '=' => {
1326 id = .equal_equal;
1327 self.index += 1;
1328 break;
1329 },
1330 else => {
1331 id = .equal;
1332 break;
1333 },
1334 },
1335 .bang => switch (c) {
1336 '=' => {
1337 id = .bang_equal;
1338 self.index += 1;
1339 break;
1340 },
1341 else => {
1342 id = .bang;
1343 break;
1344 },
1345 },
1346 .pipe => switch (c) {
1347 '=' => {
1348 id = .pipe_equal;
1349 self.index += 1;
1350 break;
1351 },
1352 '|' => {
1353 id = .pipe_pipe;
1354 self.index += 1;
1355 break;
1356 },
1357 else => {
1358 id = .pipe;
1359 break;
1360 },
1361 },
1362 .colon => switch (c) {
1363 '>' => {
1364 if (self.langopts.hasDigraphs()) {
1365 id = .r_bracket;
1366 self.index += 1;
1367 } else {
1368 id = .colon;
1369 }
1370 break;
1371 },
1372 ':' => {
1373 if (self.langopts.standard.atLeast(.c23)) {
1374 id = .colon_colon;
1375 self.index += 1;
1376 break;
1377 } else {
1378 id = .colon;
1379 break;
1380 }
1381 },
1382 else => {
1383 id = .colon;
1384 break;
1385 },
1386 },
1387 .percent => switch (c) {
1388 '=' => {
1389 id = .percent_equal;
1390 self.index += 1;
1391 break;
1392 },
1393 '>' => {
1394 if (self.langopts.hasDigraphs()) {
1395 id = .r_brace;
1396 self.index += 1;
1397 } else {
1398 id = .percent;
1399 }
1400 break;
1401 },
1402 ':' => {
1403 if (self.langopts.hasDigraphs()) {
1404 state = .hash_digraph;
1405 } else {
1406 id = .percent;
1407 break;
1408 }
1409 },
1410 else => {
1411 id = .percent;
1412 break;
1413 },
1414 },
1415 .asterisk => switch (c) {
1416 '=' => {
1417 id = .asterisk_equal;
1418 self.index += 1;
1419 break;
1420 },
1421 else => {
1422 id = .asterisk;
1423 break;
1424 },
1425 },
1426 .plus => switch (c) {
1427 '=' => {
1428 id = .plus_equal;
1429 self.index += 1;
1430 break;
1431 },
1432 '+' => {
1433 id = .plus_plus;
1434 self.index += 1;
1435 break;
1436 },
1437 else => {
1438 id = .plus;
1439 break;
1440 },
1441 },
1442 .angle_bracket_left => switch (c) {
1443 '<' => state = .angle_bracket_angle_bracket_left,
1444 '=' => {
1445 id = .angle_bracket_left_equal;
1446 self.index += 1;
1447 break;
1448 },
1449 ':' => {
1450 if (self.langopts.hasDigraphs()) {
1451 id = .l_bracket;
1452 self.index += 1;
1453 } else {
1454 id = .angle_bracket_left;
1455 }
1456 break;
1457 },
1458 '%' => {
1459 if (self.langopts.hasDigraphs()) {
1460 id = .l_brace;
1461 self.index += 1;
1462 } else {
1463 id = .angle_bracket_left;
1464 }
1465 break;
1466 },
1467 else => {
1468 id = .angle_bracket_left;
1469 break;
1470 },
1471 },
1472 .angle_bracket_angle_bracket_left => switch (c) {
1473 '=' => {
1474 id = .angle_bracket_angle_bracket_left_equal;
1475 self.index += 1;
1476 break;
1477 },
1478 else => {
1479 id = .angle_bracket_angle_bracket_left;
1480 break;
1481 },
1482 },
1483 .angle_bracket_right => switch (c) {
1484 '>' => state = .angle_bracket_angle_bracket_right,
1485 '=' => {
1486 id = .angle_bracket_right_equal;
1487 self.index += 1;
1488 break;
1489 },
1490 else => {
1491 id = .angle_bracket_right;
1492 break;
1493 },
1494 },
1495 .angle_bracket_angle_bracket_right => switch (c) {
1496 '=' => {
1497 id = .angle_bracket_angle_bracket_right_equal;
1498 self.index += 1;
1499 break;
1500 },
1501 else => {
1502 id = .angle_bracket_angle_bracket_right;
1503 break;
1504 },
1505 },
1506 .caret => switch (c) {
1507 '=' => {
1508 id = .caret_equal;
1509 self.index += 1;
1510 break;
1511 },
1512 else => {
1513 id = .caret;
1514 break;
1515 },
1516 },
1517 .period => switch (c) {
1518 '.' => state = .period2,
1519 '0'...'9' => state = .pp_num,
1520 else => {
1521 id = .period;
1522 break;
1523 },
1524 },
1525 .period2 => switch (c) {
1526 '.' => {
1527 id = .ellipsis;
1528 self.index += 1;
1529 break;
1530 },
1531 else => {
1532 id = .period;
1533 self.index -= 1;
1534 break;
1535 },
1536 },
1537 .minus => switch (c) {
1538 '>' => {
1539 id = .arrow;
1540 self.index += 1;
1541 break;
1542 },
1543 '=' => {
1544 id = .minus_equal;
1545 self.index += 1;
1546 break;
1547 },
1548 '-' => {
1549 id = .minus_minus;
1550 self.index += 1;
1551 break;
1552 },
1553 else => {
1554 id = .minus;
1555 break;
1556 },
1557 },
1558 .ampersand => switch (c) {
1559 '&' => {
1560 id = .ampersand_ampersand;
1561 self.index += 1;
1562 break;
1563 },
1564 '=' => {
1565 id = .ampersand_equal;
1566 self.index += 1;
1567 break;
1568 },
1569 else => {
1570 id = .ampersand;
1571 break;
1572 },
1573 },
1574 .hash => switch (c) {
1575 '#' => {
1576 id = .hash_hash;
1577 self.index += 1;
1578 break;
1579 },
1580 else => {
1581 id = .hash;
1582 break;
1583 },
1584 },
1585 .hash_digraph => switch (c) {
1586 '%' => state = .hash_hash_digraph_partial,
1587 else => {
1588 id = .hash;
1589 break;
1590 },
1591 },
1592 .hash_hash_digraph_partial => switch (c) {
1593 ':' => {
1594 id = .hash_hash;
1595 self.index += 1;
1596 break;
1597 },
1598 else => {
1599 id = .hash;
1600 self.index -= 1; // re-tokenize the percent
1601 break;
1602 },
1603 },
1604 .slash => switch (c) {
1605 '/' => state = .line_comment,
1606 '*' => state = .multi_line_comment,
1607 '=' => {
1608 id = .slash_equal;
1609 self.index += 1;
1610 break;
1611 },
1612 else => {
1613 id = .slash;
1614 break;
1615 },
1616 },
1617 .line_comment => switch (c) {
1618 '\n' => {
1619 if (self.langopts.preserve_comments) {
1620 id = .comment;
1621 break;
1622 }
1623 self.index -= 1;
1624 state = .start;
1625 },
1626 else => {},
1627 },
1628 .multi_line_comment => switch (c) {
1629 '*' => state = .multi_line_comment_asterisk,
1630 '\n' => self.line += 1,
1631 else => {},
1632 },
1633 .multi_line_comment_asterisk => switch (c) {
1634 '/' => {
1635 if (self.langopts.preserve_comments) {
1636 self.index += 1;
1637 id = .comment;
1638 break;
1639 }
1640 state = .multi_line_comment_done;
1641 },
1642 '\n' => {
1643 self.line += 1;
1644 state = .multi_line_comment;
1645 },
1646 '*' => {},
1647 else => state = .multi_line_comment,
1648 },
1649 .multi_line_comment_done => switch (c) {
1650 '\n' => {
1651 start = self.index;
1652 id = .nl;
1653 self.index += 1;
1654 self.line += 1;
1655 break;
1656 },
1657 '\r' => unreachable,
1658 '\t', '\x0B', '\x0C', ' ' => {
1659 start = self.index;
1660 state = .whitespace;
1661 },
1662 else => {
1663 id = .whitespace;
1664 break;
1665 },
1666 },
1667 .pp_num => switch (c) {
1668 'a'...'d',
1669 'A'...'D',
1670 'f'...'o',
1671 'F'...'O',
1672 'q'...'z',
1673 'Q'...'Z',
1674 '0'...'9',
1675 '_',
1676 '.',
1677 => {},
1678 'e', 'E', 'p', 'P' => state = .pp_num_exponent,
1679 '\'' => if (self.langopts.standard.atLeast(.c23)) {
1680 state = .pp_num_digit_separator;
1681 } else {
1682 id = .pp_num;
1683 break;
1684 },
1685 else => {
1686 id = .pp_num;
1687 break;
1688 },
1689 },
1690 .pp_num_digit_separator => switch (c) {
1691 'a'...'d',
1692 'A'...'D',
1693 'f'...'o',
1694 'F'...'O',
1695 'q'...'z',
1696 'Q'...'Z',
1697 '0'...'9',
1698 '_',
1699 => state = .pp_num,
1700 else => {
1701 self.index -= 1;
1702 id = .pp_num;
1703 break;
1704 },
1705 },
1706 .pp_num_exponent => switch (c) {
1707 'a'...'o',
1708 'q'...'z',
1709 'A'...'O',
1710 'Q'...'Z',
1711 '0'...'9',
1712 '_',
1713 '.',
1714 '+',
1715 '-',
1716 => state = .pp_num,
1717 'p', 'P' => {},
1718 else => {
1719 id = .pp_num;
1720 break;
1721 },
1722 },
1723 }
1724 } else if (self.index == self.buf.len) {
1725 switch (state) {
1726 .start, .line_comment => {},
1727 .u, .u8, .U, .L, .identifier => id = Token.getTokenId(self.langopts, self.buf[start..self.index]),
1728 .extended_identifier => id = .extended_identifier,
1729
1730 .period2 => {
1731 self.index -= 1;
1732 id = .period;
1733 },
1734
1735 .multi_line_comment,
1736 .multi_line_comment_asterisk,
1737 => id = .unterminated_comment,
1738
1739 .char_escape_sequence, .char_literal, .char_literal_start => id = .unterminated_char_literal,
1740 .string_escape_sequence, .string_literal => id = .unterminated_string_literal,
1741
1742 .whitespace => id = .whitespace,
1743 .multi_line_comment_done => id = .whitespace,
1744
1745 .equal => id = .equal,
1746 .bang => id = .bang,
1747 .minus => id = .minus,
1748 .slash => id = .slash,
1749 .ampersand => id = .ampersand,
1750 .hash => id = .hash,
1751 .period => id = .period,
1752 .pipe => id = .pipe,
1753 .angle_bracket_angle_bracket_right => id = .angle_bracket_angle_bracket_right,
1754 .angle_bracket_right => id = .angle_bracket_right,
1755 .angle_bracket_angle_bracket_left => id = .angle_bracket_angle_bracket_left,
1756 .angle_bracket_left => id = .angle_bracket_left,
1757 .plus => id = .plus,
1758 .colon => id = .colon,
1759 .percent => id = .percent,
1760 .caret => id = .caret,
1761 .asterisk => id = .asterisk,
1762 .hash_digraph => id = .hash,
1763 .hash_hash_digraph_partial => {
1764 id = .hash;
1765 self.index -= 1; // re-tokenize the percent
1766 },
1767 .pp_num, .pp_num_exponent, .pp_num_digit_separator => id = .pp_num,
1768 }
1769 }
1770
1771 return .{
1772 .id = id,
1773 .start = start,
1774 .end = self.index,
1775 .line = self.line,
1776 .source = self.source,
1777 };
1778}
1779
1780pub fn nextNoWS(self: *Tokenizer) Token {
1781 var tok = self.next();
1782 while (tok.id == .whitespace or tok.id == .comment) tok = self.next();
1783 return tok;
1784}
1785
1786pub fn nextNoWSComments(self: *Tokenizer) Token {
1787 var tok = self.next();
1788 while (tok.id == .whitespace) tok = self.next();
1789 return tok;
1790}
1791
1792/// Try to tokenize a '::' even if not supported by the current language standard.
1793pub fn colonColon(self: *Tokenizer) Token {
1794 var tok = self.nextNoWS();
1795 if (tok.id == .colon and self.buf[self.index] == ':') {
1796 self.index += 1;
1797 tok.id = .colon_colon;
1798 }
1799 return tok;
1800}
1801
1802test "operators" {
1803 try expectTokens(
1804 \\ ! != | || |= = ==
1805 \\ ( ) { } [ ] . .. ...
1806 \\ ^ ^= + ++ += - -- -=
1807 \\ * *= % %= -> : ; / /=
1808 \\ , & && &= ? < <= <<
1809 \\ <<= > >= >> >>= ~ # ##
1810 \\
1811 , &.{
1812 .bang,
1813 .bang_equal,
1814 .pipe,
1815 .pipe_pipe,
1816 .pipe_equal,
1817 .equal,
1818 .equal_equal,
1819 .nl,
1820 .l_paren,
1821 .r_paren,
1822 .l_brace,
1823 .r_brace,
1824 .l_bracket,
1825 .r_bracket,
1826 .period,
1827 .period,
1828 .period,
1829 .ellipsis,
1830 .nl,
1831 .caret,
1832 .caret_equal,
1833 .plus,
1834 .plus_plus,
1835 .plus_equal,
1836 .minus,
1837 .minus_minus,
1838 .minus_equal,
1839 .nl,
1840 .asterisk,
1841 .asterisk_equal,
1842 .percent,
1843 .percent_equal,
1844 .arrow,
1845 .colon,
1846 .semicolon,
1847 .slash,
1848 .slash_equal,
1849 .nl,
1850 .comma,
1851 .ampersand,
1852 .ampersand_ampersand,
1853 .ampersand_equal,
1854 .question_mark,
1855 .angle_bracket_left,
1856 .angle_bracket_left_equal,
1857 .angle_bracket_angle_bracket_left,
1858 .nl,
1859 .angle_bracket_angle_bracket_left_equal,
1860 .angle_bracket_right,
1861 .angle_bracket_right_equal,
1862 .angle_bracket_angle_bracket_right,
1863 .angle_bracket_angle_bracket_right_equal,
1864 .tilde,
1865 .hash,
1866 .hash_hash,
1867 .nl,
1868 });
1869}
1870
1871test "keywords" {
1872 try expectTokens(
1873 \\auto __auto_type break case char const continue default do
1874 \\double else enum extern float for goto if int
1875 \\long register return short signed sizeof static
1876 \\struct switch typedef union unsigned void volatile
1877 \\while _Bool _Complex _Imaginary inline restrict _Alignas
1878 \\_Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local
1879 \\__attribute __attribute__
1880 \\
1881 , &.{
1882 .keyword_auto,
1883 .keyword_auto_type,
1884 .keyword_break,
1885 .keyword_case,
1886 .keyword_char,
1887 .keyword_const,
1888 .keyword_continue,
1889 .keyword_default,
1890 .keyword_do,
1891 .nl,
1892 .keyword_double,
1893 .keyword_else,
1894 .keyword_enum,
1895 .keyword_extern,
1896 .keyword_float,
1897 .keyword_for,
1898 .keyword_goto,
1899 .keyword_if,
1900 .keyword_int,
1901 .nl,
1902 .keyword_long,
1903 .keyword_register,
1904 .keyword_return,
1905 .keyword_short,
1906 .keyword_signed,
1907 .keyword_sizeof,
1908 .keyword_static,
1909 .nl,
1910 .keyword_struct,
1911 .keyword_switch,
1912 .keyword_typedef,
1913 .keyword_union,
1914 .keyword_unsigned,
1915 .keyword_void,
1916 .keyword_volatile,
1917 .nl,
1918 .keyword_while,
1919 .keyword_bool,
1920 .keyword_complex,
1921 .keyword_imaginary,
1922 .keyword_inline,
1923 .keyword_restrict,
1924 .keyword_alignas,
1925 .nl,
1926 .keyword_alignof,
1927 .keyword_atomic,
1928 .keyword_generic,
1929 .keyword_noreturn,
1930 .keyword_static_assert,
1931 .keyword_thread_local,
1932 .nl,
1933 .keyword_attribute1,
1934 .keyword_attribute2,
1935 .nl,
1936 });
1937}
1938
1939test "preprocessor keywords" {
1940 try expectTokens(
1941 \\#include
1942 \\#include_next
1943 \\#embed
1944 \\#define
1945 \\#ifdef
1946 \\#ifndef
1947 \\#error
1948 \\#pragma
1949 \\
1950 , &.{
1951 .hash,
1952 .keyword_include,
1953 .nl,
1954 .hash,
1955 .keyword_include_next,
1956 .nl,
1957 .hash,
1958 .keyword_embed,
1959 .nl,
1960 .hash,
1961 .keyword_define,
1962 .nl,
1963 .hash,
1964 .keyword_ifdef,
1965 .nl,
1966 .hash,
1967 .keyword_ifndef,
1968 .nl,
1969 .hash,
1970 .keyword_error,
1971 .nl,
1972 .hash,
1973 .keyword_pragma,
1974 .nl,
1975 });
1976}
1977
1978test "line continuation" {
1979 try expectTokens(
1980 \\#define foo \
1981 \\ bar
1982 \\"foo\
1983 \\ bar"
1984 \\#define "foo"
1985 \\ "bar"
1986 \\#define "foo" \
1987 \\ "bar"
1988 , &.{
1989 .hash,
1990 .keyword_define,
1991 .identifier,
1992 .identifier,
1993 .nl,
1994 .string_literal,
1995 .nl,
1996 .hash,
1997 .keyword_define,
1998 .string_literal,
1999 .nl,
2000 .string_literal,
2001 .nl,
2002 .hash,
2003 .keyword_define,
2004 .string_literal,
2005 .string_literal,
2006 });
2007}
2008
2009test "string prefix" {
2010 try expectTokens(
2011 \\"foo"
2012 \\u"foo"
2013 \\u8"foo"
2014 \\U"foo"
2015 \\L"foo"
2016 \\'foo'
2017 \\u8'A'
2018 \\u'foo'
2019 \\U'foo'
2020 \\L'foo'
2021 \\
2022 , &.{
2023 .string_literal,
2024 .nl,
2025 .string_literal_utf_16,
2026 .nl,
2027 .string_literal_utf_8,
2028 .nl,
2029 .string_literal_utf_32,
2030 .nl,
2031 .string_literal_wide,
2032 .nl,
2033 .char_literal,
2034 .nl,
2035 .char_literal_utf_8,
2036 .nl,
2037 .char_literal_utf_16,
2038 .nl,
2039 .char_literal_utf_32,
2040 .nl,
2041 .char_literal_wide,
2042 .nl,
2043 });
2044}
2045
2046test "num suffixes" {
2047 try expectTokens(
2048 \\ 1.0f 1.0L 1.0 .0 1. 0x1p0f 0X1p0
2049 \\ 0l 0lu 0ll 0llu 0
2050 \\ 1u 1ul 1ull 1
2051 \\ 1.0i 1.0I
2052 \\ 1.0if 1.0If 1.0fi 1.0fI
2053 \\ 1.0il 1.0Il 1.0li 1.0lI
2054 \\
2055 , &.{
2056 .pp_num,
2057 .pp_num,
2058 .pp_num,
2059 .pp_num,
2060 .pp_num,
2061 .pp_num,
2062 .pp_num,
2063 .nl,
2064 .pp_num,
2065 .pp_num,
2066 .pp_num,
2067 .pp_num,
2068 .pp_num,
2069 .nl,
2070 .pp_num,
2071 .pp_num,
2072 .pp_num,
2073 .pp_num,
2074 .nl,
2075 .pp_num,
2076 .pp_num,
2077 .nl,
2078 .pp_num,
2079 .pp_num,
2080 .pp_num,
2081 .pp_num,
2082 .nl,
2083 .pp_num,
2084 .pp_num,
2085 .pp_num,
2086 .pp_num,
2087 .nl,
2088 });
2089}
2090
2091test "comments" {
2092 try expectTokens(
2093 \\//foo
2094 \\#foo
2095 , &.{
2096 .nl,
2097 .hash,
2098 .identifier,
2099 });
2100}
2101
2102test "extended identifiers" {
2103 try expectTokens("𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2104 try expectTokens("u𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2105 try expectTokens("u8𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2106 try expectTokens("U𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2107 try expectTokens("L𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier});
2108 try expectTokens("1™", &.{ .pp_num, .extended_identifier });
2109 try expectTokens("1.™", &.{ .pp_num, .extended_identifier });
2110 try expectTokens("..™", &.{ .period, .period, .extended_identifier });
2111 try expectTokens("0™", &.{ .pp_num, .extended_identifier });
2112 try expectTokens("0b\u{E0000}", &.{ .pp_num, .extended_identifier });
2113 try expectTokens("0b0\u{E0000}", &.{ .pp_num, .extended_identifier });
2114 try expectTokens("01\u{E0000}", &.{ .pp_num, .extended_identifier });
2115 try expectTokens("010\u{E0000}", &.{ .pp_num, .extended_identifier });
2116 try expectTokens("0x\u{E0000}", &.{ .pp_num, .extended_identifier });
2117 try expectTokens("0x0\u{E0000}", &.{ .pp_num, .extended_identifier });
2118 try expectTokens("\"\\0\u{E0000}\"", &.{.string_literal});
2119 try expectTokens("\"\\x\u{E0000}\"", &.{.string_literal});
2120 try expectTokens("\"\\u\u{E0000}\"", &.{.string_literal});
2121 try expectTokens("1e\u{E0000}", &.{ .pp_num, .extended_identifier });
2122 try expectTokens("1e1\u{E0000}", &.{ .pp_num, .extended_identifier });
2123}
2124
2125test "digraphs" {
2126 try expectTokens("%:<::><%%>%:%:", &.{ .hash, .l_bracket, .r_bracket, .l_brace, .r_brace, .hash_hash });
2127 try expectTokens("\"%:<::><%%>%:%:\"", &.{.string_literal});
2128 try expectTokens("%:%42 %:%", &.{ .hash, .percent, .pp_num, .hash, .percent });
2129}
2130
2131test "C23 keywords" {
2132 try expectTokensExtra("true false alignas alignof bool static_assert thread_local nullptr typeof_unqual", &.{
2133 .keyword_true,
2134 .keyword_false,
2135 .keyword_c23_alignas,
2136 .keyword_c23_alignof,
2137 .keyword_c23_bool,
2138 .keyword_c23_static_assert,
2139 .keyword_c23_thread_local,
2140 .keyword_nullptr,
2141 .keyword_typeof_unqual,
2142 }, .c23);
2143}
2144
2145fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, standard: ?LangOpts.Standard) !void {
2146 var comp = Compilation.init(std.testing.allocator);
2147 defer comp.deinit();
2148 if (standard) |provided| {
2149 comp.langopts.standard = provided;
2150 }
2151 const source = try comp.addSourceFromBuffer("path", contents);
2152 var tokenizer = Tokenizer{
2153 .buf = source.buf,
2154 .source = source.id,
2155 .langopts = comp.langopts,
2156 };
2157 var i: usize = 0;
2158 while (i < expected_tokens.len) {
2159 const token = tokenizer.next();
2160 if (token.id == .whitespace) continue;
2161 const expected_token_id = expected_tokens[i];
2162 i += 1;
2163 if (!std.meta.eql(token.id, expected_token_id)) {
2164 std.debug.print("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
2165 return error.TokensDoNotEqual;
2166 }
2167 }
2168 const last_token = tokenizer.next();
2169 try std.testing.expect(last_token.id == .eof);
2170}
2171
2172fn expectTokens(contents: []const u8, expected_tokens: []const Token.Id) !void {
2173 return expectTokensExtra(contents, expected_tokens, null);
2174}
lib/compiler/aro/aro/Toolchain.zig created+489
......@@ -0,0 +1,489 @@
1const std = @import("std");
2const Driver = @import("Driver.zig");
3const Compilation = @import("Compilation.zig");
4const mem = std.mem;
5const system_defaults = @import("system_defaults");
6const target_util = @import("target.zig");
7const Linux = @import("toolchains/Linux.zig");
8const Multilib = @import("Driver/Multilib.zig");
9const Filesystem = @import("Driver/Filesystem.zig").Filesystem;
10
11pub const PathList = std.ArrayListUnmanaged([]const u8);
12
13pub const RuntimeLibKind = enum {
14 compiler_rt,
15 libgcc,
16};
17
18pub const FileKind = enum {
19 object,
20 static,
21 shared,
22};
23
24pub const LibGCCKind = enum {
25 unspecified,
26 static,
27 shared,
28};
29
30pub const UnwindLibKind = enum {
31 none,
32 compiler_rt,
33 libgcc,
34};
35
36const Inner = union(enum) {
37 uninitialized,
38 linux: Linux,
39 unknown: void,
40
41 fn deinit(self: *Inner, allocator: mem.Allocator) void {
42 switch (self.*) {
43 .linux => |*linux| linux.deinit(allocator),
44 .uninitialized, .unknown => {},
45 }
46 }
47};
48
49const Toolchain = @This();
50
51filesystem: Filesystem = .{ .real = {} },
52driver: *Driver,
53arena: mem.Allocator,
54
55/// The list of toolchain specific path prefixes to search for libraries.
56library_paths: PathList = .{},
57
58/// The list of toolchain specific path prefixes to search for files.
59file_paths: PathList = .{},
60
61/// The list of toolchain specific path prefixes to search for programs.
62program_paths: PathList = .{},
63
64selected_multilib: Multilib = .{},
65
66inner: Inner = .{ .uninitialized = {} },
67
68pub fn getTarget(tc: *const Toolchain) std.Target {
69 return tc.driver.comp.target;
70}
71
72fn getDefaultLinker(tc: *const Toolchain) []const u8 {
73 return switch (tc.inner) {
74 .uninitialized => unreachable,
75 .linux => |linux| linux.getDefaultLinker(tc.getTarget()),
76 .unknown => "ld",
77 };
78}
79
80/// Call this after driver has finished parsing command line arguments to find the toolchain
81pub fn discover(tc: *Toolchain) !void {
82 if (tc.inner != .uninitialized) return;
83
84 const target = tc.getTarget();
85 tc.inner = switch (target.os.tag) {
86 .elfiamcu,
87 .linux,
88 => if (target.cpu.arch == .hexagon)
89 .{ .unknown = {} } // TODO
90 else if (target.cpu.arch.isMIPS())
91 .{ .unknown = {} } // TODO
92 else if (target.cpu.arch.isPPC())
93 .{ .unknown = {} } // TODO
94 else if (target.cpu.arch == .ve)
95 .{ .unknown = {} } // TODO
96 else
97 .{ .linux = .{} },
98 else => .{ .unknown = {} }, // TODO
99 };
100 return switch (tc.inner) {
101 .uninitialized => unreachable,
102 .linux => |*linux| linux.discover(tc),
103 .unknown => {},
104 };
105}
106
107pub fn deinit(tc: *Toolchain) void {
108 const gpa = tc.driver.comp.gpa;
109 tc.inner.deinit(gpa);
110
111 tc.library_paths.deinit(gpa);
112 tc.file_paths.deinit(gpa);
113 tc.program_paths.deinit(gpa);
114}
115
116/// Write linker path to `buf` and return a slice of it
117pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
118 // --ld-path= takes precedence over -fuse-ld= and specifies the executable
119 // name. -B, COMPILER_PATH and PATH are consulted if the value does not
120 // contain a path component separator.
121 // -fuse-ld=lld can be used with --ld-path= to indicate that the binary
122 // that --ld-path= points to is lld.
123 const use_linker = tc.driver.use_linker orelse system_defaults.linker;
124
125 if (tc.driver.linker_path) |ld_path| {
126 var path = ld_path;
127 if (path.len > 0) {
128 if (std.fs.path.dirname(path) == null) {
129 path = tc.getProgramPath(path, buf);
130 }
131 if (tc.filesystem.canExecute(path)) {
132 return path;
133 }
134 }
135 return tc.driver.fatal(
136 "invalid linker name in argument '--ld-path={s}'",
137 .{path},
138 );
139 }
140
141 // If we're passed -fuse-ld= with no argument, or with the argument ld,
142 // then use whatever the default system linker is.
143 if (use_linker.len == 0 or mem.eql(u8, use_linker, "ld")) {
144 const default = tc.getDefaultLinker();
145 if (std.fs.path.isAbsolute(default)) return default;
146 return tc.getProgramPath(default, buf);
147 }
148
149 // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
150 // for the linker flavor is brittle. In addition, prepending "ld." or "ld64."
151 // to a relative path is surprising. This is more complex due to priorities
152 // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead.
153 if (mem.indexOfScalar(u8, use_linker, '/') != null) {
154 try tc.driver.comp.addDiagnostic(.{ .tag = .fuse_ld_path }, &.{});
155 }
156
157 if (std.fs.path.isAbsolute(use_linker)) {
158 if (tc.filesystem.canExecute(use_linker)) {
159 return use_linker;
160 }
161 } else {
162 var linker_name = try std.ArrayList(u8).initCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker
163 defer linker_name.deinit();
164 if (tc.getTarget().isDarwin()) {
165 linker_name.appendSliceAssumeCapacity("ld64.");
166 } else {
167 linker_name.appendSliceAssumeCapacity("ld.");
168 }
169 linker_name.appendSliceAssumeCapacity(use_linker);
170 const linker_path = tc.getProgramPath(linker_name.items, buf);
171 if (tc.filesystem.canExecute(linker_path)) {
172 return linker_path;
173 }
174 }
175
176 if (tc.driver.use_linker) |linker| {
177 return tc.driver.fatal(
178 "invalid linker name in argument '-fuse-ld={s}'",
179 .{linker},
180 );
181 }
182 const default_linker = tc.getDefaultLinker();
183 return tc.getProgramPath(default_linker, buf);
184}
185
186/// If an explicit target is provided, also check the prefixed tool-specific name
187/// TODO: this isn't exactly right since our target names don't necessarily match up
188/// with GCC's.
189/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools
190fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, buf: *[64]u8) std.BoundedArray([]const u8, 2) {
191 var possible_names: std.BoundedArray([]const u8, 2) = .{};
192 if (raw_triple) |triple| {
193 if (std.fmt.bufPrint(buf, "{s}-{s}", .{ triple, name })) |res| {
194 possible_names.appendAssumeCapacity(res);
195 } else |_| {}
196 }
197 possible_names.appendAssumeCapacity(name);
198
199 return possible_names;
200}
201
202/// Add toolchain `file_paths` to argv as `-L` arguments
203pub fn addFilePathLibArgs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
204 try argv.ensureUnusedCapacity(tc.file_paths.items.len);
205
206 var bytes_needed: usize = 0;
207 for (tc.file_paths.items) |path| {
208 bytes_needed += path.len + 2; // +2 for `-L`
209 }
210 var bytes = try tc.arena.alloc(u8, bytes_needed);
211 var index: usize = 0;
212 for (tc.file_paths.items) |path| {
213 @memcpy(bytes[index..][0..2], "-L");
214 @memcpy(bytes[index + 2 ..][0..path.len], path);
215 argv.appendAssumeCapacity(bytes[index..][0 .. path.len + 2]);
216 index += path.len + 2;
217 }
218}
219
220/// Search for an executable called `name` or `{triple}-{name} in program_paths and the $PATH environment variable
221/// If not found there, just use `name`
222/// Writes the result to `buf` and returns a slice of it
223fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8 {
224 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
225 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
226
227 var tool_specific_buf: [64]u8 = undefined;
228 const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf);
229
230 for (possible_names.constSlice()) |tool_name| {
231 for (tc.program_paths.items) |program_path| {
232 defer fib.reset();
233
234 const candidate = std.fs.path.join(fib.allocator(), &.{ program_path, tool_name }) catch continue;
235
236 if (tc.filesystem.canExecute(candidate) and candidate.len <= buf.len) {
237 @memcpy(buf[0..candidate.len], candidate);
238 return buf[0..candidate.len];
239 }
240 }
241 return tc.filesystem.findProgramByName(tc.driver.comp.gpa, name, tc.driver.comp.environment.path, buf) orelse continue;
242 }
243 @memcpy(buf[0..name.len], name);
244 return buf[0..name.len];
245}
246
247pub fn getSysroot(tc: *const Toolchain) []const u8 {
248 return tc.driver.sysroot orelse system_defaults.sysroot;
249}
250
251/// Search for `name` in a variety of places
252/// TODO: cache results based on `name` so we're not repeatedly allocating the same strings?
253pub fn getFilePath(tc: *const Toolchain, name: []const u8) ![]const u8 {
254 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
255 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
256 const allocator = fib.allocator();
257
258 const sysroot = tc.getSysroot();
259
260 // todo check resource dir
261 // todo check compiler RT path
262 const aro_dir = std.fs.path.dirname(tc.driver.aro_name) orelse "";
263 const candidate = try std.fs.path.join(allocator, &.{ aro_dir, "..", name });
264 if (tc.filesystem.exists(candidate)) {
265 return tc.arena.dupe(u8, candidate);
266 }
267
268 if (tc.searchPaths(&fib, sysroot, tc.library_paths.items, name)) |path| {
269 return tc.arena.dupe(u8, path);
270 }
271
272 if (tc.searchPaths(&fib, sysroot, tc.file_paths.items, name)) |path| {
273 return try tc.arena.dupe(u8, path);
274 }
275
276 return name;
277}
278
279/// Search a list of `path_prefixes` for the existence `name`
280/// Assumes that `fba` is a fixed-buffer allocator, so does not free joined path candidates
281fn searchPaths(tc: *const Toolchain, fib: *std.heap.FixedBufferAllocator, sysroot: []const u8, path_prefixes: []const []const u8, name: []const u8) ?[]const u8 {
282 for (path_prefixes) |path| {
283 fib.reset();
284 if (path.len == 0) continue;
285
286 const candidate = if (path[0] == '=')
287 std.fs.path.join(fib.allocator(), &.{ sysroot, path[1..], name }) catch continue
288 else
289 std.fs.path.join(fib.allocator(), &.{ path, name }) catch continue;
290
291 if (tc.filesystem.exists(candidate)) {
292 return candidate;
293 }
294 }
295 return null;
296}
297
298const PathKind = enum {
299 library,
300 file,
301 program,
302};
303
304/// Join `components` into a path. If the path exists, dupe it into the toolchain arena and
305/// add it to the specified path list.
306pub fn addPathIfExists(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
307 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
308 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
309
310 const candidate = try std.fs.path.join(fib.allocator(), components);
311
312 if (tc.filesystem.exists(candidate)) {
313 const duped = try tc.arena.dupe(u8, candidate);
314 const dest = switch (dest_kind) {
315 .library => &tc.library_paths,
316 .file => &tc.file_paths,
317 .program => &tc.program_paths,
318 };
319 try dest.append(tc.driver.comp.gpa, duped);
320 }
321}
322
323/// Join `components` using the toolchain arena and add the resulting path to `dest_kind`. Does not check
324/// whether the path actually exists
325pub fn addPathFromComponents(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void {
326 const full_path = try std.fs.path.join(tc.arena, components);
327 const dest = switch (dest_kind) {
328 .library => &tc.library_paths,
329 .file => &tc.file_paths,
330 .program => &tc.program_paths,
331 };
332 try dest.append(tc.driver.comp.gpa, full_path);
333}
334
335/// Add linker args to `argv`. Does not add path to linker executable as first item; that must be handled separately
336/// Items added to `argv` will be string literals or owned by `tc.arena` so they must not be individually freed
337pub fn buildLinkerArgs(tc: *Toolchain, argv: *std.ArrayList([]const u8)) !void {
338 return switch (tc.inner) {
339 .uninitialized => unreachable,
340 .linux => |*linux| linux.buildLinkerArgs(tc, argv),
341 .unknown => @panic("This toolchain does not support linking yet"),
342 };
343}
344
345fn getDefaultRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
346 if (tc.getTarget().isAndroid()) {
347 return .compiler_rt;
348 }
349 return .libgcc;
350}
351
352pub fn getRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
353 const libname = tc.driver.rtlib orelse system_defaults.rtlib;
354 if (mem.eql(u8, libname, "compiler-rt"))
355 return .compiler_rt
356 else if (mem.eql(u8, libname, "libgcc"))
357 return .libgcc
358 else
359 return tc.getDefaultRuntimeLibKind();
360}
361
362/// TODO
363pub fn getCompilerRt(tc: *const Toolchain, component: []const u8, file_kind: FileKind) ![]const u8 {
364 _ = file_kind;
365 _ = component;
366 _ = tc;
367 return "";
368}
369
370fn getLibGCCKind(tc: *const Toolchain) LibGCCKind {
371 const target = tc.getTarget();
372 if (tc.driver.static_libgcc or tc.driver.static or tc.driver.static_pie or target.isAndroid()) {
373 return .static;
374 }
375 if (tc.driver.shared_libgcc) {
376 return .shared;
377 }
378 return .unspecified;
379}
380
381fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind {
382 const libname = tc.driver.unwindlib orelse system_defaults.unwindlib;
383 if (libname.len == 0 or mem.eql(u8, libname, "platform")) {
384 switch (tc.getRuntimeLibKind()) {
385 .compiler_rt => {
386 const target = tc.getTarget();
387 if (target.isAndroid() or target.os.tag == .aix) {
388 return .compiler_rt;
389 } else {
390 return .none;
391 }
392 },
393 .libgcc => return .libgcc,
394 }
395 } else if (mem.eql(u8, libname, "none")) {
396 return .none;
397 } else if (mem.eql(u8, libname, "libgcc")) {
398 return .libgcc;
399 } else if (mem.eql(u8, libname, "libunwind")) {
400 if (tc.getRuntimeLibKind() == .libgcc) {
401 try tc.driver.comp.addDiagnostic(.{ .tag = .incompatible_unwindlib }, &.{});
402 }
403 return .compiler_rt;
404 } else {
405 unreachable;
406 }
407}
408
409fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 {
410 if (is_solaris) {
411 return if (needed) "-zignore" else "-zrecord";
412 } else {
413 return if (needed) "--as-needed" else "--no-as-needed";
414 }
415}
416
417fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
418 const unw = try tc.getUnwindLibKind();
419 const target = tc.getTarget();
420 if ((target.isAndroid() and unw == .libgcc) or
421 target.os.tag == .elfiamcu or
422 target.ofmt == .wasm or
423 target_util.isWindowsMSVCEnvironment(target) or
424 unw == .none) return;
425
426 const lgk = tc.getLibGCCKind();
427 const as_needed = lgk == .unspecified and !target.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
428 if (as_needed) {
429 try argv.append(getAsNeededOption(target.os.tag == .solaris, true));
430 }
431 switch (unw) {
432 .none => return,
433 .libgcc => if (lgk == .static) try argv.append("-lgcc_eh") else try argv.append("-lgcc_s"),
434 .compiler_rt => if (target.os.tag == .aix) {
435 if (lgk != .static) {
436 try argv.append("-lunwind");
437 }
438 } else if (lgk == .static) {
439 try argv.append("-l:libunwind.a");
440 } else if (lgk == .shared) {
441 if (target_util.isCygwinMinGW(target)) {
442 try argv.append("-l:libunwind.dll.a");
443 } else {
444 try argv.append("-l:libunwind.so");
445 }
446 } else {
447 try argv.append("-lunwind");
448 },
449 }
450
451 if (as_needed) {
452 try argv.append(getAsNeededOption(target.os.tag == .solaris, false));
453 }
454}
455
456fn addLibGCC(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
457 const libgcc_kind = tc.getLibGCCKind();
458 if (libgcc_kind == .static or libgcc_kind == .unspecified) {
459 try argv.append("-lgcc");
460 }
461 try tc.addUnwindLibrary(argv);
462 if (libgcc_kind == .shared) {
463 try argv.append("-lgcc");
464 }
465}
466
467pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
468 const target = tc.getTarget();
469 const rlt = tc.getRuntimeLibKind();
470 switch (rlt) {
471 .compiler_rt => {
472 // TODO
473 },
474 .libgcc => {
475 if (target_util.isKnownWindowsMSVCEnvironment(target)) {
476 const rtlib_str = tc.driver.rtlib orelse system_defaults.rtlib;
477 if (!mem.eql(u8, rtlib_str, "platform")) {
478 try tc.driver.comp.addDiagnostic(.{ .tag = .unsupported_rtlib_gcc, .extra = .{ .str = "MSVC" } }, &.{});
479 }
480 } else {
481 try tc.addLibGCC(argv);
482 }
483 },
484 }
485
486 if (target.isAndroid() and !tc.driver.static and !tc.driver.static_pie) {
487 try argv.append("-ldl");
488 }
489}
lib/compiler/aro/aro/Tree.zig created+1334
......@@ -0,0 +1,1334 @@
1const std = @import("std");
2const Interner = @import("../backend.zig").Interner;
3const Attribute = @import("Attribute.zig");
4const CodeGen = @import("CodeGen.zig");
5const Compilation = @import("Compilation.zig");
6const number_affixes = @import("Tree/number_affixes.zig");
7const Source = @import("Source.zig");
8const Tokenizer = @import("Tokenizer.zig");
9const Type = @import("Type.zig");
10const Value = @import("Value.zig");
11const StringInterner = @import("StringInterner.zig");
12
13pub const Token = struct {
14 id: Id,
15 flags: packed struct {
16 expansion_disabled: bool = false,
17 is_macro_arg: bool = false,
18 } = .{},
19 /// This location contains the actual token slice which might be generated.
20 /// If it is generated then there is guaranteed to be at least one
21 /// expansion location.
22 loc: Source.Location,
23 expansion_locs: ?[*]Source.Location = null,
24
25 pub fn expansionSlice(tok: Token) []const Source.Location {
26 const locs = tok.expansion_locs orelse return &[0]Source.Location{};
27 var i: usize = 0;
28 while (locs[i].id != .unused) : (i += 1) {}
29 return locs[0..i];
30 }
31
32 pub fn addExpansionLocation(tok: *Token, gpa: std.mem.Allocator, new: []const Source.Location) !void {
33 if (new.len == 0 or tok.id == .whitespace) return;
34 var list = std.ArrayList(Source.Location).init(gpa);
35 defer {
36 @memset(list.items.ptr[list.items.len..list.capacity], .{});
37 // Add a sentinel to indicate the end of the list since
38 // the ArrayList's capacity isn't guaranteed to be exactly
39 // what we ask for.
40 if (list.capacity > 0) {
41 list.items.ptr[list.capacity - 1].byte_offset = 1;
42 }
43 tok.expansion_locs = list.items.ptr;
44 }
45
46 if (tok.expansion_locs) |locs| {
47 var i: usize = 0;
48 while (locs[i].id != .unused) : (i += 1) {}
49 list.items = locs[0..i];
50 while (locs[i].byte_offset != 1) : (i += 1) {}
51 list.capacity = i + 1;
52 }
53
54 const min_len = @max(list.items.len + new.len + 1, 4);
55 const wanted_len = std.math.ceilPowerOfTwo(usize, min_len) catch
56 return error.OutOfMemory;
57 try list.ensureTotalCapacity(wanted_len);
58
59 for (new) |new_loc| {
60 if (new_loc.id == .generated) continue;
61 list.appendAssumeCapacity(new_loc);
62 }
63 }
64
65 pub fn free(expansion_locs: ?[*]Source.Location, gpa: std.mem.Allocator) void {
66 const locs = expansion_locs orelse return;
67 var i: usize = 0;
68 while (locs[i].id != .unused) : (i += 1) {}
69 while (locs[i].byte_offset != 1) : (i += 1) {}
70 gpa.free(locs[0 .. i + 1]);
71 }
72
73 pub fn dupe(tok: Token, gpa: std.mem.Allocator) !Token {
74 var copy = tok;
75 copy.expansion_locs = null;
76 try copy.addExpansionLocation(gpa, tok.expansionSlice());
77 return copy;
78 }
79
80 pub fn checkMsEof(tok: Token, source: Source, comp: *Compilation) !void {
81 std.debug.assert(tok.id == .eof);
82 if (source.buf.len > tok.loc.byte_offset and source.buf[tok.loc.byte_offset] == 0x1A) {
83 try comp.addDiagnostic(.{
84 .tag = .ctrl_z_eof,
85 .loc = .{
86 .id = source.id,
87 .byte_offset = tok.loc.byte_offset,
88 .line = tok.loc.line,
89 },
90 }, &.{});
91 }
92 }
93
94 pub const List = std.MultiArrayList(Token);
95 pub const Id = Tokenizer.Token.Id;
96 pub const NumberPrefix = number_affixes.Prefix;
97 pub const NumberSuffix = number_affixes.Suffix;
98};
99
100pub const TokenIndex = u32;
101pub const NodeIndex = enum(u32) { none, _ };
102pub const ValueMap = std.AutoHashMap(NodeIndex, Value);
103
104const Tree = @This();
105
106comp: *Compilation,
107arena: std.heap.ArenaAllocator,
108generated: []const u8,
109tokens: Token.List.Slice,
110nodes: Node.List.Slice,
111data: []const NodeIndex,
112root_decls: []const NodeIndex,
113value_map: ValueMap,
114
115pub const genIr = CodeGen.genIr;
116
117pub fn deinit(tree: *Tree) void {
118 tree.comp.gpa.free(tree.root_decls);
119 tree.comp.gpa.free(tree.data);
120 tree.nodes.deinit(tree.comp.gpa);
121 tree.arena.deinit();
122 tree.value_map.deinit();
123}
124
125pub const GNUAssemblyQualifiers = struct {
126 @"volatile": bool = false,
127 @"inline": bool = false,
128 goto: bool = false,
129};
130
131pub const Node = struct {
132 tag: Tag,
133 ty: Type = .{ .specifier = .void },
134 data: Data,
135
136 pub const Range = struct { start: u32, end: u32 };
137
138 pub const Data = union {
139 decl: struct {
140 name: TokenIndex,
141 node: NodeIndex = .none,
142 },
143 decl_ref: TokenIndex,
144 range: Range,
145 if3: struct {
146 cond: NodeIndex,
147 body: u32,
148 },
149 un: NodeIndex,
150 bin: struct {
151 lhs: NodeIndex,
152 rhs: NodeIndex,
153 },
154 member: struct {
155 lhs: NodeIndex,
156 index: u32,
157 },
158 union_init: struct {
159 field_index: u32,
160 node: NodeIndex,
161 },
162 cast: struct {
163 operand: NodeIndex,
164 kind: CastKind,
165 },
166 int: u64,
167 return_zero: bool,
168
169 pub fn forDecl(data: Data, tree: *const Tree) struct {
170 decls: []const NodeIndex,
171 cond: NodeIndex,
172 incr: NodeIndex,
173 body: NodeIndex,
174 } {
175 const items = tree.data[data.range.start..data.range.end];
176 const decls = items[0 .. items.len - 3];
177
178 return .{
179 .decls = decls,
180 .cond = items[items.len - 3],
181 .incr = items[items.len - 2],
182 .body = items[items.len - 1],
183 };
184 }
185
186 pub fn forStmt(data: Data, tree: *const Tree) struct {
187 init: NodeIndex,
188 cond: NodeIndex,
189 incr: NodeIndex,
190 body: NodeIndex,
191 } {
192 const items = tree.data[data.if3.body..];
193
194 return .{
195 .init = items[0],
196 .cond = items[1],
197 .incr = items[2],
198 .body = data.if3.cond,
199 };
200 }
201 };
202
203 pub const List = std.MultiArrayList(Node);
204};
205
206pub const CastKind = enum(u8) {
207 /// Does nothing except possibly add qualifiers
208 no_op,
209 /// Interpret one bit pattern as another. Used for operands which have the same
210 /// size and unrelated types, e.g. casting one pointer type to another
211 bitcast,
212 /// Convert T[] to T *
213 array_to_pointer,
214 /// Converts an lvalue to an rvalue
215 lval_to_rval,
216 /// Convert a function type to a pointer to a function
217 function_to_pointer,
218 /// Convert a pointer type to a _Bool
219 pointer_to_bool,
220 /// Convert a pointer type to an integer type
221 pointer_to_int,
222 /// Convert _Bool to an integer type
223 bool_to_int,
224 /// Convert _Bool to a floating type
225 bool_to_float,
226 /// Convert a _Bool to a pointer; will cause a warning
227 bool_to_pointer,
228 /// Convert an integer type to _Bool
229 int_to_bool,
230 /// Convert an integer to a floating type
231 int_to_float,
232 /// Convert a complex integer to a complex floating type
233 complex_int_to_complex_float,
234 /// Convert an integer type to a pointer type
235 int_to_pointer,
236 /// Convert a floating type to a _Bool
237 float_to_bool,
238 /// Convert a floating type to an integer
239 float_to_int,
240 /// Convert a complex floating type to a complex integer
241 complex_float_to_complex_int,
242 /// Convert one integer type to another
243 int_cast,
244 /// Convert one complex integer type to another
245 complex_int_cast,
246 /// Convert real part of complex integer to a integer
247 complex_int_to_real,
248 /// Create a complex integer type using operand as the real part
249 real_to_complex_int,
250 /// Convert one floating type to another
251 float_cast,
252 /// Convert one complex floating type to another
253 complex_float_cast,
254 /// Convert real part of complex float to a float
255 complex_float_to_real,
256 /// Create a complex floating type using operand as the real part
257 real_to_complex_float,
258 /// Convert type to void
259 to_void,
260 /// Convert a literal 0 to a null pointer
261 null_to_pointer,
262 /// GNU cast-to-union extension
263 union_cast,
264 /// Create vector where each value is same as the input scalar.
265 vector_splat,
266};
267
268pub const Tag = enum(u8) {
269 /// Must appear at index 0. Also used as the tag for __builtin_types_compatible_p arguments, since the arguments are types
270 /// Reaching it is always the result of a bug.
271 invalid,
272
273 // ====== Decl ======
274
275 // _Static_assert
276 static_assert,
277
278 // function prototype
279 fn_proto,
280 static_fn_proto,
281 inline_fn_proto,
282 inline_static_fn_proto,
283
284 // function definition
285 fn_def,
286 static_fn_def,
287 inline_fn_def,
288 inline_static_fn_def,
289
290 // variable declaration
291 @"var",
292 extern_var,
293 static_var,
294 // same as static_var, used for __func__, __FUNCTION__ and __PRETTY_FUNCTION__
295 implicit_static_var,
296 threadlocal_var,
297 threadlocal_extern_var,
298 threadlocal_static_var,
299
300 /// __asm__("...") at file scope
301 file_scope_asm,
302
303 // typedef declaration
304 typedef,
305
306 // container declarations
307 /// { lhs; rhs; }
308 struct_decl_two,
309 /// { lhs; rhs; }
310 union_decl_two,
311 /// { lhs, rhs, }
312 enum_decl_two,
313 /// { range }
314 struct_decl,
315 /// { range }
316 union_decl,
317 /// { range }
318 enum_decl,
319 /// struct decl_ref;
320 struct_forward_decl,
321 /// union decl_ref;
322 union_forward_decl,
323 /// enum decl_ref;
324 enum_forward_decl,
325
326 /// name = node
327 enum_field_decl,
328 /// ty name : node
329 /// name == 0 means unnamed
330 record_field_decl,
331 /// Used when a record has an unnamed record as a field
332 indirect_record_field_decl,
333
334 // ====== Stmt ======
335
336 labeled_stmt,
337 /// { first; second; } first and second may be null
338 compound_stmt_two,
339 /// { data }
340 compound_stmt,
341 /// if (first) data[second] else data[second+1];
342 if_then_else_stmt,
343 /// if (first) second; second may be null
344 if_then_stmt,
345 /// switch (first) second
346 switch_stmt,
347 /// case first: second
348 case_stmt,
349 /// case data[body]...data[body+1]: cond
350 case_range_stmt,
351 /// default: first
352 default_stmt,
353 /// while (first) second
354 while_stmt,
355 /// do second while(first);
356 do_while_stmt,
357 /// for (data[..]; data[len-3]; data[len-2]) data[len-1]
358 for_decl_stmt,
359 /// for (;;;) first
360 forever_stmt,
361 /// for (data[first]; data[first+1]; data[first+2]) second
362 for_stmt,
363 /// goto first;
364 goto_stmt,
365 /// goto *un;
366 computed_goto_stmt,
367 // continue; first and second unused
368 continue_stmt,
369 // break; first and second unused
370 break_stmt,
371 // null statement (just a semicolon); first and second unused
372 null_stmt,
373 /// return first; first may be null
374 return_stmt,
375 /// Assembly statement of the form __asm__("string literal")
376 gnu_asm_simple,
377
378 // ====== Expr ======
379
380 /// lhs , rhs
381 comma_expr,
382 /// lhs ? data[0] : data[1]
383 binary_cond_expr,
384 /// Used as the base for casts of the lhs in `binary_cond_expr`.
385 cond_dummy_expr,
386 /// lhs ? data[0] : data[1]
387 cond_expr,
388 /// lhs = rhs
389 assign_expr,
390 /// lhs *= rhs
391 mul_assign_expr,
392 /// lhs /= rhs
393 div_assign_expr,
394 /// lhs %= rhs
395 mod_assign_expr,
396 /// lhs += rhs
397 add_assign_expr,
398 /// lhs -= rhs
399 sub_assign_expr,
400 /// lhs <<= rhs
401 shl_assign_expr,
402 /// lhs >>= rhs
403 shr_assign_expr,
404 /// lhs &= rhs
405 bit_and_assign_expr,
406 /// lhs ^= rhs
407 bit_xor_assign_expr,
408 /// lhs |= rhs
409 bit_or_assign_expr,
410 /// lhs || rhs
411 bool_or_expr,
412 /// lhs && rhs
413 bool_and_expr,
414 /// lhs | rhs
415 bit_or_expr,
416 /// lhs ^ rhs
417 bit_xor_expr,
418 /// lhs & rhs
419 bit_and_expr,
420 /// lhs == rhs
421 equal_expr,
422 /// lhs != rhs
423 not_equal_expr,
424 /// lhs < rhs
425 less_than_expr,
426 /// lhs <= rhs
427 less_than_equal_expr,
428 /// lhs > rhs
429 greater_than_expr,
430 /// lhs >= rhs
431 greater_than_equal_expr,
432 /// lhs << rhs
433 shl_expr,
434 /// lhs >> rhs
435 shr_expr,
436 /// lhs + rhs
437 add_expr,
438 /// lhs - rhs
439 sub_expr,
440 /// lhs * rhs
441 mul_expr,
442 /// lhs / rhs
443 div_expr,
444 /// lhs % rhs
445 mod_expr,
446 /// Explicit: (type) cast
447 explicit_cast,
448 /// Implicit: cast
449 implicit_cast,
450 /// &un
451 addr_of_expr,
452 /// &&decl_ref
453 addr_of_label,
454 /// *un
455 deref_expr,
456 /// +un
457 plus_expr,
458 /// -un
459 negate_expr,
460 /// ~un
461 bit_not_expr,
462 /// !un
463 bool_not_expr,
464 /// ++un
465 pre_inc_expr,
466 /// --un
467 pre_dec_expr,
468 /// __imag un
469 imag_expr,
470 /// __real un
471 real_expr,
472 /// lhs[rhs] lhs is pointer/array type, rhs is integer type
473 array_access_expr,
474 /// first(second) second may be 0
475 call_expr_one,
476 /// data[0](data[1..])
477 call_expr,
478 /// decl
479 builtin_call_expr_one,
480 builtin_call_expr,
481 /// lhs.member
482 member_access_expr,
483 /// lhs->member
484 member_access_ptr_expr,
485 /// un++
486 post_inc_expr,
487 /// un--
488 post_dec_expr,
489 /// (un)
490 paren_expr,
491 /// decl_ref
492 decl_ref_expr,
493 /// decl_ref
494 enumeration_ref,
495 /// C23 bool literal `true` / `false`
496 bool_literal,
497 /// C23 nullptr literal
498 nullptr_literal,
499 /// integer literal, always unsigned
500 int_literal,
501 /// Same as int_literal, but originates from a char literal
502 char_literal,
503 /// a floating point literal
504 float_literal,
505 /// wraps a float or double literal: un
506 imaginary_literal,
507 /// tree.str[index..][0..len]
508 string_literal_expr,
509 /// sizeof(un?)
510 sizeof_expr,
511 /// _Alignof(un?)
512 alignof_expr,
513 /// _Generic(controlling lhs, chosen rhs)
514 generic_expr_one,
515 /// _Generic(controlling range[0], chosen range[1], rest range[2..])
516 generic_expr,
517 /// ty: un
518 generic_association_expr,
519 // default: un
520 generic_default_expr,
521 /// __builtin_choose_expr(lhs, data[0], data[1])
522 builtin_choose_expr,
523 /// __builtin_types_compatible_p(lhs, rhs)
524 builtin_types_compatible_p,
525 /// decl - special builtins require custom parsing
526 special_builtin_call_one,
527 /// ({ un })
528 stmt_expr,
529
530 // ====== Initializer expressions ======
531
532 /// { lhs, rhs }
533 array_init_expr_two,
534 /// { range }
535 array_init_expr,
536 /// { lhs, rhs }
537 struct_init_expr_two,
538 /// { range }
539 struct_init_expr,
540 /// { union_init }
541 union_init_expr,
542 /// (ty){ un }
543 compound_literal_expr,
544 /// (static ty){ un }
545 static_compound_literal_expr,
546 /// (thread_local ty){ un }
547 thread_local_compound_literal_expr,
548 /// (static thread_local ty){ un }
549 static_thread_local_compound_literal_expr,
550
551 /// Inserted at the end of a function body if no return stmt is found.
552 /// ty is the functions return type
553 /// data is return_zero which is true if the function is called "main" and ty is compatible with int
554 implicit_return,
555
556 /// Inserted in array_init_expr to represent unspecified elements.
557 /// data.int contains the amount of elements.
558 array_filler_expr,
559 /// Inserted in record and scalar initializers for unspecified elements.
560 default_init_expr,
561
562 pub fn isImplicit(tag: Tag) bool {
563 return switch (tag) {
564 .implicit_cast,
565 .implicit_return,
566 .array_filler_expr,
567 .default_init_expr,
568 .implicit_static_var,
569 .cond_dummy_expr,
570 => true,
571 else => false,
572 };
573 }
574};
575
576pub fn isBitfield(tree: *const Tree, node: NodeIndex) bool {
577 return tree.bitfieldWidth(node, false) != null;
578}
579
580/// Returns null if node is not a bitfield. If inspect_lval is true, this function will
581/// recurse into implicit lval_to_rval casts (useful for arithmetic conversions)
582pub fn bitfieldWidth(tree: *const Tree, node: NodeIndex, inspect_lval: bool) ?u32 {
583 if (node == .none) return null;
584 switch (tree.nodes.items(.tag)[@intFromEnum(node)]) {
585 .member_access_expr, .member_access_ptr_expr => {
586 const member = tree.nodes.items(.data)[@intFromEnum(node)].member;
587 var ty = tree.nodes.items(.ty)[@intFromEnum(member.lhs)];
588 if (ty.isPtr()) ty = ty.elemType();
589 const record_ty = ty.get(.@"struct") orelse ty.get(.@"union") orelse return null;
590 const field = record_ty.data.record.fields[member.index];
591 return field.bit_width;
592 },
593 .implicit_cast => {
594 if (!inspect_lval) return null;
595
596 const data = tree.nodes.items(.data)[@intFromEnum(node)];
597 return switch (data.cast.kind) {
598 .lval_to_rval => tree.bitfieldWidth(data.cast.operand, false),
599 else => null,
600 };
601 },
602 else => return null,
603 }
604}
605
606pub fn isLval(tree: *const Tree, node: NodeIndex) bool {
607 var is_const: bool = undefined;
608 return tree.isLvalExtra(node, &is_const);
609}
610
611pub fn isLvalExtra(tree: *const Tree, node: NodeIndex, is_const: *bool) bool {
612 is_const.* = false;
613 switch (tree.nodes.items(.tag)[@intFromEnum(node)]) {
614 .compound_literal_expr,
615 .static_compound_literal_expr,
616 .thread_local_compound_literal_expr,
617 .static_thread_local_compound_literal_expr,
618 => {
619 is_const.* = tree.nodes.items(.ty)[@intFromEnum(node)].isConst();
620 return true;
621 },
622 .string_literal_expr => return true,
623 .member_access_ptr_expr => {
624 const lhs_expr = tree.nodes.items(.data)[@intFromEnum(node)].member.lhs;
625 const ptr_ty = tree.nodes.items(.ty)[@intFromEnum(lhs_expr)];
626 if (ptr_ty.isPtr()) is_const.* = ptr_ty.elemType().isConst();
627 return true;
628 },
629 .array_access_expr => {
630 const lhs_expr = tree.nodes.items(.data)[@intFromEnum(node)].bin.lhs;
631 if (lhs_expr != .none) {
632 const array_ty = tree.nodes.items(.ty)[@intFromEnum(lhs_expr)];
633 if (array_ty.isPtr() or array_ty.isArray()) is_const.* = array_ty.elemType().isConst();
634 }
635 return true;
636 },
637 .decl_ref_expr => {
638 const decl_ty = tree.nodes.items(.ty)[@intFromEnum(node)];
639 is_const.* = decl_ty.isConst();
640 return true;
641 },
642 .deref_expr => {
643 const data = tree.nodes.items(.data)[@intFromEnum(node)];
644 const operand_ty = tree.nodes.items(.ty)[@intFromEnum(data.un)];
645 if (operand_ty.isFunc()) return false;
646 if (operand_ty.isPtr() or operand_ty.isArray()) is_const.* = operand_ty.elemType().isConst();
647 return true;
648 },
649 .member_access_expr => {
650 const data = tree.nodes.items(.data)[@intFromEnum(node)];
651 return tree.isLvalExtra(data.member.lhs, is_const);
652 },
653 .paren_expr => {
654 const data = tree.nodes.items(.data)[@intFromEnum(node)];
655 return tree.isLvalExtra(data.un, is_const);
656 },
657 .builtin_choose_expr => {
658 const data = tree.nodes.items(.data)[@intFromEnum(node)];
659
660 if (tree.value_map.get(data.if3.cond)) |val| {
661 const offset = @intFromBool(val.isZero(tree.comp));
662 return tree.isLvalExtra(tree.data[data.if3.body + offset], is_const);
663 }
664 return false;
665 },
666 else => return false,
667 }
668}
669
670pub fn tokSlice(tree: *const Tree, tok_i: TokenIndex) []const u8 {
671 if (tree.tokens.items(.id)[tok_i].lexeme()) |some| return some;
672 const loc = tree.tokens.items(.loc)[tok_i];
673 var tmp_tokenizer = Tokenizer{
674 .buf = tree.comp.getSource(loc.id).buf,
675 .langopts = tree.comp.langopts,
676 .index = loc.byte_offset,
677 .source = .generated,
678 };
679 const tok = tmp_tokenizer.next();
680 return tmp_tokenizer.buf[tok.start..tok.end];
681}
682
683pub fn dump(tree: *const Tree, config: std.io.tty.Config, writer: anytype) !void {
684 const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper();
685 defer mapper.deinit(tree.comp.gpa);
686
687 for (tree.root_decls) |i| {
688 try tree.dumpNode(i, 0, mapper, config, writer);
689 try writer.writeByte('\n');
690 }
691}
692
693fn dumpFieldAttributes(tree: *const Tree, attributes: []const Attribute, level: u32, writer: anytype) !void {
694 for (attributes) |attr| {
695 try writer.writeByteNTimes(' ', level);
696 try writer.print("field attr: {s}", .{@tagName(attr.tag)});
697 try tree.dumpAttribute(attr, writer);
698 }
699}
700
701fn dumpAttribute(tree: *const Tree, attr: Attribute, writer: anytype) !void {
702 switch (attr.tag) {
703 inline else => |tag| {
704 const args = @field(attr.args, @tagName(tag));
705 const fields = @typeInfo(@TypeOf(args)).Struct.fields;
706 if (fields.len == 0) {
707 try writer.writeByte('\n');
708 return;
709 }
710 try writer.writeByte(' ');
711 inline for (fields, 0..) |f, i| {
712 if (comptime std.mem.eql(u8, f.name, "__name_tok")) continue;
713 if (i != 0) {
714 try writer.writeAll(", ");
715 }
716 try writer.writeAll(f.name);
717 try writer.writeAll(": ");
718 switch (f.type) {
719 Interner.Ref => try writer.print("\"{s}\"", .{tree.interner.get(@field(args, f.name)).bytes}),
720 ?Interner.Ref => try writer.print("\"{?s}\"", .{if (@field(args, f.name)) |str| tree.interner.get(str).bytes else null}),
721 else => switch (@typeInfo(f.type)) {
722 .Enum => try writer.writeAll(@tagName(@field(args, f.name))),
723 else => try writer.print("{any}", .{@field(args, f.name)}),
724 },
725 }
726 }
727 try writer.writeByte('\n');
728 return;
729 },
730 }
731}
732
733fn dumpNode(
734 tree: *const Tree,
735 node: NodeIndex,
736 level: u32,
737 mapper: StringInterner.TypeMapper,
738 config: std.io.tty.Config,
739 w: anytype,
740) !void {
741 const delta = 2;
742 const half = delta / 2;
743 const TYPE = std.io.tty.Color.bright_magenta;
744 const TAG = std.io.tty.Color.bright_cyan;
745 const IMPLICIT = std.io.tty.Color.bright_blue;
746 const NAME = std.io.tty.Color.bright_red;
747 const LITERAL = std.io.tty.Color.bright_green;
748 const ATTRIBUTE = std.io.tty.Color.bright_yellow;
749 std.debug.assert(node != .none);
750
751 const tag = tree.nodes.items(.tag)[@intFromEnum(node)];
752 const data = tree.nodes.items(.data)[@intFromEnum(node)];
753 const ty = tree.nodes.items(.ty)[@intFromEnum(node)];
754 try w.writeByteNTimes(' ', level);
755
756 try config.setColor(w, if (tag.isImplicit()) IMPLICIT else TAG);
757 try w.print("{s}: ", .{@tagName(tag)});
758 if (tag == .implicit_cast or tag == .explicit_cast) {
759 try config.setColor(w, .white);
760 try w.print("({s}) ", .{@tagName(data.cast.kind)});
761 }
762 try config.setColor(w, TYPE);
763 try w.writeByte('\'');
764 try ty.dump(mapper, tree.comp.langopts, w);
765 try w.writeByte('\'');
766
767 if (tree.isLval(node)) {
768 try config.setColor(w, ATTRIBUTE);
769 try w.writeAll(" lvalue");
770 }
771 if (tree.isBitfield(node)) {
772 try config.setColor(w, ATTRIBUTE);
773 try w.writeAll(" bitfield");
774 }
775 if (tree.value_map.get(node)) |val| {
776 try config.setColor(w, LITERAL);
777 try w.writeAll(" (value: ");
778 try val.print(ty, tree.comp, w);
779 try w.writeByte(')');
780 }
781 if (tag == .implicit_return and data.return_zero) {
782 try config.setColor(w, IMPLICIT);
783 try w.writeAll(" (value: 0)");
784 try config.setColor(w, .reset);
785 }
786
787 try w.writeAll("\n");
788 try config.setColor(w, .reset);
789
790 if (ty.specifier == .attributed) {
791 try config.setColor(w, ATTRIBUTE);
792 for (ty.data.attributed.attributes) |attr| {
793 try w.writeByteNTimes(' ', level + half);
794 try w.print("attr: {s}", .{@tagName(attr.tag)});
795 try tree.dumpAttribute(attr, w);
796 }
797 try config.setColor(w, .reset);
798 }
799
800 switch (tag) {
801 .invalid => unreachable,
802 .file_scope_asm => {
803 try w.writeByteNTimes(' ', level + 1);
804 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
805 },
806 .gnu_asm_simple => {
807 try w.writeByteNTimes(' ', level);
808 try tree.dumpNode(data.un, level, mapper, config, w);
809 },
810 .static_assert => {
811 try w.writeByteNTimes(' ', level + 1);
812 try w.writeAll("condition:\n");
813 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
814 if (data.bin.rhs != .none) {
815 try w.writeByteNTimes(' ', level + 1);
816 try w.writeAll("diagnostic:\n");
817 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
818 }
819 },
820 .fn_proto,
821 .static_fn_proto,
822 .inline_fn_proto,
823 .inline_static_fn_proto,
824 => {
825 try w.writeByteNTimes(' ', level + half);
826 try w.writeAll("name: ");
827 try config.setColor(w, NAME);
828 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
829 try config.setColor(w, .reset);
830 },
831 .fn_def,
832 .static_fn_def,
833 .inline_fn_def,
834 .inline_static_fn_def,
835 => {
836 try w.writeByteNTimes(' ', level + half);
837 try w.writeAll("name: ");
838 try config.setColor(w, NAME);
839 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
840 try config.setColor(w, .reset);
841 try w.writeByteNTimes(' ', level + half);
842 try w.writeAll("body:\n");
843 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
844 },
845 .typedef,
846 .@"var",
847 .extern_var,
848 .static_var,
849 .implicit_static_var,
850 .threadlocal_var,
851 .threadlocal_extern_var,
852 .threadlocal_static_var,
853 => {
854 try w.writeByteNTimes(' ', level + half);
855 try w.writeAll("name: ");
856 try config.setColor(w, NAME);
857 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
858 try config.setColor(w, .reset);
859 if (data.decl.node != .none) {
860 try w.writeByteNTimes(' ', level + half);
861 try w.writeAll("init:\n");
862 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
863 }
864 },
865 .enum_field_decl => {
866 try w.writeByteNTimes(' ', level + half);
867 try w.writeAll("name: ");
868 try config.setColor(w, NAME);
869 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
870 try config.setColor(w, .reset);
871 if (data.decl.node != .none) {
872 try w.writeByteNTimes(' ', level + half);
873 try w.writeAll("value:\n");
874 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
875 }
876 },
877 .record_field_decl => {
878 if (data.decl.name != 0) {
879 try w.writeByteNTimes(' ', level + half);
880 try w.writeAll("name: ");
881 try config.setColor(w, NAME);
882 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
883 try config.setColor(w, .reset);
884 }
885 if (data.decl.node != .none) {
886 try w.writeByteNTimes(' ', level + half);
887 try w.writeAll("bits:\n");
888 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
889 }
890 },
891 .indirect_record_field_decl => {},
892 .compound_stmt,
893 .array_init_expr,
894 .struct_init_expr,
895 .enum_decl,
896 .struct_decl,
897 .union_decl,
898 => {
899 const maybe_field_attributes = if (ty.getRecord()) |record| record.field_attributes else null;
900 for (tree.data[data.range.start..data.range.end], 0..) |stmt, i| {
901 if (i != 0) try w.writeByte('\n');
902 try tree.dumpNode(stmt, level + delta, mapper, config, w);
903 if (maybe_field_attributes) |field_attributes| {
904 if (field_attributes[i].len == 0) continue;
905
906 try config.setColor(w, ATTRIBUTE);
907 try tree.dumpFieldAttributes(field_attributes[i], level + delta + half, w);
908 try config.setColor(w, .reset);
909 }
910 }
911 },
912 .compound_stmt_two,
913 .array_init_expr_two,
914 .struct_init_expr_two,
915 .enum_decl_two,
916 .struct_decl_two,
917 .union_decl_two,
918 => {
919 var attr_array = [2][]const Attribute{ &.{}, &.{} };
920 const empty: [][]const Attribute = &attr_array;
921 const field_attributes = if (ty.getRecord()) |record| (record.field_attributes orelse empty.ptr) else empty.ptr;
922 if (data.bin.lhs != .none) {
923 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
924 if (field_attributes[0].len > 0) {
925 try config.setColor(w, ATTRIBUTE);
926 try tree.dumpFieldAttributes(field_attributes[0], level + delta + half, w);
927 try config.setColor(w, .reset);
928 }
929 }
930 if (data.bin.rhs != .none) {
931 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
932 if (field_attributes[1].len > 0) {
933 try config.setColor(w, ATTRIBUTE);
934 try tree.dumpFieldAttributes(field_attributes[1], level + delta + half, w);
935 try config.setColor(w, .reset);
936 }
937 }
938 },
939 .union_init_expr => {
940 try w.writeByteNTimes(' ', level + half);
941 try w.writeAll("field index: ");
942 try config.setColor(w, LITERAL);
943 try w.print("{d}\n", .{data.union_init.field_index});
944 try config.setColor(w, .reset);
945 if (data.union_init.node != .none) {
946 try tree.dumpNode(data.union_init.node, level + delta, mapper, config, w);
947 }
948 },
949 .compound_literal_expr,
950 .static_compound_literal_expr,
951 .thread_local_compound_literal_expr,
952 .static_thread_local_compound_literal_expr,
953 => {
954 try tree.dumpNode(data.un, level + half, mapper, config, w);
955 },
956 .labeled_stmt => {
957 try w.writeByteNTimes(' ', level + half);
958 try w.writeAll("label: ");
959 try config.setColor(w, LITERAL);
960 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
961 try config.setColor(w, .reset);
962 if (data.decl.node != .none) {
963 try w.writeByteNTimes(' ', level + half);
964 try w.writeAll("stmt:\n");
965 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
966 }
967 },
968 .case_stmt => {
969 try w.writeByteNTimes(' ', level + half);
970 try w.writeAll("value:\n");
971 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
972 if (data.bin.rhs != .none) {
973 try w.writeByteNTimes(' ', level + half);
974 try w.writeAll("stmt:\n");
975 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
976 }
977 },
978 .case_range_stmt => {
979 try w.writeByteNTimes(' ', level + half);
980 try w.writeAll("range start:\n");
981 try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, config, w);
982
983 try w.writeByteNTimes(' ', level + half);
984 try w.writeAll("range end:\n");
985 try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, config, w);
986
987 if (data.if3.cond != .none) {
988 try w.writeByteNTimes(' ', level + half);
989 try w.writeAll("stmt:\n");
990 try tree.dumpNode(data.if3.cond, level + delta, mapper, config, w);
991 }
992 },
993 .default_stmt => {
994 if (data.un != .none) {
995 try w.writeByteNTimes(' ', level + half);
996 try w.writeAll("stmt:\n");
997 try tree.dumpNode(data.un, level + delta, mapper, config, w);
998 }
999 },
1000 .binary_cond_expr, .cond_expr, .if_then_else_stmt, .builtin_choose_expr => {
1001 try w.writeByteNTimes(' ', level + half);
1002 try w.writeAll("cond:\n");
1003 try tree.dumpNode(data.if3.cond, level + delta, mapper, config, w);
1004
1005 try w.writeByteNTimes(' ', level + half);
1006 try w.writeAll("then:\n");
1007 try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, config, w);
1008
1009 try w.writeByteNTimes(' ', level + half);
1010 try w.writeAll("else:\n");
1011 try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, config, w);
1012 },
1013 .builtin_types_compatible_p => {
1014 std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.lhs)] == .invalid);
1015 std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.rhs)] == .invalid);
1016
1017 try w.writeByteNTimes(' ', level + half);
1018 try w.writeAll("lhs: ");
1019
1020 const lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.lhs)];
1021 try config.setColor(w, TYPE);
1022 try lhs_ty.dump(mapper, tree.comp.langopts, w);
1023 try config.setColor(w, .reset);
1024 try w.writeByte('\n');
1025
1026 try w.writeByteNTimes(' ', level + half);
1027 try w.writeAll("rhs: ");
1028
1029 const rhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.rhs)];
1030 try config.setColor(w, TYPE);
1031 try rhs_ty.dump(mapper, tree.comp.langopts, w);
1032 try config.setColor(w, .reset);
1033 try w.writeByte('\n');
1034 },
1035 .if_then_stmt => {
1036 try w.writeByteNTimes(' ', level + half);
1037 try w.writeAll("cond:\n");
1038 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1039
1040 if (data.bin.rhs != .none) {
1041 try w.writeByteNTimes(' ', level + half);
1042 try w.writeAll("then:\n");
1043 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1044 }
1045 },
1046 .switch_stmt, .while_stmt, .do_while_stmt => {
1047 try w.writeByteNTimes(' ', level + half);
1048 try w.writeAll("cond:\n");
1049 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1050
1051 if (data.bin.rhs != .none) {
1052 try w.writeByteNTimes(' ', level + half);
1053 try w.writeAll("body:\n");
1054 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1055 }
1056 },
1057 .for_decl_stmt => {
1058 const for_decl = data.forDecl(tree);
1059
1060 try w.writeByteNTimes(' ', level + half);
1061 try w.writeAll("decl:\n");
1062 for (for_decl.decls) |decl| {
1063 try tree.dumpNode(decl, level + delta, mapper, config, w);
1064 try w.writeByte('\n');
1065 }
1066 if (for_decl.cond != .none) {
1067 try w.writeByteNTimes(' ', level + half);
1068 try w.writeAll("cond:\n");
1069 try tree.dumpNode(for_decl.cond, level + delta, mapper, config, w);
1070 }
1071 if (for_decl.incr != .none) {
1072 try w.writeByteNTimes(' ', level + half);
1073 try w.writeAll("incr:\n");
1074 try tree.dumpNode(for_decl.incr, level + delta, mapper, config, w);
1075 }
1076 if (for_decl.body != .none) {
1077 try w.writeByteNTimes(' ', level + half);
1078 try w.writeAll("body:\n");
1079 try tree.dumpNode(for_decl.body, level + delta, mapper, config, w);
1080 }
1081 },
1082 .forever_stmt => {
1083 if (data.un != .none) {
1084 try w.writeByteNTimes(' ', level + half);
1085 try w.writeAll("body:\n");
1086 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1087 }
1088 },
1089 .for_stmt => {
1090 const for_stmt = data.forStmt(tree);
1091
1092 if (for_stmt.init != .none) {
1093 try w.writeByteNTimes(' ', level + half);
1094 try w.writeAll("init:\n");
1095 try tree.dumpNode(for_stmt.init, level + delta, mapper, config, w);
1096 }
1097 if (for_stmt.cond != .none) {
1098 try w.writeByteNTimes(' ', level + half);
1099 try w.writeAll("cond:\n");
1100 try tree.dumpNode(for_stmt.cond, level + delta, mapper, config, w);
1101 }
1102 if (for_stmt.incr != .none) {
1103 try w.writeByteNTimes(' ', level + half);
1104 try w.writeAll("incr:\n");
1105 try tree.dumpNode(for_stmt.incr, level + delta, mapper, config, w);
1106 }
1107 if (for_stmt.body != .none) {
1108 try w.writeByteNTimes(' ', level + half);
1109 try w.writeAll("body:\n");
1110 try tree.dumpNode(for_stmt.body, level + delta, mapper, config, w);
1111 }
1112 },
1113 .goto_stmt, .addr_of_label => {
1114 try w.writeByteNTimes(' ', level + half);
1115 try w.writeAll("label: ");
1116 try config.setColor(w, LITERAL);
1117 try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
1118 try config.setColor(w, .reset);
1119 },
1120 .continue_stmt, .break_stmt, .implicit_return, .null_stmt => {},
1121 .return_stmt => {
1122 if (data.un != .none) {
1123 try w.writeByteNTimes(' ', level + half);
1124 try w.writeAll("expr:\n");
1125 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1126 }
1127 },
1128 .call_expr => {
1129 try w.writeByteNTimes(' ', level + half);
1130 try w.writeAll("lhs:\n");
1131 try tree.dumpNode(tree.data[data.range.start], level + delta, mapper, config, w);
1132
1133 try w.writeByteNTimes(' ', level + half);
1134 try w.writeAll("args:\n");
1135 for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, config, w);
1136 },
1137 .call_expr_one => {
1138 try w.writeByteNTimes(' ', level + half);
1139 try w.writeAll("lhs:\n");
1140 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1141 if (data.bin.rhs != .none) {
1142 try w.writeByteNTimes(' ', level + half);
1143 try w.writeAll("arg:\n");
1144 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1145 }
1146 },
1147 .builtin_call_expr => {
1148 try w.writeByteNTimes(' ', level + half);
1149 try w.writeAll("name: ");
1150 try config.setColor(w, NAME);
1151 try w.print("{s}\n", .{tree.tokSlice(@intFromEnum(tree.data[data.range.start]))});
1152 try config.setColor(w, .reset);
1153
1154 try w.writeByteNTimes(' ', level + half);
1155 try w.writeAll("args:\n");
1156 for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, config, w);
1157 },
1158 .builtin_call_expr_one => {
1159 try w.writeByteNTimes(' ', level + half);
1160 try w.writeAll("name: ");
1161 try config.setColor(w, NAME);
1162 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
1163 try config.setColor(w, .reset);
1164 if (data.decl.node != .none) {
1165 try w.writeByteNTimes(' ', level + half);
1166 try w.writeAll("arg:\n");
1167 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
1168 }
1169 },
1170 .special_builtin_call_one => {
1171 try w.writeByteNTimes(' ', level + half);
1172 try w.writeAll("name: ");
1173 try config.setColor(w, NAME);
1174 try w.print("{s}\n", .{tree.tokSlice(data.decl.name)});
1175 try config.setColor(w, .reset);
1176 if (data.decl.node != .none) {
1177 try w.writeByteNTimes(' ', level + half);
1178 try w.writeAll("arg:\n");
1179 try tree.dumpNode(data.decl.node, level + delta, mapper, config, w);
1180 }
1181 },
1182 .comma_expr,
1183 .assign_expr,
1184 .mul_assign_expr,
1185 .div_assign_expr,
1186 .mod_assign_expr,
1187 .add_assign_expr,
1188 .sub_assign_expr,
1189 .shl_assign_expr,
1190 .shr_assign_expr,
1191 .bit_and_assign_expr,
1192 .bit_xor_assign_expr,
1193 .bit_or_assign_expr,
1194 .bool_or_expr,
1195 .bool_and_expr,
1196 .bit_or_expr,
1197 .bit_xor_expr,
1198 .bit_and_expr,
1199 .equal_expr,
1200 .not_equal_expr,
1201 .less_than_expr,
1202 .less_than_equal_expr,
1203 .greater_than_expr,
1204 .greater_than_equal_expr,
1205 .shl_expr,
1206 .shr_expr,
1207 .add_expr,
1208 .sub_expr,
1209 .mul_expr,
1210 .div_expr,
1211 .mod_expr,
1212 => {
1213 try w.writeByteNTimes(' ', level + 1);
1214 try w.writeAll("lhs:\n");
1215 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1216 try w.writeByteNTimes(' ', level + 1);
1217 try w.writeAll("rhs:\n");
1218 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1219 },
1220 .explicit_cast, .implicit_cast => try tree.dumpNode(data.cast.operand, level + delta, mapper, config, w),
1221 .addr_of_expr,
1222 .computed_goto_stmt,
1223 .deref_expr,
1224 .plus_expr,
1225 .negate_expr,
1226 .bit_not_expr,
1227 .bool_not_expr,
1228 .pre_inc_expr,
1229 .pre_dec_expr,
1230 .imag_expr,
1231 .real_expr,
1232 .post_inc_expr,
1233 .post_dec_expr,
1234 .paren_expr,
1235 => {
1236 try w.writeByteNTimes(' ', level + 1);
1237 try w.writeAll("operand:\n");
1238 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1239 },
1240 .decl_ref_expr => {
1241 try w.writeByteNTimes(' ', level + 1);
1242 try w.writeAll("name: ");
1243 try config.setColor(w, NAME);
1244 try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
1245 try config.setColor(w, .reset);
1246 },
1247 .enumeration_ref => {
1248 try w.writeByteNTimes(' ', level + 1);
1249 try w.writeAll("name: ");
1250 try config.setColor(w, NAME);
1251 try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)});
1252 try config.setColor(w, .reset);
1253 },
1254 .bool_literal,
1255 .nullptr_literal,
1256 .int_literal,
1257 .char_literal,
1258 .float_literal,
1259 .string_literal_expr,
1260 => {},
1261 .member_access_expr, .member_access_ptr_expr => {
1262 try w.writeByteNTimes(' ', level + 1);
1263 try w.writeAll("lhs:\n");
1264 try tree.dumpNode(data.member.lhs, level + delta, mapper, config, w);
1265
1266 var lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
1267 if (lhs_ty.isPtr()) lhs_ty = lhs_ty.elemType();
1268 lhs_ty = lhs_ty.canonicalize(.standard);
1269
1270 try w.writeByteNTimes(' ', level + 1);
1271 try w.writeAll("name: ");
1272 try config.setColor(w, NAME);
1273 try w.print("{s}\n", .{mapper.lookup(lhs_ty.data.record.fields[data.member.index].name)});
1274 try config.setColor(w, .reset);
1275 },
1276 .array_access_expr => {
1277 if (data.bin.lhs != .none) {
1278 try w.writeByteNTimes(' ', level + 1);
1279 try w.writeAll("lhs:\n");
1280 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1281 }
1282 try w.writeByteNTimes(' ', level + 1);
1283 try w.writeAll("index:\n");
1284 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1285 },
1286 .sizeof_expr, .alignof_expr => {
1287 if (data.un != .none) {
1288 try w.writeByteNTimes(' ', level + 1);
1289 try w.writeAll("expr:\n");
1290 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1291 }
1292 },
1293 .generic_expr_one => {
1294 try w.writeByteNTimes(' ', level + 1);
1295 try w.writeAll("controlling:\n");
1296 try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w);
1297 try w.writeByteNTimes(' ', level + 1);
1298 if (data.bin.rhs != .none) {
1299 try w.writeAll("chosen:\n");
1300 try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w);
1301 }
1302 },
1303 .generic_expr => {
1304 const nodes = tree.data[data.range.start..data.range.end];
1305 try w.writeByteNTimes(' ', level + 1);
1306 try w.writeAll("controlling:\n");
1307 try tree.dumpNode(nodes[0], level + delta, mapper, config, w);
1308 try w.writeByteNTimes(' ', level + 1);
1309 try w.writeAll("chosen:\n");
1310 try tree.dumpNode(nodes[1], level + delta, mapper, config, w);
1311 try w.writeByteNTimes(' ', level + 1);
1312 try w.writeAll("rest:\n");
1313 for (nodes[2..]) |expr| {
1314 try tree.dumpNode(expr, level + delta, mapper, config, w);
1315 }
1316 },
1317 .generic_association_expr, .generic_default_expr, .stmt_expr, .imaginary_literal => {
1318 try tree.dumpNode(data.un, level + delta, mapper, config, w);
1319 },
1320 .array_filler_expr => {
1321 try w.writeByteNTimes(' ', level + 1);
1322 try w.writeAll("count: ");
1323 try config.setColor(w, LITERAL);
1324 try w.print("{d}\n", .{data.int});
1325 try config.setColor(w, .reset);
1326 },
1327 .struct_forward_decl,
1328 .union_forward_decl,
1329 .enum_forward_decl,
1330 .default_init_expr,
1331 .cond_dummy_expr,
1332 => {},
1333 }
1334}
lib/compiler/aro/aro/Tree/number_affixes.zig created+187
......@@ -0,0 +1,187 @@
1const std = @import("std");
2const mem = std.mem;
3
4pub const Prefix = enum(u8) {
5 binary = 2,
6 octal = 8,
7 decimal = 10,
8 hex = 16,
9
10 pub fn digitAllowed(prefix: Prefix, c: u8) bool {
11 return switch (c) {
12 '0', '1' => true,
13 '2'...'7' => prefix != .binary,
14 '8'...'9' => prefix == .decimal or prefix == .hex,
15 'a'...'f', 'A'...'F' => prefix == .hex,
16 else => false,
17 };
18 }
19
20 pub fn fromString(buf: []const u8) Prefix {
21 if (buf.len == 1) return .decimal;
22 // tokenizer enforces that first byte is a decimal digit or period
23 switch (buf[0]) {
24 '.', '1'...'9' => return .decimal,
25 '0' => {},
26 else => unreachable,
27 }
28 switch (buf[1]) {
29 'x', 'X' => return if (buf.len == 2) .decimal else .hex,
30 'b', 'B' => return if (buf.len == 2) .decimal else .binary,
31 else => {
32 if (mem.indexOfAny(u8, buf, "eE.")) |_| {
33 // This is a decimal floating point number that happens to start with zero
34 return .decimal;
35 } else if (Suffix.fromString(buf[1..], .int)) |_| {
36 // This is `0` with a valid suffix
37 return .decimal;
38 } else {
39 return .octal;
40 }
41 },
42 }
43 }
44
45 /// Length of this prefix as a string
46 pub fn stringLen(prefix: Prefix) usize {
47 return switch (prefix) {
48 .binary => 2,
49 .octal => 1,
50 .decimal => 0,
51 .hex => 2,
52 };
53 }
54};
55
56pub const Suffix = enum {
57 // zig fmt: off
58
59 // int and imaginary int
60 None, I,
61
62 // unsigned real integers
63 U, UL, ULL,
64
65 // unsigned imaginary integers
66 IU, IUL, IULL,
67
68 // long or long double, real and imaginary
69 L, IL,
70
71 // long long and imaginary long long
72 LL, ILL,
73
74 // float and imaginary float
75 F, IF,
76
77 // _Float16
78 F16,
79
80 // __float80
81 W,
82
83 // Imaginary __float80
84 IW,
85
86 // _Float128
87 Q, F128,
88
89 // Imaginary _Float128
90 IQ, IF128,
91
92 // Imaginary _Bitint
93 IWB, IUWB,
94
95 // _Bitint
96 WB, UWB,
97
98 // zig fmt: on
99
100 const Tuple = struct { Suffix, []const []const u8 };
101
102 const IntSuffixes = &[_]Tuple{
103 .{ .U, &.{"U"} },
104 .{ .L, &.{"L"} },
105 .{ .WB, &.{"WB"} },
106 .{ .UL, &.{ "U", "L" } },
107 .{ .UWB, &.{ "U", "WB" } },
108 .{ .LL, &.{"LL"} },
109 .{ .ULL, &.{ "U", "LL" } },
110
111 .{ .I, &.{"I"} },
112
113 .{ .IWB, &.{ "I", "WB" } },
114 .{ .IU, &.{ "I", "U" } },
115 .{ .IL, &.{ "I", "L" } },
116 .{ .IUL, &.{ "I", "U", "L" } },
117 .{ .IUWB, &.{ "I", "U", "WB" } },
118 .{ .ILL, &.{ "I", "LL" } },
119 .{ .IULL, &.{ "I", "U", "LL" } },
120 };
121
122 const FloatSuffixes = &[_]Tuple{
123 .{ .F16, &.{"F16"} },
124 .{ .F, &.{"F"} },
125 .{ .L, &.{"L"} },
126 .{ .W, &.{"W"} },
127 .{ .F128, &.{"F128"} },
128 .{ .Q, &.{"Q"} },
129
130 .{ .I, &.{"I"} },
131 .{ .IL, &.{ "I", "L" } },
132 .{ .IF, &.{ "I", "F" } },
133 .{ .IW, &.{ "I", "W" } },
134 .{ .IF128, &.{ "I", "F128" } },
135 .{ .IQ, &.{ "I", "Q" } },
136 };
137
138 pub fn fromString(buf: []const u8, suffix_kind: enum { int, float }) ?Suffix {
139 if (buf.len == 0) return .None;
140
141 const suffixes = switch (suffix_kind) {
142 .float => FloatSuffixes,
143 .int => IntSuffixes,
144 };
145 var scratch: [4]u8 = undefined;
146 top: for (suffixes) |candidate| {
147 const tag = candidate[0];
148 const parts = candidate[1];
149 var len: usize = 0;
150 for (parts) |part| len += part.len;
151 if (len != buf.len) continue;
152
153 for (parts) |part| {
154 const lower = std.ascii.lowerString(&scratch, part);
155 if (mem.indexOf(u8, buf, part) == null and mem.indexOf(u8, buf, lower) == null) continue :top;
156 }
157 return tag;
158 }
159 return null;
160 }
161
162 pub fn isImaginary(suffix: Suffix) bool {
163 return switch (suffix) {
164 .I, .IL, .IF, .IU, .IUL, .ILL, .IULL, .IWB, .IUWB, .IF128, .IQ, .IW => true,
165 .None, .L, .F16, .F, .U, .UL, .LL, .ULL, .WB, .UWB, .F128, .Q, .W => false,
166 };
167 }
168
169 pub fn isSignedInteger(suffix: Suffix) bool {
170 return switch (suffix) {
171 .None, .L, .LL, .I, .IL, .ILL, .WB, .IWB => true,
172 .U, .UL, .ULL, .IU, .IUL, .IULL, .UWB, .IUWB => false,
173 .F, .IF, .F16, .F128, .IF128, .Q, .IQ, .W, .IW => unreachable,
174 };
175 }
176
177 pub fn signedness(suffix: Suffix) std.builtin.Signedness {
178 return if (suffix.isSignedInteger()) .signed else .unsigned;
179 }
180
181 pub fn isBitInt(suffix: Suffix) bool {
182 return switch (suffix) {
183 .WB, .UWB, .IWB, .IUWB => true,
184 else => false,
185 };
186 }
187};
lib/compiler/aro/aro/Type.zig created+2670
......@@ -0,0 +1,2670 @@
1const std = @import("std");
2const Tree = @import("Tree.zig");
3const TokenIndex = Tree.TokenIndex;
4const NodeIndex = Tree.NodeIndex;
5const Parser = @import("Parser.zig");
6const Compilation = @import("Compilation.zig");
7const Attribute = @import("Attribute.zig");
8const StringInterner = @import("StringInterner.zig");
9const StringId = StringInterner.StringId;
10const target_util = @import("target.zig");
11const LangOpts = @import("LangOpts.zig");
12
13pub const Qualifiers = packed struct {
14 @"const": bool = false,
15 atomic: bool = false,
16 @"volatile": bool = false,
17 restrict: bool = false,
18
19 // for function parameters only, stored here since it fits in the padding
20 register: bool = false,
21
22 pub fn any(quals: Qualifiers) bool {
23 return quals.@"const" or quals.restrict or quals.@"volatile" or quals.atomic;
24 }
25
26 pub fn dump(quals: Qualifiers, w: anytype) !void {
27 if (quals.@"const") try w.writeAll("const ");
28 if (quals.atomic) try w.writeAll("_Atomic ");
29 if (quals.@"volatile") try w.writeAll("volatile ");
30 if (quals.restrict) try w.writeAll("restrict ");
31 if (quals.register) try w.writeAll("register ");
32 }
33
34 /// Merge the const/volatile qualifiers, used by type resolution
35 /// of the conditional operator
36 pub fn mergeCV(a: Qualifiers, b: Qualifiers) Qualifiers {
37 return .{
38 .@"const" = a.@"const" or b.@"const",
39 .@"volatile" = a.@"volatile" or b.@"volatile",
40 };
41 }
42
43 /// Merge all qualifiers, used by typeof()
44 fn mergeAll(a: Qualifiers, b: Qualifiers) Qualifiers {
45 return .{
46 .@"const" = a.@"const" or b.@"const",
47 .atomic = a.atomic or b.atomic,
48 .@"volatile" = a.@"volatile" or b.@"volatile",
49 .restrict = a.restrict or b.restrict,
50 .register = a.register or b.register,
51 };
52 }
53
54 /// Checks if a has all the qualifiers of b
55 pub fn hasQuals(a: Qualifiers, b: Qualifiers) bool {
56 if (b.@"const" and !a.@"const") return false;
57 if (b.@"volatile" and !a.@"volatile") return false;
58 if (b.atomic and !a.atomic) return false;
59 return true;
60 }
61
62 /// register is a storage class and not actually a qualifier
63 /// so it is not preserved by typeof()
64 pub fn inheritFromTypeof(quals: Qualifiers) Qualifiers {
65 var res = quals;
66 res.register = false;
67 return res;
68 }
69
70 pub const Builder = struct {
71 @"const": ?TokenIndex = null,
72 atomic: ?TokenIndex = null,
73 @"volatile": ?TokenIndex = null,
74 restrict: ?TokenIndex = null,
75
76 pub fn finish(b: Qualifiers.Builder, p: *Parser, ty: *Type) !void {
77 if (ty.specifier != .pointer and b.restrict != null) {
78 try p.errStr(.restrict_non_pointer, b.restrict.?, try p.typeStr(ty.*));
79 }
80 if (b.atomic) |some| {
81 if (ty.isArray()) try p.errStr(.atomic_array, some, try p.typeStr(ty.*));
82 if (ty.isFunc()) try p.errStr(.atomic_func, some, try p.typeStr(ty.*));
83 if (ty.hasIncompleteSize()) try p.errStr(.atomic_incomplete, some, try p.typeStr(ty.*));
84 }
85
86 if (b.@"const" != null) ty.qual.@"const" = true;
87 if (b.atomic != null) ty.qual.atomic = true;
88 if (b.@"volatile" != null) ty.qual.@"volatile" = true;
89 if (b.restrict != null) ty.qual.restrict = true;
90 }
91 };
92};
93
94// TODO improve memory usage
95pub const Func = struct {
96 return_type: Type,
97 params: []Param,
98
99 pub const Param = struct {
100 ty: Type,
101 name: StringId,
102 name_tok: TokenIndex,
103 };
104
105 fn eql(a: *const Func, b: *const Func, a_spec: Specifier, b_spec: Specifier, comp: *const Compilation) bool {
106 // return type cannot have qualifiers
107 if (!a.return_type.eql(b.return_type, comp, false)) return false;
108
109 if (a.params.len != b.params.len) {
110 if (a_spec == .old_style_func or b_spec == .old_style_func) {
111 const maybe_has_params = if (a_spec == .old_style_func) b else a;
112 for (maybe_has_params.params) |param| {
113 if (param.ty.undergoesDefaultArgPromotion(comp)) return false;
114 }
115 return true;
116 }
117 }
118 if ((a_spec == .func) != (b_spec == .func)) return false;
119 // TODO validate this
120 for (a.params, b.params) |param, b_qual| {
121 var a_unqual = param.ty;
122 a_unqual.qual.@"const" = false;
123 a_unqual.qual.@"volatile" = false;
124 var b_unqual = b_qual.ty;
125 b_unqual.qual.@"const" = false;
126 b_unqual.qual.@"volatile" = false;
127 if (!a_unqual.eql(b_unqual, comp, true)) return false;
128 }
129 return true;
130 }
131};
132
133pub const Array = struct {
134 len: u64,
135 elem: Type,
136};
137
138pub const Expr = struct {
139 node: NodeIndex,
140 ty: Type,
141};
142
143pub const Attributed = struct {
144 attributes: []Attribute,
145 base: Type,
146
147 pub fn create(allocator: std.mem.Allocator, base: Type, existing_attributes: []const Attribute, attributes: []const Attribute) !*Attributed {
148 const attributed_type = try allocator.create(Attributed);
149 errdefer allocator.destroy(attributed_type);
150
151 const all_attrs = try allocator.alloc(Attribute, existing_attributes.len + attributes.len);
152 @memcpy(all_attrs[0..existing_attributes.len], existing_attributes);
153 @memcpy(all_attrs[existing_attributes.len..], attributes);
154
155 attributed_type.* = .{
156 .attributes = all_attrs,
157 .base = base,
158 };
159 return attributed_type;
160 }
161};
162
163// TODO improve memory usage
164pub const Enum = struct {
165 fields: []Field,
166 tag_ty: Type,
167 name: StringId,
168 fixed: bool,
169
170 pub const Field = struct {
171 ty: Type,
172 name: StringId,
173 name_tok: TokenIndex,
174 node: NodeIndex,
175 };
176
177 pub fn isIncomplete(e: Enum) bool {
178 return e.fields.len == std.math.maxInt(usize);
179 }
180
181 pub fn create(allocator: std.mem.Allocator, name: StringId, fixed_ty: ?Type) !*Enum {
182 var e = try allocator.create(Enum);
183 e.name = name;
184 e.fields.len = std.math.maxInt(usize);
185 if (fixed_ty) |some| e.tag_ty = some;
186 e.fixed = fixed_ty != null;
187 return e;
188 }
189};
190
191// might not need all 4 of these when finished,
192// but currently it helps having all 4 when diff-ing
193// the rust code.
194pub const TypeLayout = struct {
195 /// The size of the type in bits.
196 ///
197 /// This is the value returned by `sizeof` and C and `std::mem::size_of` in Rust
198 /// (but in bits instead of bytes). This is a multiple of `pointer_alignment_bits`.
199 size_bits: u64,
200 /// The alignment of the type, in bits, when used as a field in a record.
201 ///
202 /// This is usually the value returned by `_Alignof` in C, but there are some edge
203 /// cases in GCC where `_Alignof` returns a smaller value.
204 field_alignment_bits: u32,
205 /// The alignment, in bits, of valid pointers to this type.
206 ///
207 /// This is the value returned by `std::mem::align_of` in Rust
208 /// (but in bits instead of bytes). `size_bits` is a multiple of this value.
209 pointer_alignment_bits: u32,
210 /// The required alignment of the type in bits.
211 ///
212 /// This value is only used by MSVC targets. It is 8 on all other
213 /// targets. On MSVC targets, this value restricts the effects of `#pragma pack` except
214 /// in some cases involving bit-fields.
215 required_alignment_bits: u32,
216};
217
218pub const FieldLayout = struct {
219 /// `offset_bits` and `size_bits` should both be INVALID if and only if the field
220 /// is an unnamed bitfield. There is no way to reference an unnamed bitfield in C, so
221 /// there should be no way to observe these values. If it is used, this value will
222 /// maximize the chance that a safety-checked overflow will occur.
223 const INVALID = std.math.maxInt(u64);
224
225 /// The offset of the field, in bits, from the start of the struct.
226 offset_bits: u64 = INVALID,
227 /// The size, in bits, of the field.
228 ///
229 /// For bit-fields, this is the width of the field.
230 size_bits: u64 = INVALID,
231
232 pub fn isUnnamed(self: FieldLayout) bool {
233 return self.offset_bits == INVALID and self.size_bits == INVALID;
234 }
235};
236
237// TODO improve memory usage
238pub const Record = struct {
239 fields: []Field,
240 type_layout: TypeLayout,
241 /// If this is null, none of the fields have attributes
242 /// Otherwise, it's a pointer to N items (where N == number of fields)
243 /// and the item at index i is the attributes for the field at index i
244 field_attributes: ?[*][]const Attribute,
245 name: StringId,
246
247 pub const Field = struct {
248 ty: Type,
249 name: StringId,
250 /// zero for anonymous fields
251 name_tok: TokenIndex = 0,
252 bit_width: ?u32 = null,
253 layout: FieldLayout = .{
254 .offset_bits = 0,
255 .size_bits = 0,
256 },
257
258 pub fn isNamed(f: *const Field) bool {
259 return f.name_tok != 0;
260 }
261
262 pub fn isAnonymousRecord(f: Field) bool {
263 return !f.isNamed() and f.ty.isRecord();
264 }
265
266 /// false for bitfields
267 pub fn isRegularField(f: *const Field) bool {
268 return f.bit_width == null;
269 }
270
271 /// bit width as specified in the C source. Asserts that `f` is a bitfield.
272 pub fn specifiedBitWidth(f: *const Field) u32 {
273 return f.bit_width.?;
274 }
275 };
276
277 pub fn isIncomplete(r: Record) bool {
278 return r.fields.len == std.math.maxInt(usize);
279 }
280
281 pub fn create(allocator: std.mem.Allocator, name: StringId) !*Record {
282 var r = try allocator.create(Record);
283 r.name = name;
284 r.fields.len = std.math.maxInt(usize);
285 r.field_attributes = null;
286 r.type_layout = .{
287 .size_bits = 8,
288 .field_alignment_bits = 8,
289 .pointer_alignment_bits = 8,
290 .required_alignment_bits = 8,
291 };
292 return r;
293 }
294
295 pub fn hasFieldOfType(self: *const Record, ty: Type, comp: *const Compilation) bool {
296 if (self.isIncomplete()) return false;
297 for (self.fields) |f| {
298 if (ty.eql(f.ty, comp, false)) return true;
299 }
300 return false;
301 }
302};
303
304pub const Specifier = enum {
305 /// A NaN-like poison value
306 invalid,
307
308 /// GNU auto type
309 /// This is a placeholder specifier - it must be replaced by the actual type specifier (determined by the initializer)
310 auto_type,
311 /// C23 auto, behaves like auto_type
312 c23_auto,
313
314 void,
315 bool,
316
317 // integers
318 char,
319 schar,
320 uchar,
321 short,
322 ushort,
323 int,
324 uint,
325 long,
326 ulong,
327 long_long,
328 ulong_long,
329 int128,
330 uint128,
331 complex_char,
332 complex_schar,
333 complex_uchar,
334 complex_short,
335 complex_ushort,
336 complex_int,
337 complex_uint,
338 complex_long,
339 complex_ulong,
340 complex_long_long,
341 complex_ulong_long,
342 complex_int128,
343 complex_uint128,
344
345 // data.int
346 bit_int,
347 complex_bit_int,
348
349 // floating point numbers
350 fp16,
351 float16,
352 float,
353 double,
354 long_double,
355 float80,
356 float128,
357 complex_float,
358 complex_double,
359 complex_long_double,
360 complex_float80,
361 complex_float128,
362
363 // data.sub_type
364 pointer,
365 unspecified_variable_len_array,
366 // data.func
367 /// int foo(int bar, char baz) and int (void)
368 func,
369 /// int foo(int bar, char baz, ...)
370 var_args_func,
371 /// int foo(bar, baz) and int foo()
372 /// is also var args, but we can give warnings about incorrect amounts of parameters
373 old_style_func,
374
375 // data.array
376 array,
377 static_array,
378 incomplete_array,
379 vector,
380 // data.expr
381 variable_len_array,
382
383 // data.record
384 @"struct",
385 @"union",
386
387 // data.enum
388 @"enum",
389
390 /// typeof(type-name)
391 typeof_type,
392
393 /// typeof(expression)
394 typeof_expr,
395
396 /// data.attributed
397 attributed,
398
399 /// C23 nullptr_t
400 nullptr_t,
401};
402
403const Type = @This();
404
405/// All fields of Type except data may be mutated
406data: union {
407 sub_type: *Type,
408 func: *Func,
409 array: *Array,
410 expr: *Expr,
411 @"enum": *Enum,
412 record: *Record,
413 attributed: *Attributed,
414 none: void,
415 int: struct {
416 bits: u16,
417 signedness: std.builtin.Signedness,
418 },
419} = .{ .none = {} },
420specifier: Specifier,
421qual: Qualifiers = .{},
422decayed: bool = false,
423
424pub const int = Type{ .specifier = .int };
425pub const invalid = Type{ .specifier = .invalid };
426
427/// Determine if type matches the given specifier, recursing into typeof
428/// types if necessary.
429pub fn is(ty: Type, specifier: Specifier) bool {
430 std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
431 return ty.get(specifier) != null;
432}
433
434pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type {
435 if (attributes.len == 0) return self;
436 const attributed_type = try Type.Attributed.create(allocator, self, self.getAttributes(), attributes);
437 return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type }, .decayed = self.decayed };
438}
439
440pub fn isCallable(ty: Type) ?Type {
441 return switch (ty.specifier) {
442 .func, .var_args_func, .old_style_func => ty,
443 .pointer => if (ty.data.sub_type.isFunc()) ty.data.sub_type.* else null,
444 .typeof_type => ty.data.sub_type.isCallable(),
445 .typeof_expr => ty.data.expr.ty.isCallable(),
446 .attributed => ty.data.attributed.base.isCallable(),
447 else => null,
448 };
449}
450
451pub fn isFunc(ty: Type) bool {
452 return switch (ty.specifier) {
453 .func, .var_args_func, .old_style_func => true,
454 .typeof_type => ty.data.sub_type.isFunc(),
455 .typeof_expr => ty.data.expr.ty.isFunc(),
456 .attributed => ty.data.attributed.base.isFunc(),
457 else => false,
458 };
459}
460
461pub fn isArray(ty: Type) bool {
462 return switch (ty.specifier) {
463 .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => !ty.isDecayed(),
464 .typeof_type => !ty.isDecayed() and ty.data.sub_type.isArray(),
465 .typeof_expr => !ty.isDecayed() and ty.data.expr.ty.isArray(),
466 .attributed => !ty.isDecayed() and ty.data.attributed.base.isArray(),
467 else => false,
468 };
469}
470
471/// Whether the type is promoted if used as a variadic argument or as an argument to a function with no prototype
472fn undergoesDefaultArgPromotion(ty: Type, comp: *const Compilation) bool {
473 return switch (ty.specifier) {
474 .bool => true,
475 .char, .uchar, .schar => true,
476 .short, .ushort => true,
477 .@"enum" => if (comp.langopts.emulate == .clang) ty.data.@"enum".isIncomplete() else false,
478 .float => true,
479
480 .typeof_type => ty.data.sub_type.undergoesDefaultArgPromotion(comp),
481 .typeof_expr => ty.data.expr.ty.undergoesDefaultArgPromotion(comp),
482 .attributed => ty.data.attributed.base.undergoesDefaultArgPromotion(comp),
483 else => false,
484 };
485}
486
487pub fn isScalar(ty: Type) bool {
488 return ty.isInt() or ty.isScalarNonInt();
489}
490
491/// To avoid calling isInt() twice for allowable loop/if controlling expressions
492pub fn isScalarNonInt(ty: Type) bool {
493 return ty.isFloat() or ty.isPtr() or ty.is(.nullptr_t);
494}
495
496pub fn isDecayed(ty: Type) bool {
497 return ty.decayed;
498}
499
500pub fn isPtr(ty: Type) bool {
501 return switch (ty.specifier) {
502 .pointer => true,
503
504 .array,
505 .static_array,
506 .incomplete_array,
507 .variable_len_array,
508 .unspecified_variable_len_array,
509 => ty.isDecayed(),
510 .typeof_type => ty.isDecayed() or ty.data.sub_type.isPtr(),
511 .typeof_expr => ty.isDecayed() or ty.data.expr.ty.isPtr(),
512 .attributed => ty.isDecayed() or ty.data.attributed.base.isPtr(),
513 else => false,
514 };
515}
516
517pub fn isInt(ty: Type) bool {
518 return switch (ty.specifier) {
519 // zig fmt: off
520 .@"enum", .bool, .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong,
521 .long_long, .ulong_long, .int128, .uint128, .complex_char, .complex_schar, .complex_uchar,
522 .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
523 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
524 .bit_int, .complex_bit_int => true,
525 // zig fmt: on
526 .typeof_type => ty.data.sub_type.isInt(),
527 .typeof_expr => ty.data.expr.ty.isInt(),
528 .attributed => ty.data.attributed.base.isInt(),
529 else => false,
530 };
531}
532
533pub fn isFloat(ty: Type) bool {
534 return switch (ty.specifier) {
535 // zig fmt: off
536 .float, .double, .long_double, .complex_float, .complex_double, .complex_long_double,
537 .fp16, .float16, .float80, .float128, .complex_float80, .complex_float128 => true,
538 // zig fmt: on
539 .typeof_type => ty.data.sub_type.isFloat(),
540 .typeof_expr => ty.data.expr.ty.isFloat(),
541 .attributed => ty.data.attributed.base.isFloat(),
542 else => false,
543 };
544}
545
546pub fn isReal(ty: Type) bool {
547 return switch (ty.specifier) {
548 // zig fmt: off
549 .complex_float, .complex_double, .complex_long_double, .complex_float80,
550 .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
551 .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
552 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
553 .complex_bit_int => false,
554 // zig fmt: on
555 .typeof_type => ty.data.sub_type.isReal(),
556 .typeof_expr => ty.data.expr.ty.isReal(),
557 .attributed => ty.data.attributed.base.isReal(),
558 else => true,
559 };
560}
561
562pub fn isComplex(ty: Type) bool {
563 return switch (ty.specifier) {
564 // zig fmt: off
565 .complex_float, .complex_double, .complex_long_double, .complex_float80,
566 .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
567 .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
568 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
569 .complex_bit_int => true,
570 // zig fmt: on
571 .typeof_type => ty.data.sub_type.isComplex(),
572 .typeof_expr => ty.data.expr.ty.isComplex(),
573 .attributed => ty.data.attributed.base.isComplex(),
574 else => false,
575 };
576}
577
578pub fn isVoidStar(ty: Type) bool {
579 return switch (ty.specifier) {
580 .pointer => ty.data.sub_type.specifier == .void,
581 .typeof_type => ty.data.sub_type.isVoidStar(),
582 .typeof_expr => ty.data.expr.ty.isVoidStar(),
583 .attributed => ty.data.attributed.base.isVoidStar(),
584 else => false,
585 };
586}
587
588pub fn isTypeof(ty: Type) bool {
589 return switch (ty.specifier) {
590 .typeof_type, .typeof_expr => true,
591 else => false,
592 };
593}
594
595pub fn isConst(ty: Type) bool {
596 return switch (ty.specifier) {
597 .typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(),
598 .typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(),
599 .attributed => ty.data.attributed.base.isConst(),
600 else => ty.qual.@"const",
601 };
602}
603
604pub fn isUnsignedInt(ty: Type, comp: *const Compilation) bool {
605 return ty.signedness(comp) == .unsigned;
606}
607
608pub fn signedness(ty: Type, comp: *const Compilation) std.builtin.Signedness {
609 return switch (ty.specifier) {
610 // zig fmt: off
611 .char, .complex_char => return comp.getCharSignedness(),
612 .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128, .bool, .complex_uchar, .complex_ushort,
613 .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => .unsigned,
614 // zig fmt: on
615 .bit_int, .complex_bit_int => ty.data.int.signedness,
616 .typeof_type => ty.data.sub_type.signedness(comp),
617 .typeof_expr => ty.data.expr.ty.signedness(comp),
618 .attributed => ty.data.attributed.base.signedness(comp),
619 else => .signed,
620 };
621}
622
623pub fn isEnumOrRecord(ty: Type) bool {
624 return switch (ty.specifier) {
625 .@"enum", .@"struct", .@"union" => true,
626 .typeof_type => ty.data.sub_type.isEnumOrRecord(),
627 .typeof_expr => ty.data.expr.ty.isEnumOrRecord(),
628 .attributed => ty.data.attributed.base.isEnumOrRecord(),
629 else => false,
630 };
631}
632
633pub fn isRecord(ty: Type) bool {
634 return switch (ty.specifier) {
635 .@"struct", .@"union" => true,
636 .typeof_type => ty.data.sub_type.isRecord(),
637 .typeof_expr => ty.data.expr.ty.isRecord(),
638 .attributed => ty.data.attributed.base.isRecord(),
639 else => false,
640 };
641}
642
643pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool {
644 return switch (ty.specifier) {
645 // anonymous records can be recognized by their names which are in
646 // the format "(anonymous TAG at path:line:col)".
647 .@"struct", .@"union" => {
648 const mapper = comp.string_interner.getSlowTypeMapper();
649 return mapper.lookup(ty.data.record.name)[0] == '(';
650 },
651 .typeof_type => ty.data.sub_type.isAnonymousRecord(comp),
652 .typeof_expr => ty.data.expr.ty.isAnonymousRecord(comp),
653 .attributed => ty.data.attributed.base.isAnonymousRecord(comp),
654 else => false,
655 };
656}
657
658pub fn elemType(ty: Type) Type {
659 return switch (ty.specifier) {
660 .pointer, .unspecified_variable_len_array => ty.data.sub_type.*,
661 .array, .static_array, .incomplete_array, .vector => ty.data.array.elem,
662 .variable_len_array => ty.data.expr.ty,
663 .typeof_type, .typeof_expr => {
664 const unwrapped = ty.canonicalize(.preserve_quals);
665 var elem = unwrapped.elemType();
666 elem.qual = elem.qual.mergeAll(unwrapped.qual);
667 return elem;
668 },
669 .attributed => ty.data.attributed.base.elemType(),
670 .invalid => Type.invalid,
671 // zig fmt: off
672 .complex_float, .complex_double, .complex_long_double, .complex_float80,
673 .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short,
674 .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong,
675 .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128,
676 .complex_bit_int => ty.makeReal(),
677 // zig fmt: on
678 else => unreachable,
679 };
680}
681
682pub fn returnType(ty: Type) Type {
683 return switch (ty.specifier) {
684 .func, .var_args_func, .old_style_func => ty.data.func.return_type,
685 .typeof_type => ty.data.sub_type.returnType(),
686 .typeof_expr => ty.data.expr.ty.returnType(),
687 .attributed => ty.data.attributed.base.returnType(),
688 .invalid => Type.invalid,
689 else => unreachable,
690 };
691}
692
693pub fn params(ty: Type) []Func.Param {
694 return switch (ty.specifier) {
695 .func, .var_args_func, .old_style_func => ty.data.func.params,
696 .typeof_type => ty.data.sub_type.params(),
697 .typeof_expr => ty.data.expr.ty.params(),
698 .attributed => ty.data.attributed.base.params(),
699 .invalid => &.{},
700 else => unreachable,
701 };
702}
703
704pub fn arrayLen(ty: Type) ?u64 {
705 return switch (ty.specifier) {
706 .array, .static_array => ty.data.array.len,
707 .typeof_type => ty.data.sub_type.arrayLen(),
708 .typeof_expr => ty.data.expr.ty.arrayLen(),
709 .attributed => ty.data.attributed.base.arrayLen(),
710 else => null,
711 };
712}
713
714/// Complex numbers are scalars but they can be initialized with a 2-element initList
715pub fn expectedInitListSize(ty: Type) ?u64 {
716 return if (ty.isComplex()) 2 else ty.arrayLen();
717}
718
719pub fn anyQual(ty: Type) bool {
720 return switch (ty.specifier) {
721 .typeof_type => ty.qual.any() or ty.data.sub_type.anyQual(),
722 .typeof_expr => ty.qual.any() or ty.data.expr.ty.anyQual(),
723 else => ty.qual.any(),
724 };
725}
726
727pub fn getAttributes(ty: Type) []const Attribute {
728 return switch (ty.specifier) {
729 .attributed => ty.data.attributed.attributes,
730 .typeof_type => ty.data.sub_type.getAttributes(),
731 .typeof_expr => ty.data.expr.ty.getAttributes(),
732 else => &.{},
733 };
734}
735
736pub fn getRecord(ty: Type) ?*const Type.Record {
737 return switch (ty.specifier) {
738 .attributed => ty.data.attributed.base.getRecord(),
739 .typeof_type => ty.data.sub_type.getRecord(),
740 .typeof_expr => ty.data.expr.ty.getRecord(),
741 .@"struct", .@"union" => ty.data.record,
742 else => null,
743 };
744}
745
746pub fn compareIntegerRanks(a: Type, b: Type, comp: *const Compilation) std.math.Order {
747 std.debug.assert(a.isInt() and b.isInt());
748 if (a.eql(b, comp, false)) return .eq;
749
750 const a_unsigned = a.isUnsignedInt(comp);
751 const b_unsigned = b.isUnsignedInt(comp);
752
753 const a_rank = a.integerRank(comp);
754 const b_rank = b.integerRank(comp);
755 if (a_unsigned == b_unsigned) {
756 return std.math.order(a_rank, b_rank);
757 }
758 if (a_unsigned) {
759 if (a_rank >= b_rank) return .gt;
760 return .lt;
761 }
762 std.debug.assert(b_unsigned);
763 if (b_rank >= a_rank) return .lt;
764 return .gt;
765}
766
767fn realIntegerConversion(a: Type, b: Type, comp: *const Compilation) Type {
768 std.debug.assert(a.isReal() and b.isReal());
769 const type_order = a.compareIntegerRanks(b, comp);
770 const a_signed = !a.isUnsignedInt(comp);
771 const b_signed = !b.isUnsignedInt(comp);
772 if (a_signed == b_signed) {
773 // If both have the same sign, use higher-rank type.
774 return switch (type_order) {
775 .lt => b,
776 .eq, .gt => a,
777 };
778 } else if (type_order != if (a_signed) std.math.Order.gt else std.math.Order.lt) {
779 // Only one is signed; and the unsigned type has rank >= the signed type
780 // Use the unsigned type
781 return if (b_signed) a else b;
782 } else if (a.bitSizeof(comp).? != b.bitSizeof(comp).?) {
783 // Signed type is higher rank and sizes are not equal
784 // Use the signed type
785 return if (a_signed) a else b;
786 } else {
787 // Signed type is higher rank but same size as unsigned type
788 // e.g. `long` and `unsigned` on x86-linux-gnu
789 // Use unsigned version of the signed type
790 return if (a_signed) a.makeIntegerUnsigned() else b.makeIntegerUnsigned();
791 }
792}
793
794pub fn makeIntegerUnsigned(ty: Type) Type {
795 // TODO discards attributed/typeof
796 var base = ty.canonicalize(.standard);
797 switch (base.specifier) {
798 // zig fmt: off
799 .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128,
800 .complex_uchar, .complex_ushort, .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128,
801 => return ty,
802 // zig fmt: on
803
804 .char, .complex_char => {
805 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 2);
806 return base;
807 },
808
809 // zig fmt: off
810 .schar, .short, .int, .long, .long_long, .int128,
811 .complex_schar, .complex_short, .complex_int, .complex_long, .complex_long_long, .complex_int128 => {
812 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 1);
813 return base;
814 },
815 // zig fmt: on
816
817 .bit_int, .complex_bit_int => {
818 base.data.int.signedness = .unsigned;
819 return base;
820 },
821 else => unreachable,
822 }
823}
824
825/// Find the common type of a and b for binary operations
826pub fn integerConversion(a: Type, b: Type, comp: *const Compilation) Type {
827 const a_real = a.isReal();
828 const b_real = b.isReal();
829 const target_ty = a.makeReal().realIntegerConversion(b.makeReal(), comp);
830 return if (a_real and b_real) target_ty else target_ty.makeComplex();
831}
832
833pub fn integerPromotion(ty: Type, comp: *Compilation) Type {
834 var specifier = ty.specifier;
835 switch (specifier) {
836 .@"enum" => {
837 if (ty.hasIncompleteSize()) return .{ .specifier = .int };
838 specifier = ty.data.@"enum".tag_ty.specifier;
839 },
840 .bit_int, .complex_bit_int => return .{ .specifier = specifier, .data = ty.data },
841 else => {},
842 }
843 return switch (specifier) {
844 else => .{
845 .specifier = switch (specifier) {
846 // zig fmt: off
847 .bool, .char, .schar, .uchar, .short => .int,
848 .ushort => if (ty.sizeof(comp).? == sizeof(.{ .specifier = .int }, comp)) Specifier.uint else .int,
849 .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128, .complex_char,
850 .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
851 .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
852 .complex_int128, .complex_uint128 => specifier,
853 // zig fmt: on
854 .typeof_type => return ty.data.sub_type.integerPromotion(comp),
855 .typeof_expr => return ty.data.expr.ty.integerPromotion(comp),
856 .attributed => return ty.data.attributed.base.integerPromotion(comp),
857 .invalid => .invalid,
858 else => unreachable, // _BitInt, or not an integer type
859 },
860 },
861 };
862}
863
864/// Promote a bitfield. If `int` can hold all the values of the underlying field,
865/// promote to int. Otherwise, promote to unsigned int
866/// Returns null if no promotion is necessary
867pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type {
868 const type_size_bits = ty.bitSizeof(comp).?;
869
870 // Note: GCC and clang will promote `long: 3` to int even though the C standard does not allow this
871 if (width < type_size_bits) {
872 return int;
873 }
874
875 if (width == type_size_bits) {
876 return if (ty.isUnsignedInt(comp)) .{ .specifier = .uint } else int;
877 }
878
879 return null;
880}
881
882pub fn hasIncompleteSize(ty: Type) bool {
883 if (ty.isDecayed()) return false;
884 return switch (ty.specifier) {
885 .void, .incomplete_array => true,
886 .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed,
887 .@"struct", .@"union" => ty.data.record.isIncomplete(),
888 .array, .static_array => ty.data.array.elem.hasIncompleteSize(),
889 .typeof_type => ty.data.sub_type.hasIncompleteSize(),
890 .typeof_expr => ty.data.expr.ty.hasIncompleteSize(),
891 .attributed => ty.data.attributed.base.hasIncompleteSize(),
892 else => false,
893 };
894}
895
896pub fn hasUnboundVLA(ty: Type) bool {
897 var cur = ty;
898 while (true) {
899 switch (cur.specifier) {
900 .unspecified_variable_len_array => return true,
901 .array,
902 .static_array,
903 .incomplete_array,
904 .variable_len_array,
905 => cur = cur.elemType(),
906 .typeof_type => cur = cur.data.sub_type.*,
907 .typeof_expr => cur = cur.data.expr.ty,
908 .attributed => cur = cur.data.attributed.base,
909 else => return false,
910 }
911 }
912}
913
914pub fn hasField(ty: Type, name: StringId) bool {
915 switch (ty.specifier) {
916 .@"struct" => {
917 std.debug.assert(!ty.data.record.isIncomplete());
918 for (ty.data.record.fields) |f| {
919 if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
920 if (name == f.name) return true;
921 }
922 },
923 .@"union" => {
924 std.debug.assert(!ty.data.record.isIncomplete());
925 for (ty.data.record.fields) |f| {
926 if (f.isAnonymousRecord() and f.ty.hasField(name)) return true;
927 if (name == f.name) return true;
928 }
929 },
930 .typeof_type => return ty.data.sub_type.hasField(name),
931 .typeof_expr => return ty.data.expr.ty.hasField(name),
932 .attributed => return ty.data.attributed.base.hasField(name),
933 .invalid => return false,
934 else => unreachable,
935 }
936 return false;
937}
938
939// TODO handle bitints
940pub fn minInt(ty: Type, comp: *const Compilation) i64 {
941 std.debug.assert(ty.isInt());
942 if (ty.isUnsignedInt(comp)) return 0;
943 return switch (ty.sizeof(comp).?) {
944 1 => std.math.minInt(i8),
945 2 => std.math.minInt(i16),
946 4 => std.math.minInt(i32),
947 8 => std.math.minInt(i64),
948 else => unreachable,
949 };
950}
951
952// TODO handle bitints
953pub fn maxInt(ty: Type, comp: *const Compilation) u64 {
954 std.debug.assert(ty.isInt());
955 return switch (ty.sizeof(comp).?) {
956 1 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u8)) else std.math.maxInt(i8),
957 2 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u16)) else std.math.maxInt(i16),
958 4 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u32)) else std.math.maxInt(i32),
959 8 => if (ty.isUnsignedInt(comp)) @as(u64, std.math.maxInt(u64)) else std.math.maxInt(i64),
960 else => unreachable,
961 };
962}
963
964const TypeSizeOrder = enum {
965 lt,
966 gt,
967 eq,
968 indeterminate,
969};
970
971pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder {
972 const a_size = a.sizeof(comp) orelse return .indeterminate;
973 const b_size = b.sizeof(comp) orelse return .indeterminate;
974 return switch (std.math.order(a_size, b_size)) {
975 .lt => .lt,
976 .gt => .gt,
977 .eq => .eq,
978 };
979}
980
981/// Size of type as reported by sizeof
982pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
983 if (ty.isPtr()) return comp.target.ptrBitWidth() / 8;
984
985 return switch (ty.specifier) {
986 .auto_type, .c23_auto => unreachable,
987 .variable_len_array, .unspecified_variable_len_array => null,
988 .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null,
989 .func, .var_args_func, .old_style_func, .void, .bool => 1,
990 .char, .schar, .uchar => 1,
991 .short => comp.target.c_type_byte_size(.short),
992 .ushort => comp.target.c_type_byte_size(.ushort),
993 .int => comp.target.c_type_byte_size(.int),
994 .uint => comp.target.c_type_byte_size(.uint),
995 .long => comp.target.c_type_byte_size(.long),
996 .ulong => comp.target.c_type_byte_size(.ulong),
997 .long_long => comp.target.c_type_byte_size(.longlong),
998 .ulong_long => comp.target.c_type_byte_size(.ulonglong),
999 .long_double => comp.target.c_type_byte_size(.longdouble),
1000 .int128, .uint128 => 16,
1001 .fp16, .float16 => 2,
1002 .float => comp.target.c_type_byte_size(.float),
1003 .double => comp.target.c_type_byte_size(.double),
1004 .float80 => 16,
1005 .float128 => 16,
1006 .bit_int => {
1007 return std.mem.alignForward(u64, (ty.data.int.bits + 7) / 8, ty.alignof(comp));
1008 },
1009 // zig fmt: off
1010 .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
1011 .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
1012 .complex_int128, .complex_uint128, .complex_float, .complex_double,
1013 .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
1014 => return 2 * ty.makeReal().sizeof(comp).?,
1015 // zig fmt: on
1016 .pointer => unreachable,
1017 .static_array,
1018 .nullptr_t,
1019 => comp.target.ptrBitWidth() / 8,
1020 .array, .vector => {
1021 const size = ty.data.array.elem.sizeof(comp) orelse return null;
1022 const arr_size = size * ty.data.array.len;
1023 if (comp.langopts.emulate == .msvc) {
1024 // msvc ignores array type alignment.
1025 // Since the size might not be a multiple of the field
1026 // alignment, the address of the second element might not be properly aligned
1027 // for the field alignment. A flexible array has size 0. See test case 0018.
1028 return arr_size;
1029 } else {
1030 return std.mem.alignForward(u64, arr_size, ty.alignof(comp));
1031 }
1032 },
1033 .@"struct", .@"union" => if (ty.data.record.isIncomplete()) null else @as(u64, ty.data.record.type_layout.size_bits / 8),
1034 .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) null else ty.data.@"enum".tag_ty.sizeof(comp),
1035 .typeof_type => ty.data.sub_type.sizeof(comp),
1036 .typeof_expr => ty.data.expr.ty.sizeof(comp),
1037 .attributed => ty.data.attributed.base.sizeof(comp),
1038 .invalid => return null,
1039 };
1040}
1041
1042pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {
1043 return switch (ty.specifier) {
1044 .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1,
1045 .typeof_type => ty.data.sub_type.bitSizeof(comp),
1046 .typeof_expr => ty.data.expr.ty.bitSizeof(comp),
1047 .attributed => ty.data.attributed.base.bitSizeof(comp),
1048 .bit_int => return ty.data.int.bits,
1049 .long_double => comp.target.c_type_bit_size(.longdouble),
1050 .float80 => return 80,
1051 else => 8 * (ty.sizeof(comp) orelse return null),
1052 };
1053}
1054
1055pub fn alignable(ty: Type) bool {
1056 return ty.isArray() or !ty.hasIncompleteSize() or ty.is(.void);
1057}
1058
1059/// Get the alignment of a type
1060pub fn alignof(ty: Type, comp: *const Compilation) u29 {
1061 // don't return the attribute for records
1062 // layout has already accounted for requested alignment
1063 if (ty.requestedAlignment(comp)) |requested| {
1064 // gcc does not respect alignment on enums
1065 if (ty.get(.@"enum")) |ty_enum| {
1066 if (comp.langopts.emulate == .gcc) {
1067 return ty_enum.alignof(comp);
1068 }
1069 } else if (ty.getRecord()) |rec| {
1070 if (ty.hasIncompleteSize()) return 0;
1071 const computed: u29 = @intCast(@divExact(rec.type_layout.field_alignment_bits, 8));
1072 return @max(requested, computed);
1073 } else if (comp.langopts.emulate == .msvc) {
1074 const type_align = ty.data.attributed.base.alignof(comp);
1075 return @max(requested, type_align);
1076 }
1077 return requested;
1078 }
1079
1080 return switch (ty.specifier) {
1081 .invalid => unreachable,
1082 .auto_type, .c23_auto => unreachable,
1083
1084 .variable_len_array,
1085 .incomplete_array,
1086 .unspecified_variable_len_array,
1087 .array,
1088 .vector,
1089 => if (ty.isPtr()) switch (comp.target.cpu.arch) {
1090 .avr => 1,
1091 else => comp.target.ptrBitWidth() / 8,
1092 } else ty.elemType().alignof(comp),
1093 .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target),
1094 .char, .schar, .uchar, .void, .bool => 1,
1095
1096 // zig fmt: off
1097 .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int,
1098 .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long,
1099 .complex_int128, .complex_uint128, .complex_float, .complex_double,
1100 .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
1101 => return ty.makeReal().alignof(comp),
1102 // zig fmt: on
1103
1104 .short => comp.target.c_type_alignment(.short),
1105 .ushort => comp.target.c_type_alignment(.ushort),
1106 .int => comp.target.c_type_alignment(.int),
1107 .uint => comp.target.c_type_alignment(.uint),
1108
1109 .long => comp.target.c_type_alignment(.long),
1110 .ulong => comp.target.c_type_alignment(.ulong),
1111 .long_long => comp.target.c_type_alignment(.longlong),
1112 .ulong_long => comp.target.c_type_alignment(.ulonglong),
1113
1114 .bit_int => @min(
1115 std.math.ceilPowerOfTwoPromote(u16, (ty.data.int.bits + 7) / 8),
1116 comp.target.maxIntAlignment(),
1117 ),
1118
1119 .float => comp.target.c_type_alignment(.float),
1120 .double => comp.target.c_type_alignment(.double),
1121 .long_double => comp.target.c_type_alignment(.longdouble),
1122
1123 .int128, .uint128 => if (comp.target.cpu.arch == .s390x and comp.target.os.tag == .linux and comp.target.isGnu()) 8 else 16,
1124 .fp16, .float16 => 2,
1125
1126 .float80, .float128 => 16,
1127 .pointer,
1128 .static_array,
1129 .nullptr_t,
1130 => switch (comp.target.cpu.arch) {
1131 .avr => 1,
1132 else => comp.target.ptrBitWidth() / 8,
1133 },
1134 .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8),
1135 .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp),
1136 .typeof_type => ty.data.sub_type.alignof(comp),
1137 .typeof_expr => ty.data.expr.ty.alignof(comp),
1138 .attributed => ty.data.attributed.base.alignof(comp),
1139 };
1140}
1141
1142/// Canonicalize a possibly-typeof() type. If the type is not a typeof() type, simply
1143/// return it. Otherwise, determine the actual qualified type.
1144/// The `qual_handling` parameter can be used to return the full set of qualifiers
1145/// added by typeof() operations, which is useful when determining the elemType of
1146/// arrays and pointers.
1147pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {
1148 var cur = ty;
1149 if (cur.specifier == .attributed) {
1150 cur = cur.data.attributed.base;
1151 cur.decayed = ty.decayed;
1152 }
1153 if (!cur.isTypeof()) return cur;
1154
1155 var qual = cur.qual;
1156 while (true) {
1157 switch (cur.specifier) {
1158 .typeof_type => cur = cur.data.sub_type.*,
1159 .typeof_expr => cur = cur.data.expr.ty,
1160 else => break,
1161 }
1162 qual = qual.mergeAll(cur.qual);
1163 }
1164 if ((cur.isArray() or cur.isPtr()) and qual_handling == .standard) {
1165 cur.qual = .{};
1166 } else {
1167 cur.qual = qual;
1168 }
1169 cur.decayed = ty.decayed;
1170 return cur;
1171}
1172
1173pub fn get(ty: *const Type, specifier: Specifier) ?*const Type {
1174 std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr);
1175 return switch (ty.specifier) {
1176 .typeof_type => ty.data.sub_type.get(specifier),
1177 .typeof_expr => ty.data.expr.ty.get(specifier),
1178 .attributed => ty.data.attributed.base.get(specifier),
1179 else => if (ty.specifier == specifier) ty else null,
1180 };
1181}
1182
1183pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 {
1184 return switch (ty.specifier) {
1185 .typeof_type => ty.data.sub_type.requestedAlignment(comp),
1186 .typeof_expr => ty.data.expr.ty.requestedAlignment(comp),
1187 .attributed => annotationAlignment(comp, ty.data.attributed.attributes),
1188 else => null,
1189 };
1190}
1191
1192pub fn enumIsPacked(ty: Type, comp: *const Compilation) bool {
1193 std.debug.assert(ty.is(.@"enum"));
1194 return comp.langopts.short_enums or target_util.packAllEnums(comp.target) or ty.hasAttribute(.@"packed");
1195}
1196
1197pub fn annotationAlignment(comp: *const Compilation, attrs: ?[]const Attribute) ?u29 {
1198 const a = attrs orelse return null;
1199
1200 var max_requested: ?u29 = null;
1201 for (a) |attribute| {
1202 if (attribute.tag != .aligned) continue;
1203 const requested = if (attribute.args.aligned.alignment) |alignment| alignment.requested else target_util.defaultAlignment(comp.target);
1204 if (max_requested == null or max_requested.? < requested) {
1205 max_requested = requested;
1206 }
1207 }
1208 return max_requested;
1209}
1210
1211pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifiers: bool) bool {
1212 const a = a_param.canonicalize(.standard);
1213 const b = b_param.canonicalize(.standard);
1214
1215 if (a.specifier == .invalid or b.specifier == .invalid) return false;
1216 if (a.alignof(comp) != b.alignof(comp)) return false;
1217 if (a.isPtr()) {
1218 if (!b.isPtr()) return false;
1219 } else if (a.isFunc()) {
1220 if (!b.isFunc()) return false;
1221 } else if (a.isArray()) {
1222 if (!b.isArray()) return false;
1223 } else if (a.specifier != b.specifier) return false;
1224
1225 if (a.qual.atomic != b.qual.atomic) return false;
1226 if (check_qualifiers) {
1227 if (a.qual.@"const" != b.qual.@"const") return false;
1228 if (a.qual.@"volatile" != b.qual.@"volatile") return false;
1229 }
1230
1231 if (a.isPtr()) {
1232 return a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers);
1233 }
1234 switch (a.specifier) {
1235 .pointer => unreachable,
1236
1237 .func,
1238 .var_args_func,
1239 .old_style_func,
1240 => if (!a.data.func.eql(b.data.func, a.specifier, b.specifier, comp)) return false,
1241
1242 .array,
1243 .static_array,
1244 .incomplete_array,
1245 .vector,
1246 => {
1247 const a_len = a.arrayLen();
1248 const b_len = b.arrayLen();
1249 if (a_len == null or b_len == null) {
1250 // At least one array is incomplete; only check child type for equality
1251 } else if (a_len.? != b_len.?) {
1252 return false;
1253 }
1254 if (!a.elemType().eql(b.elemType(), comp, false)) return false;
1255 },
1256 .variable_len_array => {
1257 if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false;
1258 },
1259 .@"struct", .@"union" => if (a.data.record != b.data.record) return false,
1260 .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false,
1261 .bit_int, .complex_bit_int => return a.data.int.bits == b.data.int.bits and a.data.int.signedness == b.data.int.signedness,
1262
1263 else => {},
1264 }
1265 return true;
1266}
1267
1268/// Decays an array to a pointer
1269pub fn decayArray(ty: *Type) void {
1270 std.debug.assert(ty.isArray());
1271 ty.decayed = true;
1272}
1273
1274pub fn originalTypeOfDecayedArray(ty: Type) Type {
1275 std.debug.assert(ty.isDecayed());
1276 var copy = ty;
1277 copy.decayed = false;
1278 return copy;
1279}
1280
1281/// Rank for floating point conversions, ignoring domain (complex vs real)
1282/// Asserts that ty is a floating point type
1283pub fn floatRank(ty: Type) usize {
1284 const real = ty.makeReal();
1285 return switch (real.specifier) {
1286 // TODO: bfloat16 => 0
1287 .float16 => 1,
1288 .fp16 => 2,
1289 .float => 3,
1290 .double => 4,
1291 .long_double => 5,
1292 .float128 => 6,
1293 // TODO: ibm128 => 7
1294 else => unreachable,
1295 };
1296}
1297
1298/// Rank for integer conversions, ignoring domain (complex vs real)
1299/// Asserts that ty is an integer type
1300pub fn integerRank(ty: Type, comp: *const Compilation) usize {
1301 const real = ty.makeReal();
1302 return @intCast(switch (real.specifier) {
1303 .bit_int => @as(u64, real.data.int.bits) << 3,
1304
1305 .bool => 1 + (ty.bitSizeof(comp).? << 3),
1306 .char, .schar, .uchar => 2 + (ty.bitSizeof(comp).? << 3),
1307 .short, .ushort => 3 + (ty.bitSizeof(comp).? << 3),
1308 .int, .uint => 4 + (ty.bitSizeof(comp).? << 3),
1309 .long, .ulong => 5 + (ty.bitSizeof(comp).? << 3),
1310 .long_long, .ulong_long => 6 + (ty.bitSizeof(comp).? << 3),
1311 .int128, .uint128 => 7 + (ty.bitSizeof(comp).? << 3),
1312
1313 else => unreachable,
1314 });
1315}
1316
1317/// Returns true if `a` and `b` are integer types that differ only in sign
1318pub fn sameRankDifferentSign(a: Type, b: Type, comp: *const Compilation) bool {
1319 if (!a.isInt() or !b.isInt()) return false;
1320 if (a.integerRank(comp) != b.integerRank(comp)) return false;
1321 return a.isUnsignedInt(comp) != b.isUnsignedInt(comp);
1322}
1323
1324pub fn makeReal(ty: Type) Type {
1325 // TODO discards attributed/typeof
1326 var base = ty.canonicalize(.standard);
1327 switch (base.specifier) {
1328 .complex_float, .complex_double, .complex_long_double, .complex_float80, .complex_float128 => {
1329 base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 5);
1330 return base;
1331 },
1332 .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128 => {
1333 base.specifier = @enumFromInt(@intFromEnum(base.specifier) - 13);
1334 return base;
1335 },
1336 .complex_bit_int => {
1337 base.specifier = .bit_int;
1338 return base;
1339 },
1340 else => return ty,
1341 }
1342}
1343
1344pub fn makeComplex(ty: Type) Type {
1345 // TODO discards attributed/typeof
1346 var base = ty.canonicalize(.standard);
1347 switch (base.specifier) {
1348 .float, .double, .long_double, .float80, .float128 => {
1349 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 5);
1350 return base;
1351 },
1352 .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128 => {
1353 base.specifier = @enumFromInt(@intFromEnum(base.specifier) + 13);
1354 return base;
1355 },
1356 .bit_int => {
1357 base.specifier = .complex_bit_int;
1358 return base;
1359 },
1360 else => return ty,
1361 }
1362}
1363
1364/// Combines types recursively in the order they were parsed, uses `.void` specifier as a sentinel value.
1365pub fn combine(inner: *Type, outer: Type) Parser.Error!void {
1366 switch (inner.specifier) {
1367 .pointer => return inner.data.sub_type.combine(outer),
1368 .unspecified_variable_len_array => {
1369 std.debug.assert(!inner.isDecayed());
1370 try inner.data.sub_type.combine(outer);
1371 },
1372 .variable_len_array => {
1373 std.debug.assert(!inner.isDecayed());
1374 try inner.data.expr.ty.combine(outer);
1375 },
1376 .array, .static_array, .incomplete_array => {
1377 std.debug.assert(!inner.isDecayed());
1378 try inner.data.array.elem.combine(outer);
1379 },
1380 .func, .var_args_func, .old_style_func => {
1381 try inner.data.func.return_type.combine(outer);
1382 },
1383 .typeof_type,
1384 .typeof_expr,
1385 => std.debug.assert(!inner.isDecayed()),
1386 .void, .invalid => inner.* = outer,
1387 else => unreachable,
1388 }
1389}
1390
1391pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser.Error!void {
1392 switch (ty.specifier) {
1393 .pointer => return ty.data.sub_type.validateCombinedType(p, source_tok),
1394 .unspecified_variable_len_array,
1395 .variable_len_array,
1396 .array,
1397 .static_array,
1398 .incomplete_array,
1399 => {
1400 const elem_ty = ty.elemType();
1401 if (elem_ty.hasIncompleteSize()) {
1402 try p.errStr(.array_incomplete_elem, source_tok, try p.typeStr(elem_ty));
1403 return error.ParsingFailed;
1404 }
1405 if (elem_ty.isFunc()) {
1406 try p.errTok(.array_func_elem, source_tok);
1407 return error.ParsingFailed;
1408 }
1409 if (elem_ty.specifier == .static_array and elem_ty.isArray()) {
1410 try p.errTok(.static_non_outermost_array, source_tok);
1411 }
1412 if (elem_ty.anyQual() and elem_ty.isArray()) {
1413 try p.errTok(.qualifier_non_outermost_array, source_tok);
1414 }
1415 },
1416 .func, .var_args_func, .old_style_func => {
1417 const ret_ty = &ty.data.func.return_type;
1418 if (ret_ty.isArray()) try p.errTok(.func_cannot_return_array, source_tok);
1419 if (ret_ty.isFunc()) try p.errTok(.func_cannot_return_func, source_tok);
1420 if (ret_ty.qual.@"const") {
1421 try p.errStr(.qual_on_ret_type, source_tok, "const");
1422 ret_ty.qual.@"const" = false;
1423 }
1424 if (ret_ty.qual.@"volatile") {
1425 try p.errStr(.qual_on_ret_type, source_tok, "volatile");
1426 ret_ty.qual.@"volatile" = false;
1427 }
1428 if (ret_ty.qual.atomic) {
1429 try p.errStr(.qual_on_ret_type, source_tok, "atomic");
1430 ret_ty.qual.atomic = false;
1431 }
1432 if (ret_ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
1433 try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value");
1434 }
1435 },
1436 .typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok),
1437 .typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok),
1438 .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok),
1439 else => {},
1440 }
1441}
1442
1443/// An unfinished Type
1444pub const Builder = struct {
1445 complex_tok: ?TokenIndex = null,
1446 bit_int_tok: ?TokenIndex = null,
1447 auto_type_tok: ?TokenIndex = null,
1448 typedef: ?struct {
1449 tok: TokenIndex,
1450 ty: Type,
1451 } = null,
1452 specifier: Builder.Specifier = .none,
1453 qual: Qualifiers.Builder = .{},
1454 typeof: ?Type = null,
1455 /// When true an error is returned instead of adding a diagnostic message.
1456 /// Used for trying to combine typedef types.
1457 error_on_invalid: bool = false,
1458
1459 pub const Specifier = union(enum) {
1460 none,
1461 void,
1462 /// GNU __auto_type extension
1463 auto_type,
1464 /// C23 auto
1465 c23_auto,
1466 nullptr_t,
1467 bool,
1468 char,
1469 schar,
1470 uchar,
1471 complex_char,
1472 complex_schar,
1473 complex_uchar,
1474
1475 unsigned,
1476 signed,
1477 short,
1478 sshort,
1479 ushort,
1480 short_int,
1481 sshort_int,
1482 ushort_int,
1483 int,
1484 sint,
1485 uint,
1486 long,
1487 slong,
1488 ulong,
1489 long_int,
1490 slong_int,
1491 ulong_int,
1492 long_long,
1493 slong_long,
1494 ulong_long,
1495 long_long_int,
1496 slong_long_int,
1497 ulong_long_int,
1498 int128,
1499 sint128,
1500 uint128,
1501 complex_unsigned,
1502 complex_signed,
1503 complex_short,
1504 complex_sshort,
1505 complex_ushort,
1506 complex_short_int,
1507 complex_sshort_int,
1508 complex_ushort_int,
1509 complex_int,
1510 complex_sint,
1511 complex_uint,
1512 complex_long,
1513 complex_slong,
1514 complex_ulong,
1515 complex_long_int,
1516 complex_slong_int,
1517 complex_ulong_int,
1518 complex_long_long,
1519 complex_slong_long,
1520 complex_ulong_long,
1521 complex_long_long_int,
1522 complex_slong_long_int,
1523 complex_ulong_long_int,
1524 complex_int128,
1525 complex_sint128,
1526 complex_uint128,
1527 bit_int: u64,
1528 sbit_int: u64,
1529 ubit_int: u64,
1530 complex_bit_int: u64,
1531 complex_sbit_int: u64,
1532 complex_ubit_int: u64,
1533
1534 fp16,
1535 float16,
1536 float,
1537 double,
1538 long_double,
1539 float80,
1540 float128,
1541 complex,
1542 complex_float,
1543 complex_double,
1544 complex_long_double,
1545 complex_float80,
1546 complex_float128,
1547
1548 pointer: *Type,
1549 unspecified_variable_len_array: *Type,
1550 decayed_unspecified_variable_len_array: *Type,
1551 func: *Func,
1552 var_args_func: *Func,
1553 old_style_func: *Func,
1554 array: *Array,
1555 decayed_array: *Array,
1556 static_array: *Array,
1557 decayed_static_array: *Array,
1558 incomplete_array: *Array,
1559 decayed_incomplete_array: *Array,
1560 vector: *Array,
1561 variable_len_array: *Expr,
1562 decayed_variable_len_array: *Expr,
1563 @"struct": *Record,
1564 @"union": *Record,
1565 @"enum": *Enum,
1566 typeof_type: *Type,
1567 decayed_typeof_type: *Type,
1568 typeof_expr: *Expr,
1569 decayed_typeof_expr: *Expr,
1570
1571 attributed: *Attributed,
1572 decayed_attributed: *Attributed,
1573
1574 pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 {
1575 return switch (spec) {
1576 .none => unreachable,
1577 .void => "void",
1578 .auto_type => "__auto_type",
1579 .c23_auto => "auto",
1580 .nullptr_t => "nullptr_t",
1581 .bool => if (langopts.standard.atLeast(.c23)) "bool" else "_Bool",
1582 .char => "char",
1583 .schar => "signed char",
1584 .uchar => "unsigned char",
1585 .unsigned => "unsigned",
1586 .signed => "signed",
1587 .short => "short",
1588 .ushort => "unsigned short",
1589 .sshort => "signed short",
1590 .short_int => "short int",
1591 .sshort_int => "signed short int",
1592 .ushort_int => "unsigned short int",
1593 .int => "int",
1594 .sint => "signed int",
1595 .uint => "unsigned int",
1596 .long => "long",
1597 .slong => "signed long",
1598 .ulong => "unsigned long",
1599 .long_int => "long int",
1600 .slong_int => "signed long int",
1601 .ulong_int => "unsigned long int",
1602 .long_long => "long long",
1603 .slong_long => "signed long long",
1604 .ulong_long => "unsigned long long",
1605 .long_long_int => "long long int",
1606 .slong_long_int => "signed long long int",
1607 .ulong_long_int => "unsigned long long int",
1608 .int128 => "__int128",
1609 .sint128 => "signed __int128",
1610 .uint128 => "unsigned __int128",
1611 .bit_int => "_BitInt",
1612 .sbit_int => "signed _BitInt",
1613 .ubit_int => "unsigned _BitInt",
1614 .complex_char => "_Complex char",
1615 .complex_schar => "_Complex signed char",
1616 .complex_uchar => "_Complex unsigned char",
1617 .complex_unsigned => "_Complex unsigned",
1618 .complex_signed => "_Complex signed",
1619 .complex_short => "_Complex short",
1620 .complex_ushort => "_Complex unsigned short",
1621 .complex_sshort => "_Complex signed short",
1622 .complex_short_int => "_Complex short int",
1623 .complex_sshort_int => "_Complex signed short int",
1624 .complex_ushort_int => "_Complex unsigned short int",
1625 .complex_int => "_Complex int",
1626 .complex_sint => "_Complex signed int",
1627 .complex_uint => "_Complex unsigned int",
1628 .complex_long => "_Complex long",
1629 .complex_slong => "_Complex signed long",
1630 .complex_ulong => "_Complex unsigned long",
1631 .complex_long_int => "_Complex long int",
1632 .complex_slong_int => "_Complex signed long int",
1633 .complex_ulong_int => "_Complex unsigned long int",
1634 .complex_long_long => "_Complex long long",
1635 .complex_slong_long => "_Complex signed long long",
1636 .complex_ulong_long => "_Complex unsigned long long",
1637 .complex_long_long_int => "_Complex long long int",
1638 .complex_slong_long_int => "_Complex signed long long int",
1639 .complex_ulong_long_int => "_Complex unsigned long long int",
1640 .complex_int128 => "_Complex __int128",
1641 .complex_sint128 => "_Complex signed __int128",
1642 .complex_uint128 => "_Complex unsigned __int128",
1643 .complex_bit_int => "_Complex _BitInt",
1644 .complex_sbit_int => "_Complex signed _BitInt",
1645 .complex_ubit_int => "_Complex unsigned _BitInt",
1646
1647 .fp16 => "__fp16",
1648 .float16 => "_Float16",
1649 .float => "float",
1650 .double => "double",
1651 .long_double => "long double",
1652 .float80 => "__float80",
1653 .float128 => "__float128",
1654 .complex => "_Complex",
1655 .complex_float => "_Complex float",
1656 .complex_double => "_Complex double",
1657 .complex_long_double => "_Complex long double",
1658 .complex_float80 => "_Complex __float80",
1659 .complex_float128 => "_Complex __float128",
1660
1661 .attributed => |attributed| Builder.fromType(attributed.base).str(langopts),
1662
1663 else => null,
1664 };
1665 }
1666 };
1667
1668 pub fn finish(b: Builder, p: *Parser) Parser.Error!Type {
1669 var ty: Type = .{ .specifier = undefined };
1670 if (b.typedef) |typedef| {
1671 ty = typedef.ty;
1672 if (ty.isArray()) {
1673 var elem = ty.elemType();
1674 try b.qual.finish(p, &elem);
1675 // TODO this really should be easier
1676 switch (ty.specifier) {
1677 .array, .static_array, .incomplete_array => {
1678 const old = ty.data.array;
1679 ty.data.array = try p.arena.create(Array);
1680 ty.data.array.* = .{
1681 .len = old.len,
1682 .elem = elem,
1683 };
1684 },
1685 .variable_len_array, .unspecified_variable_len_array => {
1686 const old = ty.data.expr;
1687 ty.data.expr = try p.arena.create(Expr);
1688 ty.data.expr.* = .{
1689 .node = old.node,
1690 .ty = elem,
1691 };
1692 },
1693 .typeof_type => {}, // TODO handle
1694 .typeof_expr => {}, // TODO handle
1695 .attributed => {}, // TODO handle
1696 else => unreachable,
1697 }
1698
1699 return ty;
1700 }
1701 try b.qual.finish(p, &ty);
1702 return ty;
1703 }
1704 switch (b.specifier) {
1705 .none => {
1706 if (b.typeof) |typeof| {
1707 ty = typeof;
1708 } else {
1709 ty.specifier = .int;
1710 if (p.comp.langopts.standard.atLeast(.c23)) {
1711 try p.err(.missing_type_specifier_c23);
1712 } else {
1713 try p.err(.missing_type_specifier);
1714 }
1715 }
1716 },
1717 .void => ty.specifier = .void,
1718 .auto_type => ty.specifier = .auto_type,
1719 .c23_auto => ty.specifier = .c23_auto,
1720 .nullptr_t => unreachable, // nullptr_t can only be accessed via typeof(nullptr)
1721 .bool => ty.specifier = .bool,
1722 .char => ty.specifier = .char,
1723 .schar => ty.specifier = .schar,
1724 .uchar => ty.specifier = .uchar,
1725 .complex_char => ty.specifier = .complex_char,
1726 .complex_schar => ty.specifier = .complex_schar,
1727 .complex_uchar => ty.specifier = .complex_uchar,
1728
1729 .unsigned => ty.specifier = .uint,
1730 .signed => ty.specifier = .int,
1731 .short_int, .sshort_int, .short, .sshort => ty.specifier = .short,
1732 .ushort, .ushort_int => ty.specifier = .ushort,
1733 .int, .sint => ty.specifier = .int,
1734 .uint => ty.specifier = .uint,
1735 .long, .slong, .long_int, .slong_int => ty.specifier = .long,
1736 .ulong, .ulong_int => ty.specifier = .ulong,
1737 .long_long, .slong_long, .long_long_int, .slong_long_int => ty.specifier = .long_long,
1738 .ulong_long, .ulong_long_int => ty.specifier = .ulong_long,
1739 .int128, .sint128 => ty.specifier = .int128,
1740 .uint128 => ty.specifier = .uint128,
1741 .complex_unsigned => ty.specifier = .complex_uint,
1742 .complex_signed => ty.specifier = .complex_int,
1743 .complex_short_int, .complex_sshort_int, .complex_short, .complex_sshort => ty.specifier = .complex_short,
1744 .complex_ushort, .complex_ushort_int => ty.specifier = .complex_ushort,
1745 .complex_int, .complex_sint => ty.specifier = .complex_int,
1746 .complex_uint => ty.specifier = .complex_uint,
1747 .complex_long, .complex_slong, .complex_long_int, .complex_slong_int => ty.specifier = .complex_long,
1748 .complex_ulong, .complex_ulong_int => ty.specifier = .complex_ulong,
1749 .complex_long_long, .complex_slong_long, .complex_long_long_int, .complex_slong_long_int => ty.specifier = .complex_long_long,
1750 .complex_ulong_long, .complex_ulong_long_int => ty.specifier = .complex_ulong_long,
1751 .complex_int128, .complex_sint128 => ty.specifier = .complex_int128,
1752 .complex_uint128 => ty.specifier = .complex_uint128,
1753 .bit_int, .sbit_int, .ubit_int, .complex_bit_int, .complex_ubit_int, .complex_sbit_int => |bits| {
1754 const unsigned = b.specifier == .ubit_int or b.specifier == .complex_ubit_int;
1755 if (unsigned) {
1756 if (bits < 1) {
1757 try p.errStr(.unsigned_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
1758 return Type.invalid;
1759 }
1760 } else {
1761 if (bits < 2) {
1762 try p.errStr(.signed_bit_int_too_small, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
1763 return Type.invalid;
1764 }
1765 }
1766 if (bits > Compilation.bit_int_max_bits) {
1767 try p.errStr(.bit_int_too_big, b.bit_int_tok.?, b.specifier.str(p.comp.langopts).?);
1768 return Type.invalid;
1769 }
1770 ty.specifier = if (b.complex_tok != null) .complex_bit_int else .bit_int;
1771 ty.data = .{ .int = .{
1772 .signedness = if (unsigned) .unsigned else .signed,
1773 .bits = @intCast(bits),
1774 } };
1775 },
1776
1777 .fp16 => ty.specifier = .fp16,
1778 .float16 => ty.specifier = .float16,
1779 .float => ty.specifier = .float,
1780 .double => ty.specifier = .double,
1781 .long_double => ty.specifier = .long_double,
1782 .float80 => ty.specifier = .float80,
1783 .float128 => ty.specifier = .float128,
1784 .complex_float => ty.specifier = .complex_float,
1785 .complex_double => ty.specifier = .complex_double,
1786 .complex_long_double => ty.specifier = .complex_long_double,
1787 .complex_float80 => ty.specifier = .complex_float80,
1788 .complex_float128 => ty.specifier = .complex_float128,
1789 .complex => {
1790 try p.errTok(.plain_complex, p.tok_i - 1);
1791 ty.specifier = .complex_double;
1792 },
1793
1794 .pointer => |data| {
1795 ty.specifier = .pointer;
1796 ty.data = .{ .sub_type = data };
1797 },
1798 .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => |data| {
1799 ty.specifier = .unspecified_variable_len_array;
1800 ty.data = .{ .sub_type = data };
1801 ty.decayed = b.specifier == .decayed_unspecified_variable_len_array;
1802 },
1803 .func => |data| {
1804 ty.specifier = .func;
1805 ty.data = .{ .func = data };
1806 },
1807 .var_args_func => |data| {
1808 ty.specifier = .var_args_func;
1809 ty.data = .{ .func = data };
1810 },
1811 .old_style_func => |data| {
1812 ty.specifier = .old_style_func;
1813 ty.data = .{ .func = data };
1814 },
1815 .array, .decayed_array => |data| {
1816 ty.specifier = .array;
1817 ty.data = .{ .array = data };
1818 ty.decayed = b.specifier == .decayed_array;
1819 },
1820 .static_array, .decayed_static_array => |data| {
1821 ty.specifier = .static_array;
1822 ty.data = .{ .array = data };
1823 ty.decayed = b.specifier == .decayed_static_array;
1824 },
1825 .incomplete_array, .decayed_incomplete_array => |data| {
1826 ty.specifier = .incomplete_array;
1827 ty.data = .{ .array = data };
1828 ty.decayed = b.specifier == .decayed_incomplete_array;
1829 },
1830 .vector => |data| {
1831 ty.specifier = .vector;
1832 ty.data = .{ .array = data };
1833 },
1834 .variable_len_array, .decayed_variable_len_array => |data| {
1835 ty.specifier = .variable_len_array;
1836 ty.data = .{ .expr = data };
1837 ty.decayed = b.specifier == .decayed_variable_len_array;
1838 },
1839 .@"struct" => |data| {
1840 ty.specifier = .@"struct";
1841 ty.data = .{ .record = data };
1842 },
1843 .@"union" => |data| {
1844 ty.specifier = .@"union";
1845 ty.data = .{ .record = data };
1846 },
1847 .@"enum" => |data| {
1848 ty.specifier = .@"enum";
1849 ty.data = .{ .@"enum" = data };
1850 },
1851 .typeof_type, .decayed_typeof_type => |data| {
1852 ty.specifier = .typeof_type;
1853 ty.data = .{ .sub_type = data };
1854 ty.decayed = b.specifier == .decayed_typeof_type;
1855 },
1856 .typeof_expr, .decayed_typeof_expr => |data| {
1857 ty.specifier = .typeof_expr;
1858 ty.data = .{ .expr = data };
1859 ty.decayed = b.specifier == .decayed_typeof_expr;
1860 },
1861 .attributed, .decayed_attributed => |data| {
1862 ty.specifier = .attributed;
1863 ty.data = .{ .attributed = data };
1864 ty.decayed = b.specifier == .decayed_attributed;
1865 },
1866 }
1867 if (!ty.isReal() and ty.isInt()) {
1868 if (b.complex_tok) |tok| try p.errTok(.complex_int, tok);
1869 }
1870 try b.qual.finish(p, &ty);
1871 return ty;
1872 }
1873
1874 fn cannotCombine(b: Builder, p: *Parser, source_tok: TokenIndex) !void {
1875 if (b.error_on_invalid) return error.CannotCombine;
1876 const ty_str = b.specifier.str(p.comp.langopts) orelse try p.typeStr(try b.finish(p));
1877 try p.errExtra(.cannot_combine_spec, source_tok, .{ .str = ty_str });
1878 if (b.typedef) |some| try p.errStr(.spec_from_typedef, some.tok, try p.typeStr(some.ty));
1879 }
1880
1881 fn duplicateSpec(b: *Builder, p: *Parser, source_tok: TokenIndex, spec: []const u8) !void {
1882 if (b.error_on_invalid) return error.CannotCombine;
1883 if (p.comp.langopts.emulate != .clang) return b.cannotCombine(p, source_tok);
1884 try p.errStr(.duplicate_decl_spec, p.tok_i, spec);
1885 }
1886
1887 pub fn combineFromTypeof(b: *Builder, p: *Parser, new: Type, source_tok: TokenIndex) Compilation.Error!void {
1888 if (b.typeof != null) return p.errStr(.cannot_combine_spec, source_tok, "typeof");
1889 if (b.specifier != .none) return p.errStr(.invalid_typeof, source_tok, @tagName(b.specifier));
1890 const inner = switch (new.specifier) {
1891 .typeof_type => new.data.sub_type.*,
1892 .typeof_expr => new.data.expr.ty,
1893 .nullptr_t => new, // typeof(nullptr) is special-cased to be an unwrapped typeof-expr
1894 else => unreachable,
1895 };
1896
1897 b.typeof = switch (inner.specifier) {
1898 .attributed => inner.data.attributed.base,
1899 else => new,
1900 };
1901 }
1902
1903 /// Try to combine type from typedef, returns true if successful.
1904 pub fn combineTypedef(b: *Builder, p: *Parser, typedef_ty: Type, name_tok: TokenIndex) bool {
1905 b.error_on_invalid = true;
1906 defer b.error_on_invalid = false;
1907
1908 const new_spec = fromType(typedef_ty);
1909 b.combineExtra(p, new_spec, 0) catch |err| switch (err) {
1910 error.FatalError => unreachable, // we do not add any diagnostics
1911 error.OutOfMemory => unreachable, // we do not add any diagnostics
1912 error.ParsingFailed => unreachable, // we do not add any diagnostics
1913 error.CannotCombine => return false,
1914 };
1915 b.typedef = .{ .tok = name_tok, .ty = typedef_ty };
1916 return true;
1917 }
1918
1919 pub fn combine(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
1920 b.combineExtra(p, new, source_tok) catch |err| switch (err) {
1921 error.CannotCombine => unreachable,
1922 else => |e| return e,
1923 };
1924 }
1925
1926 fn combineExtra(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void {
1927 if (b.typeof != null) {
1928 if (b.error_on_invalid) return error.CannotCombine;
1929 try p.errStr(.invalid_typeof, source_tok, @tagName(new));
1930 }
1931
1932 switch (new) {
1933 .complex => b.complex_tok = source_tok,
1934 .bit_int => b.bit_int_tok = source_tok,
1935 .auto_type => b.auto_type_tok = source_tok,
1936 else => {},
1937 }
1938
1939 if (new == .int128 and !target_util.hasInt128(p.comp.target)) {
1940 try p.errStr(.type_not_supported_on_target, source_tok, "__int128");
1941 }
1942
1943 switch (new) {
1944 else => switch (b.specifier) {
1945 .none => b.specifier = new,
1946 else => return b.cannotCombine(p, source_tok),
1947 },
1948 .signed => b.specifier = switch (b.specifier) {
1949 .none => .signed,
1950 .char => .schar,
1951 .short => .sshort,
1952 .short_int => .sshort_int,
1953 .int => .sint,
1954 .long => .slong,
1955 .long_int => .slong_int,
1956 .long_long => .slong_long,
1957 .long_long_int => .slong_long_int,
1958 .int128 => .sint128,
1959 .bit_int => |bits| .{ .sbit_int = bits },
1960 .complex => .complex_signed,
1961 .complex_char => .complex_schar,
1962 .complex_short => .complex_sshort,
1963 .complex_short_int => .complex_sshort_int,
1964 .complex_int => .complex_sint,
1965 .complex_long => .complex_slong,
1966 .complex_long_int => .complex_slong_int,
1967 .complex_long_long => .complex_slong_long,
1968 .complex_long_long_int => .complex_slong_long_int,
1969 .complex_int128 => .complex_sint128,
1970 .complex_bit_int => |bits| .{ .complex_sbit_int = bits },
1971 .signed,
1972 .sshort,
1973 .sshort_int,
1974 .sint,
1975 .slong,
1976 .slong_int,
1977 .slong_long,
1978 .slong_long_int,
1979 .sint128,
1980 .sbit_int,
1981 .complex_schar,
1982 .complex_signed,
1983 .complex_sshort,
1984 .complex_sshort_int,
1985 .complex_sint,
1986 .complex_slong,
1987 .complex_slong_int,
1988 .complex_slong_long,
1989 .complex_slong_long_int,
1990 .complex_sint128,
1991 .complex_sbit_int,
1992 => return b.duplicateSpec(p, source_tok, "signed"),
1993 else => return b.cannotCombine(p, source_tok),
1994 },
1995 .unsigned => b.specifier = switch (b.specifier) {
1996 .none => .unsigned,
1997 .char => .uchar,
1998 .short => .ushort,
1999 .short_int => .ushort_int,
2000 .int => .uint,
2001 .long => .ulong,
2002 .long_int => .ulong_int,
2003 .long_long => .ulong_long,
2004 .long_long_int => .ulong_long_int,
2005 .int128 => .uint128,
2006 .bit_int => |bits| .{ .ubit_int = bits },
2007 .complex => .complex_unsigned,
2008 .complex_char => .complex_uchar,
2009 .complex_short => .complex_ushort,
2010 .complex_short_int => .complex_ushort_int,
2011 .complex_int => .complex_uint,
2012 .complex_long => .complex_ulong,
2013 .complex_long_int => .complex_ulong_int,
2014 .complex_long_long => .complex_ulong_long,
2015 .complex_long_long_int => .complex_ulong_long_int,
2016 .complex_int128 => .complex_uint128,
2017 .complex_bit_int => |bits| .{ .complex_ubit_int = bits },
2018 .unsigned,
2019 .ushort,
2020 .ushort_int,
2021 .uint,
2022 .ulong,
2023 .ulong_int,
2024 .ulong_long,
2025 .ulong_long_int,
2026 .uint128,
2027 .ubit_int,
2028 .complex_uchar,
2029 .complex_unsigned,
2030 .complex_ushort,
2031 .complex_ushort_int,
2032 .complex_uint,
2033 .complex_ulong,
2034 .complex_ulong_int,
2035 .complex_ulong_long,
2036 .complex_ulong_long_int,
2037 .complex_uint128,
2038 .complex_ubit_int,
2039 => return b.duplicateSpec(p, source_tok, "unsigned"),
2040 else => return b.cannotCombine(p, source_tok),
2041 },
2042 .char => b.specifier = switch (b.specifier) {
2043 .none => .char,
2044 .unsigned => .uchar,
2045 .signed => .schar,
2046 .complex => .complex_char,
2047 .complex_signed => .complex_schar,
2048 .complex_unsigned => .complex_uchar,
2049 else => return b.cannotCombine(p, source_tok),
2050 },
2051 .short => b.specifier = switch (b.specifier) {
2052 .none => .short,
2053 .unsigned => .ushort,
2054 .signed => .sshort,
2055 .int => .short_int,
2056 .sint => .sshort_int,
2057 .uint => .ushort_int,
2058 .complex => .complex_short,
2059 .complex_signed => .complex_sshort,
2060 .complex_unsigned => .complex_ushort,
2061 else => return b.cannotCombine(p, source_tok),
2062 },
2063 .int => b.specifier = switch (b.specifier) {
2064 .none => .int,
2065 .signed => .sint,
2066 .unsigned => .uint,
2067 .short => .short_int,
2068 .sshort => .sshort_int,
2069 .ushort => .ushort_int,
2070 .long => .long_int,
2071 .slong => .slong_int,
2072 .ulong => .ulong_int,
2073 .long_long => .long_long_int,
2074 .slong_long => .slong_long_int,
2075 .ulong_long => .ulong_long_int,
2076 .complex => .complex_int,
2077 .complex_signed => .complex_sint,
2078 .complex_unsigned => .complex_uint,
2079 .complex_short => .complex_short_int,
2080 .complex_sshort => .complex_sshort_int,
2081 .complex_ushort => .complex_ushort_int,
2082 .complex_long => .complex_long_int,
2083 .complex_slong => .complex_slong_int,
2084 .complex_ulong => .complex_ulong_int,
2085 .complex_long_long => .complex_long_long_int,
2086 .complex_slong_long => .complex_slong_long_int,
2087 .complex_ulong_long => .complex_ulong_long_int,
2088 else => return b.cannotCombine(p, source_tok),
2089 },
2090 .long => b.specifier = switch (b.specifier) {
2091 .none => .long,
2092 .long => .long_long,
2093 .unsigned => .ulong,
2094 .signed => .long,
2095 .int => .long_int,
2096 .sint => .slong_int,
2097 .ulong => .ulong_long,
2098 .complex => .complex_long,
2099 .complex_signed => .complex_slong,
2100 .complex_unsigned => .complex_ulong,
2101 .complex_long => .complex_long_long,
2102 .complex_slong => .complex_slong_long,
2103 .complex_ulong => .complex_ulong_long,
2104 else => return b.cannotCombine(p, source_tok),
2105 },
2106 .int128 => b.specifier = switch (b.specifier) {
2107 .none => .int128,
2108 .unsigned => .uint128,
2109 .signed => .sint128,
2110 .complex => .complex_int128,
2111 .complex_signed => .complex_sint128,
2112 .complex_unsigned => .complex_uint128,
2113 else => return b.cannotCombine(p, source_tok),
2114 },
2115 .bit_int => b.specifier = switch (b.specifier) {
2116 .none => .{ .bit_int = new.bit_int },
2117 .unsigned => .{ .ubit_int = new.bit_int },
2118 .signed => .{ .sbit_int = new.bit_int },
2119 .complex => .{ .complex_bit_int = new.bit_int },
2120 .complex_signed => .{ .complex_sbit_int = new.bit_int },
2121 .complex_unsigned => .{ .complex_ubit_int = new.bit_int },
2122 else => return b.cannotCombine(p, source_tok),
2123 },
2124 .auto_type => b.specifier = switch (b.specifier) {
2125 .none => .auto_type,
2126 else => return b.cannotCombine(p, source_tok),
2127 },
2128 .c23_auto => b.specifier = switch (b.specifier) {
2129 .none => .c23_auto,
2130 else => return b.cannotCombine(p, source_tok),
2131 },
2132 .fp16 => b.specifier = switch (b.specifier) {
2133 .none => .fp16,
2134 else => return b.cannotCombine(p, source_tok),
2135 },
2136 .float16 => b.specifier = switch (b.specifier) {
2137 .none => .float16,
2138 else => return b.cannotCombine(p, source_tok),
2139 },
2140 .float => b.specifier = switch (b.specifier) {
2141 .none => .float,
2142 .complex => .complex_float,
2143 else => return b.cannotCombine(p, source_tok),
2144 },
2145 .double => b.specifier = switch (b.specifier) {
2146 .none => .double,
2147 .long => .long_double,
2148 .complex_long => .complex_long_double,
2149 .complex => .complex_double,
2150 else => return b.cannotCombine(p, source_tok),
2151 },
2152 .float80 => b.specifier = switch (b.specifier) {
2153 .none => .float80,
2154 .complex => .complex_float80,
2155 else => return b.cannotCombine(p, source_tok),
2156 },
2157 .float128 => b.specifier = switch (b.specifier) {
2158 .none => .float128,
2159 .complex => .complex_float128,
2160 else => return b.cannotCombine(p, source_tok),
2161 },
2162 .complex => b.specifier = switch (b.specifier) {
2163 .none => .complex,
2164 .float => .complex_float,
2165 .double => .complex_double,
2166 .long_double => .complex_long_double,
2167 .float80 => .complex_float80,
2168 .float128 => .complex_float128,
2169 .char => .complex_char,
2170 .schar => .complex_schar,
2171 .uchar => .complex_uchar,
2172 .unsigned => .complex_unsigned,
2173 .signed => .complex_signed,
2174 .short => .complex_short,
2175 .sshort => .complex_sshort,
2176 .ushort => .complex_ushort,
2177 .short_int => .complex_short_int,
2178 .sshort_int => .complex_sshort_int,
2179 .ushort_int => .complex_ushort_int,
2180 .int => .complex_int,
2181 .sint => .complex_sint,
2182 .uint => .complex_uint,
2183 .long => .complex_long,
2184 .slong => .complex_slong,
2185 .ulong => .complex_ulong,
2186 .long_int => .complex_long_int,
2187 .slong_int => .complex_slong_int,
2188 .ulong_int => .complex_ulong_int,
2189 .long_long => .complex_long_long,
2190 .slong_long => .complex_slong_long,
2191 .ulong_long => .complex_ulong_long,
2192 .long_long_int => .complex_long_long_int,
2193 .slong_long_int => .complex_slong_long_int,
2194 .ulong_long_int => .complex_ulong_long_int,
2195 .int128 => .complex_int128,
2196 .sint128 => .complex_sint128,
2197 .uint128 => .complex_uint128,
2198 .bit_int => |bits| .{ .complex_bit_int = bits },
2199 .sbit_int => |bits| .{ .complex_sbit_int = bits },
2200 .ubit_int => |bits| .{ .complex_ubit_int = bits },
2201 .complex,
2202 .complex_float,
2203 .complex_double,
2204 .complex_long_double,
2205 .complex_float80,
2206 .complex_float128,
2207 .complex_char,
2208 .complex_schar,
2209 .complex_uchar,
2210 .complex_unsigned,
2211 .complex_signed,
2212 .complex_short,
2213 .complex_sshort,
2214 .complex_ushort,
2215 .complex_short_int,
2216 .complex_sshort_int,
2217 .complex_ushort_int,
2218 .complex_int,
2219 .complex_sint,
2220 .complex_uint,
2221 .complex_long,
2222 .complex_slong,
2223 .complex_ulong,
2224 .complex_long_int,
2225 .complex_slong_int,
2226 .complex_ulong_int,
2227 .complex_long_long,
2228 .complex_slong_long,
2229 .complex_ulong_long,
2230 .complex_long_long_int,
2231 .complex_slong_long_int,
2232 .complex_ulong_long_int,
2233 .complex_int128,
2234 .complex_sint128,
2235 .complex_uint128,
2236 .complex_bit_int,
2237 .complex_sbit_int,
2238 .complex_ubit_int,
2239 => return b.duplicateSpec(p, source_tok, "_Complex"),
2240 else => return b.cannotCombine(p, source_tok),
2241 },
2242 }
2243 }
2244
2245 pub fn fromType(ty: Type) Builder.Specifier {
2246 return switch (ty.specifier) {
2247 .void => .void,
2248 .auto_type => .auto_type,
2249 .c23_auto => .c23_auto,
2250 .nullptr_t => .nullptr_t,
2251 .bool => .bool,
2252 .char => .char,
2253 .schar => .schar,
2254 .uchar => .uchar,
2255 .short => .short,
2256 .ushort => .ushort,
2257 .int => .int,
2258 .uint => .uint,
2259 .long => .long,
2260 .ulong => .ulong,
2261 .long_long => .long_long,
2262 .ulong_long => .ulong_long,
2263 .int128 => .int128,
2264 .uint128 => .uint128,
2265 .bit_int => if (ty.data.int.signedness == .unsigned) {
2266 return .{ .ubit_int = ty.data.int.bits };
2267 } else {
2268 return .{ .bit_int = ty.data.int.bits };
2269 },
2270 .complex_char => .complex_char,
2271 .complex_schar => .complex_schar,
2272 .complex_uchar => .complex_uchar,
2273 .complex_short => .complex_short,
2274 .complex_ushort => .complex_ushort,
2275 .complex_int => .complex_int,
2276 .complex_uint => .complex_uint,
2277 .complex_long => .complex_long,
2278 .complex_ulong => .complex_ulong,
2279 .complex_long_long => .complex_long_long,
2280 .complex_ulong_long => .complex_ulong_long,
2281 .complex_int128 => .complex_int128,
2282 .complex_uint128 => .complex_uint128,
2283 .complex_bit_int => if (ty.data.int.signedness == .unsigned) {
2284 return .{ .complex_ubit_int = ty.data.int.bits };
2285 } else {
2286 return .{ .complex_bit_int = ty.data.int.bits };
2287 },
2288 .fp16 => .fp16,
2289 .float16 => .float16,
2290 .float => .float,
2291 .double => .double,
2292 .float80 => .float80,
2293 .float128 => .float128,
2294 .long_double => .long_double,
2295 .complex_float => .complex_float,
2296 .complex_double => .complex_double,
2297 .complex_long_double => .complex_long_double,
2298 .complex_float80 => .complex_float80,
2299 .complex_float128 => .complex_float128,
2300
2301 .pointer => .{ .pointer = ty.data.sub_type },
2302 .unspecified_variable_len_array => if (ty.isDecayed())
2303 .{ .decayed_unspecified_variable_len_array = ty.data.sub_type }
2304 else
2305 .{ .unspecified_variable_len_array = ty.data.sub_type },
2306 .func => .{ .func = ty.data.func },
2307 .var_args_func => .{ .var_args_func = ty.data.func },
2308 .old_style_func => .{ .old_style_func = ty.data.func },
2309 .array => if (ty.isDecayed())
2310 .{ .decayed_array = ty.data.array }
2311 else
2312 .{ .array = ty.data.array },
2313 .static_array => if (ty.isDecayed())
2314 .{ .decayed_static_array = ty.data.array }
2315 else
2316 .{ .static_array = ty.data.array },
2317 .incomplete_array => if (ty.isDecayed())
2318 .{ .decayed_incomplete_array = ty.data.array }
2319 else
2320 .{ .incomplete_array = ty.data.array },
2321 .vector => .{ .vector = ty.data.array },
2322 .variable_len_array => if (ty.isDecayed())
2323 .{ .decayed_variable_len_array = ty.data.expr }
2324 else
2325 .{ .variable_len_array = ty.data.expr },
2326 .@"struct" => .{ .@"struct" = ty.data.record },
2327 .@"union" => .{ .@"union" = ty.data.record },
2328 .@"enum" => .{ .@"enum" = ty.data.@"enum" },
2329
2330 .typeof_type => if (ty.isDecayed())
2331 .{ .decayed_typeof_type = ty.data.sub_type }
2332 else
2333 .{ .typeof_type = ty.data.sub_type },
2334 .typeof_expr => if (ty.isDecayed())
2335 .{ .decayed_typeof_expr = ty.data.expr }
2336 else
2337 .{ .typeof_expr = ty.data.expr },
2338
2339 .attributed => if (ty.isDecayed())
2340 .{ .decayed_attributed = ty.data.attributed }
2341 else
2342 .{ .attributed = ty.data.attributed },
2343 else => unreachable,
2344 };
2345 }
2346};
2347
2348pub fn getAttribute(ty: Type, comptime tag: Attribute.Tag) ?Attribute.ArgumentsForTag(tag) {
2349 switch (ty.specifier) {
2350 .typeof_type => return ty.data.sub_type.getAttribute(tag),
2351 .typeof_expr => return ty.data.expr.ty.getAttribute(tag),
2352 .attributed => {
2353 for (ty.data.attributed.attributes) |attribute| {
2354 if (attribute.tag == tag) return @field(attribute.args, @tagName(tag));
2355 }
2356 return null;
2357 },
2358 else => return null,
2359 }
2360}
2361
2362pub fn hasAttribute(ty: Type, tag: Attribute.Tag) bool {
2363 for (ty.getAttributes()) |attr| {
2364 if (attr.tag == tag) return true;
2365 }
2366 return false;
2367}
2368
2369/// printf format modifier
2370pub fn formatModifier(ty: Type) []const u8 {
2371 return switch (ty.specifier) {
2372 .schar, .uchar => "hh",
2373 .short, .ushort => "h",
2374 .int, .uint => "",
2375 .long, .ulong => "l",
2376 .long_long, .ulong_long => "ll",
2377 else => unreachable,
2378 };
2379}
2380
2381/// Suffix for integer values of this type
2382pub fn intValueSuffix(ty: Type, comp: *const Compilation) []const u8 {
2383 return switch (ty.specifier) {
2384 .schar, .short, .int => "",
2385 .long => "L",
2386 .long_long => "LL",
2387 .uchar, .char => {
2388 if (ty.specifier == .char and comp.getCharSignedness() == .signed) return "";
2389 // Only 8-bit char supported currently;
2390 // TODO: handle platforms with 16-bit int + 16-bit char
2391 std.debug.assert(ty.sizeof(comp).? == 1);
2392 return "";
2393 },
2394 .ushort => {
2395 if (ty.sizeof(comp).? < int.sizeof(comp).?) {
2396 return "";
2397 }
2398 return "U";
2399 },
2400 .uint => "U",
2401 .ulong => "UL",
2402 .ulong_long => "ULL",
2403 else => unreachable, // not integer
2404 };
2405}
2406
2407/// Print type in C style
2408pub fn print(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2409 _ = try ty.printPrologue(mapper, langopts, w);
2410 try ty.printEpilogue(mapper, langopts, w);
2411}
2412
2413pub fn printNamed(ty: Type, name: []const u8, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2414 const simple = try ty.printPrologue(mapper, langopts, w);
2415 if (simple) try w.writeByte(' ');
2416 try w.writeAll(name);
2417 try ty.printEpilogue(mapper, langopts, w);
2418}
2419
2420const StringGetter = fn (TokenIndex) []const u8;
2421
2422/// return true if `ty` is simple
2423fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!bool {
2424 if (ty.qual.atomic) {
2425 var non_atomic_ty = ty;
2426 non_atomic_ty.qual.atomic = false;
2427 try w.writeAll("_Atomic(");
2428 try non_atomic_ty.print(mapper, langopts, w);
2429 try w.writeAll(")");
2430 return true;
2431 }
2432 if (ty.isPtr()) {
2433 const elem_ty = ty.elemType();
2434 const simple = try elem_ty.printPrologue(mapper, langopts, w);
2435 if (simple) try w.writeByte(' ');
2436 if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('(');
2437 try w.writeByte('*');
2438 try ty.qual.dump(w);
2439 return false;
2440 }
2441 switch (ty.specifier) {
2442 .pointer => unreachable,
2443 .func, .var_args_func, .old_style_func => {
2444 const ret_ty = ty.data.func.return_type;
2445 const simple = try ret_ty.printPrologue(mapper, langopts, w);
2446 if (simple) try w.writeByte(' ');
2447 return false;
2448 },
2449 .array, .static_array, .incomplete_array, .unspecified_variable_len_array, .variable_len_array => {
2450 const elem_ty = ty.elemType();
2451 const simple = try elem_ty.printPrologue(mapper, langopts, w);
2452 if (simple) try w.writeByte(' ');
2453 return false;
2454 },
2455 .typeof_type, .typeof_expr => {
2456 const actual = ty.canonicalize(.standard);
2457 return actual.printPrologue(mapper, langopts, w);
2458 },
2459 .attributed => {
2460 const actual = ty.canonicalize(.standard);
2461 return actual.printPrologue(mapper, langopts, w);
2462 },
2463 else => {},
2464 }
2465 try ty.qual.dump(w);
2466
2467 switch (ty.specifier) {
2468 .@"enum" => if (ty.data.@"enum".fixed) {
2469 try w.print("enum {s}: ", .{mapper.lookup(ty.data.@"enum".name)});
2470 try ty.data.@"enum".tag_ty.dump(mapper, langopts, w);
2471 } else {
2472 try w.print("enum {s}", .{mapper.lookup(ty.data.@"enum".name)});
2473 },
2474 .@"struct" => try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)}),
2475 .@"union" => try w.print("union {s}", .{mapper.lookup(ty.data.record.name)}),
2476 .vector => {
2477 const len = ty.data.array.len;
2478 const elem_ty = ty.data.array.elem;
2479 try w.print("__attribute__((__vector_size__({d} * sizeof(", .{len});
2480 _ = try elem_ty.printPrologue(mapper, langopts, w);
2481 try w.writeAll(")))) ");
2482 _ = try elem_ty.printPrologue(mapper, langopts, w);
2483 try w.print(" (vector of {d} '", .{len});
2484 _ = try elem_ty.printPrologue(mapper, langopts, w);
2485 try w.writeAll("' values)");
2486 },
2487 else => try w.writeAll(Builder.fromType(ty).str(langopts).?),
2488 }
2489 return true;
2490}
2491
2492fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2493 if (ty.qual.atomic) return;
2494 if (ty.isPtr()) {
2495 const elem_ty = ty.elemType();
2496 if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')');
2497 try elem_ty.printEpilogue(mapper, langopts, w);
2498 return;
2499 }
2500 switch (ty.specifier) {
2501 .pointer => unreachable, // handled above
2502 .func, .var_args_func, .old_style_func => {
2503 try w.writeByte('(');
2504 for (ty.data.func.params, 0..) |param, i| {
2505 if (i != 0) try w.writeAll(", ");
2506 _ = try param.ty.printPrologue(mapper, langopts, w);
2507 try param.ty.printEpilogue(mapper, langopts, w);
2508 }
2509 if (ty.specifier != .func) {
2510 if (ty.data.func.params.len != 0) try w.writeAll(", ");
2511 try w.writeAll("...");
2512 } else if (ty.data.func.params.len == 0) {
2513 try w.writeAll("void");
2514 }
2515 try w.writeByte(')');
2516 try ty.data.func.return_type.printEpilogue(mapper, langopts, w);
2517 },
2518 .array, .static_array => {
2519 try w.writeByte('[');
2520 if (ty.specifier == .static_array) try w.writeAll("static ");
2521 try ty.qual.dump(w);
2522 try w.print("{d}]", .{ty.data.array.len});
2523 try ty.data.array.elem.printEpilogue(mapper, langopts, w);
2524 },
2525 .incomplete_array => {
2526 try w.writeByte('[');
2527 try ty.qual.dump(w);
2528 try w.writeByte(']');
2529 try ty.data.array.elem.printEpilogue(mapper, langopts, w);
2530 },
2531 .unspecified_variable_len_array => {
2532 try w.writeByte('[');
2533 try ty.qual.dump(w);
2534 try w.writeAll("*]");
2535 try ty.data.sub_type.printEpilogue(mapper, langopts, w);
2536 },
2537 .variable_len_array => {
2538 try w.writeByte('[');
2539 try ty.qual.dump(w);
2540 try w.writeAll("<expr>]");
2541 try ty.data.expr.ty.printEpilogue(mapper, langopts, w);
2542 },
2543 .typeof_type, .typeof_expr => {
2544 const actual = ty.canonicalize(.standard);
2545 try actual.printEpilogue(mapper, langopts, w);
2546 },
2547 .attributed => {
2548 const actual = ty.canonicalize(.standard);
2549 try actual.printEpilogue(mapper, langopts, w);
2550 },
2551 else => {},
2552 }
2553}
2554
2555/// Useful for debugging, too noisy to be enabled by default.
2556const dump_detailed_containers = false;
2557
2558// Print as Zig types since those are actually readable
2559pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2560 try ty.qual.dump(w);
2561 switch (ty.specifier) {
2562 .invalid => try w.writeAll("invalid"),
2563 .pointer => {
2564 try w.writeAll("*");
2565 try ty.data.sub_type.dump(mapper, langopts, w);
2566 },
2567 .func, .var_args_func, .old_style_func => {
2568 if (ty.specifier == .old_style_func)
2569 try w.writeAll("kr (")
2570 else
2571 try w.writeAll("fn (");
2572 for (ty.data.func.params, 0..) |param, i| {
2573 if (i != 0) try w.writeAll(", ");
2574 if (param.name != .empty) try w.print("{s}: ", .{mapper.lookup(param.name)});
2575 try param.ty.dump(mapper, langopts, w);
2576 }
2577 if (ty.specifier != .func) {
2578 if (ty.data.func.params.len != 0) try w.writeAll(", ");
2579 try w.writeAll("...");
2580 }
2581 try w.writeAll(") ");
2582 try ty.data.func.return_type.dump(mapper, langopts, w);
2583 },
2584 .array, .static_array => {
2585 if (ty.isDecayed()) try w.writeAll("*d");
2586 try w.writeByte('[');
2587 if (ty.specifier == .static_array) try w.writeAll("static ");
2588 try w.print("{d}]", .{ty.data.array.len});
2589 try ty.data.array.elem.dump(mapper, langopts, w);
2590 },
2591 .vector => {
2592 try w.print("vector({d}, ", .{ty.data.array.len});
2593 try ty.data.array.elem.dump(mapper, langopts, w);
2594 try w.writeAll(")");
2595 },
2596 .incomplete_array => {
2597 if (ty.isDecayed()) try w.writeAll("*d");
2598 try w.writeAll("[]");
2599 try ty.data.array.elem.dump(mapper, langopts, w);
2600 },
2601 .@"enum" => {
2602 const enum_ty = ty.data.@"enum";
2603 if (enum_ty.isIncomplete() and !enum_ty.fixed) {
2604 try w.print("enum {s}", .{mapper.lookup(enum_ty.name)});
2605 } else {
2606 try w.print("enum {s}: ", .{mapper.lookup(enum_ty.name)});
2607 try enum_ty.tag_ty.dump(mapper, langopts, w);
2608 }
2609 if (dump_detailed_containers) try dumpEnum(enum_ty, mapper, w);
2610 },
2611 .@"struct" => {
2612 try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)});
2613 if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
2614 },
2615 .@"union" => {
2616 try w.print("union {s}", .{mapper.lookup(ty.data.record.name)});
2617 if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
2618 },
2619 .unspecified_variable_len_array => {
2620 if (ty.isDecayed()) try w.writeAll("*d");
2621 try w.writeAll("[*]");
2622 try ty.data.sub_type.dump(mapper, langopts, w);
2623 },
2624 .variable_len_array => {
2625 if (ty.isDecayed()) try w.writeAll("*d");
2626 try w.writeAll("[<expr>]");
2627 try ty.data.expr.ty.dump(mapper, langopts, w);
2628 },
2629 .typeof_type => {
2630 try w.writeAll("typeof(");
2631 try ty.data.sub_type.dump(mapper, langopts, w);
2632 try w.writeAll(")");
2633 },
2634 .typeof_expr => {
2635 try w.writeAll("typeof(<expr>: ");
2636 try ty.data.expr.ty.dump(mapper, langopts, w);
2637 try w.writeAll(")");
2638 },
2639 .attributed => {
2640 if (ty.isDecayed()) try w.writeAll("*d:");
2641 try w.writeAll("attributed(");
2642 try ty.data.attributed.base.dump(mapper, langopts, w);
2643 try w.writeAll(")");
2644 },
2645 else => {
2646 try w.writeAll(Builder.fromType(ty).str(langopts).?);
2647 if (ty.specifier == .bit_int or ty.specifier == .complex_bit_int) {
2648 try w.print("({d})", .{ty.data.int.bits});
2649 }
2650 },
2651 }
2652}
2653
2654fn dumpEnum(@"enum": *Enum, mapper: StringInterner.TypeMapper, w: anytype) @TypeOf(w).Error!void {
2655 try w.writeAll(" {");
2656 for (@"enum".fields) |field| {
2657 try w.print(" {s} = {d},", .{ mapper.lookup(field.name), field.value });
2658 }
2659 try w.writeAll(" }");
2660}
2661
2662fn dumpRecord(record: *Record, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2663 try w.writeAll(" {");
2664 for (record.fields) |field| {
2665 try w.writeByte(' ');
2666 try field.ty.dump(mapper, langopts, w);
2667 try w.print(" {s}: {d};", .{ mapper.lookup(field.name), field.bit_width });
2668 }
2669 try w.writeAll(" }");
2670}
lib/compiler/aro/aro/Value.zig created+726
......@@ -0,0 +1,726 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const BigIntConst = std.math.big.int.Const;
4const BigIntMutable = std.math.big.int.Mutable;
5const backend = @import("../backend.zig");
6const Interner = backend.Interner;
7const BigIntSpace = Interner.Tag.Int.BigIntSpace;
8const Compilation = @import("Compilation.zig");
9const Type = @import("Type.zig");
10const target_util = @import("target.zig");
11
12const Value = @This();
13
14opt_ref: Interner.OptRef = .none,
15
16pub const zero = Value{ .opt_ref = .zero };
17pub const one = Value{ .opt_ref = .one };
18pub const @"null" = Value{ .opt_ref = .null };
19
20pub fn intern(comp: *Compilation, k: Interner.Key) !Value {
21 const r = try comp.interner.put(comp.gpa, k);
22 return .{ .opt_ref = @enumFromInt(@intFromEnum(r)) };
23}
24
25pub fn int(i: anytype, comp: *Compilation) !Value {
26 const info = @typeInfo(@TypeOf(i));
27 if (info == .ComptimeInt or info.Int.signedness == .unsigned) {
28 return intern(comp, .{ .int = .{ .u64 = i } });
29 } else {
30 return intern(comp, .{ .int = .{ .i64 = i } });
31 }
32}
33
34pub fn ref(v: Value) Interner.Ref {
35 std.debug.assert(v.opt_ref != .none);
36 return @enumFromInt(@intFromEnum(v.opt_ref));
37}
38
39pub fn is(v: Value, tag: std.meta.Tag(Interner.Key), comp: *const Compilation) bool {
40 if (v.opt_ref == .none) return false;
41 return comp.interner.get(v.ref()) == tag;
42}
43
44/// Number of bits needed to hold `v`.
45/// Asserts that `v` is not negative
46pub fn minUnsignedBits(v: Value, comp: *const Compilation) usize {
47 var space: BigIntSpace = undefined;
48 const big = v.toBigInt(&space, comp);
49 assert(big.positive);
50 return big.bitCountAbs();
51}
52
53test "minUnsignedBits" {
54 const Test = struct {
55 fn checkIntBits(comp: *Compilation, v: u64, expected: usize) !void {
56 const val = try intern(comp, .{ .int = .{ .u64 = v } });
57 try std.testing.expectEqual(expected, val.minUnsignedBits(comp));
58 }
59 };
60
61 var comp = Compilation.init(std.testing.allocator);
62 defer comp.deinit();
63 comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
64
65 try Test.checkIntBits(&comp, 0, 0);
66 try Test.checkIntBits(&comp, 1, 1);
67 try Test.checkIntBits(&comp, 2, 2);
68 try Test.checkIntBits(&comp, std.math.maxInt(i8), 7);
69 try Test.checkIntBits(&comp, std.math.maxInt(u8), 8);
70 try Test.checkIntBits(&comp, std.math.maxInt(i16), 15);
71 try Test.checkIntBits(&comp, std.math.maxInt(u16), 16);
72 try Test.checkIntBits(&comp, std.math.maxInt(i32), 31);
73 try Test.checkIntBits(&comp, std.math.maxInt(u32), 32);
74 try Test.checkIntBits(&comp, std.math.maxInt(i64), 63);
75 try Test.checkIntBits(&comp, std.math.maxInt(u64), 64);
76}
77
78/// Minimum number of bits needed to represent `v` in 2's complement notation
79/// Asserts that `v` is negative.
80pub fn minSignedBits(v: Value, comp: *const Compilation) usize {
81 var space: BigIntSpace = undefined;
82 const big = v.toBigInt(&space, comp);
83 assert(!big.positive);
84 return big.bitCountTwosComp();
85}
86
87test "minSignedBits" {
88 const Test = struct {
89 fn checkIntBits(comp: *Compilation, v: i64, expected: usize) !void {
90 const val = try intern(comp, .{ .int = .{ .i64 = v } });
91 try std.testing.expectEqual(expected, val.minSignedBits(comp));
92 }
93 };
94
95 var comp = Compilation.init(std.testing.allocator);
96 defer comp.deinit();
97 comp.target = (try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-linux-gnu" })).toTarget();
98
99 try Test.checkIntBits(&comp, -1, 1);
100 try Test.checkIntBits(&comp, -2, 2);
101 try Test.checkIntBits(&comp, -10, 5);
102 try Test.checkIntBits(&comp, -101, 8);
103 try Test.checkIntBits(&comp, std.math.minInt(i8), 8);
104 try Test.checkIntBits(&comp, std.math.minInt(i16), 16);
105 try Test.checkIntBits(&comp, std.math.minInt(i32), 32);
106 try Test.checkIntBits(&comp, std.math.minInt(i64), 64);
107}
108
109pub const FloatToIntChangeKind = enum {
110 /// value did not change
111 none,
112 /// floating point number too small or large for destination integer type
113 out_of_range,
114 /// tried to convert a NaN or Infinity
115 overflow,
116 /// fractional value was converted to zero
117 nonzero_to_zero,
118 /// fractional part truncated
119 value_changed,
120};
121
122/// Converts the stored value from a float to an integer.
123/// `.none` value remains unchanged.
124pub fn floatToInt(v: *Value, dest_ty: Type, comp: *Compilation) !FloatToIntChangeKind {
125 if (v.opt_ref == .none) return .none;
126
127 const float_val = v.toFloat(f128, comp);
128 const was_zero = float_val == 0;
129
130 if (dest_ty.is(.bool)) {
131 const was_one = float_val == 1.0;
132 v.* = fromBool(!was_zero);
133 if (was_zero or was_one) return .none;
134 return .value_changed;
135 } else if (dest_ty.isUnsignedInt(comp) and v.compare(.lt, zero, comp)) {
136 v.* = zero;
137 return .out_of_range;
138 }
139
140 const had_fraction = @rem(float_val, 1) != 0;
141 const is_negative = std.math.signbit(float_val);
142 const floored = @floor(@abs(float_val));
143
144 var rational = try std.math.big.Rational.init(comp.gpa);
145 defer rational.deinit();
146 rational.setFloat(f128, floored) catch |err| switch (err) {
147 error.NonFiniteFloat => {
148 v.* = .{};
149 return .overflow;
150 },
151 error.OutOfMemory => return error.OutOfMemory,
152 };
153
154 // The float is reduced in rational.setFloat, so we assert that denominator is equal to one
155 const big_one = std.math.big.int.Const{ .limbs = &.{1}, .positive = true };
156 assert(rational.q.toConst().eqlAbs(big_one));
157
158 if (is_negative) {
159 rational.negate();
160 }
161
162 const signedness = dest_ty.signedness(comp);
163 const bits: usize = @intCast(dest_ty.bitSizeof(comp).?);
164
165 // rational.p.truncate(rational.p.toConst(), signedness: Signedness, bit_count: usize)
166 const fits = rational.p.fitsInTwosComp(signedness, bits);
167 v.* = try intern(comp, .{ .int = .{ .big_int = rational.p.toConst() } });
168 try rational.p.truncate(&rational.p, signedness, bits);
169
170 if (!was_zero and v.isZero(comp)) return .nonzero_to_zero;
171 if (!fits) return .out_of_range;
172 if (had_fraction) return .value_changed;
173 return .none;
174}
175
176/// Converts the stored value from an integer to a float.
177/// `.none` value remains unchanged.
178pub fn intToFloat(v: *Value, dest_ty: Type, comp: *Compilation) !void {
179 if (v.opt_ref == .none) return;
180 const bits = dest_ty.bitSizeof(comp).?;
181 return switch (comp.interner.get(v.ref()).int) {
182 inline .u64, .i64 => |data| {
183 const f: Interner.Key.Float = switch (bits) {
184 16 => .{ .f16 = @floatFromInt(data) },
185 32 => .{ .f32 = @floatFromInt(data) },
186 64 => .{ .f64 = @floatFromInt(data) },
187 80 => .{ .f80 = @floatFromInt(data) },
188 128 => .{ .f128 = @floatFromInt(data) },
189 else => unreachable,
190 };
191 v.* = try intern(comp, .{ .float = f });
192 },
193 .big_int => |data| {
194 const big_f = bigIntToFloat(data.limbs, data.positive);
195 const f: Interner.Key.Float = switch (bits) {
196 16 => .{ .f16 = @floatCast(big_f) },
197 32 => .{ .f32 = @floatCast(big_f) },
198 64 => .{ .f64 = @floatCast(big_f) },
199 80 => .{ .f80 = @floatCast(big_f) },
200 128 => .{ .f128 = @floatCast(big_f) },
201 else => unreachable,
202 };
203 v.* = try intern(comp, .{ .float = f });
204 },
205 };
206}
207
208/// Truncates or extends bits based on type.
209/// `.none` value remains unchanged.
210pub fn intCast(v: *Value, dest_ty: Type, comp: *Compilation) !void {
211 if (v.opt_ref == .none) return;
212 const bits: usize = @intCast(dest_ty.bitSizeof(comp).?);
213 var space: BigIntSpace = undefined;
214 const big = v.toBigInt(&space, comp);
215
216 const limbs = try comp.gpa.alloc(
217 std.math.big.Limb,
218 std.math.big.int.calcTwosCompLimbCount(@max(big.bitCountTwosComp(), bits)),
219 );
220 defer comp.gpa.free(limbs);
221 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
222 result_bigint.truncate(big, dest_ty.signedness(comp), bits);
223
224 v.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
225}
226
227/// Converts the stored value from an integer to a float.
228/// `.none` value remains unchanged.
229pub fn floatCast(v: *Value, dest_ty: Type, comp: *Compilation) !void {
230 if (v.opt_ref == .none) return;
231 // TODO complex values
232 const bits = dest_ty.makeReal().bitSizeof(comp).?;
233 const f: Interner.Key.Float = switch (bits) {
234 16 => .{ .f16 = v.toFloat(f16, comp) },
235 32 => .{ .f32 = v.toFloat(f32, comp) },
236 64 => .{ .f64 = v.toFloat(f64, comp) },
237 80 => .{ .f80 = v.toFloat(f80, comp) },
238 128 => .{ .f128 = v.toFloat(f128, comp) },
239 else => unreachable,
240 };
241 v.* = try intern(comp, .{ .float = f });
242}
243
244pub fn toFloat(v: Value, comptime T: type, comp: *const Compilation) T {
245 return switch (comp.interner.get(v.ref())) {
246 .int => |repr| switch (repr) {
247 inline .u64, .i64 => |data| @floatFromInt(data),
248 .big_int => |data| @floatCast(bigIntToFloat(data.limbs, data.positive)),
249 },
250 .float => |repr| switch (repr) {
251 inline else => |data| @floatCast(data),
252 },
253 else => unreachable,
254 };
255}
256
257fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 {
258 if (limbs.len == 0) return 0;
259
260 const base = std.math.maxInt(std.math.big.Limb) + 1;
261 var result: f128 = 0;
262 var i: usize = limbs.len;
263 while (i != 0) {
264 i -= 1;
265 const limb: f128 = @as(f128, @floatFromInt(limbs[i]));
266 result = @mulAdd(f128, base, result, limb);
267 }
268 if (positive) {
269 return result;
270 } else {
271 return -result;
272 }
273}
274
275pub fn toBigInt(val: Value, space: *BigIntSpace, comp: *const Compilation) BigIntConst {
276 return switch (comp.interner.get(val.ref()).int) {
277 inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(),
278 .big_int => |b| b,
279 };
280}
281
282pub fn isZero(v: Value, comp: *const Compilation) bool {
283 if (v.opt_ref == .none) return false;
284 switch (v.ref()) {
285 .zero => return true,
286 .one => return false,
287 .null => return target_util.nullRepr(comp.target) == 0,
288 else => {},
289 }
290 const key = comp.interner.get(v.ref());
291 switch (key) {
292 .float => |repr| switch (repr) {
293 inline else => |data| return data == 0,
294 },
295 .int => |repr| switch (repr) {
296 inline .i64, .u64 => |data| return data == 0,
297 .big_int => |data| return data.eqlZero(),
298 },
299 .bytes => return false,
300 else => unreachable,
301 }
302}
303
304/// Converts value to zero or one;
305/// `.none` value remains unchanged.
306pub fn boolCast(v: *Value, comp: *const Compilation) void {
307 if (v.opt_ref == .none) return;
308 v.* = fromBool(v.toBool(comp));
309}
310
311pub fn fromBool(b: bool) Value {
312 return if (b) one else zero;
313}
314
315pub fn toBool(v: Value, comp: *const Compilation) bool {
316 return !v.isZero(comp);
317}
318
319pub fn toInt(v: Value, comptime T: type, comp: *const Compilation) ?T {
320 if (v.opt_ref == .none) return null;
321 if (comp.interner.get(v.ref()) != .int) return null;
322 var space: BigIntSpace = undefined;
323 const big_int = v.toBigInt(&space, comp);
324 return big_int.to(T) catch null;
325}
326
327pub fn add(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
328 const bits: usize = @intCast(ty.bitSizeof(comp).?);
329 if (ty.isFloat()) {
330 const f: Interner.Key.Float = switch (bits) {
331 16 => .{ .f16 = lhs.toFloat(f16, comp) + rhs.toFloat(f16, comp) },
332 32 => .{ .f32 = lhs.toFloat(f32, comp) + rhs.toFloat(f32, comp) },
333 64 => .{ .f64 = lhs.toFloat(f64, comp) + rhs.toFloat(f64, comp) },
334 80 => .{ .f80 = lhs.toFloat(f80, comp) + rhs.toFloat(f80, comp) },
335 128 => .{ .f128 = lhs.toFloat(f128, comp) + rhs.toFloat(f128, comp) },
336 else => unreachable,
337 };
338 res.* = try intern(comp, .{ .float = f });
339 return false;
340 } else {
341 var lhs_space: BigIntSpace = undefined;
342 var rhs_space: BigIntSpace = undefined;
343 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
344 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
345
346 const limbs = try comp.gpa.alloc(
347 std.math.big.Limb,
348 std.math.big.int.calcTwosCompLimbCount(bits),
349 );
350 defer comp.gpa.free(limbs);
351 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
352
353 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, ty.signedness(comp), bits);
354 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
355 return overflowed;
356 }
357}
358
359pub fn sub(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
360 const bits: usize = @intCast(ty.bitSizeof(comp).?);
361 if (ty.isFloat()) {
362 const f: Interner.Key.Float = switch (bits) {
363 16 => .{ .f16 = lhs.toFloat(f16, comp) - rhs.toFloat(f16, comp) },
364 32 => .{ .f32 = lhs.toFloat(f32, comp) - rhs.toFloat(f32, comp) },
365 64 => .{ .f64 = lhs.toFloat(f64, comp) - rhs.toFloat(f64, comp) },
366 80 => .{ .f80 = lhs.toFloat(f80, comp) - rhs.toFloat(f80, comp) },
367 128 => .{ .f128 = lhs.toFloat(f128, comp) - rhs.toFloat(f128, comp) },
368 else => unreachable,
369 };
370 res.* = try intern(comp, .{ .float = f });
371 return false;
372 } else {
373 var lhs_space: BigIntSpace = undefined;
374 var rhs_space: BigIntSpace = undefined;
375 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
376 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
377
378 const limbs = try comp.gpa.alloc(
379 std.math.big.Limb,
380 std.math.big.int.calcTwosCompLimbCount(bits),
381 );
382 defer comp.gpa.free(limbs);
383 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
384
385 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, ty.signedness(comp), bits);
386 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
387 return overflowed;
388 }
389}
390
391pub fn mul(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
392 const bits: usize = @intCast(ty.bitSizeof(comp).?);
393 if (ty.isFloat()) {
394 const f: Interner.Key.Float = switch (bits) {
395 16 => .{ .f16 = lhs.toFloat(f16, comp) * rhs.toFloat(f16, comp) },
396 32 => .{ .f32 = lhs.toFloat(f32, comp) * rhs.toFloat(f32, comp) },
397 64 => .{ .f64 = lhs.toFloat(f64, comp) * rhs.toFloat(f64, comp) },
398 80 => .{ .f80 = lhs.toFloat(f80, comp) * rhs.toFloat(f80, comp) },
399 128 => .{ .f128 = lhs.toFloat(f128, comp) * rhs.toFloat(f128, comp) },
400 else => unreachable,
401 };
402 res.* = try intern(comp, .{ .float = f });
403 return false;
404 } else {
405 var lhs_space: BigIntSpace = undefined;
406 var rhs_space: BigIntSpace = undefined;
407 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
408 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
409
410 const limbs = try comp.gpa.alloc(
411 std.math.big.Limb,
412 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
413 );
414 defer comp.gpa.free(limbs);
415 var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined };
416
417 const limbs_buffer = try comp.gpa.alloc(
418 std.math.big.Limb,
419 std.math.big.int.calcMulLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len, 1),
420 );
421 defer comp.gpa.free(limbs_buffer);
422
423 result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, comp.gpa);
424
425 const signedness = ty.signedness(comp);
426 const overflowed = !result_bigint.toConst().fitsInTwosComp(signedness, bits);
427 if (overflowed) {
428 result_bigint.truncate(result_bigint.toConst(), signedness, bits);
429 }
430 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
431 return overflowed;
432 }
433}
434
435/// caller guarantees rhs != 0
436pub fn div(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
437 const bits: usize = @intCast(ty.bitSizeof(comp).?);
438 if (ty.isFloat()) {
439 const f: Interner.Key.Float = switch (bits) {
440 16 => .{ .f16 = lhs.toFloat(f16, comp) / rhs.toFloat(f16, comp) },
441 32 => .{ .f32 = lhs.toFloat(f32, comp) / rhs.toFloat(f32, comp) },
442 64 => .{ .f64 = lhs.toFloat(f64, comp) / rhs.toFloat(f64, comp) },
443 80 => .{ .f80 = lhs.toFloat(f80, comp) / rhs.toFloat(f80, comp) },
444 128 => .{ .f128 = lhs.toFloat(f128, comp) / rhs.toFloat(f128, comp) },
445 else => unreachable,
446 };
447 res.* = try intern(comp, .{ .float = f });
448 return false;
449 } else {
450 var lhs_space: BigIntSpace = undefined;
451 var rhs_space: BigIntSpace = undefined;
452 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
453 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
454
455 const limbs_q = try comp.gpa.alloc(
456 std.math.big.Limb,
457 lhs_bigint.limbs.len,
458 );
459 defer comp.gpa.free(limbs_q);
460 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
461
462 const limbs_r = try comp.gpa.alloc(
463 std.math.big.Limb,
464 rhs_bigint.limbs.len,
465 );
466 defer comp.gpa.free(limbs_r);
467 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
468
469 const limbs_buffer = try comp.gpa.alloc(
470 std.math.big.Limb,
471 std.math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
472 );
473 defer comp.gpa.free(limbs_buffer);
474
475 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
476
477 res.* = try intern(comp, .{ .int = .{ .big_int = result_q.toConst() } });
478 return !result_q.toConst().fitsInTwosComp(ty.signedness(comp), bits);
479 }
480}
481
482/// caller guarantees rhs != 0
483/// caller guarantees lhs != std.math.minInt(T) OR rhs != -1
484pub fn rem(lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !Value {
485 var lhs_space: BigIntSpace = undefined;
486 var rhs_space: BigIntSpace = undefined;
487 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
488 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
489
490 const signedness = ty.signedness(comp);
491 if (signedness == .signed) {
492 var spaces: [3]BigIntSpace = undefined;
493 const min_val = BigIntMutable.init(&spaces[0].limbs, ty.minInt(comp)).toConst();
494 const negative = BigIntMutable.init(&spaces[1].limbs, -1).toConst();
495 const big_one = BigIntMutable.init(&spaces[2].limbs, 1).toConst();
496 if (lhs_bigint.eql(min_val) and rhs_bigint.eql(negative)) {
497 return .{};
498 } else if (rhs_bigint.order(big_one).compare(.lt)) {
499 // lhs - @divTrunc(lhs, rhs) * rhs
500 var tmp: Value = undefined;
501 _ = try tmp.div(lhs, rhs, ty, comp);
502 _ = try tmp.mul(tmp, rhs, ty, comp);
503 _ = try tmp.sub(lhs, tmp, ty, comp);
504 return tmp;
505 }
506 }
507
508 const limbs_q = try comp.gpa.alloc(
509 std.math.big.Limb,
510 lhs_bigint.limbs.len,
511 );
512 defer comp.gpa.free(limbs_q);
513 var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined };
514
515 const limbs_r = try comp.gpa.alloc(
516 std.math.big.Limb,
517 rhs_bigint.limbs.len,
518 );
519 defer comp.gpa.free(limbs_r);
520 var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined };
521
522 const limbs_buffer = try comp.gpa.alloc(
523 std.math.big.Limb,
524 std.math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
525 );
526 defer comp.gpa.free(limbs_buffer);
527
528 result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer);
529 return intern(comp, .{ .int = .{ .big_int = result_r.toConst() } });
530}
531
532pub fn bitOr(lhs: Value, rhs: Value, comp: *Compilation) !Value {
533 var lhs_space: BigIntSpace = undefined;
534 var rhs_space: BigIntSpace = undefined;
535 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
536 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
537
538 const limbs = try comp.gpa.alloc(
539 std.math.big.Limb,
540 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
541 );
542 defer comp.gpa.free(limbs);
543 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
544
545 result_bigint.bitOr(lhs_bigint, rhs_bigint);
546 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
547}
548
549pub fn bitXor(lhs: Value, rhs: Value, comp: *Compilation) !Value {
550 var lhs_space: BigIntSpace = undefined;
551 var rhs_space: BigIntSpace = undefined;
552 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
553 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
554
555 const limbs = try comp.gpa.alloc(
556 std.math.big.Limb,
557 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
558 );
559 defer comp.gpa.free(limbs);
560 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
561
562 result_bigint.bitXor(lhs_bigint, rhs_bigint);
563 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
564}
565
566pub fn bitAnd(lhs: Value, rhs: Value, comp: *Compilation) !Value {
567 var lhs_space: BigIntSpace = undefined;
568 var rhs_space: BigIntSpace = undefined;
569 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
570 const rhs_bigint = rhs.toBigInt(&rhs_space, comp);
571
572 const limbs = try comp.gpa.alloc(
573 std.math.big.Limb,
574 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
575 );
576 defer comp.gpa.free(limbs);
577 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
578
579 result_bigint.bitAnd(lhs_bigint, rhs_bigint);
580 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
581}
582
583pub fn bitNot(val: Value, ty: Type, comp: *Compilation) !Value {
584 const bits: usize = @intCast(ty.bitSizeof(comp).?);
585 var val_space: Value.BigIntSpace = undefined;
586 const val_bigint = val.toBigInt(&val_space, comp);
587
588 const limbs = try comp.gpa.alloc(
589 std.math.big.Limb,
590 std.math.big.int.calcTwosCompLimbCount(bits),
591 );
592 defer comp.gpa.free(limbs);
593 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
594
595 result_bigint.bitNotWrap(val_bigint, ty.signedness(comp), bits);
596 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
597}
598
599pub fn shl(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool {
600 var lhs_space: Value.BigIntSpace = undefined;
601 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
602 const shift = rhs.toInt(usize, comp) orelse std.math.maxInt(usize);
603
604 const bits: usize = @intCast(ty.bitSizeof(comp).?);
605 if (shift > bits) {
606 if (lhs_bigint.positive) {
607 res.* = try intern(comp, .{ .int = .{ .u64 = ty.maxInt(comp) } });
608 } else {
609 res.* = try intern(comp, .{ .int = .{ .i64 = ty.minInt(comp) } });
610 }
611 return true;
612 }
613
614 const limbs = try comp.gpa.alloc(
615 std.math.big.Limb,
616 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
617 );
618 defer comp.gpa.free(limbs);
619 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
620
621 result_bigint.shiftLeft(lhs_bigint, shift);
622 const signedness = ty.signedness(comp);
623 const overflowed = !result_bigint.toConst().fitsInTwosComp(signedness, bits);
624 if (overflowed) {
625 result_bigint.truncate(result_bigint.toConst(), signedness, bits);
626 }
627 res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
628 return overflowed;
629}
630
631pub fn shr(lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !Value {
632 var lhs_space: Value.BigIntSpace = undefined;
633 const lhs_bigint = lhs.toBigInt(&lhs_space, comp);
634 const shift = rhs.toInt(usize, comp) orelse return zero;
635
636 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
637 if (result_limbs == 0) {
638 // The shift is enough to remove all the bits from the number, which means the
639 // result is 0 or -1 depending on the sign.
640 if (lhs_bigint.positive) {
641 return zero;
642 } else {
643 return intern(comp, .{ .int = .{ .i64 = -1 } });
644 }
645 }
646
647 const bits: usize = @intCast(ty.bitSizeof(comp).?);
648 const limbs = try comp.gpa.alloc(
649 std.math.big.Limb,
650 std.math.big.int.calcTwosCompLimbCount(bits),
651 );
652 defer comp.gpa.free(limbs);
653 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };
654
655 result_bigint.shiftRight(lhs_bigint, shift);
656 return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } });
657}
658
659pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, comp: *const Compilation) bool {
660 if (op == .eq) {
661 return lhs.opt_ref == rhs.opt_ref;
662 } else if (lhs.opt_ref == rhs.opt_ref) {
663 return std.math.Order.eq.compare(op);
664 }
665
666 const lhs_key = comp.interner.get(lhs.ref());
667 const rhs_key = comp.interner.get(rhs.ref());
668 if (lhs_key == .float or rhs_key == .float) {
669 const lhs_f128 = lhs.toFloat(f128, comp);
670 const rhs_f128 = rhs.toFloat(f128, comp);
671 return std.math.compare(lhs_f128, op, rhs_f128);
672 }
673
674 var lhs_bigint_space: BigIntSpace = undefined;
675 var rhs_bigint_space: BigIntSpace = undefined;
676 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space, comp);
677 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, comp);
678 return lhs_bigint.order(rhs_bigint).compare(op);
679}
680
681pub fn print(v: Value, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w).Error!void {
682 if (ty.is(.bool)) {
683 return w.writeAll(if (v.isZero(comp)) "false" else "true");
684 }
685 const key = comp.interner.get(v.ref());
686 switch (key) {
687 .null => return w.writeAll("nullptr_t"),
688 .int => |repr| switch (repr) {
689 inline else => |x| return w.print("{d}", .{x}),
690 },
691 .float => |repr| switch (repr) {
692 .f16 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000) / 1000}),
693 .f32 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000000) / 1000000}),
694 inline else => |x| return w.print("{d}", .{@as(f64, @floatCast(x))}),
695 },
696 .bytes => |b| return printString(b, ty, comp, w),
697 else => unreachable, // not a value
698 }
699}
700
701pub fn printString(bytes: []const u8, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w).Error!void {
702 const size: Compilation.CharUnitSize = @enumFromInt(ty.elemType().sizeof(comp).?);
703 const without_null = bytes[0 .. bytes.len - @intFromEnum(size)];
704 switch (size) {
705 inline .@"1", .@"2" => |sz| {
706 const data_slice: []const sz.Type() = @alignCast(std.mem.bytesAsSlice(sz.Type(), without_null));
707 const formatter = if (sz == .@"1") std.zig.fmtEscapes(data_slice) else std.unicode.fmtUtf16le(data_slice);
708 try w.print("\"{}\"", .{formatter});
709 },
710 .@"4" => {
711 try w.writeByte('"');
712 const data_slice = std.mem.bytesAsSlice(u32, without_null);
713 var buf: [4]u8 = undefined;
714 for (data_slice) |item| {
715 if (item <= std.math.maxInt(u21) and std.unicode.utf8ValidCodepoint(@intCast(item))) {
716 const codepoint: u21 = @intCast(item);
717 const written = std.unicode.utf8Encode(codepoint, &buf) catch unreachable;
718 try w.print("{s}", .{buf[0..written]});
719 } else {
720 try w.print("\\x{x}", .{item});
721 }
722 }
723 try w.writeByte('"');
724 },
725 }
726}
lib/compiler/aro/aro/char_info.zig created+1111
......@@ -0,0 +1,1111 @@
1//! This module provides functions for classifying characters according to
2//! various C standards. All classification routines *do not* consider
3//! characters from the basic character set; it is assumed those will be
4//! checked separately
5//! isXidStart and isXidContinue are adapted from https://github.com/dtolnay/unicode-ident
6
7const assert = @import("std").debug.assert;
8const tables = @import("char_info/identifier_tables.zig");
9
10/// C11 Standard Annex D
11pub fn isC11IdChar(codepoint: u21) bool {
12 assert(codepoint > 0x7F);
13 return switch (codepoint) {
14 // 1
15 0x00A8,
16 0x00AA,
17 0x00AD,
18 0x00AF,
19 0x00B2...0x00B5,
20 0x00B7...0x00BA,
21 0x00BC...0x00BE,
22 0x00C0...0x00D6,
23 0x00D8...0x00F6,
24 0x00F8...0x00FF,
25
26 // 2
27 0x0100...0x167F,
28 0x1681...0x180D,
29 0x180F...0x1FFF,
30
31 // 3
32 0x200B...0x200D,
33 0x202A...0x202E,
34 0x203F...0x2040,
35 0x2054,
36 0x2060...0x206F,
37
38 // 4
39 0x2070...0x218F,
40 0x2460...0x24FF,
41 0x2776...0x2793,
42 0x2C00...0x2DFF,
43 0x2E80...0x2FFF,
44
45 // 5
46 0x3004...0x3007,
47 0x3021...0x302F,
48 0x3031...0x303F,
49
50 // 6
51 0x3040...0xD7FF,
52
53 // 7
54 0xF900...0xFD3D,
55 0xFD40...0xFDCF,
56 0xFDF0...0xFE44,
57 0xFE47...0xFFFD,
58
59 // 8
60 0x10000...0x1FFFD,
61 0x20000...0x2FFFD,
62 0x30000...0x3FFFD,
63 0x40000...0x4FFFD,
64 0x50000...0x5FFFD,
65 0x60000...0x6FFFD,
66 0x70000...0x7FFFD,
67 0x80000...0x8FFFD,
68 0x90000...0x9FFFD,
69 0xA0000...0xAFFFD,
70 0xB0000...0xBFFFD,
71 0xC0000...0xCFFFD,
72 0xD0000...0xDFFFD,
73 0xE0000...0xEFFFD,
74 => true,
75 else => false,
76 };
77}
78
79/// C99 Standard Annex D
80pub fn isC99IdChar(codepoint: u21) bool {
81 assert(codepoint > 0x7F);
82 return switch (codepoint) {
83 // Latin
84 0x00AA,
85 0x00BA,
86 0x00C0...0x00D6,
87 0x00D8...0x00F6,
88 0x00F8...0x01F5,
89 0x01FA...0x0217,
90 0x0250...0x02A8,
91 0x1E00...0x1E9B,
92 0x1EA0...0x1EF9,
93 0x207F,
94
95 // Greek
96 0x0386,
97 0x0388...0x038A,
98 0x038C,
99 0x038E...0x03A1,
100 0x03A3...0x03CE,
101 0x03D0...0x03D6,
102 0x03DA,
103 0x03DC,
104 0x03DE,
105 0x03E0,
106 0x03E2...0x03F3,
107 0x1F00...0x1F15,
108 0x1F18...0x1F1D,
109 0x1F20...0x1F45,
110 0x1F48...0x1F4D,
111 0x1F50...0x1F57,
112 0x1F59,
113 0x1F5B,
114 0x1F5D,
115 0x1F5F...0x1F7D,
116 0x1F80...0x1FB4,
117 0x1FB6...0x1FBC,
118 0x1FC2...0x1FC4,
119 0x1FC6...0x1FCC,
120 0x1FD0...0x1FD3,
121 0x1FD6...0x1FDB,
122 0x1FE0...0x1FEC,
123 0x1FF2...0x1FF4,
124 0x1FF6...0x1FFC,
125
126 // Cyrillic
127 0x0401...0x040C,
128 0x040E...0x044F,
129 0x0451...0x045C,
130 0x045E...0x0481,
131 0x0490...0x04C4,
132 0x04C7...0x04C8,
133 0x04CB...0x04CC,
134 0x04D0...0x04EB,
135 0x04EE...0x04F5,
136 0x04F8...0x04F9,
137
138 // Armenian
139 0x0531...0x0556,
140 0x0561...0x0587,
141
142 // Hebrew
143 0x05B0...0x05B9,
144 0x05BB...0x05BD,
145 0x05BF,
146 0x05C1...0x05C2,
147 0x05D0...0x05EA,
148 0x05F0...0x05F2,
149
150 // Arabic
151 0x0621...0x063A,
152 0x0640...0x0652,
153 0x0670...0x06B7,
154 0x06BA...0x06BE,
155 0x06C0...0x06CE,
156 0x06D0...0x06DC,
157 0x06E5...0x06E8,
158 0x06EA...0x06ED,
159
160 // Devanagari
161 0x0901...0x0903,
162 0x0905...0x0939,
163 0x093E...0x094D,
164 0x0950...0x0952,
165 0x0958...0x0963,
166
167 // Bengali
168 0x0981...0x0983,
169 0x0985...0x098C,
170 0x098F...0x0990,
171 0x0993...0x09A8,
172 0x09AA...0x09B0,
173 0x09B2,
174 0x09B6...0x09B9,
175 0x09BE...0x09C4,
176 0x09C7...0x09C8,
177 0x09CB...0x09CD,
178 0x09DC...0x09DD,
179 0x09DF...0x09E3,
180 0x09F0...0x09F1,
181
182 // Gurmukhi
183 0x0A02,
184 0x0A05...0x0A0A,
185 0x0A0F...0x0A10,
186 0x0A13...0x0A28,
187 0x0A2A...0x0A30,
188 0x0A32...0x0A33,
189 0x0A35...0x0A36,
190 0x0A38...0x0A39,
191 0x0A3E...0x0A42,
192 0x0A47...0x0A48,
193 0x0A4B...0x0A4D,
194 0x0A59...0x0A5C,
195 0x0A5E,
196 0x0A74,
197
198 // Gujarati
199 0x0A81...0x0A83,
200 0x0A85...0x0A8B,
201 0x0A8D,
202 0x0A8F...0x0A91,
203 0x0A93...0x0AA8,
204 0x0AAA...0x0AB0,
205 0x0AB2...0x0AB3,
206 0x0AB5...0x0AB9,
207 0x0ABD...0x0AC5,
208 0x0AC7...0x0AC9,
209 0x0ACB...0x0ACD,
210 0x0AD0,
211 0x0AE0,
212
213 // Oriya
214 0x0B01...0x0B03,
215 0x0B05...0x0B0C,
216 0x0B0F...0x0B10,
217 0x0B13...0x0B28,
218 0x0B2A...0x0B30,
219 0x0B32...0x0B33,
220 0x0B36...0x0B39,
221 0x0B3E...0x0B43,
222 0x0B47...0x0B48,
223 0x0B4B...0x0B4D,
224 0x0B5C...0x0B5D,
225 0x0B5F...0x0B61,
226
227 // Tamil
228 0x0B82...0x0B83,
229 0x0B85...0x0B8A,
230 0x0B8E...0x0B90,
231 0x0B92...0x0B95,
232 0x0B99...0x0B9A,
233 0x0B9C,
234 0x0B9E...0x0B9F,
235 0x0BA3...0x0BA4,
236 0x0BA8...0x0BAA,
237 0x0BAE...0x0BB5,
238 0x0BB7...0x0BB9,
239 0x0BBE...0x0BC2,
240 0x0BC6...0x0BC8,
241 0x0BCA...0x0BCD,
242
243 // Telugu
244 0x0C01...0x0C03,
245 0x0C05...0x0C0C,
246 0x0C0E...0x0C10,
247 0x0C12...0x0C28,
248 0x0C2A...0x0C33,
249 0x0C35...0x0C39,
250 0x0C3E...0x0C44,
251 0x0C46...0x0C48,
252 0x0C4A...0x0C4D,
253 0x0C60...0x0C61,
254
255 // Kannada
256 0x0C82...0x0C83,
257 0x0C85...0x0C8C,
258 0x0C8E...0x0C90,
259 0x0C92...0x0CA8,
260 0x0CAA...0x0CB3,
261 0x0CB5...0x0CB9,
262 0x0CBE...0x0CC4,
263 0x0CC6...0x0CC8,
264 0x0CCA...0x0CCD,
265 0x0CDE,
266 0x0CE0...0x0CE1,
267
268 // Malayalam
269 0x0D02...0x0D03,
270 0x0D05...0x0D0C,
271 0x0D0E...0x0D10,
272 0x0D12...0x0D28,
273 0x0D2A...0x0D39,
274 0x0D3E...0x0D43,
275 0x0D46...0x0D48,
276 0x0D4A...0x0D4D,
277 0x0D60...0x0D61,
278
279 // Thai (excluding digits 0x0E50...0x0E59; originally 0x0E01...0x0E3A and 0x0E40...0x0E5B
280 0x0E01...0x0E3A,
281 0x0E40...0x0E4F,
282 0x0E5A...0x0E5B,
283
284 // Lao
285 0x0E81...0x0E82,
286 0x0E84,
287 0x0E87...0x0E88,
288 0x0E8A,
289 0x0E8D,
290 0x0E94...0x0E97,
291 0x0E99...0x0E9F,
292 0x0EA1...0x0EA3,
293 0x0EA5,
294 0x0EA7,
295 0x0EAA...0x0EAB,
296 0x0EAD...0x0EAE,
297 0x0EB0...0x0EB9,
298 0x0EBB...0x0EBD,
299 0x0EC0...0x0EC4,
300 0x0EC6,
301 0x0EC8...0x0ECD,
302 0x0EDC...0x0EDD,
303
304 // Tibetan
305 0x0F00,
306 0x0F18...0x0F19,
307 0x0F35,
308 0x0F37,
309 0x0F39,
310 0x0F3E...0x0F47,
311 0x0F49...0x0F69,
312 0x0F71...0x0F84,
313 0x0F86...0x0F8B,
314 0x0F90...0x0F95,
315 0x0F97,
316 0x0F99...0x0FAD,
317 0x0FB1...0x0FB7,
318 0x0FB9,
319
320 // Georgian
321 0x10A0...0x10C5,
322 0x10D0...0x10F6,
323
324 // Hiragana
325 0x3041...0x3093,
326 0x309B...0x309C,
327
328 // Katakana
329 0x30A1...0x30F6,
330 0x30FB...0x30FC,
331
332 // Bopomofo
333 0x3105...0x312C,
334
335 // CJK Unified Ideographs
336 0x4E00...0x9FA5,
337
338 // Hangul
339 0xAC00...0xD7A3,
340
341 // Digits
342 0x0660...0x0669,
343 0x06F0...0x06F9,
344 0x0966...0x096F,
345 0x09E6...0x09EF,
346 0x0A66...0x0A6F,
347 0x0AE6...0x0AEF,
348 0x0B66...0x0B6F,
349 0x0BE7...0x0BEF,
350 0x0C66...0x0C6F,
351 0x0CE6...0x0CEF,
352 0x0D66...0x0D6F,
353 0x0E50...0x0E59,
354 0x0ED0...0x0ED9,
355 0x0F20...0x0F33,
356
357 // Special characters
358 0x00B5,
359 0x00B7,
360 0x02B0...0x02B8,
361 0x02BB,
362 0x02BD...0x02C1,
363 0x02D0...0x02D1,
364 0x02E0...0x02E4,
365 0x037A,
366 0x0559,
367 0x093D,
368 0x0B3D,
369 0x1FBE,
370 0x203F...0x2040,
371 0x2102,
372 0x2107,
373 0x210A...0x2113,
374 0x2115,
375 0x2118...0x211D,
376 0x2124,
377 0x2126,
378 0x2128,
379 0x212A...0x2131,
380 0x2133...0x2138,
381 0x2160...0x2182,
382 0x3005...0x3007,
383 0x3021...0x3029,
384 => true,
385 else => false,
386 };
387}
388
389/// C11 standard Annex D
390pub fn isC11DisallowedInitialIdChar(codepoint: u21) bool {
391 assert(codepoint > 0x7F);
392 return switch (codepoint) {
393 0x0300...0x036F,
394 0x1DC0...0x1DFF,
395 0x20D0...0x20FF,
396 0xFE20...0xFE2F,
397 => true,
398 else => false,
399 };
400}
401
402/// These are "digit" characters; C99 disallows them as the first
403/// character of an identifier
404pub fn isC99DisallowedInitialIDChar(codepoint: u21) bool {
405 assert(codepoint > 0x7F);
406 return switch (codepoint) {
407 0x0660...0x0669,
408 0x06F0...0x06F9,
409 0x0966...0x096F,
410 0x09E6...0x09EF,
411 0x0A66...0x0A6F,
412 0x0AE6...0x0AEF,
413 0x0B66...0x0B6F,
414 0x0BE7...0x0BEF,
415 0x0C66...0x0C6F,
416 0x0CE6...0x0CEF,
417 0x0D66...0x0D6F,
418 0x0E50...0x0E59,
419 0x0ED0...0x0ED9,
420 0x0F20...0x0F33,
421 => true,
422 else => false,
423 };
424}
425
426pub fn isInvisible(codepoint: u21) bool {
427 assert(codepoint > 0x7F);
428 return switch (codepoint) {
429 0x00ad, // SOFT HYPHEN
430 0x200b, // ZERO WIDTH SPACE
431 0x200c, // ZERO WIDTH NON-JOINER
432 0x200d, // ZERO WIDTH JOINER
433 0x2060, // WORD JOINER
434 0x2061, // FUNCTION APPLICATION
435 0x2062, // INVISIBLE TIMES
436 0x2063, // INVISIBLE SEPARATOR
437 0x2064, // INVISIBLE PLUS
438 0xfeff, // ZERO WIDTH NO-BREAK SPACE
439 => true,
440 else => false,
441 };
442}
443
444/// Checks for identifier characters which resemble non-identifier characters
445pub fn homoglyph(codepoint: u21) ?u21 {
446 assert(codepoint > 0x7F);
447 return switch (codepoint) {
448 0x01c3 => '!', // LATIN LETTER RETROFLEX CLICK
449 0x037e => ';', // GREEK QUESTION MARK
450 0x2212 => '-', // MINUS SIGN
451 0x2215 => '/', // DIVISION SLASH
452 0x2216 => '\\', // SET MINUS
453 0x2217 => '*', // ASTERISK OPERATOR
454 0x2223 => '|', // DIVIDES
455 0x2227 => '^', // LOGICAL AND
456 0x2236 => ':', // RATIO
457 0x223c => '~', // TILDE OPERATOR
458 0xa789 => ':', // MODIFIER LETTER COLON
459 0xff01 => '!', // FULLWIDTH EXCLAMATION MARK
460 0xff03 => '#', // FULLWIDTH NUMBER SIGN
461 0xff04 => '$', // FULLWIDTH DOLLAR SIGN
462 0xff05 => '%', // FULLWIDTH PERCENT SIGN
463 0xff06 => '&', // FULLWIDTH AMPERSAND
464 0xff08 => '(', // FULLWIDTH LEFT PARENTHESIS
465 0xff09 => ')', // FULLWIDTH RIGHT PARENTHESIS
466 0xff0a => '*', // FULLWIDTH ASTERISK
467 0xff0b => '+', // FULLWIDTH ASTERISK
468 0xff0c => ',', // FULLWIDTH COMMA
469 0xff0d => '-', // FULLWIDTH HYPHEN-MINUS
470 0xff0e => '.', // FULLWIDTH FULL STOP
471 0xff0f => '/', // FULLWIDTH SOLIDUS
472 0xff1a => ':', // FULLWIDTH COLON
473 0xff1b => ';', // FULLWIDTH SEMICOLON
474 0xff1c => '<', // FULLWIDTH LESS-THAN SIGN
475 0xff1d => '=', // FULLWIDTH EQUALS SIGN
476 0xff1e => '>', // FULLWIDTH GREATER-THAN SIGN
477 0xff1f => '?', // FULLWIDTH QUESTION MARK
478 0xff20 => '@', // FULLWIDTH COMMERCIAL AT
479 0xff3b => '[', // FULLWIDTH LEFT SQUARE BRACKET
480 0xff3c => '\\', // FULLWIDTH REVERSE SOLIDUS
481 0xff3d => ']', // FULLWIDTH RIGHT SQUARE BRACKET
482 0xff3e => '^', // FULLWIDTH CIRCUMFLEX ACCENT
483 0xff5b => '{', // FULLWIDTH LEFT CURLY BRACKET
484 0xff5c => '|', // FULLWIDTH VERTICAL LINE
485 0xff5d => '}', // FULLWIDTH RIGHT CURLY BRACKET
486 0xff5e => '~', // FULLWIDTH TILDE
487 else => null,
488 };
489}
490
491pub fn isXidStart(c: u21) bool {
492 assert(c > 0x7F);
493 const idx = c / 8 / tables.chunk;
494 const chunk: usize = if (idx < tables.trie_start.len) tables.trie_start[idx] else 0;
495 const offset = chunk * tables.chunk / 2 + c / 8 % tables.chunk;
496 return (tables.leaf[offset] >> (@as(u3, @intCast(c % 8)))) & 1 != 0;
497}
498
499pub fn isXidContinue(c: u21) bool {
500 assert(c > 0x7F);
501 const idx = c / 8 / tables.chunk;
502 const chunk: usize = if (idx < tables.trie_continue.len) tables.trie_continue[idx] else 0;
503 const offset = chunk * tables.chunk / 2 + c / 8 % tables.chunk;
504 return (tables.leaf[offset] >> (@as(u3, @intCast(c % 8)))) & 1 != 0;
505}
506
507test "isXidStart / isXidContinue panic check" {
508 const std = @import("std");
509 for (0x80..0x110000) |i| {
510 const c: u21 = @intCast(i);
511 if (std.unicode.utf8ValidCodepoint(c)) {
512 _ = isXidStart(c);
513 _ = isXidContinue(c);
514 }
515 }
516}
517
518test isXidStart {
519 const std = @import("std");
520 try std.testing.expect(!isXidStart('᠑'));
521 try std.testing.expect(!isXidStart('™'));
522 try std.testing.expect(!isXidStart('£'));
523 try std.testing.expect(!isXidStart('\u{1f914}')); // 🤔
524}
525
526test isXidContinue {
527 const std = @import("std");
528 try std.testing.expect(isXidContinue('᠑'));
529 try std.testing.expect(!isXidContinue('™'));
530 try std.testing.expect(!isXidContinue('£'));
531 try std.testing.expect(!isXidContinue('\u{1f914}')); // 🤔
532}
533
534pub const NfcQuickCheck = enum { no, maybe, yes };
535
536pub fn isNormalized(codepoint: u21) NfcQuickCheck {
537 return switch (codepoint) {
538 0x0340...0x0341,
539 0x0343...0x0344,
540 0x0374,
541 0x037E,
542 0x0387,
543 0x0958...0x095F,
544 0x09DC...0x09DD,
545 0x09DF,
546 0x0A33,
547 0x0A36,
548 0x0A59...0x0A5B,
549 0x0A5E,
550 0x0B5C...0x0B5D,
551 0x0F43,
552 0x0F4D,
553 0x0F52,
554 0x0F57,
555 0x0F5C,
556 0x0F69,
557 0x0F73,
558 0x0F75...0x0F76,
559 0x0F78,
560 0x0F81,
561 0x0F93,
562 0x0F9D,
563 0x0FA2,
564 0x0FA7,
565 0x0FAC,
566 0x0FB9,
567 0x1F71,
568 0x1F73,
569 0x1F75,
570 0x1F77,
571 0x1F79,
572 0x1F7B,
573 0x1F7D,
574 0x1FBB,
575 0x1FBE,
576 0x1FC9,
577 0x1FCB,
578 0x1FD3,
579 0x1FDB,
580 0x1FE3,
581 0x1FEB,
582 0x1FEE...0x1FEF,
583 0x1FF9,
584 0x1FFB,
585 0x1FFD,
586 0x2000...0x2001,
587 0x2126,
588 0x212A...0x212B,
589 0x2329,
590 0x232A,
591 0x2ADC,
592 0xF900...0xFA0D,
593 0xFA10,
594 0xFA12,
595 0xFA15...0xFA1E,
596 0xFA20,
597 0xFA22,
598 0xFA25...0xFA26,
599 0xFA2A...0xFA6D,
600 0xFA70...0xFAD9,
601 0xFB1D,
602 0xFB1F,
603 0xFB2A...0xFB36,
604 0xFB38...0xFB3C,
605 0xFB3E,
606 0xFB40...0xFB41,
607 0xFB43...0xFB44,
608 0xFB46...0xFB4E,
609 0x1D15E...0x1D164,
610 0x1D1BB...0x1D1C0,
611 0x2F800...0x2FA1D,
612 => .no,
613 0x0300...0x0304,
614 0x0306...0x030C,
615 0x030F,
616 0x0311,
617 0x0313...0x0314,
618 0x031B,
619 0x0323...0x0328,
620 0x032D...0x032E,
621 0x0330...0x0331,
622 0x0338,
623 0x0342,
624 0x0345,
625 0x0653...0x0655,
626 0x093C,
627 0x09BE,
628 0x09D7,
629 0x0B3E,
630 0x0B56,
631 0x0B57,
632 0x0BBE,
633 0x0BD7,
634 0x0C56,
635 0x0CC2,
636 0x0CD5...0x0CD6,
637 0x0D3E,
638 0x0D57,
639 0x0DCA,
640 0x0DCF,
641 0x0DDF,
642 0x102E,
643 0x1161...0x1175,
644 0x11A8...0x11C2,
645 0x1B35,
646 0x3099...0x309A,
647 0x110BA,
648 0x11127,
649 0x1133E,
650 0x11357,
651 0x114B0,
652 0x114BA,
653 0x114BD,
654 0x115AF,
655 => .maybe,
656 else => .yes,
657 };
658}
659
660pub const CanonicalCombiningClass = enum(u8) {
661 not_reordered = 0,
662 overlay = 1,
663 han_reading = 6,
664 nukta = 7,
665 kana_voicing = 8,
666 virama = 9,
667 ccc10 = 10,
668 ccc11 = 11,
669 ccc12 = 12,
670 ccc13 = 13,
671 ccc14 = 14,
672 ccc15 = 15,
673 ccc16 = 16,
674 ccc17 = 17,
675 ccc18 = 18,
676 ccc19 = 19,
677 ccc20 = 20,
678 ccc21 = 21,
679 ccc22 = 22,
680 ccc23 = 23,
681 ccc24 = 24,
682 ccc25 = 25,
683 ccc26 = 26,
684 ccc27 = 27,
685 ccc28 = 28,
686 ccc29 = 29,
687 ccc30 = 30,
688 ccc31 = 31,
689 ccc32 = 32,
690 ccc33 = 33,
691 ccc34 = 34,
692 ccc35 = 35,
693 ccc36 = 36,
694 ccc84 = 84,
695 ccc91 = 91,
696 ccc103 = 103,
697 ccc107 = 107,
698 ccc118 = 118,
699 ccc122 = 122,
700 ccc129 = 129,
701 ccc130 = 130,
702 ccc132 = 132,
703 attached_below = 202,
704 attached_above = 214,
705 attached_above_right = 216,
706 below_left = 218,
707 below = 220,
708 below_right = 222,
709 left = 224,
710 right = 226,
711 above_left = 228,
712 above = 230,
713 above_right = 232,
714 double_below = 233,
715 double_above = 234,
716 iota_subscript = 240,
717};
718
719pub fn getCanonicalClass(codepoint: u21) CanonicalCombiningClass {
720 return switch (codepoint) {
721 0x300...0x314 => .above,
722 0x315...0x315 => .above_right,
723 0x316...0x319 => .below,
724 0x31A...0x31A => .above_right,
725 0x31B...0x31B => .attached_above_right,
726 0x31C...0x320 => .below,
727 0x321...0x322 => .attached_below,
728 0x323...0x326 => .below,
729 0x327...0x328 => .attached_below,
730 0x329...0x333 => .below,
731 0x334...0x338 => .overlay,
732 0x339...0x33C => .below,
733 0x33D...0x344 => .above,
734 0x345...0x345 => .iota_subscript,
735 0x346...0x346 => .above,
736 0x347...0x349 => .below,
737 0x34A...0x34C => .above,
738 0x34D...0x34E => .below,
739 0x350...0x352 => .above,
740 0x353...0x356 => .below,
741 0x357...0x357 => .above,
742 0x358...0x358 => .above_right,
743 0x359...0x35A => .below,
744 0x35B...0x35B => .above,
745 0x35C...0x35C => .double_below,
746 0x35D...0x35E => .double_above,
747 0x35F...0x35F => .double_below,
748 0x360...0x361 => .double_above,
749 0x362...0x362 => .double_below,
750 0x363...0x36F => .above,
751 0x483...0x487 => .above,
752 0x591...0x591 => .below,
753 0x592...0x595 => .above,
754 0x596...0x596 => .below,
755 0x597...0x599 => .above,
756 0x59A...0x59A => .below_right,
757 0x59B...0x59B => .below,
758 0x59C...0x5A1 => .above,
759 0x5A2...0x5A7 => .below,
760 0x5A8...0x5A9 => .above,
761 0x5AA...0x5AA => .below,
762 0x5AB...0x5AC => .above,
763 0x5AD...0x5AD => .below_right,
764 0x5AE...0x5AE => .above_left,
765 0x5AF...0x5AF => .above,
766 0x5B0...0x5B0 => .ccc10,
767 0x5B1...0x5B1 => .ccc11,
768 0x5B2...0x5B2 => .ccc12,
769 0x5B3...0x5B3 => .ccc13,
770 0x5B4...0x5B4 => .ccc14,
771 0x5B5...0x5B5 => .ccc15,
772 0x5B6...0x5B6 => .ccc16,
773 0x5B7...0x5B7 => .ccc17,
774 0x5B8...0x5B8 => .ccc18,
775 0x5B9...0x5BA => .ccc19,
776 0x5BB...0x5BB => .ccc20,
777 0x5BC...0x5BC => .ccc21,
778 0x5BD...0x5BD => .ccc22,
779 0x5BF...0x5BF => .ccc23,
780 0x5C1...0x5C1 => .ccc24,
781 0x5C2...0x5C2 => .ccc25,
782 0x5C4...0x5C4 => .above,
783 0x5C5...0x5C5 => .below,
784 0x5C7...0x5C7 => .ccc18,
785 0x610...0x617 => .above,
786 0x618...0x618 => .ccc30,
787 0x619...0x619 => .ccc31,
788 0x61A...0x61A => .ccc32,
789 0x64B...0x64B => .ccc27,
790 0x64C...0x64C => .ccc28,
791 0x64D...0x64D => .ccc29,
792 0x64E...0x64E => .ccc30,
793 0x64F...0x64F => .ccc31,
794 0x650...0x650 => .ccc32,
795 0x651...0x651 => .ccc33,
796 0x652...0x652 => .ccc34,
797 0x653...0x654 => .above,
798 0x655...0x656 => .below,
799 0x657...0x65B => .above,
800 0x65C...0x65C => .below,
801 0x65D...0x65E => .above,
802 0x65F...0x65F => .below,
803 0x670...0x670 => .ccc35,
804 0x6D6...0x6DC => .above,
805 0x6DF...0x6E2 => .above,
806 0x6E3...0x6E3 => .below,
807 0x6E4...0x6E4 => .above,
808 0x6E7...0x6E8 => .above,
809 0x6EA...0x6EA => .below,
810 0x6EB...0x6EC => .above,
811 0x6ED...0x6ED => .below,
812 0x711...0x711 => .ccc36,
813 0x730...0x730 => .above,
814 0x731...0x731 => .below,
815 0x732...0x733 => .above,
816 0x734...0x734 => .below,
817 0x735...0x736 => .above,
818 0x737...0x739 => .below,
819 0x73A...0x73A => .above,
820 0x73B...0x73C => .below,
821 0x73D...0x73D => .above,
822 0x73E...0x73E => .below,
823 0x73F...0x741 => .above,
824 0x742...0x742 => .below,
825 0x743...0x743 => .above,
826 0x744...0x744 => .below,
827 0x745...0x745 => .above,
828 0x746...0x746 => .below,
829 0x747...0x747 => .above,
830 0x748...0x748 => .below,
831 0x749...0x74A => .above,
832 0x7EB...0x7F1 => .above,
833 0x7F2...0x7F2 => .below,
834 0x7F3...0x7F3 => .above,
835 0x7FD...0x7FD => .below,
836 0x816...0x819 => .above,
837 0x81B...0x823 => .above,
838 0x825...0x827 => .above,
839 0x829...0x82D => .above,
840 0x859...0x85B => .below,
841 0x898...0x898 => .above,
842 0x899...0x89B => .below,
843 0x89C...0x89F => .above,
844 0x8CA...0x8CE => .above,
845 0x8CF...0x8D3 => .below,
846 0x8D4...0x8E1 => .above,
847 0x8E3...0x8E3 => .below,
848 0x8E4...0x8E5 => .above,
849 0x8E6...0x8E6 => .below,
850 0x8E7...0x8E8 => .above,
851 0x8E9...0x8E9 => .below,
852 0x8EA...0x8EC => .above,
853 0x8ED...0x8EF => .below,
854 0x8F0...0x8F0 => .ccc27,
855 0x8F1...0x8F1 => .ccc28,
856 0x8F2...0x8F2 => .ccc29,
857 0x8F3...0x8F5 => .above,
858 0x8F6...0x8F6 => .below,
859 0x8F7...0x8F8 => .above,
860 0x8F9...0x8FA => .below,
861 0x8FB...0x8FF => .above,
862 0x93C...0x93C => .nukta,
863 0x94D...0x94D => .virama,
864 0x951...0x951 => .above,
865 0x952...0x952 => .below,
866 0x953...0x954 => .above,
867 0x9BC...0x9BC => .nukta,
868 0x9CD...0x9CD => .virama,
869 0x9FE...0x9FE => .above,
870 0xA3C...0xA3C => .nukta,
871 0xA4D...0xA4D => .virama,
872 0xABC...0xABC => .nukta,
873 0xACD...0xACD => .virama,
874 0xB3C...0xB3C => .nukta,
875 0xB4D...0xB4D => .virama,
876 0xBCD...0xBCD => .virama,
877 0xC3C...0xC3C => .nukta,
878 0xC4D...0xC4D => .virama,
879 0xC55...0xC55 => .ccc84,
880 0xC56...0xC56 => .ccc91,
881 0xCBC...0xCBC => .nukta,
882 0xCCD...0xCCD => .virama,
883 0xD3B...0xD3C => .virama,
884 0xD4D...0xD4D => .virama,
885 0xDCA...0xDCA => .virama,
886 0xE38...0xE39 => .ccc103,
887 0xE3A...0xE3A => .virama,
888 0xE48...0xE4B => .ccc107,
889 0xEB8...0xEB9 => .ccc118,
890 0xEBA...0xEBA => .virama,
891 0xEC8...0xECB => .ccc122,
892 0xF18...0xF19 => .below,
893 0xF35...0xF35 => .below,
894 0xF37...0xF37 => .below,
895 0xF39...0xF39 => .attached_above_right,
896 0xF71...0xF71 => .ccc129,
897 0xF72...0xF72 => .ccc130,
898 0xF74...0xF74 => .ccc132,
899 0xF7A...0xF7D => .ccc130,
900 0xF80...0xF80 => .ccc130,
901 0xF82...0xF83 => .above,
902 0xF84...0xF84 => .virama,
903 0xF86...0xF87 => .above,
904 0xFC6...0xFC6 => .below,
905 0x1037...0x1037 => .nukta,
906 0x1039...0x103A => .virama,
907 0x108D...0x108D => .below,
908 0x135D...0x135F => .above,
909 0x1714...0x1715 => .virama,
910 0x1734...0x1734 => .virama,
911 0x17D2...0x17D2 => .virama,
912 0x17DD...0x17DD => .above,
913 0x18A9...0x18A9 => .above_left,
914 0x1939...0x1939 => .below_right,
915 0x193A...0x193A => .above,
916 0x193B...0x193B => .below,
917 0x1A17...0x1A17 => .above,
918 0x1A18...0x1A18 => .below,
919 0x1A60...0x1A60 => .virama,
920 0x1A75...0x1A7C => .above,
921 0x1A7F...0x1A7F => .below,
922 0x1AB0...0x1AB4 => .above,
923 0x1AB5...0x1ABA => .below,
924 0x1ABB...0x1ABC => .above,
925 0x1ABD...0x1ABD => .below,
926 0x1ABF...0x1AC0 => .below,
927 0x1AC1...0x1AC2 => .above,
928 0x1AC3...0x1AC4 => .below,
929 0x1AC5...0x1AC9 => .above,
930 0x1ACA...0x1ACA => .below,
931 0x1ACB...0x1ACE => .above,
932 0x1B34...0x1B34 => .nukta,
933 0x1B44...0x1B44 => .virama,
934 0x1B6B...0x1B6B => .above,
935 0x1B6C...0x1B6C => .below,
936 0x1B6D...0x1B73 => .above,
937 0x1BAA...0x1BAB => .virama,
938 0x1BE6...0x1BE6 => .nukta,
939 0x1BF2...0x1BF3 => .virama,
940 0x1C37...0x1C37 => .nukta,
941 0x1CD0...0x1CD2 => .above,
942 0x1CD4...0x1CD4 => .overlay,
943 0x1CD5...0x1CD9 => .below,
944 0x1CDA...0x1CDB => .above,
945 0x1CDC...0x1CDF => .below,
946 0x1CE0...0x1CE0 => .above,
947 0x1CE2...0x1CE8 => .overlay,
948 0x1CED...0x1CED => .below,
949 0x1CF4...0x1CF4 => .above,
950 0x1CF8...0x1CF9 => .above,
951 0x1DC0...0x1DC1 => .above,
952 0x1DC2...0x1DC2 => .below,
953 0x1DC3...0x1DC9 => .above,
954 0x1DCA...0x1DCA => .below,
955 0x1DCB...0x1DCC => .above,
956 0x1DCD...0x1DCD => .double_above,
957 0x1DCE...0x1DCE => .attached_above,
958 0x1DCF...0x1DCF => .below,
959 0x1DD0...0x1DD0 => .attached_below,
960 0x1DD1...0x1DF5 => .above,
961 0x1DF6...0x1DF6 => .above_right,
962 0x1DF7...0x1DF8 => .above_left,
963 0x1DF9...0x1DF9 => .below,
964 0x1DFA...0x1DFA => .below_left,
965 0x1DFB...0x1DFB => .above,
966 0x1DFC...0x1DFC => .double_below,
967 0x1DFD...0x1DFD => .below,
968 0x1DFE...0x1DFE => .above,
969 0x1DFF...0x1DFF => .below,
970 0x20D0...0x20D1 => .above,
971 0x20D2...0x20D3 => .overlay,
972 0x20D4...0x20D7 => .above,
973 0x20D8...0x20DA => .overlay,
974 0x20DB...0x20DC => .above,
975 0x20E1...0x20E1 => .above,
976 0x20E5...0x20E6 => .overlay,
977 0x20E7...0x20E7 => .above,
978 0x20E8...0x20E8 => .below,
979 0x20E9...0x20E9 => .above,
980 0x20EA...0x20EB => .overlay,
981 0x20EC...0x20EF => .below,
982 0x20F0...0x20F0 => .above,
983 0x2CEF...0x2CF1 => .above,
984 0x2D7F...0x2D7F => .virama,
985 0x2DE0...0x2DFF => .above,
986 0x302A...0x302A => .below_left,
987 0x302B...0x302B => .above_left,
988 0x302C...0x302C => .above_right,
989 0x302D...0x302D => .below_right,
990 0x302E...0x302F => .left,
991 0x3099...0x309A => .kana_voicing,
992 0xA66F...0xA66F => .above,
993 0xA674...0xA67D => .above,
994 0xA69E...0xA69F => .above,
995 0xA6F0...0xA6F1 => .above,
996 0xA806...0xA806 => .virama,
997 0xA82C...0xA82C => .virama,
998 0xA8C4...0xA8C4 => .virama,
999 0xA8E0...0xA8F1 => .above,
1000 0xA92B...0xA92D => .below,
1001 0xA953...0xA953 => .virama,
1002 0xA9B3...0xA9B3 => .nukta,
1003 0xA9C0...0xA9C0 => .virama,
1004 0xAAB0...0xAAB0 => .above,
1005 0xAAB2...0xAAB3 => .above,
1006 0xAAB4...0xAAB4 => .below,
1007 0xAAB7...0xAAB8 => .above,
1008 0xAABE...0xAABF => .above,
1009 0xAAC1...0xAAC1 => .above,
1010 0xAAF6...0xAAF6 => .virama,
1011 0xABED...0xABED => .virama,
1012 0xFB1E...0xFB1E => .ccc26,
1013 0xFE20...0xFE26 => .above,
1014 0xFE27...0xFE2D => .below,
1015 0xFE2E...0xFE2F => .above,
1016 0x101FD...0x101FD => .below,
1017 0x102E0...0x102E0 => .below,
1018 0x10376...0x1037A => .above,
1019 0x10A0D...0x10A0D => .below,
1020 0x10A0F...0x10A0F => .above,
1021 0x10A38...0x10A38 => .above,
1022 0x10A39...0x10A39 => .overlay,
1023 0x10A3A...0x10A3A => .below,
1024 0x10A3F...0x10A3F => .virama,
1025 0x10AE5...0x10AE5 => .above,
1026 0x10AE6...0x10AE6 => .below,
1027 0x10D24...0x10D27 => .above,
1028 0x10EAB...0x10EAC => .above,
1029 0x10EFD...0x10EFF => .below,
1030 0x10F46...0x10F47 => .below,
1031 0x10F48...0x10F4A => .above,
1032 0x10F4B...0x10F4B => .below,
1033 0x10F4C...0x10F4C => .above,
1034 0x10F4D...0x10F50 => .below,
1035 0x10F82...0x10F82 => .above,
1036 0x10F83...0x10F83 => .below,
1037 0x10F84...0x10F84 => .above,
1038 0x10F85...0x10F85 => .below,
1039 0x11046...0x11046 => .virama,
1040 0x11070...0x11070 => .virama,
1041 0x1107F...0x1107F => .virama,
1042 0x110B9...0x110B9 => .virama,
1043 0x110BA...0x110BA => .nukta,
1044 0x11100...0x11102 => .above,
1045 0x11133...0x11134 => .virama,
1046 0x11173...0x11173 => .nukta,
1047 0x111C0...0x111C0 => .virama,
1048 0x111CA...0x111CA => .nukta,
1049 0x11235...0x11235 => .virama,
1050 0x11236...0x11236 => .nukta,
1051 0x112E9...0x112E9 => .nukta,
1052 0x112EA...0x112EA => .virama,
1053 0x1133B...0x1133C => .nukta,
1054 0x1134D...0x1134D => .virama,
1055 0x11366...0x1136C => .above,
1056 0x11370...0x11374 => .above,
1057 0x11442...0x11442 => .virama,
1058 0x11446...0x11446 => .nukta,
1059 0x1145E...0x1145E => .above,
1060 0x114C2...0x114C2 => .virama,
1061 0x114C3...0x114C3 => .nukta,
1062 0x115BF...0x115BF => .virama,
1063 0x115C0...0x115C0 => .nukta,
1064 0x1163F...0x1163F => .virama,
1065 0x116B6...0x116B6 => .virama,
1066 0x116B7...0x116B7 => .nukta,
1067 0x1172B...0x1172B => .virama,
1068 0x11839...0x11839 => .virama,
1069 0x1183A...0x1183A => .nukta,
1070 0x1193D...0x1193E => .virama,
1071 0x11943...0x11943 => .nukta,
1072 0x119E0...0x119E0 => .virama,
1073 0x11A34...0x11A34 => .virama,
1074 0x11A47...0x11A47 => .virama,
1075 0x11A99...0x11A99 => .virama,
1076 0x11C3F...0x11C3F => .virama,
1077 0x11D42...0x11D42 => .nukta,
1078 0x11D44...0x11D45 => .virama,
1079 0x11D97...0x11D97 => .virama,
1080 0x11F41...0x11F42 => .virama,
1081 0x16AF0...0x16AF4 => .overlay,
1082 0x16B30...0x16B36 => .above,
1083 0x16FF0...0x16FF1 => .han_reading,
1084 0x1BC9E...0x1BC9E => .overlay,
1085 0x1D165...0x1D166 => .attached_above_right,
1086 0x1D167...0x1D169 => .overlay,
1087 0x1D16D...0x1D16D => .right,
1088 0x1D16E...0x1D172 => .attached_above_right,
1089 0x1D17B...0x1D182 => .below,
1090 0x1D185...0x1D189 => .above,
1091 0x1D18A...0x1D18B => .below,
1092 0x1D1AA...0x1D1AD => .above,
1093 0x1D242...0x1D244 => .above,
1094 0x1E000...0x1E006 => .above,
1095 0x1E008...0x1E018 => .above,
1096 0x1E01B...0x1E021 => .above,
1097 0x1E023...0x1E024 => .above,
1098 0x1E026...0x1E02A => .above,
1099 0x1E08F...0x1E08F => .above,
1100 0x1E130...0x1E136 => .above,
1101 0x1E2AE...0x1E2AE => .above,
1102 0x1E2EC...0x1E2EF => .above,
1103 0x1E4EC...0x1E4ED => .above_right,
1104 0x1E4EE...0x1E4EE => .below,
1105 0x1E4EF...0x1E4EF => .above,
1106 0x1E8D0...0x1E8D6 => .below,
1107 0x1E944...0x1E949 => .above,
1108 0x1E94A...0x1E94A => .nukta,
1109 else => .not_reordered,
1110 };
1111}
lib/compiler/aro/aro/char_info/identifier_tables.zig created+627
......@@ -0,0 +1,627 @@
1//! Adapted from the `unicode-ident` crate: https://github.com/dtolnay/unicode-ident
2//! and Unicode Standard Annex #31 https://www.unicode.org/reports/tr31/
3//! Licensed under the MIT License and the Unicode license
4
5pub const chunk = 64;
6
7pub const trie_start: [402]u8 align(8) = .{
8 0x04, 0x0B, 0x0F, 0x13, 0x17, 0x1B, 0x1F, 0x23, 0x27, 0x2D, 0x31, 0x34, 0x38, 0x3C, 0x40, 0x02,
9 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
10 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
11 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
12 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
13 0x05, 0x05, 0x51, 0x54, 0x58, 0x5C, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
14 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00,
15 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60, 0x64, 0x66,
16 0x6A, 0x6E, 0x72, 0x28, 0x76, 0x78, 0x7C, 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9E, 0xA2,
17 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00,
18 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
19 0x00, 0x00, 0x00, 0x00, 0x05, 0xB1, 0x00, 0xB5, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
20 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC8, 0x00, 0x00, 0x00, 0xAF,
23 0xCE, 0xD2, 0xD6, 0xBC, 0xDA, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
25 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
26 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
27 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
28 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
29 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05,
30 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
31 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00,
32 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
33 0x05, 0xE7,
34};
35
36pub const trie_continue: [1793]u8 align(8) = .{
37 0x08, 0x0D, 0x11, 0x15, 0x19, 0x1D, 0x21, 0x25, 0x2A, 0x2F, 0x31, 0x36, 0x3A, 0x3E, 0x42, 0x02,
38 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x4F, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
39 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
40 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
41 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
42 0x05, 0x05, 0x51, 0x56, 0x5A, 0x5E, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
43 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x64, 0x68,
45 0x6C, 0x70, 0x74, 0x28, 0x76, 0x7A, 0x7E, 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9B, 0xA0, 0xA4,
46 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x05, 0xB3, 0x00, 0xB7, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
49 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC, 0xC4, 0xC6, 0xCA, 0x00, 0xCC, 0x00, 0xAF,
52 0xD0, 0xD4, 0xD8, 0xBC, 0xDC, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00,
53 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
54 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
55 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
56 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
57 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
58 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05,
59 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
60 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00,
61 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
62 0x05, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0xC2,
150};
151
152pub const leaf: [7584]u8 align(64) = .{
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xAA, 0xFF, 0xFF, 0xFF, 0x3F,
160 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x5F, 0xDC, 0x1F, 0xCF, 0x0F, 0xFF, 0x1F, 0xDC, 0x1F,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
163 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
164 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
165 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
166 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xA0, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
171 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
172 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
173 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
174 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
175 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
176 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xB8,
178 0x40, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
179 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
180 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00,
181 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xB8,
182 0xC0, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
185 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
186 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00,
187 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
188 0xFB, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
190 0xFF, 0x01, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xB6, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF,
192 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x60, 0xC0, 0x00, 0x9C,
193 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
194 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x02, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x07, 0x30, 0x04,
195 0x00, 0x00, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF,
196 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x9F, 0xFF, 0xFD, 0xFF, 0x9F,
197 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
198 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x24,
199 0xFF, 0xFF, 0x3F, 0x04, 0x10, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0xFF,
200 0xFF, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0x01, 0xFF, 0x03, 0x00, 0xFE, 0xFF,
202 0xE1, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0x23, 0x00, 0x40, 0x00, 0xB0, 0x03, 0x00, 0x03, 0x10,
203 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x07, 0xFF, 0xFF,
204 0xFF, 0x7E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF,
205 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0xFF,
206 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0xF3, 0x9F, 0x79, 0x80, 0xB0, 0xCF, 0xFF, 0x03, 0x50,
207 0xE0, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0x03, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x1C, 0x00,
208 0xE0, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02,
209 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x00, 0xB0, 0x03, 0x00, 0x02, 0x00,
210 0xE8, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0xEE, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0xD3, 0x87, 0x39, 0x02, 0x5E, 0xC0, 0xFF, 0x3F, 0x00,
212 0xEE, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0xBF, 0x3B, 0x01, 0x00, 0xCF, 0xFF, 0x00, 0xFE,
213 0xEE, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0x9F, 0x39, 0xE0, 0xB0, 0xCF, 0xFF, 0x02, 0x00,
214 0xEC, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0xC3, 0xC7, 0x3D, 0x81, 0x00, 0xC0, 0xFF, 0x00, 0x00,
215 0xE0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0x23, 0x00, 0x00, 0x00, 0x27, 0x03, 0x00, 0x00, 0x00,
216 0xE1, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0x23, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x06, 0x00,
217 0xF0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00, 0x40, 0x70, 0x80, 0x03, 0x00, 0x00, 0xFC,
218 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xF3, 0xDF, 0x3D, 0x60, 0x27, 0xCF, 0xFF, 0x00, 0x00,
220 0xEF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0xF3, 0xDF, 0x3D, 0x60, 0x60, 0xCF, 0xFF, 0x0E, 0x00,
221 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7D, 0xF0, 0x80, 0xCF, 0xFF, 0x00, 0xFC,
222 0xEE, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x84, 0x5F, 0xFF, 0xC0, 0xFF, 0x0C, 0x00,
223 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0x05, 0x20, 0x5F, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00,
225 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00,
226 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x7F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
228 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0x3F, 0x5F, 0x7F, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00,
229 0x01, 0x00, 0x00, 0x03, 0xFF, 0x03, 0xA0, 0xC2, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0xFE, 0xFF,
230 0xDF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x80, 0x00, 0x00, 0x3F, 0x3C, 0x62, 0xC0, 0xE1, 0xFF,
232 0x03, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
233 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
234 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
235 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00,
236 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
238 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
239 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
240 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
241 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
242 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF,
244 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
245 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
246 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F,
247 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF,
248 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
249 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0xFE, 0x03, 0x00,
250 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F,
251 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
252 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
253 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
254 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
255 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
256 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
257 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
258 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01,
259 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xDF, 0x01, 0x00,
260 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00,
261 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
262 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01,
263 0xFF, 0xFF, 0x3F, 0x80, 0xFF, 0xFF, 0x1F, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xDF, 0x0D, 0x00,
264 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x30, 0xFF, 0x03, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
266 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
267 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
268 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0xB8, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
270 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
271 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x0F, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
272 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
273 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0xF8, 0xFF, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00,
277 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x9F,
278 0xFF, 0x03, 0xFF, 0x03, 0x80, 0x00, 0xFF, 0xBF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x03, 0x00, 0xF8, 0x0F, 0x00,
280 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
281 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F,
282 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x6F, 0x04,
283 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
284 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
286 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
287 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
288 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
289 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0xF0, 0x00, 0xFF, 0xFF,
290 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
292 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
294 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x80,
296 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x1F, 0xE2, 0xFF, 0x01, 0x00,
297 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
298 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
300 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x78, 0x0C, 0x00,
301 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
302 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00,
303 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
304 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0x0F, 0x00,
305 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x80,
306 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
307 0xE0, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
308 0xFF, 0xFF, 0x7F, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
309 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
310 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
311 0xE0, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
312 0xFF, 0xFF, 0x7F, 0xE6, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
313 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
314 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
315 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
316 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
317 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
318 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
319 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
320 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
321 0xFF, 0x1F, 0xFF, 0xFF, 0x00, 0x0C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x80,
322 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
323 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
324 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF,
325 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xBF,
326 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
327 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
328 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF,
329 0xBB, 0xF7, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
330 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x68,
331 0x00, 0xFC, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
332 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0xDF, 0xFF, 0x00, 0x7C,
333 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
334 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xE8,
335 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
336 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x7F,
337 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF7, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0xC4,
338 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x3E, 0x05, 0x00, 0x00, 0x38, 0xFF, 0x07, 0x1C, 0x00,
339 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF,
340 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00,
341 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0x7F, 0xFC,
342 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x38, 0xFF, 0xFF, 0x7C, 0x00,
343 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF,
344 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x37, 0xFF, 0x03,
345 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
346 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
347 0x7F, 0x00, 0xF8, 0xA0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
348 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
349 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
350 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
351 0x7F, 0x00, 0xF8, 0xE0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
352 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
353 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF,
354 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
355 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
356 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA,
358 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
359 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF,
360 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00,
361 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA,
362 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
363 0x00, 0x00, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF,
364 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00,
365 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
366 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
370 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
376 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
379 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
380 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
382 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
383 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7,
384 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
386 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
387 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7,
388 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x3F, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x91, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
390 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x37, 0x00,
391 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x01, 0x00, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
394 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00,
395 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00,
396 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x6F, 0xF0, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x87, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
398 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00,
399 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00,
400 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
403 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
407 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
412 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
415 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF,
416 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
417 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00,
418 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00,
419 0xF8, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x90, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0x00,
420 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
421 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x80,
422 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03,
423 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x00,
424 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xDE, 0xFF, 0x17, 0x00, 0x00, 0x00, 0x00,
425 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x0F, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
427 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0xE0, 0x03, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x03,
431 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xFB, 0x9F, 0x39, 0x81, 0xE0, 0xCF, 0x1F, 0x1F, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
434 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
437 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xC3, 0x03, 0x00, 0x00, 0x00,
438 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00,
441 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x11, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
446 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0x0F, 0xFF, 0x03, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80,
451 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00,
453 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x80,
455 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0xBF, 0xF9, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1B, 0x00, 0x00, 0x00,
457 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0x00, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
458 0xFF, 0x03, 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00,
463 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
464 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x6F,
469 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
470 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xBF, 0xFD, 0xFF, 0xFF,
472 0xFF, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x01, 0x00, 0xFF, 0x03, 0x00, 0x00, 0xFC, 0xFF,
474 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xB4, 0xFF, 0x00, 0xFF, 0x03, 0xBF, 0xFD, 0xFF, 0xFF,
476 0xFF, 0x7F, 0xFB, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x00,
479 0xF4, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
483 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x07, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00,
486 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
487 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE3, 0x07, 0xF8,
500 0xE7, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF,
508 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
509 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xE0,
510 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF,
512 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
513 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x0F, 0x00, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xE0,
514 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
522 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00,
523 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
524 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
528 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x6F, 0xFF, 0x7F,
533 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F,
534 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
539 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F,
540 0xFF, 0x01, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
544 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
550 0xFF, 0xFF, 0xFF, 0xDF, 0x64, 0xDE, 0xFF, 0xEB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
551 0xBF, 0xE7, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0x7B, 0x5F, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
552 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
553 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
554 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7,
555 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
556 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
558 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7,
559 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
560 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
561 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x00,
562 0x10, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x3F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x7F, 0xFF, 0xFF, 0xF9, 0xDB, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
570 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
590 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
594 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0xEF, 0xFF, 0xFF, 0xFF, 0x96, 0xFE, 0xF7, 0x0A, 0x84, 0xEA, 0x96, 0xAA, 0x96, 0xF7, 0xF7, 0x5E,
598 0xFF, 0xFB, 0xFF, 0x0F, 0xEE, 0xFB, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
602 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
603 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
604 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
605 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
606 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0xFF, 0xFF,
607 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
608 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
609 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
610 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
611 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
612 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
613 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
614 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
615 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
616 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
617 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
618 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627};
lib/compiler/aro/aro/features.zig created+76
......@@ -0,0 +1,76 @@
1const std = @import("std");
2const Compilation = @import("Compilation.zig");
3const target_util = @import("target.zig");
4
5/// Used to implement the __has_feature macro.
6pub fn hasFeature(comp: *Compilation, ext: []const u8) bool {
7 const list = .{
8 .assume_nonnull = true,
9 .attribute_analyzer_noreturn = true,
10 .attribute_availability = true,
11 .attribute_availability_with_message = true,
12 .attribute_availability_app_extension = true,
13 .attribute_availability_with_version_underscores = true,
14 .attribute_availability_tvos = true,
15 .attribute_availability_watchos = true,
16 .attribute_availability_with_strict = true,
17 .attribute_availability_with_replacement = true,
18 .attribute_availability_in_templates = true,
19 .attribute_availability_swift = true,
20 .attribute_cf_returns_not_retained = true,
21 .attribute_cf_returns_retained = true,
22 .attribute_cf_returns_on_parameters = true,
23 .attribute_deprecated_with_message = true,
24 .attribute_deprecated_with_replacement = true,
25 .attribute_ext_vector_type = true,
26 .attribute_ns_returns_not_retained = true,
27 .attribute_ns_returns_retained = true,
28 .attribute_ns_consumes_self = true,
29 .attribute_ns_consumed = true,
30 .attribute_cf_consumed = true,
31 .attribute_overloadable = true,
32 .attribute_unavailable_with_message = true,
33 .attribute_unused_on_fields = true,
34 .attribute_diagnose_if_objc = true,
35 .blocks = false, // TODO
36 .c_thread_safety_attributes = true,
37 .enumerator_attributes = true,
38 .nullability = true,
39 .nullability_on_arrays = true,
40 .nullability_nullable_result = true,
41 .c_alignas = comp.langopts.standard.atLeast(.c11),
42 .c_alignof = comp.langopts.standard.atLeast(.c11),
43 .c_atomic = comp.langopts.standard.atLeast(.c11),
44 .c_generic_selections = comp.langopts.standard.atLeast(.c11),
45 .c_static_assert = comp.langopts.standard.atLeast(.c11),
46 .c_thread_local = comp.langopts.standard.atLeast(.c11) and target_util.isTlsSupported(comp.target),
47 };
48 inline for (std.meta.fields(@TypeOf(list))) |f| {
49 if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
50 }
51 return false;
52}
53
54/// Used to implement the __has_extension macro.
55pub fn hasExtension(comp: *Compilation, ext: []const u8) bool {
56 const list = .{
57 // C11 features
58 .c_alignas = true,
59 .c_alignof = true,
60 .c_atomic = false, // TODO
61 .c_generic_selections = true,
62 .c_static_assert = true,
63 .c_thread_local = target_util.isTlsSupported(comp.target),
64 // misc
65 .overloadable_unmarked = false, // TODO
66 .statement_attributes_with_gnu_syntax = false, // TODO
67 .gnu_asm = true,
68 .gnu_asm_goto_with_outputs = true,
69 .matrix_types = false, // TODO
70 .matrix_types_scalar_division = false, // TODO
71 };
72 inline for (std.meta.fields(@TypeOf(list))) |f| {
73 if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name);
74 }
75 return false;
76}
lib/compiler/aro/aro/pragmas/gcc.zig created+199
......@@ -0,0 +1,199 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const TokenIndex = @import("../Tree.zig").TokenIndex;
9
10const GCC = @This();
11
12pragma: Pragma = .{
13 .beforeParse = beforeParse,
14 .beforePreprocess = beforePreprocess,
15 .afterParse = afterParse,
16 .deinit = deinit,
17 .preprocessorHandler = preprocessorHandler,
18 .parserHandler = parserHandler,
19 .preserveTokens = preserveTokens,
20},
21original_options: Diagnostics.Options = .{},
22options_stack: std.ArrayListUnmanaged(Diagnostics.Options) = .{},
23
24const Directive = enum {
25 warning,
26 @"error",
27 diagnostic,
28 poison,
29 const Diagnostics = enum {
30 ignored,
31 warning,
32 @"error",
33 fatal,
34 push,
35 pop,
36 };
37};
38
39fn beforePreprocess(pragma: *Pragma, comp: *Compilation) void {
40 var self = @fieldParentPtr(GCC, "pragma", pragma);
41 self.original_options = comp.diagnostics.options;
42}
43
44fn beforeParse(pragma: *Pragma, comp: *Compilation) void {
45 var self = @fieldParentPtr(GCC, "pragma", pragma);
46 comp.diagnostics.options = self.original_options;
47 self.options_stack.items.len = 0;
48}
49
50fn afterParse(pragma: *Pragma, comp: *Compilation) void {
51 var self = @fieldParentPtr(GCC, "pragma", pragma);
52 comp.diagnostics.options = self.original_options;
53 self.options_stack.items.len = 0;
54}
55
56pub fn init(allocator: mem.Allocator) !*Pragma {
57 var gcc = try allocator.create(GCC);
58 gcc.* = .{};
59 return &gcc.pragma;
60}
61
62fn deinit(pragma: *Pragma, comp: *Compilation) void {
63 var self = @fieldParentPtr(GCC, "pragma", pragma);
64 self.options_stack.deinit(comp.gpa);
65 comp.gpa.destroy(self);
66}
67
68fn diagnosticHandler(self: *GCC, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
69 const diagnostic_tok = pp.tokens.get(start_idx);
70 if (diagnostic_tok.id == .nl) return;
71
72 const diagnostic = std.meta.stringToEnum(Directive.Diagnostics, pp.expandedSlice(diagnostic_tok)) orelse
73 return error.UnknownPragma;
74
75 switch (diagnostic) {
76 .ignored, .warning, .@"error", .fatal => {
77 const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
78 error.ExpectedStringLiteral => {
79 return pp.comp.addDiagnostic(.{
80 .tag = .pragma_requires_string_literal,
81 .loc = diagnostic_tok.loc,
82 .extra = .{ .str = "GCC diagnostic" },
83 }, diagnostic_tok.expansionSlice());
84 },
85 else => |e| return e,
86 };
87 if (!mem.startsWith(u8, str, "-W")) {
88 const next = pp.tokens.get(start_idx + 1);
89 return pp.comp.addDiagnostic(.{
90 .tag = .malformed_warning_check,
91 .loc = next.loc,
92 .extra = .{ .str = "GCC diagnostic" },
93 }, next.expansionSlice());
94 }
95 const new_kind: Diagnostics.Kind = switch (diagnostic) {
96 .ignored => .off,
97 .warning => .warning,
98 .@"error" => .@"error",
99 .fatal => .@"fatal error",
100 else => unreachable,
101 };
102
103 try pp.comp.diagnostics.set(str[2..], new_kind);
104 },
105 .push => try self.options_stack.append(pp.comp.gpa, pp.comp.diagnostics.options),
106 .pop => pp.comp.diagnostics.options = self.options_stack.popOrNull() orelse self.original_options,
107 }
108}
109
110fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
111 var self = @fieldParentPtr(GCC, "pragma", pragma);
112 const directive_tok = pp.tokens.get(start_idx + 1);
113 if (directive_tok.id == .nl) return;
114
115 const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse
116 return pp.comp.addDiagnostic(.{
117 .tag = .unknown_gcc_pragma,
118 .loc = directive_tok.loc,
119 }, directive_tok.expansionSlice());
120
121 switch (gcc_pragma) {
122 .warning, .@"error" => {
123 const text = Pragma.pasteTokens(pp, start_idx + 2) catch |err| switch (err) {
124 error.ExpectedStringLiteral => {
125 return pp.comp.addDiagnostic(.{
126 .tag = .pragma_requires_string_literal,
127 .loc = directive_tok.loc,
128 .extra = .{ .str = @tagName(gcc_pragma) },
129 }, directive_tok.expansionSlice());
130 },
131 else => |e| return e,
132 };
133 const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diagnostics.arena.allocator().dupe(u8, text) };
134 const diagnostic_tag: Diagnostics.Tag = if (gcc_pragma == .warning) .pragma_warning_message else .pragma_error_message;
135 return pp.comp.addDiagnostic(
136 .{ .tag = diagnostic_tag, .loc = directive_tok.loc, .extra = extra },
137 directive_tok.expansionSlice(),
138 );
139 },
140 .diagnostic => return self.diagnosticHandler(pp, start_idx + 2) catch |err| switch (err) {
141 error.UnknownPragma => {
142 const tok = pp.tokens.get(start_idx + 2);
143 return pp.comp.addDiagnostic(.{
144 .tag = .unknown_gcc_pragma_directive,
145 .loc = tok.loc,
146 }, tok.expansionSlice());
147 },
148 else => |e| return e,
149 },
150 .poison => {
151 var i: usize = 2;
152 while (true) : (i += 1) {
153 const tok = pp.tokens.get(start_idx + i);
154 if (tok.id == .nl) break;
155
156 if (!tok.id.isMacroIdentifier()) {
157 return pp.comp.addDiagnostic(.{
158 .tag = .pragma_poison_identifier,
159 .loc = tok.loc,
160 }, tok.expansionSlice());
161 }
162 const str = pp.expandedSlice(tok);
163 if (pp.defines.get(str) != null) {
164 try pp.comp.addDiagnostic(.{
165 .tag = .pragma_poison_macro,
166 .loc = tok.loc,
167 }, tok.expansionSlice());
168 }
169 try pp.poisoned_identifiers.put(str, {});
170 }
171 return;
172 },
173 }
174}
175
176fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
177 var self = @fieldParentPtr(GCC, "pragma", pragma);
178 const directive_tok = p.pp.tokens.get(start_idx + 1);
179 if (directive_tok.id == .nl) return;
180 const name = p.pp.expandedSlice(directive_tok);
181 if (mem.eql(u8, name, "diagnostic")) {
182 return self.diagnosticHandler(p.pp, start_idx + 2) catch |err| switch (err) {
183 error.UnknownPragma => {}, // handled during preprocessing
184 error.StopPreprocessing => unreachable, // Only used by #pragma once
185 else => |e| return e,
186 };
187 }
188}
189
190fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
191 const next = pp.tokens.get(start_idx + 1);
192 if (next.id != .nl) {
193 const name = pp.expandedSlice(next);
194 if (mem.eql(u8, name, "poison")) {
195 return false;
196 }
197 }
198 return true;
199}
lib/compiler/aro/aro/pragmas/message.zig created+50
......@@ -0,0 +1,50 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const TokenIndex = @import("../Tree.zig").TokenIndex;
9const Source = @import("../Source.zig");
10
11const Message = @This();
12
13pragma: Pragma = .{
14 .deinit = deinit,
15 .preprocessorHandler = preprocessorHandler,
16},
17
18pub fn init(allocator: mem.Allocator) !*Pragma {
19 var once = try allocator.create(Message);
20 once.* = .{};
21 return &once.pragma;
22}
23
24fn deinit(pragma: *Pragma, comp: *Compilation) void {
25 const self = @fieldParentPtr(Message, "pragma", pragma);
26 comp.gpa.destroy(self);
27}
28
29fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
30 const message_tok = pp.tokens.get(start_idx);
31 const message_expansion_locs = message_tok.expansionSlice();
32
33 const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) {
34 error.ExpectedStringLiteral => {
35 return pp.comp.addDiagnostic(.{
36 .tag = .pragma_requires_string_literal,
37 .loc = message_tok.loc,
38 .extra = .{ .str = "message" },
39 }, message_expansion_locs);
40 },
41 else => |e| return e,
42 };
43
44 const loc = if (message_expansion_locs.len != 0)
45 message_expansion_locs[message_expansion_locs.len - 1]
46 else
47 message_tok.loc;
48 const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diagnostics.arena.allocator().dupe(u8, str) };
49 return pp.comp.addDiagnostic(.{ .tag = .pragma_message, .loc = loc, .extra = extra }, &.{});
50}
lib/compiler/aro/aro/pragmas/once.zig created+56
......@@ -0,0 +1,56 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const TokenIndex = @import("../Tree.zig").TokenIndex;
9const Source = @import("../Source.zig");
10
11const Once = @This();
12
13pragma: Pragma = .{
14 .afterParse = afterParse,
15 .deinit = deinit,
16 .preprocessorHandler = preprocessorHandler,
17},
18pragma_once: std.AutoHashMap(Source.Id, void),
19preprocess_count: u32 = 0,
20
21pub fn init(allocator: mem.Allocator) !*Pragma {
22 var once = try allocator.create(Once);
23 once.* = .{
24 .pragma_once = std.AutoHashMap(Source.Id, void).init(allocator),
25 };
26 return &once.pragma;
27}
28
29fn afterParse(pragma: *Pragma, _: *Compilation) void {
30 var self = @fieldParentPtr(Once, "pragma", pragma);
31 self.pragma_once.clearRetainingCapacity();
32}
33
34fn deinit(pragma: *Pragma, comp: *Compilation) void {
35 var self = @fieldParentPtr(Once, "pragma", pragma);
36 self.pragma_once.deinit();
37 comp.gpa.destroy(self);
38}
39
40fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
41 var self = @fieldParentPtr(Once, "pragma", pragma);
42 const name_tok = pp.tokens.get(start_idx);
43 const next = pp.tokens.get(start_idx + 1);
44 if (next.id != .nl) {
45 try pp.comp.addDiagnostic(.{
46 .tag = .extra_tokens_directive_end,
47 .loc = name_tok.loc,
48 }, next.expansionSlice());
49 }
50 const seen = self.preprocess_count == pp.preprocess_count;
51 const prev = try self.pragma_once.fetchPut(name_tok.loc.id, {});
52 if (prev != null and !seen) {
53 return error.StopPreprocessing;
54 }
55 self.preprocess_count = pp.preprocess_count;
56}
lib/compiler/aro/aro/pragmas/pack.zig created+164
......@@ -0,0 +1,164 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const Pragma = @import("../Pragma.zig");
5const Diagnostics = @import("../Diagnostics.zig");
6const Preprocessor = @import("../Preprocessor.zig");
7const Parser = @import("../Parser.zig");
8const Tree = @import("../Tree.zig");
9const TokenIndex = Tree.TokenIndex;
10
11const Pack = @This();
12
13pragma: Pragma = .{
14 .deinit = deinit,
15 .parserHandler = parserHandler,
16 .preserveTokens = preserveTokens,
17},
18stack: std.ArrayListUnmanaged(struct { label: []const u8, val: u8 }) = .{},
19
20pub fn init(allocator: mem.Allocator) !*Pragma {
21 var pack = try allocator.create(Pack);
22 pack.* = .{};
23 return &pack.pragma;
24}
25
26fn deinit(pragma: *Pragma, comp: *Compilation) void {
27 var self = @fieldParentPtr(Pack, "pragma", pragma);
28 self.stack.deinit(comp.gpa);
29 comp.gpa.destroy(self);
30}
31
32fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void {
33 var pack = @fieldParentPtr(Pack, "pragma", pragma);
34 var idx = start_idx + 1;
35 const l_paren = p.pp.tokens.get(idx);
36 if (l_paren.id != .l_paren) {
37 return p.comp.addDiagnostic(.{
38 .tag = .pragma_pack_lparen,
39 .loc = l_paren.loc,
40 }, l_paren.expansionSlice());
41 }
42 idx += 1;
43
44 // TODO -fapple-pragma-pack -fxl-pragma-pack
45 const apple_or_xl = false;
46 const tok_ids = p.pp.tokens.items(.id);
47 const arg = idx;
48 switch (tok_ids[arg]) {
49 .identifier => {
50 idx += 1;
51 const Action = enum {
52 show,
53 push,
54 pop,
55 };
56 const action = std.meta.stringToEnum(Action, p.tokSlice(arg)) orelse {
57 return p.errTok(.pragma_pack_unknown_action, arg);
58 };
59 switch (action) {
60 .show => {
61 try p.errExtra(.pragma_pack_show, arg, .{ .unsigned = p.pragma_pack orelse 8 });
62 },
63 .push, .pop => {
64 var new_val: ?u8 = null;
65 var label: ?[]const u8 = null;
66 if (tok_ids[idx] == .comma) {
67 idx += 1;
68 const next = idx;
69 idx += 1;
70 switch (tok_ids[next]) {
71 .pp_num => new_val = (try packInt(p, next)) orelse return,
72 .identifier => {
73 label = p.tokSlice(next);
74 if (tok_ids[idx] == .comma) {
75 idx += 1;
76 const int = idx;
77 idx += 1;
78 if (tok_ids[int] != .pp_num) return p.errTok(.pragma_pack_int_ident, int);
79 new_val = (try packInt(p, int)) orelse return;
80 }
81 },
82 else => return p.errTok(.pragma_pack_int_ident, next),
83 }
84 }
85 if (action == .push) {
86 try pack.stack.append(p.gpa, .{ .label = label orelse "", .val = p.pragma_pack orelse 8 });
87 } else {
88 pack.pop(p, label);
89 if (new_val != null) {
90 try p.errTok(.pragma_pack_undefined_pop, arg);
91 } else if (pack.stack.items.len == 0) {
92 try p.errTok(.pragma_pack_empty_stack, arg);
93 }
94 }
95 if (new_val) |some| {
96 p.pragma_pack = some;
97 }
98 },
99 }
100 },
101 .r_paren => if (apple_or_xl) {
102 pack.pop(p, null);
103 } else {
104 p.pragma_pack = null;
105 },
106 .pp_num => {
107 const new_val = (try packInt(p, arg)) orelse return;
108 idx += 1;
109 if (apple_or_xl) {
110 try pack.stack.append(p.gpa, .{ .label = "", .val = p.pragma_pack });
111 }
112 p.pragma_pack = new_val;
113 },
114 else => {},
115 }
116
117 if (tok_ids[idx] != .r_paren) {
118 return p.errTok(.pragma_pack_rparen, idx);
119 }
120}
121
122fn packInt(p: *Parser, tok_i: TokenIndex) Compilation.Error!?u8 {
123 const res = p.parseNumberToken(tok_i) catch |err| switch (err) {
124 error.ParsingFailed => {
125 try p.errTok(.pragma_pack_int, tok_i);
126 return null;
127 },
128 else => |e| return e,
129 };
130 const int = res.val.toInt(u64, p.comp) orelse 99;
131 switch (int) {
132 1, 2, 4, 8, 16 => return @intCast(int),
133 else => {
134 try p.errTok(.pragma_pack_int, tok_i);
135 return null;
136 },
137 }
138}
139
140fn pop(pack: *Pack, p: *Parser, maybe_label: ?[]const u8) void {
141 if (maybe_label) |label| {
142 var i = pack.stack.items.len;
143 while (i > 0) {
144 i -= 1;
145 if (std.mem.eql(u8, pack.stack.items[i].label, label)) {
146 const prev = pack.stack.orderedRemove(i);
147 p.pragma_pack = prev.val;
148 return;
149 }
150 }
151 } else {
152 const prev = pack.stack.popOrNull() orelse {
153 p.pragma_pack = 2;
154 return;
155 };
156 p.pragma_pack = prev.val;
157 }
158}
159
160fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool {
161 _ = pp;
162 _ = start_idx;
163 return true;
164}
lib/compiler/aro/aro/record_layout.zig created+671
......@@ -0,0 +1,671 @@
1//! Record layout code adapted from https://github.com/mahkoh/repr-c
2//! Licensed under MIT license: https://github.com/mahkoh/repr-c/tree/master/repc/facade
3
4const std = @import("std");
5const Type = @import("Type.zig");
6const Attribute = @import("Attribute.zig");
7const Compilation = @import("Compilation.zig");
8const Parser = @import("Parser.zig");
9const Record = Type.Record;
10const Field = Record.Field;
11const TypeLayout = Type.TypeLayout;
12const FieldLayout = Type.FieldLayout;
13const target_util = @import("target.zig");
14
15const BITS_PER_BYTE = 8;
16
17const OngoingBitfield = struct {
18 size_bits: u64,
19 unused_size_bits: u64,
20};
21
22const SysVContext = struct {
23 /// Does the record have an __attribute__((packed)) annotation.
24 attr_packed: bool,
25 /// The value of #pragma pack(N) at the type level if any.
26 max_field_align_bits: ?u64,
27 /// The alignment of this record.
28 aligned_bits: u32,
29 is_union: bool,
30 /// The size of the record. This might not be a multiple of 8 if the record contains bit-fields.
31 /// For structs, this is also the offset of the first bit after the last field.
32 size_bits: u64,
33 /// non-null if the previous field was a non-zero-sized bit-field. Only used by MinGW.
34 ongoing_bitfield: ?OngoingBitfield,
35
36 comp: *const Compilation,
37
38 fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) SysVContext {
39 var pack_value: ?u64 = null;
40 if (pragma_pack) |pak| {
41 pack_value = pak * BITS_PER_BYTE;
42 }
43 var req_align: u29 = BITS_PER_BYTE;
44 if (ty.requestedAlignment(comp)) |aln| {
45 req_align = aln * BITS_PER_BYTE;
46 }
47 return SysVContext{
48 .attr_packed = ty.hasAttribute(.@"packed"),
49 .max_field_align_bits = pack_value,
50 .aligned_bits = req_align,
51 .is_union = ty.is(.@"union"),
52 .size_bits = 0,
53 .comp = comp,
54 .ongoing_bitfield = null,
55 };
56 }
57
58 fn layoutFields(self: *SysVContext, rec: *const Record) void {
59 for (rec.fields, 0..) |*fld, fld_indx| {
60 if (fld.ty.specifier == .invalid) continue;
61 const type_layout = computeLayout(fld.ty, self.comp);
62
63 var field_attrs: ?[]const Attribute = null;
64 if (rec.field_attributes) |attrs| {
65 field_attrs = attrs[fld_indx];
66 }
67 if (self.comp.target.isMinGW()) {
68 fld.layout = self.layoutMinGWField(fld, field_attrs, type_layout);
69 } else {
70 if (fld.isRegularField()) {
71 fld.layout = self.layoutRegularField(field_attrs, type_layout);
72 } else {
73 fld.layout = self.layoutBitField(field_attrs, type_layout, fld.isNamed(), fld.specifiedBitWidth());
74 }
75 }
76 }
77 }
78
79 /// On MinGW the alignment of the field is calculated in the usual way except that the alignment of
80 /// the underlying type is ignored in three cases
81 /// - the field is packed
82 /// - the field is a bit-field and the previous field was a non-zero-sized bit-field with the same type size
83 /// - the field is a zero-sized bit-field and the previous field was not a non-zero-sized bit-field
84 /// See test case 0068.
85 fn ignoreTypeAlignment(is_attr_packed: bool, bit_width: ?u32, ongoing_bitfield: ?OngoingBitfield, fld_layout: TypeLayout) bool {
86 if (is_attr_packed) return true;
87 if (bit_width) |width| {
88 if (ongoing_bitfield) |ongoing| {
89 if (ongoing.size_bits == fld_layout.size_bits) return true;
90 } else {
91 if (width == 0) return true;
92 }
93 }
94 return false;
95 }
96
97 fn layoutMinGWField(
98 self: *SysVContext,
99 field: *const Field,
100 field_attrs: ?[]const Attribute,
101 field_layout: TypeLayout,
102 ) FieldLayout {
103 const annotation_alignment_bits = BITS_PER_BYTE * (Type.annotationAlignment(self.comp, field_attrs) orelse 1);
104 const is_attr_packed = self.attr_packed or isPacked(field_attrs);
105 const ignore_type_alignment = ignoreTypeAlignment(is_attr_packed, field.bit_width, self.ongoing_bitfield, field_layout);
106
107 var field_alignment_bits: u64 = field_layout.field_alignment_bits;
108 if (ignore_type_alignment) {
109 field_alignment_bits = BITS_PER_BYTE;
110 }
111 field_alignment_bits = @max(field_alignment_bits, annotation_alignment_bits);
112 if (self.max_field_align_bits) |bits| {
113 field_alignment_bits = @min(field_alignment_bits, bits);
114 }
115
116 // The field affects the record alignment in one of three cases
117 // - the field is a regular field
118 // - the field is a zero-width bit-field following a non-zero-width bit-field
119 // - the field is a non-zero-width bit-field and not packed.
120 // See test case 0069.
121 const update_record_alignment =
122 field.isRegularField() or
123 (field.specifiedBitWidth() == 0 and self.ongoing_bitfield != null) or
124 (field.specifiedBitWidth() != 0 and !is_attr_packed);
125
126 // If a field affects the alignment of a record, the alignment is calculated in the
127 // usual way except that __attribute__((packed)) is ignored on a zero-width bit-field.
128 // See test case 0068.
129 if (update_record_alignment) {
130 var ty_alignment_bits = field_layout.field_alignment_bits;
131 if (is_attr_packed and (field.isRegularField() or field.specifiedBitWidth() != 0)) {
132 ty_alignment_bits = BITS_PER_BYTE;
133 }
134 ty_alignment_bits = @max(ty_alignment_bits, annotation_alignment_bits);
135 if (self.max_field_align_bits) |bits| {
136 ty_alignment_bits = @intCast(@min(ty_alignment_bits, bits));
137 }
138 self.aligned_bits = @max(self.aligned_bits, ty_alignment_bits);
139 }
140
141 // NOTE: ty_alignment_bits and field_alignment_bits are different in the following case:
142 // Y = { size: 64, alignment: 64 }struct {
143 // { offset: 0, size: 1 }c { size: 8, alignment: 8 }char:1,
144 // @attr_packed _ { size: 64, alignment: 64 }long long:0,
145 // { offset: 8, size: 8 }d { size: 8, alignment: 8 }char,
146 // }
147 if (field.isRegularField()) {
148 return self.layoutRegularFieldMinGW(field_layout.size_bits, field_alignment_bits);
149 } else {
150 return self.layoutBitFieldMinGW(field_layout.size_bits, field_alignment_bits, field.isNamed(), field.specifiedBitWidth());
151 }
152 }
153
154 fn layoutBitFieldMinGW(
155 self: *SysVContext,
156 ty_size_bits: u64,
157 field_alignment_bits: u64,
158 is_named: bool,
159 width: u64,
160 ) FieldLayout {
161 std.debug.assert(width <= ty_size_bits); // validated in parser
162
163 // In a union, the size of the underlying type does not affect the size of the union.
164 // See test case 0070.
165 if (self.is_union) {
166 self.size_bits = @max(self.size_bits, width);
167 if (!is_named) return .{};
168 return .{
169 .offset_bits = 0,
170 .size_bits = width,
171 };
172 }
173 if (width == 0) {
174 self.ongoing_bitfield = null;
175 } else {
176 // If there is an ongoing bit-field in a struct whose underlying type has the same size and
177 // if there is enough space left to place this bit-field, then this bit-field is placed in
178 // the ongoing bit-field and the size of the struct is not affected by this
179 // bit-field. See test case 0037.
180 if (self.ongoing_bitfield) |*ongoing| {
181 if (ongoing.size_bits == ty_size_bits and ongoing.unused_size_bits >= width) {
182 const offset_bits = self.size_bits - ongoing.unused_size_bits;
183 ongoing.unused_size_bits -= width;
184 if (!is_named) return .{};
185 return .{
186 .offset_bits = offset_bits,
187 .size_bits = width,
188 };
189 }
190 }
191 // Otherwise this field is part of a new ongoing bit-field.
192 self.ongoing_bitfield = .{
193 .size_bits = ty_size_bits,
194 .unused_size_bits = ty_size_bits - width,
195 };
196 }
197 const offset_bits = std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
198 self.size_bits = if (width == 0) offset_bits else offset_bits + ty_size_bits;
199 if (!is_named) return .{};
200 return .{
201 .offset_bits = offset_bits,
202 .size_bits = width,
203 };
204 }
205
206 fn layoutRegularFieldMinGW(
207 self: *SysVContext,
208 ty_size_bits: u64,
209 field_alignment_bits: u64,
210 ) FieldLayout {
211 self.ongoing_bitfield = null;
212 // A struct field starts at the next offset in the struct that is properly
213 // aligned with respect to the start of the struct. See test case 0033.
214 // A union field always starts at offset 0.
215 const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, field_alignment_bits);
216
217 // Set the size of the record to the maximum of the current size and the end of
218 // the field. See test case 0034.
219 self.size_bits = @max(self.size_bits, offset_bits + ty_size_bits);
220
221 return .{
222 .offset_bits = offset_bits,
223 .size_bits = ty_size_bits,
224 };
225 }
226
227 fn layoutRegularField(
228 self: *SysVContext,
229 fld_attrs: ?[]const Attribute,
230 fld_layout: TypeLayout,
231 ) FieldLayout {
232 var fld_align_bits = fld_layout.field_alignment_bits;
233
234 // If the struct or the field is packed, then the alignment of the underlying type is
235 // ignored. See test case 0084.
236 if (self.attr_packed or isPacked(fld_attrs)) {
237 fld_align_bits = BITS_PER_BYTE;
238 }
239
240 // The field alignment can be increased by __attribute__((aligned)) annotations on the
241 // field. See test case 0085.
242 if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
243 fld_align_bits = @max(fld_align_bits, anno * BITS_PER_BYTE);
244 }
245
246 // #pragma pack takes precedence over all other attributes. See test cases 0084 and
247 // 0085.
248 if (self.max_field_align_bits) |req_bits| {
249 fld_align_bits = @intCast(@min(fld_align_bits, req_bits));
250 }
251
252 // A struct field starts at the next offset in the struct that is properly
253 // aligned with respect to the start of the struct.
254 const offset_bits = if (self.is_union) 0 else std.mem.alignForward(u64, self.size_bits, fld_align_bits);
255 const size_bits = fld_layout.size_bits;
256
257 // The alignment of a record is the maximum of its field alignments. See test cases
258 // 0084, 0085, 0086.
259 self.size_bits = @max(self.size_bits, offset_bits + size_bits);
260 self.aligned_bits = @max(self.aligned_bits, fld_align_bits);
261
262 return .{
263 .offset_bits = offset_bits,
264 .size_bits = size_bits,
265 };
266 }
267
268 fn layoutBitField(
269 self: *SysVContext,
270 fld_attrs: ?[]const Attribute,
271 fld_layout: TypeLayout,
272 is_named: bool,
273 bit_width: u64,
274 ) FieldLayout {
275 const ty_size_bits = fld_layout.size_bits;
276 var ty_fld_algn_bits: u32 = fld_layout.field_alignment_bits;
277
278 if (bit_width > 0) {
279 std.debug.assert(bit_width <= ty_size_bits); // Checked in parser
280 // Some targets ignore the alignment of the underlying type when laying out
281 // non-zero-sized bit-fields. See test case 0072. On such targets, bit-fields never
282 // cross a storage boundary. See test case 0081.
283 if (target_util.ignoreNonZeroSizedBitfieldTypeAlignment(self.comp.target)) {
284 ty_fld_algn_bits = 1;
285 }
286 } else {
287 // Some targets ignore the alignment of the underlying type when laying out
288 // zero-sized bit-fields. See test case 0073.
289 if (target_util.ignoreZeroSizedBitfieldTypeAlignment(self.comp.target)) {
290 ty_fld_algn_bits = 1;
291 }
292 // Some targets have a minimum alignment of zero-sized bit-fields. See test case
293 // 0074.
294 if (target_util.minZeroWidthBitfieldAlignment(self.comp.target)) |target_align| {
295 ty_fld_algn_bits = @max(ty_fld_algn_bits, target_align);
296 }
297 }
298
299 // __attribute__((packed)) on the record is identical to __attribute__((packed)) on each
300 // field. See test case 0067.
301 const attr_packed = self.attr_packed or isPacked(fld_attrs);
302 const has_packing_annotation = attr_packed or self.max_field_align_bits != null;
303
304 const annotation_alignment: u32 = if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| anno * BITS_PER_BYTE else 1;
305
306 const first_unused_bit: u64 = if (self.is_union) 0 else self.size_bits;
307 var field_align_bits: u64 = 1;
308
309 if (bit_width == 0) {
310 field_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
311 } else if (self.comp.langopts.emulate == .gcc) {
312 // On GCC, the field alignment is at least the alignment requested by annotations
313 // except as restricted by #pragma pack. See test case 0083.
314 field_align_bits = annotation_alignment;
315 if (self.max_field_align_bits) |max_bits| {
316 field_align_bits = @min(annotation_alignment, max_bits);
317 }
318
319 // On GCC, if there are no packing annotations and
320 // - the field would otherwise start at an offset such that it would cross a
321 // storage boundary or
322 // - the alignment of the type is larger than its size,
323 // then it is aligned to the type's field alignment. See test case 0083.
324 if (!has_packing_annotation) {
325 const start_bit = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
326
327 const does_field_cross_boundary = start_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
328
329 if (ty_fld_algn_bits > ty_size_bits or does_field_cross_boundary) {
330 field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
331 }
332 }
333 } else {
334 std.debug.assert(self.comp.langopts.emulate == .clang);
335
336 // On Clang, the alignment requested by annotations is not respected if it is
337 // larger than the value of #pragma pack. See test case 0083.
338 if (annotation_alignment <= self.max_field_align_bits orelse std.math.maxInt(u29)) {
339 field_align_bits = @max(field_align_bits, annotation_alignment);
340 }
341 // On Clang, if there are no packing annotations and the field would cross a
342 // storage boundary if it were positioned at the first unused bit in the record,
343 // it is aligned to the type's field alignment. See test case 0083.
344 if (!has_packing_annotation) {
345 const does_field_cross_boundary = first_unused_bit % ty_fld_algn_bits + bit_width > ty_size_bits;
346
347 if (does_field_cross_boundary)
348 field_align_bits = @max(field_align_bits, ty_fld_algn_bits);
349 }
350 }
351
352 const offset_bits = std.mem.alignForward(u64, first_unused_bit, field_align_bits);
353 self.size_bits = @max(self.size_bits, offset_bits + bit_width);
354
355 // Unnamed fields do not contribute to the record alignment except on a few targets.
356 // See test case 0079.
357 if (is_named or target_util.unnamedFieldAffectsAlignment(self.comp.target)) {
358 var inherited_align_bits: u32 = undefined;
359
360 if (bit_width == 0) {
361 // If the width is 0, #pragma pack and __attribute__((packed)) are ignored.
362 // See test case 0075.
363 inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
364 } else if (self.max_field_align_bits) |max_align_bits| {
365 // Otherwise, if a #pragma pack is in effect, __attribute__((packed)) on the field or
366 // record is ignored. See test case 0076.
367 inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
368 inherited_align_bits = @intCast(@min(inherited_align_bits, max_align_bits));
369 } else if (attr_packed) {
370 // Otherwise, if the field or the record is packed, the field alignment is 1 bit unless
371 // it is explicitly increased with __attribute__((aligned)). See test case 0077.
372 inherited_align_bits = annotation_alignment;
373 } else {
374 // Otherwise, the field alignment is the field alignment of the underlying type unless
375 // it is explicitly increased with __attribute__((aligned)). See test case 0078.
376 inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment);
377 }
378 self.aligned_bits = @max(self.aligned_bits, inherited_align_bits);
379 }
380
381 if (!is_named) return .{};
382 return .{
383 .size_bits = bit_width,
384 .offset_bits = offset_bits,
385 };
386 }
387};
388
389const MsvcContext = struct {
390 req_align_bits: u32,
391 max_field_align_bits: ?u32,
392 /// The alignment of pointers that point to an object of this type. This is greater than or equal
393 /// to the required alignment. Once all fields have been laid out, the size of the record will be
394 /// rounded up to this value.
395 pointer_align_bits: u32,
396 /// The alignment of this type when it is used as a record field. This is greater than or equal to
397 /// the pointer alignment.
398 field_align_bits: u32,
399 size_bits: u64,
400 ongoing_bitfield: ?OngoingBitfield,
401 contains_non_bitfield: bool,
402 is_union: bool,
403 comp: *const Compilation,
404
405 fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) MsvcContext {
406 var pack_value: ?u32 = null;
407 if (ty.hasAttribute(.@"packed")) {
408 // __attribute__((packed)) behaves like #pragma pack(1) in clang. See test case 0056.
409 pack_value = BITS_PER_BYTE;
410 }
411 if (pack_value == null) {
412 if (pragma_pack) |pack| {
413 pack_value = pack * BITS_PER_BYTE;
414 }
415 }
416 if (pack_value) |pack| {
417 pack_value = msvcPragmaPack(comp, pack);
418 }
419
420 // The required alignment can be increased by adding a __declspec(align)
421 // annotation. See test case 0023.
422 var must_align: u29 = BITS_PER_BYTE;
423 if (ty.requestedAlignment(comp)) |req_align| {
424 must_align = req_align * BITS_PER_BYTE;
425 }
426 return MsvcContext{
427 .req_align_bits = must_align,
428 .pointer_align_bits = must_align,
429 .field_align_bits = must_align,
430 .size_bits = 0,
431 .max_field_align_bits = pack_value,
432 .ongoing_bitfield = null,
433 .contains_non_bitfield = false,
434 .is_union = ty.is(.@"union"),
435 .comp = comp,
436 };
437 }
438
439 fn layoutField(self: *MsvcContext, fld: *const Field, fld_attrs: ?[]const Attribute) FieldLayout {
440 const type_layout = computeLayout(fld.ty, self.comp);
441
442 // The required alignment of the field is the maximum of the required alignment of the
443 // underlying type and the __declspec(align) annotation on the field itself.
444 // See test case 0028.
445 var req_align = type_layout.required_alignment_bits;
446 if (Type.annotationAlignment(self.comp, fld_attrs)) |anno| {
447 req_align = @max(anno * BITS_PER_BYTE, req_align);
448 }
449
450 // The required alignment of a record is the maximum of the required alignments of its
451 // fields except that the required alignment of bitfields is ignored.
452 // See test case 0029.
453 if (fld.isRegularField()) {
454 self.req_align_bits = @max(self.req_align_bits, req_align);
455 }
456
457 // The offset of the field is based on the field alignment of the underlying type.
458 // See test case 0027.
459 var fld_align_bits = type_layout.field_alignment_bits;
460 if (self.max_field_align_bits) |max_align| {
461 fld_align_bits = @min(fld_align_bits, max_align);
462 }
463 // check the requested alignment of the field type.
464 if (fld.ty.requestedAlignment(self.comp)) |type_req_align| {
465 fld_align_bits = @max(fld_align_bits, type_req_align * 8);
466 }
467
468 if (isPacked(fld_attrs)) {
469 // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
470 // pack(1) had been applied only to this field. See test case 0057.
471 fld_align_bits = BITS_PER_BYTE;
472 }
473 // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma
474 // pack(1) had been applied only to this field. See test case 0057.
475 fld_align_bits = @max(fld_align_bits, req_align);
476 if (fld.isRegularField()) {
477 return self.layoutRegularField(type_layout.size_bits, fld_align_bits);
478 } else {
479 return self.layoutBitField(type_layout.size_bits, fld_align_bits, fld.specifiedBitWidth());
480 }
481 }
482
483 fn layoutBitField(self: *MsvcContext, ty_size_bits: u64, field_align: u32, bit_width: u32) FieldLayout {
484 if (bit_width == 0) {
485 // A zero-sized bit-field that does not follow a non-zero-sized bit-field does not affect
486 // the overall layout of the record. Even in a union where the order would otherwise
487 // not matter. See test case 0035.
488 if (self.ongoing_bitfield) |_| {
489 self.ongoing_bitfield = null;
490 } else {
491 // this field takes 0 space.
492 return .{ .offset_bits = self.size_bits, .size_bits = bit_width };
493 }
494 } else {
495 std.debug.assert(bit_width <= ty_size_bits);
496 // If there is an ongoing bit-field in a struct whose underlying type has the same size and
497 // if there is enough space left to place this bit-field, then this bit-field is placed in
498 // the ongoing bit-field and the overall layout of the struct is not affected by this
499 // bit-field. See test case 0037.
500 if (!self.is_union) {
501 if (self.ongoing_bitfield) |*p| {
502 if (p.size_bits == ty_size_bits and p.unused_size_bits >= bit_width) {
503 const offset_bits = self.size_bits - p.unused_size_bits;
504 p.unused_size_bits -= bit_width;
505 return .{ .offset_bits = offset_bits, .size_bits = bit_width };
506 }
507 }
508 }
509 // Otherwise this field is part of a new ongoing bit-field.
510 self.ongoing_bitfield = .{ .size_bits = ty_size_bits, .unused_size_bits = ty_size_bits - bit_width };
511 }
512 const offset_bits = if (!self.is_union) bits: {
513 // This is the one place in the layout of a record where the pointer alignment might
514 // get assigned a smaller value than the field alignment. This can only happen if
515 // the field or the type of the field has a required alignment. Otherwise the value
516 // of field_alignment_bits is already bound by max_field_alignment_bits.
517 // See test case 0038.
518 const p_align = if (self.max_field_align_bits) |max_fld_align|
519 @min(max_fld_align, field_align)
520 else
521 field_align;
522 self.pointer_align_bits = @max(self.pointer_align_bits, p_align);
523 self.field_align_bits = @max(self.field_align_bits, field_align);
524
525 const offset_bits = std.mem.alignForward(u64, self.size_bits, field_align);
526 self.size_bits = if (bit_width == 0) offset_bits else offset_bits + ty_size_bits;
527
528 break :bits offset_bits;
529 } else bits: {
530 // Bit-fields do not affect the alignment of a union. See test case 0041.
531 self.size_bits = @max(self.size_bits, ty_size_bits);
532 break :bits 0;
533 };
534 return .{ .offset_bits = offset_bits, .size_bits = bit_width };
535 }
536
537 fn layoutRegularField(self: *MsvcContext, size_bits: u64, field_align: u32) FieldLayout {
538 self.contains_non_bitfield = true;
539 self.ongoing_bitfield = null;
540 // The alignment of the field affects both the pointer alignment and the field
541 // alignment of the record. See test case 0032.
542 self.pointer_align_bits = @max(self.pointer_align_bits, field_align);
543 self.field_align_bits = @max(self.field_align_bits, field_align);
544 const offset_bits = switch (self.is_union) {
545 true => 0,
546 false => std.mem.alignForward(u64, self.size_bits, field_align),
547 };
548 self.size_bits = @max(self.size_bits, offset_bits + size_bits);
549 return .{ .offset_bits = offset_bits, .size_bits = size_bits };
550 }
551 fn handleZeroSizedRecord(self: *MsvcContext) void {
552 if (self.is_union) {
553 // MSVC does not allow unions without fields.
554 // If all fields in a union have size 0, the size of the union is set to
555 // - its field alignment if it contains at least one non-bitfield
556 // - 4 bytes if it contains only bitfields
557 // See test case 0025.
558 if (self.contains_non_bitfield) {
559 self.size_bits = self.field_align_bits;
560 } else {
561 self.size_bits = 4 * BITS_PER_BYTE;
562 }
563 } else {
564 // If all fields in a struct have size 0, its size is set to its required alignment
565 // but at least to 4 bytes. See test case 0026.
566 self.size_bits = @max(self.req_align_bits, 4 * BITS_PER_BYTE);
567 self.pointer_align_bits = @intCast(@min(self.pointer_align_bits, self.size_bits));
568 }
569 }
570};
571
572pub fn compute(rec: *Type.Record, ty: Type, comp: *const Compilation, pragma_pack: ?u8) void {
573 switch (comp.langopts.emulate) {
574 .gcc, .clang => {
575 var context = SysVContext.init(ty, comp, pragma_pack);
576
577 context.layoutFields(rec);
578
579 context.size_bits = std.mem.alignForward(u64, context.size_bits, context.aligned_bits);
580
581 rec.type_layout = .{
582 .size_bits = context.size_bits,
583 .field_alignment_bits = context.aligned_bits,
584 .pointer_alignment_bits = context.aligned_bits,
585 .required_alignment_bits = BITS_PER_BYTE,
586 };
587 },
588 .msvc => {
589 var context = MsvcContext.init(ty, comp, pragma_pack);
590 for (rec.fields, 0..) |*fld, fld_indx| {
591 if (fld.ty.specifier == .invalid) continue;
592 var field_attrs: ?[]const Attribute = null;
593 if (rec.field_attributes) |attrs| {
594 field_attrs = attrs[fld_indx];
595 }
596
597 fld.layout = context.layoutField(fld, field_attrs);
598 }
599 if (context.size_bits == 0) {
600 // As an extension, MSVC allows records that only contain zero-sized bitfields and empty
601 // arrays. Such records would be zero-sized but this case is handled here separately to
602 // ensure that there are no zero-sized records.
603 context.handleZeroSizedRecord();
604 }
605 context.size_bits = std.mem.alignForward(u64, context.size_bits, context.pointer_align_bits);
606 rec.type_layout = .{
607 .size_bits = context.size_bits,
608 .field_alignment_bits = context.field_align_bits,
609 .pointer_alignment_bits = context.pointer_align_bits,
610 .required_alignment_bits = context.req_align_bits,
611 };
612 },
613 }
614}
615
616fn computeLayout(ty: Type, comp: *const Compilation) TypeLayout {
617 if (ty.getRecord()) |rec| {
618 const requested = BITS_PER_BYTE * (ty.requestedAlignment(comp) orelse 0);
619 return .{
620 .size_bits = rec.type_layout.size_bits,
621 .pointer_alignment_bits = @max(requested, rec.type_layout.pointer_alignment_bits),
622 .field_alignment_bits = @max(requested, rec.type_layout.field_alignment_bits),
623 .required_alignment_bits = rec.type_layout.required_alignment_bits,
624 };
625 } else {
626 const type_align = ty.alignof(comp) * BITS_PER_BYTE;
627 return .{
628 .size_bits = ty.bitSizeof(comp) orelse 0,
629 .pointer_alignment_bits = type_align,
630 .field_alignment_bits = type_align,
631 .required_alignment_bits = BITS_PER_BYTE,
632 };
633 }
634}
635
636fn isPacked(attrs: ?[]const Attribute) bool {
637 const a = attrs orelse return false;
638
639 for (a) |attribute| {
640 if (attribute.tag != .@"packed") continue;
641 return true;
642 }
643 return false;
644}
645
646// The effect of #pragma pack(N) depends on the target.
647//
648// x86: By default, there is no maximum field alignment. N={1,2,4} set the maximum field
649// alignment to that value. All other N activate the default.
650// x64: By default, there is no maximum field alignment. N={1,2,4,8} set the maximum field
651// alignment to that value. All other N activate the default.
652// arm: By default, the maximum field alignment is 8. N={1,2,4,8,16} set the maximum field
653// alignment to that value. All other N activate the default.
654// arm64: By default, the maximum field alignment is 8. N={1,2,4,8} set the maximum field
655// alignment to that value. N=16 disables the maximum field alignment. All other N
656// activate the default.
657//
658// See test case 0020.
659pub fn msvcPragmaPack(comp: *const Compilation, pack: u32) ?u32 {
660 return switch (pack) {
661 8, 16, 32 => pack,
662 64 => if (comp.target.cpu.arch == .x86) null else pack,
663 128 => if (comp.target.cpu.arch == .thumb) pack else null,
664 else => {
665 return switch (comp.target.cpu.arch) {
666 .thumb, .aarch64 => 64,
667 else => null,
668 };
669 },
670 };
671}
lib/compiler/aro/aro/target.zig created+830
......@@ -0,0 +1,830 @@
1const std = @import("std");
2const LangOpts = @import("LangOpts.zig");
3const Type = @import("Type.zig");
4const TargetSet = @import("Builtins/Properties.zig").TargetSet;
5
6/// intmax_t for this target
7pub fn intMaxType(target: std.Target) Type {
8 switch (target.cpu.arch) {
9 .aarch64,
10 .aarch64_be,
11 .sparc64,
12 => if (target.os.tag != .openbsd) return .{ .specifier = .long },
13
14 .bpfel,
15 .bpfeb,
16 .loongarch64,
17 .riscv64,
18 .powerpc64,
19 .powerpc64le,
20 .tce,
21 .tcele,
22 .ve,
23 => return .{ .specifier = .long },
24
25 .x86_64 => switch (target.os.tag) {
26 .windows, .openbsd => {},
27 else => switch (target.abi) {
28 .gnux32, .muslx32 => {},
29 else => return .{ .specifier = .long },
30 },
31 },
32
33 else => {},
34 }
35 return .{ .specifier = .long_long };
36}
37
38/// intptr_t for this target
39pub fn intPtrType(target: std.Target) Type {
40 switch (target.os.tag) {
41 .haiku => return .{ .specifier = .long },
42 .nacl => return .{ .specifier = .int },
43 else => {},
44 }
45
46 switch (target.cpu.arch) {
47 .aarch64, .aarch64_be => switch (target.os.tag) {
48 .windows => return .{ .specifier = .long_long },
49 else => {},
50 },
51
52 .msp430,
53 .csky,
54 .loongarch32,
55 .riscv32,
56 .xcore,
57 .hexagon,
58 .tce,
59 .tcele,
60 .m68k,
61 .spir,
62 .spirv32,
63 .arc,
64 .avr,
65 => return .{ .specifier = .int },
66
67 .sparc, .sparcel => switch (target.os.tag) {
68 .netbsd, .openbsd => {},
69 else => return .{ .specifier = .int },
70 },
71
72 .powerpc, .powerpcle => switch (target.os.tag) {
73 .linux, .freebsd, .netbsd => return .{ .specifier = .int },
74 else => {},
75 },
76
77 // 32-bit x86 Darwin, OpenBSD, and RTEMS use long (the default); others use int
78 .x86 => switch (target.os.tag) {
79 .openbsd, .rtems => {},
80 else => if (!target.os.tag.isDarwin()) return .{ .specifier = .int },
81 },
82
83 .x86_64 => switch (target.os.tag) {
84 .windows => return .{ .specifier = .long_long },
85 else => switch (target.abi) {
86 .gnux32, .muslx32 => return .{ .specifier = .int },
87 else => {},
88 },
89 },
90
91 else => {},
92 }
93
94 return .{ .specifier = .long };
95}
96
97/// int16_t for this target
98pub fn int16Type(target: std.Target) Type {
99 return switch (target.cpu.arch) {
100 .avr => .{ .specifier = .int },
101 else => .{ .specifier = .short },
102 };
103}
104
105/// int64_t for this target
106pub fn int64Type(target: std.Target) Type {
107 switch (target.cpu.arch) {
108 .loongarch64,
109 .ve,
110 .riscv64,
111 .powerpc64,
112 .powerpc64le,
113 .bpfel,
114 .bpfeb,
115 => return .{ .specifier = .long },
116
117 .sparc64 => return intMaxType(target),
118
119 .x86, .x86_64 => if (!target.isDarwin()) return intMaxType(target),
120 .aarch64, .aarch64_be => if (!target.isDarwin() and target.os.tag != .openbsd and target.os.tag != .windows) return .{ .specifier = .long },
121 else => {},
122 }
123 return .{ .specifier = .long_long };
124}
125
126/// This function returns 1 if function alignment is not observable or settable.
127pub fn defaultFunctionAlignment(target: std.Target) u8 {
128 return switch (target.cpu.arch) {
129 .arm, .armeb => 4,
130 .aarch64, .aarch64_32, .aarch64_be => 4,
131 .sparc, .sparcel, .sparc64 => 4,
132 .riscv64 => 2,
133 else => 1,
134 };
135}
136
137pub fn isTlsSupported(target: std.Target) bool {
138 if (target.isDarwin()) {
139 var supported = false;
140 switch (target.os.tag) {
141 .macos => supported = !(target.os.isAtLeast(.macos, .{ .major = 10, .minor = 7, .patch = 0 }) orelse false),
142 else => {},
143 }
144 return supported;
145 }
146 return switch (target.cpu.arch) {
147 .tce, .tcele, .bpfel, .bpfeb, .msp430, .nvptx, .nvptx64, .x86, .arm, .armeb, .thumb, .thumbeb => false,
148 else => true,
149 };
150}
151
152pub fn ignoreNonZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
153 switch (target.cpu.arch) {
154 .avr => return true,
155 .arm => {
156 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
157 switch (target.os.tag) {
158 .ios => return true,
159 else => return false,
160 }
161 }
162 },
163 else => return false,
164 }
165 return false;
166}
167
168pub fn ignoreZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
169 switch (target.cpu.arch) {
170 .avr => return true,
171 else => return false,
172 }
173}
174
175pub fn minZeroWidthBitfieldAlignment(target: std.Target) ?u29 {
176 switch (target.cpu.arch) {
177 .avr => return 8,
178 .arm => {
179 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
180 switch (target.os.tag) {
181 .ios => return 32,
182 else => return null,
183 }
184 } else return null;
185 },
186 else => return null,
187 }
188}
189
190pub fn unnamedFieldAffectsAlignment(target: std.Target) bool {
191 switch (target.cpu.arch) {
192 .aarch64 => {
193 if (target.isDarwin() or target.os.tag == .windows) return false;
194 return true;
195 },
196 .armeb => {
197 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
198 if (std.Target.Abi.default(target.cpu.arch, target.os) == .eabi) return true;
199 }
200 },
201 .arm => return true,
202 .avr => return true,
203 .thumb => {
204 if (target.os.tag == .windows) return false;
205 return true;
206 },
207 else => return false,
208 }
209 return false;
210}
211
212pub fn packAllEnums(target: std.Target) bool {
213 return switch (target.cpu.arch) {
214 .hexagon => true,
215 else => false,
216 };
217}
218
219/// Default alignment (in bytes) for __attribute__((aligned)) when no alignment is specified
220pub fn defaultAlignment(target: std.Target) u29 {
221 switch (target.cpu.arch) {
222 .avr => return 1,
223 .arm => if (target.isAndroid() or target.os.tag == .ios) return 16 else return 8,
224 .sparc => if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) return 16 else return 8,
225 .mips, .mipsel => switch (target.abi) {
226 .none, .gnuabi64 => return 16,
227 else => return 8,
228 },
229 .s390x, .armeb, .thumbeb, .thumb => return 8,
230 else => return 16,
231 }
232}
233pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
234 // Android is linux but not gcc, so these checks go first
235 // the rest for documentation as fn returns .clang
236 if (target.isDarwin() or
237 target.isAndroid() or
238 target.isBSD() or
239 target.os.tag == .fuchsia or
240 target.os.tag == .solaris or
241 target.os.tag == .haiku or
242 target.cpu.arch == .hexagon)
243 {
244 return .clang;
245 }
246 if (target.os.tag == .uefi) return .msvc;
247 // this is before windows to grab WindowsGnu
248 if (target.abi.isGnu() or
249 target.os.tag == .linux)
250 {
251 return .gcc;
252 }
253 if (target.os.tag == .windows) {
254 return .msvc;
255 }
256 if (target.cpu.arch == .avr) return .gcc;
257 return .clang;
258}
259
260pub fn hasFloat128(target: std.Target) bool {
261 if (target.cpu.arch.isWasm()) return true;
262 if (target.isDarwin()) return false;
263 if (target.cpu.arch.isPPC() or target.cpu.arch.isPPC64()) return std.Target.powerpc.featureSetHas(target.cpu.features, .float128);
264 return switch (target.os.tag) {
265 .dragonfly,
266 .haiku,
267 .linux,
268 .openbsd,
269 .solaris,
270 => target.cpu.arch.isX86(),
271 else => false,
272 };
273}
274
275pub fn hasInt128(target: std.Target) bool {
276 if (target.cpu.arch == .wasm32) return true;
277 if (target.cpu.arch == .x86_64) return true;
278 return target.ptrBitWidth() >= 64;
279}
280
281pub fn hasHalfPrecisionFloatABI(target: std.Target) bool {
282 return switch (target.cpu.arch) {
283 .thumb, .thumbeb, .arm, .aarch64 => true,
284 else => false,
285 };
286}
287
288pub const FPSemantics = enum {
289 None,
290 IEEEHalf,
291 BFloat,
292 IEEESingle,
293 IEEEDouble,
294 IEEEQuad,
295 /// Minifloat 5-bit exponent 2-bit mantissa
296 E5M2,
297 /// Minifloat 4-bit exponent 3-bit mantissa
298 E4M3,
299 x87ExtendedDouble,
300 IBMExtendedDouble,
301
302 /// Only intended for generating float.h macros for the preprocessor
303 pub fn forType(ty: std.Target.CType, target: std.Target) FPSemantics {
304 std.debug.assert(ty == .float or ty == .double or ty == .longdouble);
305 return switch (target.c_type_bit_size(ty)) {
306 32 => .IEEESingle,
307 64 => .IEEEDouble,
308 80 => .x87ExtendedDouble,
309 128 => switch (target.cpu.arch) {
310 .powerpc, .powerpcle, .powerpc64, .powerpc64le => .IBMExtendedDouble,
311 else => .IEEEQuad,
312 },
313 else => unreachable,
314 };
315 }
316
317 pub fn halfPrecisionType(target: std.Target) ?FPSemantics {
318 switch (target.cpu.arch) {
319 .aarch64,
320 .aarch64_32,
321 .aarch64_be,
322 .arm,
323 .armeb,
324 .hexagon,
325 .riscv32,
326 .riscv64,
327 .spirv32,
328 .spirv64,
329 => return .IEEEHalf,
330 .x86, .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .sse2)) return .IEEEHalf,
331 else => {},
332 }
333 return null;
334 }
335
336 pub fn chooseValue(self: FPSemantics, comptime T: type, values: [6]T) T {
337 return switch (self) {
338 .IEEEHalf => values[0],
339 .IEEESingle => values[1],
340 .IEEEDouble => values[2],
341 .x87ExtendedDouble => values[3],
342 .IBMExtendedDouble => values[4],
343 .IEEEQuad => values[5],
344 else => unreachable,
345 };
346 }
347};
348
349pub fn isLP64(target: std.Target) bool {
350 return target.c_type_bit_size(.int) == 32 and target.ptrBitWidth() == 64;
351}
352
353pub fn isKnownWindowsMSVCEnvironment(target: std.Target) bool {
354 return target.os.tag == .windows and target.abi == .msvc;
355}
356
357pub fn isWindowsMSVCEnvironment(target: std.Target) bool {
358 return target.os.tag == .windows and (target.abi == .msvc or target.abi == .none);
359}
360
361pub fn isCygwinMinGW(target: std.Target) bool {
362 return target.os.tag == .windows and (target.abi == .gnu or target.abi == .cygnus);
363}
364
365pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool {
366 var it = enabled_for.iterator();
367 while (it.next()) |val| {
368 switch (val) {
369 .basic => return true,
370 .x86_64 => if (target.cpu.arch == .x86_64) return true,
371 .aarch64 => if (target.cpu.arch == .aarch64) return true,
372 .arm => if (target.cpu.arch == .arm) return true,
373 .ppc => switch (target.cpu.arch) {
374 .powerpc, .powerpc64, .powerpc64le => return true,
375 else => {},
376 },
377 else => {
378 // Todo: handle other target predicates
379 },
380 }
381 }
382 return false;
383}
384
385pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {
386 if (target.os.tag == .aix) return .double;
387 switch (target.cpu.arch) {
388 .x86, .x86_64 => {
389 if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) {
390 if (target.os.version_range.semver.min.order(.{ .major = 6, .minor = 99, .patch = 26 }) != .gt) {
391 // NETBSD <= 6.99.26 on 32-bit x86 defaults to double
392 return .double;
393 }
394 }
395 if (std.Target.x86.featureSetHas(target.cpu.features, .sse)) {
396 return .source;
397 }
398 return .extended;
399 },
400 else => {},
401 }
402 return .source;
403}
404
405/// Value of the `-m` flag for `ld` for this target
406pub fn ldEmulationOption(target: std.Target, arm_endianness: ?std.builtin.Endian) ?[]const u8 {
407 return switch (target.cpu.arch) {
408 .x86 => if (target.os.tag == .elfiamcu) "elf_iamcu" else "elf_i386",
409 .arm,
410 .armeb,
411 .thumb,
412 .thumbeb,
413 => switch (arm_endianness orelse target.cpu.arch.endian()) {
414 .little => "armelf_linux_eabi",
415 .big => "armelfb_linux_eabi",
416 },
417 .aarch64 => "aarch64linux",
418 .aarch64_be => "aarch64linuxb",
419 .m68k => "m68kelf",
420 .powerpc => if (target.os.tag == .linux) "elf32ppclinux" else "elf32ppc",
421 .powerpcle => if (target.os.tag == .linux) "elf32lppclinux" else "elf32lppc",
422 .powerpc64 => "elf64ppc",
423 .powerpc64le => "elf64lppc",
424 .riscv32 => "elf32lriscv",
425 .riscv64 => "elf64lriscv",
426 .sparc, .sparcel => "elf32_sparc",
427 .sparc64 => "elf64_sparc",
428 .loongarch32 => "elf32loongarch",
429 .loongarch64 => "elf64loongarch",
430 .mips => "elf32btsmip",
431 .mipsel => "elf32ltsmip",
432 .mips64 => if (target.abi == .gnuabin32) "elf32btsmipn32" else "elf64btsmip",
433 .mips64el => if (target.abi == .gnuabin32) "elf32ltsmipn32" else "elf64ltsmip",
434 .x86_64 => if (target.abi == .gnux32 or target.abi == .muslx32) "elf32_x86_64" else "elf_x86_64",
435 .ve => "elf64ve",
436 .csky => "cskyelf_linux",
437 else => null,
438 };
439}
440
441pub fn get32BitArchVariant(target: std.Target) ?std.Target {
442 var copy = target;
443 switch (target.cpu.arch) {
444 .amdgcn,
445 .avr,
446 .msp430,
447 .spu_2,
448 .ve,
449 .bpfel,
450 .bpfeb,
451 .s390x,
452 => return null,
453
454 .arc,
455 .arm,
456 .armeb,
457 .csky,
458 .hexagon,
459 .m68k,
460 .le32,
461 .mips,
462 .mipsel,
463 .powerpc,
464 .powerpcle,
465 .r600,
466 .riscv32,
467 .sparc,
468 .sparcel,
469 .tce,
470 .tcele,
471 .thumb,
472 .thumbeb,
473 .x86,
474 .xcore,
475 .nvptx,
476 .amdil,
477 .hsail,
478 .spir,
479 .kalimba,
480 .shave,
481 .lanai,
482 .wasm32,
483 .renderscript32,
484 .aarch64_32,
485 .spirv32,
486 .loongarch32,
487 .dxil,
488 .xtensa,
489 => {}, // Already 32 bit
490
491 .aarch64 => copy.cpu.arch = .arm,
492 .aarch64_be => copy.cpu.arch = .armeb,
493 .le64 => copy.cpu.arch = .le32,
494 .amdil64 => copy.cpu.arch = .amdil,
495 .nvptx64 => copy.cpu.arch = .nvptx,
496 .wasm64 => copy.cpu.arch = .wasm32,
497 .hsail64 => copy.cpu.arch = .hsail,
498 .spir64 => copy.cpu.arch = .spir,
499 .spirv64 => copy.cpu.arch = .spirv32,
500 .renderscript64 => copy.cpu.arch = .renderscript32,
501 .loongarch64 => copy.cpu.arch = .loongarch32,
502 .mips64 => copy.cpu.arch = .mips,
503 .mips64el => copy.cpu.arch = .mipsel,
504 .powerpc64 => copy.cpu.arch = .powerpc,
505 .powerpc64le => copy.cpu.arch = .powerpcle,
506 .riscv64 => copy.cpu.arch = .riscv32,
507 .sparc64 => copy.cpu.arch = .sparc,
508 .x86_64 => copy.cpu.arch = .x86,
509 }
510 return copy;
511}
512
513pub fn get64BitArchVariant(target: std.Target) ?std.Target {
514 var copy = target;
515 switch (target.cpu.arch) {
516 .arc,
517 .avr,
518 .csky,
519 .dxil,
520 .hexagon,
521 .kalimba,
522 .lanai,
523 .m68k,
524 .msp430,
525 .r600,
526 .shave,
527 .sparcel,
528 .spu_2,
529 .tce,
530 .tcele,
531 .xcore,
532 .xtensa,
533 => return null,
534
535 .aarch64,
536 .aarch64_be,
537 .amdgcn,
538 .bpfeb,
539 .bpfel,
540 .le64,
541 .amdil64,
542 .nvptx64,
543 .wasm64,
544 .hsail64,
545 .spir64,
546 .spirv64,
547 .renderscript64,
548 .loongarch64,
549 .mips64,
550 .mips64el,
551 .powerpc64,
552 .powerpc64le,
553 .riscv64,
554 .s390x,
555 .sparc64,
556 .ve,
557 .x86_64,
558 => {}, // Already 64 bit
559
560 .aarch64_32 => copy.cpu.arch = .aarch64,
561 .amdil => copy.cpu.arch = .amdil64,
562 .arm => copy.cpu.arch = .aarch64,
563 .armeb => copy.cpu.arch = .aarch64_be,
564 .hsail => copy.cpu.arch = .hsail64,
565 .le32 => copy.cpu.arch = .le64,
566 .loongarch32 => copy.cpu.arch = .loongarch64,
567 .mips => copy.cpu.arch = .mips64,
568 .mipsel => copy.cpu.arch = .mips64el,
569 .nvptx => copy.cpu.arch = .nvptx64,
570 .powerpc => copy.cpu.arch = .powerpc64,
571 .powerpcle => copy.cpu.arch = .powerpc64le,
572 .renderscript32 => copy.cpu.arch = .renderscript64,
573 .riscv32 => copy.cpu.arch = .riscv64,
574 .sparc => copy.cpu.arch = .sparc64,
575 .spir => copy.cpu.arch = .spir64,
576 .spirv32 => copy.cpu.arch = .spirv64,
577 .thumb => copy.cpu.arch = .aarch64,
578 .thumbeb => copy.cpu.arch = .aarch64_be,
579 .wasm32 => copy.cpu.arch = .wasm64,
580 .x86 => copy.cpu.arch = .x86_64,
581 }
582 return copy;
583}
584
585/// Adapted from Zig's src/codegen/llvm.zig
586pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
587 // 64 bytes is assumed to be large enough to hold any target triple; increase if necessary
588 std.debug.assert(buf.len >= 64);
589
590 var stream = std.io.fixedBufferStream(buf);
591 const writer = stream.writer();
592
593 const llvm_arch = switch (target.cpu.arch) {
594 .arm => "arm",
595 .armeb => "armeb",
596 .aarch64 => "aarch64",
597 .aarch64_be => "aarch64_be",
598 .aarch64_32 => "aarch64_32",
599 .arc => "arc",
600 .avr => "avr",
601 .bpfel => "bpfel",
602 .bpfeb => "bpfeb",
603 .csky => "csky",
604 .dxil => "dxil",
605 .hexagon => "hexagon",
606 .loongarch32 => "loongarch32",
607 .loongarch64 => "loongarch64",
608 .m68k => "m68k",
609 .mips => "mips",
610 .mipsel => "mipsel",
611 .mips64 => "mips64",
612 .mips64el => "mips64el",
613 .msp430 => "msp430",
614 .powerpc => "powerpc",
615 .powerpcle => "powerpcle",
616 .powerpc64 => "powerpc64",
617 .powerpc64le => "powerpc64le",
618 .r600 => "r600",
619 .amdgcn => "amdgcn",
620 .riscv32 => "riscv32",
621 .riscv64 => "riscv64",
622 .sparc => "sparc",
623 .sparc64 => "sparc64",
624 .sparcel => "sparcel",
625 .s390x => "s390x",
626 .tce => "tce",
627 .tcele => "tcele",
628 .thumb => "thumb",
629 .thumbeb => "thumbeb",
630 .x86 => "i386",
631 .x86_64 => "x86_64",
632 .xcore => "xcore",
633 .xtensa => "xtensa",
634 .nvptx => "nvptx",
635 .nvptx64 => "nvptx64",
636 .le32 => "le32",
637 .le64 => "le64",
638 .amdil => "amdil",
639 .amdil64 => "amdil64",
640 .hsail => "hsail",
641 .hsail64 => "hsail64",
642 .spir => "spir",
643 .spir64 => "spir64",
644 .spirv32 => "spirv32",
645 .spirv64 => "spirv64",
646 .kalimba => "kalimba",
647 .shave => "shave",
648 .lanai => "lanai",
649 .wasm32 => "wasm32",
650 .wasm64 => "wasm64",
651 .renderscript32 => "renderscript32",
652 .renderscript64 => "renderscript64",
653 .ve => "ve",
654 // Note: spu_2 is not supported in LLVM; this is the Zig arch name
655 .spu_2 => "spu_2",
656 };
657 writer.writeAll(llvm_arch) catch unreachable;
658 writer.writeByte('-') catch unreachable;
659
660 const llvm_os = switch (target.os.tag) {
661 .freestanding => "unknown",
662 .ananas => "ananas",
663 .cloudabi => "cloudabi",
664 .dragonfly => "dragonfly",
665 .freebsd => "freebsd",
666 .fuchsia => "fuchsia",
667 .kfreebsd => "kfreebsd",
668 .linux => "linux",
669 .lv2 => "lv2",
670 .netbsd => "netbsd",
671 .openbsd => "openbsd",
672 .solaris => "solaris",
673 .illumos => "illumos",
674 .windows => "windows",
675 .zos => "zos",
676 .haiku => "haiku",
677 .minix => "minix",
678 .rtems => "rtems",
679 .nacl => "nacl",
680 .aix => "aix",
681 .cuda => "cuda",
682 .nvcl => "nvcl",
683 .amdhsa => "amdhsa",
684 .ps4 => "ps4",
685 .ps5 => "ps5",
686 .elfiamcu => "elfiamcu",
687 .mesa3d => "mesa3d",
688 .contiki => "contiki",
689 .amdpal => "amdpal",
690 .hermit => "hermit",
691 .hurd => "hurd",
692 .wasi => "wasi",
693 .emscripten => "emscripten",
694 .uefi => "windows",
695 .macos => "macosx",
696 .ios => "ios",
697 .tvos => "tvos",
698 .watchos => "watchos",
699 .driverkit => "driverkit",
700 .shadermodel => "shadermodel",
701 .liteos => "liteos",
702 .opencl,
703 .glsl450,
704 .vulkan,
705 .plan9,
706 .other,
707 => "unknown",
708 };
709 writer.writeAll(llvm_os) catch unreachable;
710
711 if (target.os.tag.isDarwin()) {
712 const min_version = target.os.version_range.semver.min;
713 writer.print("{d}.{d}.{d}", .{
714 min_version.major,
715 min_version.minor,
716 min_version.patch,
717 }) catch unreachable;
718 }
719 writer.writeByte('-') catch unreachable;
720
721 const llvm_abi = switch (target.abi) {
722 .none => "unknown",
723 .gnu => "gnu",
724 .gnuabin32 => "gnuabin32",
725 .gnuabi64 => "gnuabi64",
726 .gnueabi => "gnueabi",
727 .gnueabihf => "gnueabihf",
728 .gnuf32 => "gnuf32",
729 .gnuf64 => "gnuf64",
730 .gnusf => "gnusf",
731 .gnux32 => "gnux32",
732 .gnuilp32 => "gnuilp32",
733 .code16 => "code16",
734 .eabi => "eabi",
735 .eabihf => "eabihf",
736 .android => "android",
737 .musl => "musl",
738 .musleabi => "musleabi",
739 .musleabihf => "musleabihf",
740 .muslx32 => "muslx32",
741 .msvc => "msvc",
742 .itanium => "itanium",
743 .cygnus => "cygnus",
744 .coreclr => "coreclr",
745 .simulator => "simulator",
746 .macabi => "macabi",
747 .pixel => "pixel",
748 .vertex => "vertex",
749 .geometry => "geometry",
750 .hull => "hull",
751 .domain => "domain",
752 .compute => "compute",
753 .library => "library",
754 .raygeneration => "raygeneration",
755 .intersection => "intersection",
756 .anyhit => "anyhit",
757 .closesthit => "closesthit",
758 .miss => "miss",
759 .callable => "callable",
760 .mesh => "mesh",
761 .amplification => "amplification",
762 };
763 writer.writeAll(llvm_abi) catch unreachable;
764 return stream.getWritten();
765}
766
767test "alignment functions - smoke test" {
768 var target: std.Target = undefined;
769 const x86 = std.Target.Cpu.Arch.x86_64;
770 target.cpu = std.Target.Cpu.baseline(x86);
771 target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
772 target.abi = std.Target.Abi.default(x86, target.os);
773
774 try std.testing.expect(isTlsSupported(target));
775 try std.testing.expect(!ignoreNonZeroSizedBitfieldTypeAlignment(target));
776 try std.testing.expect(minZeroWidthBitfieldAlignment(target) == null);
777 try std.testing.expect(!unnamedFieldAffectsAlignment(target));
778 try std.testing.expect(defaultAlignment(target) == 16);
779 try std.testing.expect(!packAllEnums(target));
780 try std.testing.expect(systemCompiler(target) == .gcc);
781
782 const arm = std.Target.Cpu.Arch.arm;
783 target.cpu = std.Target.Cpu.baseline(arm);
784 target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
785 target.abi = std.Target.Abi.default(arm, target.os);
786
787 try std.testing.expect(!isTlsSupported(target));
788 try std.testing.expect(ignoreNonZeroSizedBitfieldTypeAlignment(target));
789 try std.testing.expectEqual(@as(?u29, 32), minZeroWidthBitfieldAlignment(target));
790 try std.testing.expect(unnamedFieldAffectsAlignment(target));
791 try std.testing.expect(defaultAlignment(target) == 16);
792 try std.testing.expect(!packAllEnums(target));
793 try std.testing.expect(systemCompiler(target) == .clang);
794}
795
796test "target size/align tests" {
797 var comp: @import("Compilation.zig") = undefined;
798
799 const x86 = std.Target.Cpu.Arch.x86;
800 comp.target.cpu.arch = x86;
801 comp.target.cpu.model = &std.Target.x86.cpu.i586;
802 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
803 comp.target.abi = std.Target.Abi.gnu;
804
805 const tt: Type = .{
806 .specifier = .long_long,
807 };
808
809 try std.testing.expectEqual(@as(u64, 8), tt.sizeof(&comp).?);
810 try std.testing.expectEqual(@as(u64, 4), tt.alignof(&comp));
811
812 const arm = std.Target.Cpu.Arch.arm;
813 comp.target.cpu = std.Target.Cpu.Model.toCpu(&std.Target.arm.cpu.cortex_r4, arm);
814 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
815 comp.target.abi = std.Target.Abi.none;
816
817 const ct: Type = .{
818 .specifier = .char,
819 };
820
821 try std.testing.expectEqual(true, std.Target.arm.featureSetHas(comp.target.cpu.features, .has_v7));
822 try std.testing.expectEqual(@as(u64, 1), ct.sizeof(&comp).?);
823 try std.testing.expectEqual(@as(u64, 1), ct.alignof(&comp));
824 try std.testing.expectEqual(true, ignoreNonZeroSizedBitfieldTypeAlignment(comp.target));
825}
826
827/// The canonical integer representation of nullptr_t.
828pub fn nullRepr(_: std.Target) u64 {
829 return 0;
830}
lib/compiler/aro/aro/text_literal.zig created+383
......@@ -0,0 +1,383 @@
1//! Parsing and classification of string and character literals
2
3const std = @import("std");
4const Compilation = @import("Compilation.zig");
5const Type = @import("Type.zig");
6const Diagnostics = @import("Diagnostics.zig");
7const Tokenizer = @import("Tokenizer.zig");
8const mem = std.mem;
9
10pub const Item = union(enum) {
11 /// decoded hex or character escape
12 value: u32,
13 /// validated unicode codepoint
14 codepoint: u21,
15 /// Char literal in the source text is not utf8 encoded
16 improperly_encoded: []const u8,
17 /// 1 or more unescaped bytes
18 utf8_text: std.unicode.Utf8View,
19};
20
21const CharDiagnostic = struct {
22 tag: Diagnostics.Tag,
23 extra: Diagnostics.Message.Extra,
24};
25
26pub const Kind = enum {
27 char,
28 wide,
29 utf_8,
30 utf_16,
31 utf_32,
32 /// Error kind that halts parsing
33 unterminated,
34
35 pub fn classify(id: Tokenizer.Token.Id, context: enum { string_literal, char_literal }) ?Kind {
36 return switch (context) {
37 .string_literal => switch (id) {
38 .string_literal => .char,
39 .string_literal_utf_8 => .utf_8,
40 .string_literal_wide => .wide,
41 .string_literal_utf_16 => .utf_16,
42 .string_literal_utf_32 => .utf_32,
43 .unterminated_string_literal => .unterminated,
44 else => null,
45 },
46 .char_literal => switch (id) {
47 .char_literal => .char,
48 .char_literal_utf_8 => .utf_8,
49 .char_literal_wide => .wide,
50 .char_literal_utf_16 => .utf_16,
51 .char_literal_utf_32 => .utf_32,
52 else => null,
53 },
54 };
55 }
56
57 /// Should only be called for string literals. Determines the result kind of two adjacent string
58 /// literals
59 pub fn concat(self: Kind, other: Kind) !Kind {
60 if (self == .unterminated or other == .unterminated) return .unterminated;
61 if (self == other) return self; // can always concat with own kind
62 if (self == .char) return other; // char + X -> X
63 if (other == .char) return self; // X + char -> X
64 return error.CannotConcat;
65 }
66
67 /// Largest unicode codepoint that can be represented by this character kind
68 /// May be smaller than the largest value that can be represented.
69 /// For example u8 char literals may only specify 0-127 via literals or
70 /// character escapes, but may specify up to \xFF via hex escapes.
71 pub fn maxCodepoint(kind: Kind, comp: *const Compilation) u21 {
72 return @intCast(switch (kind) {
73 .char => std.math.maxInt(u7),
74 .wide => @min(0x10FFFF, comp.types.wchar.maxInt(comp)),
75 .utf_8 => std.math.maxInt(u7),
76 .utf_16 => std.math.maxInt(u16),
77 .utf_32 => 0x10FFFF,
78 .unterminated => unreachable,
79 });
80 }
81
82 /// Largest integer that can be represented by this character kind
83 pub fn maxInt(kind: Kind, comp: *const Compilation) u32 {
84 return @intCast(switch (kind) {
85 .char, .utf_8 => std.math.maxInt(u8),
86 .wide => comp.types.wchar.maxInt(comp),
87 .utf_16 => std.math.maxInt(u16),
88 .utf_32 => std.math.maxInt(u32),
89 .unterminated => unreachable,
90 });
91 }
92
93 /// The C type of a character literal of this kind
94 pub fn charLiteralType(kind: Kind, comp: *const Compilation) Type {
95 return switch (kind) {
96 .char => Type.int,
97 .wide => comp.types.wchar,
98 .utf_8 => .{ .specifier = .uchar },
99 .utf_16 => comp.types.uint_least16_t,
100 .utf_32 => comp.types.uint_least32_t,
101 .unterminated => unreachable,
102 };
103 }
104
105 /// Return the actual contents of the literal with leading / trailing quotes and
106 /// specifiers removed
107 pub fn contentSlice(kind: Kind, delimited: []const u8) []const u8 {
108 const end = delimited.len - 1; // remove trailing quote
109 return switch (kind) {
110 .char => delimited[1..end],
111 .wide => delimited[2..end],
112 .utf_8 => delimited[3..end],
113 .utf_16 => delimited[2..end],
114 .utf_32 => delimited[2..end],
115 .unterminated => unreachable,
116 };
117 }
118
119 /// The size of a character unit for a string literal of this kind
120 pub fn charUnitSize(kind: Kind, comp: *const Compilation) Compilation.CharUnitSize {
121 return switch (kind) {
122 .char => .@"1",
123 .wide => switch (comp.types.wchar.sizeof(comp).?) {
124 2 => .@"2",
125 4 => .@"4",
126 else => unreachable,
127 },
128 .utf_8 => .@"1",
129 .utf_16 => .@"2",
130 .utf_32 => .@"4",
131 .unterminated => unreachable,
132 };
133 }
134
135 /// Required alignment within aro (on compiler host) for writing to Interner.strings.
136 pub fn internalStorageAlignment(kind: Kind, comp: *const Compilation) usize {
137 return switch (kind.charUnitSize(comp)) {
138 inline else => |size| @alignOf(size.Type()),
139 };
140 }
141
142 /// The C type of an element of a string literal of this kind
143 pub fn elementType(kind: Kind, comp: *const Compilation) Type {
144 return switch (kind) {
145 .unterminated => unreachable,
146 .char => .{ .specifier = .char },
147 .utf_8 => if (comp.langopts.hasChar8_T()) .{ .specifier = .uchar } else .{ .specifier = .char },
148 else => kind.charLiteralType(comp),
149 };
150 }
151};
152
153pub const Parser = struct {
154 literal: []const u8,
155 i: usize = 0,
156 kind: Kind,
157 max_codepoint: u21,
158 /// We only want to issue a max of 1 error per char literal
159 errored: bool = false,
160 errors_buffer: [4]CharDiagnostic,
161 errors_len: usize,
162 comp: *const Compilation,
163
164 pub fn init(literal: []const u8, kind: Kind, max_codepoint: u21, comp: *const Compilation) Parser {
165 return .{
166 .literal = literal,
167 .comp = comp,
168 .kind = kind,
169 .max_codepoint = max_codepoint,
170 .errors_buffer = undefined,
171 .errors_len = 0,
172 };
173 }
174
175 fn prefixLen(self: *const Parser) usize {
176 return switch (self.kind) {
177 .unterminated => unreachable,
178 .char => 0,
179 .utf_8 => 2,
180 .wide, .utf_16, .utf_32 => 1,
181 };
182 }
183
184 pub fn errors(p: *Parser) []CharDiagnostic {
185 return p.errors_buffer[0..p.errors_len];
186 }
187
188 pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void {
189 if (self.errored) return;
190 self.errored = true;
191 const diagnostic = .{ .tag = tag, .extra = extra };
192 if (self.errors_len == self.errors_buffer.len) {
193 self.errors_buffer[self.errors_buffer.len - 1] = diagnostic;
194 } else {
195 self.errors_buffer[self.errors_len] = diagnostic;
196 self.errors_len += 1;
197 }
198 }
199
200 pub fn warn(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void {
201 if (self.errored) return;
202 if (self.errors_len < self.errors_buffer.len) {
203 self.errors_buffer[self.errors_len] = .{ .tag = tag, .extra = extra };
204 self.errors_len += 1;
205 }
206 }
207
208 pub fn next(self: *Parser) ?Item {
209 if (self.i >= self.literal.len) return null;
210
211 const start = self.i;
212 if (self.literal[start] != '\\') {
213 self.i = mem.indexOfScalarPos(u8, self.literal, start + 1, '\\') orelse self.literal.len;
214 const unescaped_slice = self.literal[start..self.i];
215
216 const view = std.unicode.Utf8View.init(unescaped_slice) catch {
217 if (self.kind != .char) {
218 self.err(.illegal_char_encoding_error, .{ .none = {} });
219 return null;
220 }
221 self.warn(.illegal_char_encoding_warning, .{ .none = {} });
222 return .{ .improperly_encoded = self.literal[start..self.i] };
223 };
224 return .{ .utf8_text = view };
225 }
226 switch (self.literal[start + 1]) {
227 'u', 'U' => return self.parseUnicodeEscape(),
228 else => return self.parseEscapedChar(),
229 }
230 }
231
232 fn parseUnicodeEscape(self: *Parser) ?Item {
233 const start = self.i;
234
235 std.debug.assert(self.literal[self.i] == '\\');
236
237 const kind = self.literal[self.i + 1];
238 std.debug.assert(kind == 'u' or kind == 'U');
239
240 self.i += 2;
241 if (self.i >= self.literal.len or !std.ascii.isHex(self.literal[self.i])) {
242 self.err(.missing_hex_escape, .{ .ascii = @intCast(kind) });
243 return null;
244 }
245 const expected_len: usize = if (kind == 'u') 4 else 8;
246 var overflowed = false;
247 var count: usize = 0;
248 var val: u32 = 0;
249
250 for (self.literal[self.i..], 0..) |c, i| {
251 if (i == expected_len) break;
252
253 const char = std.fmt.charToDigit(c, 16) catch {
254 break;
255 };
256
257 val, const overflow = @shlWithOverflow(val, 4);
258 overflowed = overflowed or overflow != 0;
259 val |= char;
260 count += 1;
261 }
262 self.i += expected_len;
263
264 if (overflowed) {
265 self.err(.escape_sequence_overflow, .{ .offset = start + self.prefixLen() });
266 return null;
267 }
268
269 if (count != expected_len) {
270 self.err(.incomplete_universal_character, .{ .none = {} });
271 return null;
272 }
273
274 if (val > std.math.maxInt(u21) or !std.unicode.utf8ValidCodepoint(@intCast(val))) {
275 self.err(.invalid_universal_character, .{ .offset = start + self.prefixLen() });
276 return null;
277 }
278
279 if (val > self.max_codepoint) {
280 self.err(.char_too_large, .{ .none = {} });
281 return null;
282 }
283
284 if (val < 0xA0 and (val != '$' and val != '@' and val != '`')) {
285 const is_error = !self.comp.langopts.standard.atLeast(.c23);
286 if (val >= 0x20 and val <= 0x7F) {
287 if (is_error) {
288 self.err(.ucn_basic_char_error, .{ .ascii = @intCast(val) });
289 } else {
290 self.warn(.ucn_basic_char_warning, .{ .ascii = @intCast(val) });
291 }
292 } else {
293 if (is_error) {
294 self.err(.ucn_control_char_error, .{ .none = {} });
295 } else {
296 self.warn(.ucn_control_char_warning, .{ .none = {} });
297 }
298 }
299 }
300
301 self.warn(.c89_ucn_in_literal, .{ .none = {} });
302 return .{ .codepoint = @intCast(val) };
303 }
304
305 fn parseEscapedChar(self: *Parser) Item {
306 self.i += 1;
307 const c = self.literal[self.i];
308 defer if (c != 'x' and (c < '0' or c > '7')) {
309 self.i += 1;
310 };
311
312 switch (c) {
313 '\n' => unreachable, // removed by line splicing
314 '\r' => unreachable, // removed by line splicing
315 '\'', '\"', '\\', '?' => return .{ .value = c },
316 'n' => return .{ .value = '\n' },
317 'r' => return .{ .value = '\r' },
318 't' => return .{ .value = '\t' },
319 'a' => return .{ .value = 0x07 },
320 'b' => return .{ .value = 0x08 },
321 'e', 'E' => {
322 self.warn(.non_standard_escape_char, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } });
323 return .{ .value = 0x1B };
324 },
325 '(', '{', '[', '%' => {
326 self.warn(.non_standard_escape_char, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } });
327 return .{ .value = c };
328 },
329 'f' => return .{ .value = 0x0C },
330 'v' => return .{ .value = 0x0B },
331 'x' => return .{ .value = self.parseNumberEscape(.hex) },
332 '0'...'7' => return .{ .value = self.parseNumberEscape(.octal) },
333 'u', 'U' => unreachable, // handled by parseUnicodeEscape
334 else => {
335 self.warn(.unknown_escape_sequence, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } });
336 return .{ .value = c };
337 },
338 }
339 }
340
341 fn parseNumberEscape(self: *Parser, base: EscapeBase) u32 {
342 var val: u32 = 0;
343 var count: usize = 0;
344 var overflowed = false;
345 const start = self.i;
346 defer self.i += count;
347 const slice = switch (base) {
348 .octal => self.literal[self.i..@min(self.literal.len, self.i + 3)], // max 3 chars
349 .hex => blk: {
350 self.i += 1;
351 break :blk self.literal[self.i..]; // skip over 'x'; could have an arbitrary number of chars
352 },
353 };
354 for (slice) |c| {
355 const char = std.fmt.charToDigit(c, @intFromEnum(base)) catch break;
356 val, const overflow = @shlWithOverflow(val, base.log2());
357 if (overflow != 0) overflowed = true;
358 val += char;
359 count += 1;
360 }
361 if (overflowed or val > self.kind.maxInt(self.comp)) {
362 self.err(.escape_sequence_overflow, .{ .offset = start + self.prefixLen() });
363 return 0;
364 }
365 if (count == 0) {
366 std.debug.assert(base == .hex);
367 self.err(.missing_hex_escape, .{ .ascii = 'x' });
368 }
369 return val;
370 }
371};
372
373const EscapeBase = enum(u8) {
374 octal = 8,
375 hex = 16,
376
377 fn log2(base: EscapeBase) u4 {
378 return switch (base) {
379 .octal => 3,
380 .hex => 4,
381 };
382 }
383};
lib/compiler/aro/aro/toolchains/Linux.zig created+483
......@@ -0,0 +1,483 @@
1const std = @import("std");
2const mem = std.mem;
3const Compilation = @import("../Compilation.zig");
4const GCCDetector = @import("../Driver/GCCDetector.zig");
5const Toolchain = @import("../Toolchain.zig");
6const Driver = @import("../Driver.zig");
7const Distro = @import("../Driver/Distro.zig");
8const target_util = @import("../target.zig");
9const system_defaults = @import("system_defaults");
10
11const Linux = @This();
12
13distro: Distro.Tag = .unknown,
14extra_opts: std.ArrayListUnmanaged([]const u8) = .{},
15gcc_detector: GCCDetector = .{},
16
17pub fn discover(self: *Linux, tc: *Toolchain) !void {
18 self.distro = Distro.detect(tc.getTarget(), tc.filesystem);
19 try self.gcc_detector.discover(tc);
20 tc.selected_multilib = self.gcc_detector.selected;
21
22 try self.gcc_detector.appendToolPath(tc);
23 try self.buildExtraOpts(tc);
24 try self.findPaths(tc);
25}
26
27fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void {
28 const gpa = tc.driver.comp.gpa;
29 const target = tc.getTarget();
30 const is_android = target.isAndroid();
31 if (self.distro.isAlpine() or is_android) {
32 try self.extra_opts.ensureUnusedCapacity(gpa, 2);
33 self.extra_opts.appendAssumeCapacity("-z");
34 self.extra_opts.appendAssumeCapacity("now");
35 }
36
37 if (self.distro.isOpenSUSE() or self.distro.isUbuntu() or self.distro.isAlpine() or is_android) {
38 try self.extra_opts.ensureUnusedCapacity(gpa, 2);
39 self.extra_opts.appendAssumeCapacity("-z");
40 self.extra_opts.appendAssumeCapacity("relro");
41 }
42
43 if (target.cpu.arch.isARM() or target.cpu.arch.isAARCH64() or is_android) {
44 try self.extra_opts.ensureUnusedCapacity(gpa, 2);
45 self.extra_opts.appendAssumeCapacity("-z");
46 self.extra_opts.appendAssumeCapacity("max-page-size=4096");
47 }
48
49 if (target.cpu.arch == .arm or target.cpu.arch == .thumb) {
50 try self.extra_opts.append(gpa, "-X");
51 }
52
53 if (!target.cpu.arch.isMIPS() and target.cpu.arch != .hexagon) {
54 const hash_style = if (is_android) .both else self.distro.getHashStyle();
55 try self.extra_opts.append(gpa, switch (hash_style) {
56 inline else => |tag| "--hash-style=" ++ @tagName(tag),
57 });
58 }
59
60 if (system_defaults.enable_linker_build_id) {
61 try self.extra_opts.append(gpa, "--build-id");
62 }
63}
64
65fn addMultiLibPaths(self: *Linux, tc: *Toolchain, sysroot: []const u8, os_lib_dir: []const u8) !void {
66 if (!self.gcc_detector.is_valid) return;
67 const gcc_triple = self.gcc_detector.gcc_triple;
68 const lib_path = self.gcc_detector.parent_lib_path;
69
70 // Add lib/gcc/$triple/$version, with an optional /multilib suffix.
71 try tc.addPathIfExists(&.{ self.gcc_detector.install_path, tc.selected_multilib.gcc_suffix }, .file);
72
73 // Add lib/gcc/$triple/$libdir
74 // For GCC built with --enable-version-specific-runtime-libs.
75 try tc.addPathIfExists(&.{ self.gcc_detector.install_path, "..", os_lib_dir }, .file);
76
77 try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", "..", os_lib_dir, tc.selected_multilib.os_suffix }, .file);
78
79 // If the GCC installation we found is inside of the sysroot, we want to
80 // prefer libraries installed in the parent prefix of the GCC installation.
81 // It is important to *not* use these paths when the GCC installation is
82 // outside of the system root as that can pick up unintended libraries.
83 // This usually happens when there is an external cross compiler on the
84 // host system, and a more minimal sysroot available that is the target of
85 // the cross. Note that GCC does include some of these directories in some
86 // configurations but this seems somewhere between questionable and simply
87 // a bug.
88 if (mem.startsWith(u8, lib_path, sysroot)) {
89 try tc.addPathIfExists(&.{ lib_path, "..", os_lib_dir }, .file);
90 }
91}
92
93fn addMultiArchPaths(self: *Linux, tc: *Toolchain) !void {
94 if (!self.gcc_detector.is_valid) return;
95 const lib_path = self.gcc_detector.parent_lib_path;
96 const gcc_triple = self.gcc_detector.gcc_triple;
97 const multilib = self.gcc_detector.selected;
98 try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", multilib.os_suffix }, .file);
99}
100
101/// TODO: Very incomplete
102fn findPaths(self: *Linux, tc: *Toolchain) !void {
103 const target = tc.getTarget();
104 const sysroot = tc.getSysroot();
105
106 var output: [64]u8 = undefined;
107
108 const os_lib_dir = getOSLibDir(target);
109 const multiarch_triple = getMultiarchTriple(target) orelse target_util.toLLVMTriple(target, &output);
110
111 try self.addMultiLibPaths(tc, sysroot, os_lib_dir);
112
113 try tc.addPathIfExists(&.{ sysroot, "/lib", multiarch_triple }, .file);
114 try tc.addPathIfExists(&.{ sysroot, "/lib", "..", os_lib_dir }, .file);
115
116 if (target.isAndroid()) {
117 // TODO
118 }
119 try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", multiarch_triple }, .file);
120 try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", "..", os_lib_dir }, .file);
121
122 try self.addMultiArchPaths(tc);
123
124 try tc.addPathIfExists(&.{ sysroot, "/lib" }, .file);
125 try tc.addPathIfExists(&.{ sysroot, "/usr", "lib" }, .file);
126}
127
128pub fn deinit(self: *Linux, allocator: std.mem.Allocator) void {
129 self.extra_opts.deinit(allocator);
130}
131
132fn isPIEDefault(self: *const Linux) bool {
133 _ = self;
134 return false;
135}
136
137fn getPIE(self: *const Linux, d: *const Driver) bool {
138 if (d.shared or d.static or d.relocatable or d.static_pie) {
139 return false;
140 }
141 return d.pie orelse self.isPIEDefault();
142}
143
144fn getStaticPIE(self: *const Linux, d: *Driver) !bool {
145 _ = self;
146 if (d.static_pie and d.pie != null) {
147 try d.err("cannot specify 'nopie' along with 'static-pie'");
148 }
149 return d.static_pie;
150}
151
152fn getStatic(self: *const Linux, d: *const Driver) bool {
153 _ = self;
154 return d.static and !d.static_pie;
155}
156
157pub fn getDefaultLinker(self: *const Linux, target: std.Target) []const u8 {
158 _ = self;
159 if (target.isAndroid()) {
160 return "ld.lld";
161 }
162 return "ld";
163}
164
165pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.ArrayList([]const u8)) Compilation.Error!void {
166 const d = tc.driver;
167 const target = tc.getTarget();
168
169 const is_pie = self.getPIE(d);
170 const is_static_pie = try self.getStaticPIE(d);
171 const is_static = self.getStatic(d);
172 const is_android = target.isAndroid();
173 const is_iamcu = target.os.tag == .elfiamcu;
174 const is_ve = target.cpu.arch == .ve;
175 const has_crt_begin_end_files = target.abi != .none; // TODO: clang checks for MIPS vendor
176
177 if (is_pie) {
178 try argv.append("-pie");
179 }
180 if (is_static_pie) {
181 try argv.appendSlice(&.{ "-static", "-pie", "--no-dynamic-linker", "-z", "text" });
182 }
183
184 if (d.rdynamic) {
185 try argv.append("-export-dynamic");
186 }
187
188 if (d.strip) {
189 try argv.append("-s");
190 }
191
192 try argv.appendSlice(self.extra_opts.items);
193 try argv.append("--eh-frame-hdr");
194
195 // Todo: Driver should parse `-EL`/`-EB` for arm to set endianness for arm targets
196 if (target_util.ldEmulationOption(d.comp.target, null)) |emulation| {
197 try argv.appendSlice(&.{ "-m", emulation });
198 } else {
199 try d.err("Unknown target triple");
200 return;
201 }
202 if (d.comp.target.cpu.arch.isRISCV()) {
203 try argv.append("-X");
204 }
205 if (d.shared) {
206 try argv.append("-shared");
207 }
208 if (is_static) {
209 try argv.append("-static");
210 } else {
211 if (d.rdynamic) {
212 try argv.append("-export-dynamic");
213 }
214 if (!d.shared and !is_static_pie and !d.relocatable) {
215 const dynamic_linker = d.comp.target.standardDynamicLinkerPath();
216 // todo: check for --dyld-prefix
217 if (dynamic_linker.get()) |path| {
218 try argv.appendSlice(&.{ "-dynamic-linker", try tc.arena.dupe(u8, path) });
219 } else {
220 try d.err("Could not find dynamic linker path");
221 }
222 }
223 }
224
225 try argv.appendSlice(&.{ "-o", d.output_name orelse "a.out" });
226
227 if (!d.nostdlib and !d.nostartfiles and !d.relocatable) {
228 if (!is_android and !is_iamcu) {
229 if (!d.shared) {
230 const crt1 = if (is_pie)
231 "Scrt1.o"
232 else if (is_static_pie)
233 "rcrt1.o"
234 else
235 "crt1.o";
236 try argv.append(try tc.getFilePath(crt1));
237 }
238 try argv.append(try tc.getFilePath("crti.o"));
239 }
240 if (is_ve) {
241 try argv.appendSlice(&.{ "-z", "max-page-size=0x4000000" });
242 }
243
244 if (is_iamcu) {
245 try argv.append(try tc.getFilePath("crt0.o"));
246 } else if (has_crt_begin_end_files) {
247 var path: []const u8 = "";
248 if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
249 const crt_begin = try tc.getCompilerRt("crtbegin", .object);
250 if (tc.filesystem.exists(crt_begin)) {
251 path = crt_begin;
252 }
253 }
254 if (path.len == 0) {
255 const crt_begin = if (tc.driver.shared)
256 if (is_android) "crtbegin_so.o" else "crtbeginS.o"
257 else if (is_static)
258 if (is_android) "crtbegin_static.o" else "crtbeginT.o"
259 else if (is_pie or is_static_pie)
260 if (is_android) "crtbegin_dynamic.o" else "crtbeginS.o"
261 else if (is_android) "crtbegin_dynamic.o" else "crtbegin.o";
262 path = try tc.getFilePath(crt_begin);
263 }
264 try argv.append(path);
265 }
266 }
267
268 // TODO add -L opts
269 // TODO add -u opts
270
271 try tc.addFilePathLibArgs(argv);
272
273 // TODO handle LTO
274
275 try argv.appendSlice(d.link_objects.items);
276
277 if (!d.nostdlib and !d.relocatable) {
278 if (!d.nodefaultlibs) {
279 if (is_static or is_static_pie) {
280 try argv.append("--start-group");
281 }
282 try tc.addRuntimeLibs(argv);
283
284 // TODO: add pthread if needed
285 if (!d.nolibc) {
286 try argv.append("-lc");
287 }
288 if (is_iamcu) {
289 try argv.append("-lgloss");
290 }
291 if (is_static or is_static_pie) {
292 try argv.append("--end-group");
293 } else {
294 try tc.addRuntimeLibs(argv);
295 }
296 if (is_iamcu) {
297 try argv.appendSlice(&.{ "--as-needed", "-lsoftfp", "--no-as-needed" });
298 }
299 }
300 if (!d.nostartfiles and !is_iamcu) {
301 if (has_crt_begin_end_files) {
302 var path: []const u8 = "";
303 if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) {
304 const crt_end = try tc.getCompilerRt("crtend", .object);
305 if (tc.filesystem.exists(crt_end)) {
306 path = crt_end;
307 }
308 }
309 if (path.len == 0) {
310 const crt_end = if (d.shared)
311 if (is_android) "crtend_so.o" else "crtendS.o"
312 else if (is_pie or is_static_pie)
313 if (is_android) "crtend_android.o" else "crtendS.o"
314 else if (is_android) "crtend_android.o" else "crtend.o";
315 path = try tc.getFilePath(crt_end);
316 }
317 try argv.append(path);
318 }
319 if (!is_android) {
320 try argv.append(try tc.getFilePath("crtn.o"));
321 }
322 }
323 }
324
325 // TODO add -T args
326}
327
328fn getMultiarchTriple(target: std.Target) ?[]const u8 {
329 const is_android = target.isAndroid();
330 const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6);
331 return switch (target.cpu.arch) {
332 .arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi",
333 .armeb, .thumbeb => if (target.abi == .gnueabihf) "armeb-linux-gnueabihf" else "armeb-linux-gnueabi",
334 .aarch64 => if (is_android) "aarch64-linux-android" else "aarch64-linux-gnu",
335 .aarch64_be => "aarch64_be-linux-gnu",
336 .x86 => if (is_android) "i686-linux-android" else "i386-linux-gnu",
337 .x86_64 => if (is_android) "x86_64-linux-android" else if (target.abi == .gnux32) "x86_64-linux-gnux32" else "x86_64-linux-gnu",
338 .m68k => "m68k-linux-gnu",
339 .mips => if (is_mips_r6) "mipsisa32r6-linux-gnu" else "mips-linux-gnu",
340 .mipsel => if (is_android) "mipsel-linux-android" else if (is_mips_r6) "mipsisa32r6el-linux-gnu" else "mipsel-linux-gnu",
341 .powerpcle => "powerpcle-linux-gnu",
342 .powerpc64 => "powerpc64-linux-gnu",
343 .powerpc64le => "powerpc64le-linux-gnu",
344 .riscv64 => "riscv64-linux-gnu",
345 .sparc => "sparc-linux-gnu",
346 .sparc64 => "sparc64-linux-gnu",
347 .s390x => "s390x-linux-gnu",
348
349 // TODO: expand this
350 else => null,
351 };
352}
353
354fn getOSLibDir(target: std.Target) []const u8 {
355 switch (target.cpu.arch) {
356 .x86,
357 .powerpc,
358 .powerpcle,
359 .sparc,
360 .sparcel,
361 => return "lib32",
362 else => {},
363 }
364 if (target.cpu.arch == .x86_64 and (target.abi == .gnux32 or target.abi == .muslx32)) {
365 return "libx32";
366 }
367 if (target.cpu.arch == .riscv32) {
368 return "lib32";
369 }
370 if (target.ptrBitWidth() == 32) {
371 return "lib";
372 }
373 return "lib64";
374}
375
376test Linux {
377 if (@import("builtin").os.tag == .windows) return error.SkipZigTest;
378
379 var arena_instance = std.heap.ArenaAllocator.init(std.testing.allocator);
380 defer arena_instance.deinit();
381 const arena = arena_instance.allocator();
382
383 var comp = Compilation.init(std.testing.allocator);
384 defer comp.deinit();
385 comp.environment = .{
386 .path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
387 };
388 defer comp.environment = .{};
389
390 const raw_triple = "x86_64-linux-gnu";
391 const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = raw_triple }) catch unreachable;
392 comp.target = cross.toTarget(); // TODO deprecated
393 comp.langopts.setEmulatedCompiler(.gcc);
394
395 var driver: Driver = .{ .comp = &comp };
396 defer driver.deinit();
397 driver.raw_target_triple = raw_triple;
398
399 const link_obj = try driver.comp.gpa.dupe(u8, "/tmp/foo.o");
400 try driver.link_objects.append(driver.comp.gpa, link_obj);
401 driver.temp_file_count += 1;
402
403 var toolchain: Toolchain = .{ .driver = &driver, .arena = arena, .filesystem = .{ .fake = &.{
404 .{ .path = "/tmp" },
405 .{ .path = "/usr" },
406 .{ .path = "/usr/lib64" },
407 .{ .path = "/usr/bin" },
408 .{ .path = "/usr/bin/ld", .executable = true },
409 .{ .path = "/lib" },
410 .{ .path = "/lib/x86_64-linux-gnu" },
411 .{ .path = "/lib/x86_64-linux-gnu/crt1.o" },
412 .{ .path = "/lib/x86_64-linux-gnu/crti.o" },
413 .{ .path = "/lib/x86_64-linux-gnu/crtn.o" },
414 .{ .path = "/lib64" },
415 .{ .path = "/usr/lib" },
416 .{ .path = "/usr/lib/gcc" },
417 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu" },
418 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9" },
419 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o" },
420 .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o" },
421 .{ .path = "/usr/lib/x86_64-linux-gnu" },
422 .{ .path = "/etc/lsb-release", .contents =
423 \\DISTRIB_ID=Ubuntu
424 \\DISTRIB_RELEASE=20.04
425 \\DISTRIB_CODENAME=focal
426 \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
427 \\
428 },
429 } } };
430 defer toolchain.deinit();
431
432 try toolchain.discover();
433
434 var argv = std.ArrayList([]const u8).init(driver.comp.gpa);
435 defer argv.deinit();
436
437 var linker_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
438 const linker_path = try toolchain.getLinkerPath(&linker_path_buf);
439 try argv.append(linker_path);
440
441 try toolchain.buildLinkerArgs(&argv);
442
443 const expected = [_][]const u8{
444 "/usr/bin/ld",
445 "-z",
446 "relro",
447 "--hash-style=gnu",
448 "--eh-frame-hdr",
449 "-m",
450 "elf_x86_64",
451 "-dynamic-linker",
452 "/lib64/ld-linux-x86-64.so.2",
453 "-o",
454 "a.out",
455 "/lib/x86_64-linux-gnu/crt1.o",
456 "/lib/x86_64-linux-gnu/crti.o",
457 "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o",
458 "-L/usr/lib/gcc/x86_64-linux-gnu/9",
459 "-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64",
460 "-L/lib/x86_64-linux-gnu",
461 "-L/lib/../lib64",
462 "-L/usr/lib/x86_64-linux-gnu",
463 "-L/usr/lib/../lib64",
464 "-L/lib",
465 "-L/usr/lib",
466 link_obj,
467 "-lgcc",
468 "--as-needed",
469 "-lgcc_s",
470 "--no-as-needed",
471 "-lc",
472 "-lgcc",
473 "--as-needed",
474 "-lgcc_s",
475 "--no-as-needed",
476 "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o",
477 "/lib/x86_64-linux-gnu/crtn.o",
478 };
479 try std.testing.expectEqual(expected.len, argv.items.len);
480 for (expected, argv.items) |expected_item, actual_item| {
481 try std.testing.expectEqualStrings(expected_item, actual_item);
482 }
483}
lib/compiler/aro/aro/tracy.zig created+310
......@@ -0,0 +1,310 @@
1//! Copied from https://github.com/ziglang/zig/blob/c9006d9479c619d9ed555164831e11a04d88d382/src/tracy.zig
2
3const std = @import("std");
4const builtin = @import("builtin");
5const build_options = @import("build_options");
6
7pub const enable = if (builtin.is_test) false else build_options.enable_tracy;
8pub const enable_allocation = enable and build_options.enable_tracy_allocation;
9pub const enable_callstack = enable and build_options.enable_tracy_callstack;
10
11// TODO: make this configurable
12const callstack_depth = 10;
13
14const ___tracy_c_zone_context = extern struct {
15 id: u32,
16 active: c_int,
17
18 pub inline fn end(self: @This()) void {
19 ___tracy_emit_zone_end(self);
20 }
21
22 pub inline fn addText(self: @This(), text: []const u8) void {
23 ___tracy_emit_zone_text(self, text.ptr, text.len);
24 }
25
26 pub inline fn setName(self: @This(), name: []const u8) void {
27 ___tracy_emit_zone_name(self, name.ptr, name.len);
28 }
29
30 pub inline fn setColor(self: @This(), color: u32) void {
31 ___tracy_emit_zone_color(self, color);
32 }
33
34 pub inline fn setValue(self: @This(), value: u64) void {
35 ___tracy_emit_zone_value(self, value);
36 }
37};
38
39pub const Ctx = if (enable) ___tracy_c_zone_context else struct {
40 pub inline fn end(self: @This()) void {
41 _ = self;
42 }
43
44 pub inline fn addText(self: @This(), text: []const u8) void {
45 _ = self;
46 _ = text;
47 }
48
49 pub inline fn setName(self: @This(), name: []const u8) void {
50 _ = self;
51 _ = name;
52 }
53
54 pub inline fn setColor(self: @This(), color: u32) void {
55 _ = self;
56 _ = color;
57 }
58
59 pub inline fn setValue(self: @This(), value: u64) void {
60 _ = self;
61 _ = value;
62 }
63};
64
65pub inline fn trace(comptime src: std.builtin.SourceLocation) Ctx {
66 if (!enable) return .{};
67
68 if (enable_callstack) {
69 return ___tracy_emit_zone_begin_callstack(&.{
70 .name = null,
71 .function = src.fn_name.ptr,
72 .file = src.file.ptr,
73 .line = src.line,
74 .color = 0,
75 }, callstack_depth, 1);
76 } else {
77 return ___tracy_emit_zone_begin(&.{
78 .name = null,
79 .function = src.fn_name.ptr,
80 .file = src.file.ptr,
81 .line = src.line,
82 .color = 0,
83 }, 1);
84 }
85}
86
87pub inline fn traceNamed(comptime src: std.builtin.SourceLocation, comptime name: [:0]const u8) Ctx {
88 if (!enable) return .{};
89
90 if (enable_callstack) {
91 return ___tracy_emit_zone_begin_callstack(&.{
92 .name = name.ptr,
93 .function = src.fn_name.ptr,
94 .file = src.file.ptr,
95 .line = src.line,
96 .color = 0,
97 }, callstack_depth, 1);
98 } else {
99 return ___tracy_emit_zone_begin(&.{
100 .name = name.ptr,
101 .function = src.fn_name.ptr,
102 .file = src.file.ptr,
103 .line = src.line,
104 .color = 0,
105 }, 1);
106 }
107}
108
109pub fn tracyAllocator(allocator: std.mem.Allocator) TracyAllocator(null) {
110 return TracyAllocator(null).init(allocator);
111}
112
113pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
114 return struct {
115 parent_allocator: std.mem.Allocator,
116
117 const Self = @This();
118
119 pub fn init(parent_allocator: std.mem.Allocator) Self {
120 return .{
121 .parent_allocator = parent_allocator,
122 };
123 }
124
125 pub fn allocator(self: *Self) std.mem.Allocator {
126 return std.mem.Allocator.init(self, allocFn, resizeFn, freeFn);
127 }
128
129 fn allocFn(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 {
130 const result = self.parent_allocator.rawAlloc(len, ptr_align, len_align, ret_addr);
131 if (result) |data| {
132 if (data.len != 0) {
133 if (name) |n| {
134 allocNamed(data.ptr, data.len, n);
135 } else {
136 alloc(data.ptr, data.len);
137 }
138 }
139 } else |_| {
140 messageColor("allocation failed", 0xFF0000);
141 }
142 return result;
143 }
144
145 fn resizeFn(self: *Self, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
146 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ret_addr)) |resized_len| {
147 if (name) |n| {
148 freeNamed(buf.ptr, n);
149 allocNamed(buf.ptr, resized_len, n);
150 } else {
151 free(buf.ptr);
152 alloc(buf.ptr, resized_len);
153 }
154
155 return resized_len;
156 }
157
158 // during normal operation the compiler hits this case thousands of times due to this
159 // emitting messages for it is both slow and causes clutter
160 return null;
161 }
162
163 fn freeFn(self: *Self, buf: []u8, buf_align: u29, ret_addr: usize) void {
164 self.parent_allocator.rawFree(buf, buf_align, ret_addr);
165 // this condition is to handle free being called on an empty slice that was never even allocated
166 // example case: `std.process.getSelfExeSharedLibPaths` can return `&[_][:0]u8{}`
167 if (buf.len != 0) {
168 if (name) |n| {
169 freeNamed(buf.ptr, n);
170 } else {
171 free(buf.ptr);
172 }
173 }
174 }
175 };
176}
177
178// This function only accepts comptime known strings, see `messageCopy` for runtime strings
179pub inline fn message(comptime msg: [:0]const u8) void {
180 if (!enable) return;
181 ___tracy_emit_messageL(msg.ptr, if (enable_callstack) callstack_depth else 0);
182}
183
184// This function only accepts comptime known strings, see `messageColorCopy` for runtime strings
185pub inline fn messageColor(comptime msg: [:0]const u8, color: u32) void {
186 if (!enable) return;
187 ___tracy_emit_messageLC(msg.ptr, color, if (enable_callstack) callstack_depth else 0);
188}
189
190pub inline fn messageCopy(msg: []const u8) void {
191 if (!enable) return;
192 ___tracy_emit_message(msg.ptr, msg.len, if (enable_callstack) callstack_depth else 0);
193}
194
195pub inline fn messageColorCopy(msg: [:0]const u8, color: u32) void {
196 if (!enable) return;
197 ___tracy_emit_messageC(msg.ptr, msg.len, color, if (enable_callstack) callstack_depth else 0);
198}
199
200pub inline fn frameMark() void {
201 if (!enable) return;
202 ___tracy_emit_frame_mark(null);
203}
204
205pub inline fn frameMarkNamed(comptime name: [:0]const u8) void {
206 if (!enable) return;
207 ___tracy_emit_frame_mark(name.ptr);
208}
209
210pub inline fn namedFrame(comptime name: [:0]const u8) Frame(name) {
211 frameMarkStart(name);
212 return .{};
213}
214
215pub fn Frame(comptime name: [:0]const u8) type {
216 return struct {
217 pub fn end(_: @This()) void {
218 frameMarkEnd(name);
219 }
220 };
221}
222
223inline fn frameMarkStart(comptime name: [:0]const u8) void {
224 if (!enable) return;
225 ___tracy_emit_frame_mark_start(name.ptr);
226}
227
228inline fn frameMarkEnd(comptime name: [:0]const u8) void {
229 if (!enable) return;
230 ___tracy_emit_frame_mark_end(name.ptr);
231}
232
233extern fn ___tracy_emit_frame_mark_start(name: [*:0]const u8) void;
234extern fn ___tracy_emit_frame_mark_end(name: [*:0]const u8) void;
235
236inline fn alloc(ptr: [*]u8, len: usize) void {
237 if (!enable) return;
238
239 if (enable_callstack) {
240 ___tracy_emit_memory_alloc_callstack(ptr, len, callstack_depth, 0);
241 } else {
242 ___tracy_emit_memory_alloc(ptr, len, 0);
243 }
244}
245
246inline fn allocNamed(ptr: [*]u8, len: usize, comptime name: [:0]const u8) void {
247 if (!enable) return;
248
249 if (enable_callstack) {
250 ___tracy_emit_memory_alloc_callstack_named(ptr, len, callstack_depth, 0, name.ptr);
251 } else {
252 ___tracy_emit_memory_alloc_named(ptr, len, 0, name.ptr);
253 }
254}
255
256inline fn free(ptr: [*]u8) void {
257 if (!enable) return;
258
259 if (enable_callstack) {
260 ___tracy_emit_memory_free_callstack(ptr, callstack_depth, 0);
261 } else {
262 ___tracy_emit_memory_free(ptr, 0);
263 }
264}
265
266inline fn freeNamed(ptr: [*]u8, comptime name: [:0]const u8) void {
267 if (!enable) return;
268
269 if (enable_callstack) {
270 ___tracy_emit_memory_free_callstack_named(ptr, callstack_depth, 0, name.ptr);
271 } else {
272 ___tracy_emit_memory_free_named(ptr, 0, name.ptr);
273 }
274}
275
276extern fn ___tracy_emit_zone_begin(
277 srcloc: *const ___tracy_source_location_data,
278 active: c_int,
279) ___tracy_c_zone_context;
280extern fn ___tracy_emit_zone_begin_callstack(
281 srcloc: *const ___tracy_source_location_data,
282 depth: c_int,
283 active: c_int,
284) ___tracy_c_zone_context;
285extern fn ___tracy_emit_zone_text(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
286extern fn ___tracy_emit_zone_name(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void;
287extern fn ___tracy_emit_zone_color(ctx: ___tracy_c_zone_context, color: u32) void;
288extern fn ___tracy_emit_zone_value(ctx: ___tracy_c_zone_context, value: u64) void;
289extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void;
290extern fn ___tracy_emit_memory_alloc(ptr: *const anyopaque, size: usize, secure: c_int) void;
291extern fn ___tracy_emit_memory_alloc_callstack(ptr: *const anyopaque, size: usize, depth: c_int, secure: c_int) void;
292extern fn ___tracy_emit_memory_free(ptr: *const anyopaque, secure: c_int) void;
293extern fn ___tracy_emit_memory_free_callstack(ptr: *const anyopaque, depth: c_int, secure: c_int) void;
294extern fn ___tracy_emit_memory_alloc_named(ptr: *const anyopaque, size: usize, secure: c_int, name: [*:0]const u8) void;
295extern fn ___tracy_emit_memory_alloc_callstack_named(ptr: *const anyopaque, size: usize, depth: c_int, secure: c_int, name: [*:0]const u8) void;
296extern fn ___tracy_emit_memory_free_named(ptr: *const anyopaque, secure: c_int, name: [*:0]const u8) void;
297extern fn ___tracy_emit_memory_free_callstack_named(ptr: *const anyopaque, depth: c_int, secure: c_int, name: [*:0]const u8) void;
298extern fn ___tracy_emit_message(txt: [*]const u8, size: usize, callstack: c_int) void;
299extern fn ___tracy_emit_messageL(txt: [*:0]const u8, callstack: c_int) void;
300extern fn ___tracy_emit_messageC(txt: [*]const u8, size: usize, color: u32, callstack: c_int) void;
301extern fn ___tracy_emit_messageLC(txt: [*:0]const u8, color: u32, callstack: c_int) void;
302extern fn ___tracy_emit_frame_mark(name: ?[*:0]const u8) void;
303
304const ___tracy_source_location_data = extern struct {
305 name: ?[*:0]const u8,
306 function: [*:0]const u8,
307 file: [*:0]const u8,
308 line: u32,
309 color: u32,
310};
lib/compiler/aro/backend.zig created+13
......@@ -0,0 +1,13 @@
1pub const Interner = @import("backend/Interner.zig");
2pub const Ir = @import("backend/Ir.zig");
3pub const Object = @import("backend/Object.zig");
4
5pub const CallingConvention = enum {
6 C,
7 stdcall,
8 thiscall,
9 vectorcall,
10};
11
12pub const version_str = "aro-zig";
13pub const version = @import("std").SemanticVersion.parse(version_str) catch unreachable;
lib/compiler/aro/backend/Interner.zig created+647
......@@ -0,0 +1,647 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const BigIntConst = std.math.big.int.Const;
5const BigIntMutable = std.math.big.int.Mutable;
6const Hash = std.hash.Wyhash;
7const Limb = std.math.big.Limb;
8
9const Interner = @This();
10
11map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
12items: std.MultiArrayList(struct {
13 tag: Tag,
14 data: u32,
15}) = .{},
16extra: std.ArrayListUnmanaged(u32) = .{},
17limbs: std.ArrayListUnmanaged(Limb) = .{},
18strings: std.ArrayListUnmanaged(u8) = .{},
19
20const KeyAdapter = struct {
21 interner: *const Interner,
22
23 pub fn eql(adapter: KeyAdapter, a: Key, b_void: void, b_map_index: usize) bool {
24 _ = b_void;
25 return adapter.interner.get(@as(Ref, @enumFromInt(b_map_index))).eql(a);
26 }
27
28 pub fn hash(adapter: KeyAdapter, a: Key) u32 {
29 _ = adapter;
30 return a.hash();
31 }
32};
33
34pub const Key = union(enum) {
35 int_ty: u16,
36 float_ty: u16,
37 ptr_ty,
38 noreturn_ty,
39 void_ty,
40 func_ty,
41 array_ty: struct {
42 len: u64,
43 child: Ref,
44 },
45 vector_ty: struct {
46 len: u32,
47 child: Ref,
48 },
49 record_ty: []const Ref,
50 /// May not be zero
51 null,
52 int: union(enum) {
53 u64: u64,
54 i64: i64,
55 big_int: BigIntConst,
56
57 pub fn toBigInt(repr: @This(), space: *Tag.Int.BigIntSpace) BigIntConst {
58 return switch (repr) {
59 .big_int => |x| x,
60 inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(),
61 };
62 }
63 },
64 float: Float,
65 bytes: []const u8,
66
67 pub const Float = union(enum) {
68 f16: f16,
69 f32: f32,
70 f64: f64,
71 f80: f80,
72 f128: f128,
73 };
74
75 pub fn hash(key: Key) u32 {
76 var hasher = Hash.init(0);
77 const tag = std.meta.activeTag(key);
78 std.hash.autoHash(&hasher, tag);
79 switch (key) {
80 .bytes => |bytes| {
81 hasher.update(bytes);
82 },
83 .record_ty => |elems| for (elems) |elem| {
84 std.hash.autoHash(&hasher, elem);
85 },
86 .float => |repr| switch (repr) {
87 inline else => |data| std.hash.autoHash(
88 &hasher,
89 @as(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(data))), @bitCast(data)),
90 ),
91 },
92 .int => |repr| {
93 var space: Tag.Int.BigIntSpace = undefined;
94 const big = repr.toBigInt(&space);
95 std.hash.autoHash(&hasher, big.positive);
96 for (big.limbs) |limb| std.hash.autoHash(&hasher, limb);
97 },
98 inline else => |info| {
99 std.hash.autoHash(&hasher, info);
100 },
101 }
102 return @truncate(hasher.final());
103 }
104
105 pub fn eql(a: Key, b: Key) bool {
106 const KeyTag = std.meta.Tag(Key);
107 const a_tag: KeyTag = a;
108 const b_tag: KeyTag = b;
109 if (a_tag != b_tag) return false;
110 switch (a) {
111 .record_ty => |a_elems| {
112 const b_elems = b.record_ty;
113 if (a_elems.len != b_elems.len) return false;
114 for (a_elems, b_elems) |a_elem, b_elem| {
115 if (a_elem != b_elem) return false;
116 }
117 return true;
118 },
119 .bytes => |a_bytes| {
120 const b_bytes = b.bytes;
121 return std.mem.eql(u8, a_bytes, b_bytes);
122 },
123 .int => |a_repr| {
124 var a_space: Tag.Int.BigIntSpace = undefined;
125 const a_big = a_repr.toBigInt(&a_space);
126 var b_space: Tag.Int.BigIntSpace = undefined;
127 const b_big = b.int.toBigInt(&b_space);
128
129 return a_big.eql(b_big);
130 },
131 inline else => |a_info, tag| {
132 const b_info = @field(b, @tagName(tag));
133 return std.meta.eql(a_info, b_info);
134 },
135 }
136 }
137
138 fn toRef(key: Key) ?Ref {
139 switch (key) {
140 .int_ty => |bits| switch (bits) {
141 1 => return .i1,
142 8 => return .i8,
143 16 => return .i16,
144 32 => return .i32,
145 64 => return .i64,
146 128 => return .i128,
147 else => {},
148 },
149 .float_ty => |bits| switch (bits) {
150 16 => return .f16,
151 32 => return .f32,
152 64 => return .f64,
153 80 => return .f80,
154 128 => return .f128,
155 else => unreachable,
156 },
157 .ptr_ty => return .ptr,
158 .func_ty => return .func,
159 .noreturn_ty => return .noreturn,
160 .void_ty => return .void,
161 .int => |repr| {
162 var space: Tag.Int.BigIntSpace = undefined;
163 const big = repr.toBigInt(&space);
164 if (big.eqlZero()) return .zero;
165 const big_one = BigIntConst{ .limbs = &.{1}, .positive = true };
166 if (big.eql(big_one)) return .one;
167 },
168 .float => |repr| switch (repr) {
169 inline else => |data| {
170 if (std.math.isPositiveZero(data)) return .zero;
171 if (data == 1) return .one;
172 },
173 },
174 .null => return .null,
175 else => {},
176 }
177 return null;
178 }
179};
180
181pub const Ref = enum(u32) {
182 const max = std.math.maxInt(u32);
183
184 ptr = max - 1,
185 noreturn = max - 2,
186 void = max - 3,
187 i1 = max - 4,
188 i8 = max - 5,
189 i16 = max - 6,
190 i32 = max - 7,
191 i64 = max - 8,
192 i128 = max - 9,
193 f16 = max - 10,
194 f32 = max - 11,
195 f64 = max - 12,
196 f80 = max - 13,
197 f128 = max - 14,
198 func = max - 15,
199 zero = max - 16,
200 one = max - 17,
201 null = max - 18,
202 _,
203};
204
205pub const OptRef = enum(u32) {
206 const max = std.math.maxInt(u32);
207
208 none = max - 0,
209 ptr = max - 1,
210 noreturn = max - 2,
211 void = max - 3,
212 i1 = max - 4,
213 i8 = max - 5,
214 i16 = max - 6,
215 i32 = max - 7,
216 i64 = max - 8,
217 i128 = max - 9,
218 f16 = max - 10,
219 f32 = max - 11,
220 f64 = max - 12,
221 f80 = max - 13,
222 f128 = max - 14,
223 func = max - 15,
224 zero = max - 16,
225 one = max - 17,
226 null = max - 18,
227 _,
228};
229
230pub const Tag = enum(u8) {
231 /// `data` is `u16`
232 int_ty,
233 /// `data` is `u16`
234 float_ty,
235 /// `data` is index to `Array`
236 array_ty,
237 /// `data` is index to `Vector`
238 vector_ty,
239 /// `data` is `u32`
240 u32,
241 /// `data` is `i32`
242 i32,
243 /// `data` is `Int`
244 int_positive,
245 /// `data` is `Int`
246 int_negative,
247 /// `data` is `f16`
248 f16,
249 /// `data` is `f32`
250 f32,
251 /// `data` is `F64`
252 f64,
253 /// `data` is `F80`
254 f80,
255 /// `data` is `F128`
256 f128,
257 /// `data` is `Bytes`
258 bytes,
259 /// `data` is `Record`
260 record_ty,
261
262 pub const Array = struct {
263 len0: u32,
264 len1: u32,
265 child: Ref,
266
267 pub fn getLen(a: Array) u64 {
268 return (PackedU64{
269 .a = a.len0,
270 .b = a.len1,
271 }).get();
272 }
273 };
274
275 pub const Vector = struct {
276 len: u32,
277 child: Ref,
278 };
279
280 pub const Int = struct {
281 limbs_index: u32,
282 limbs_len: u32,
283
284 /// Big enough to fit any non-BigInt value
285 pub const BigIntSpace = struct {
286 /// The +1 is headroom so that operations such as incrementing once
287 /// or decrementing once are possible without using an allocator.
288 limbs: [(@sizeOf(u64) / @sizeOf(std.math.big.Limb)) + 1]std.math.big.Limb,
289 };
290 };
291
292 pub const F64 = struct {
293 piece0: u32,
294 piece1: u32,
295
296 pub fn get(self: F64) f64 {
297 const int_bits = @as(u64, self.piece0) | (@as(u64, self.piece1) << 32);
298 return @bitCast(int_bits);
299 }
300
301 fn pack(val: f64) F64 {
302 const bits = @as(u64, @bitCast(val));
303 return .{
304 .piece0 = @as(u32, @truncate(bits)),
305 .piece1 = @as(u32, @truncate(bits >> 32)),
306 };
307 }
308 };
309
310 pub const F80 = struct {
311 piece0: u32,
312 piece1: u32,
313 piece2: u32, // u16 part, top bits
314
315 pub fn get(self: F80) f80 {
316 const int_bits = @as(u80, self.piece0) |
317 (@as(u80, self.piece1) << 32) |
318 (@as(u80, self.piece2) << 64);
319 return @bitCast(int_bits);
320 }
321
322 fn pack(val: f80) F80 {
323 const bits = @as(u80, @bitCast(val));
324 return .{
325 .piece0 = @as(u32, @truncate(bits)),
326 .piece1 = @as(u32, @truncate(bits >> 32)),
327 .piece2 = @as(u16, @truncate(bits >> 64)),
328 };
329 }
330 };
331
332 pub const F128 = struct {
333 piece0: u32,
334 piece1: u32,
335 piece2: u32,
336 piece3: u32,
337
338 pub fn get(self: F128) f128 {
339 const int_bits = @as(u128, self.piece0) |
340 (@as(u128, self.piece1) << 32) |
341 (@as(u128, self.piece2) << 64) |
342 (@as(u128, self.piece3) << 96);
343 return @bitCast(int_bits);
344 }
345
346 fn pack(val: f128) F128 {
347 const bits = @as(u128, @bitCast(val));
348 return .{
349 .piece0 = @as(u32, @truncate(bits)),
350 .piece1 = @as(u32, @truncate(bits >> 32)),
351 .piece2 = @as(u32, @truncate(bits >> 64)),
352 .piece3 = @as(u32, @truncate(bits >> 96)),
353 };
354 }
355 };
356
357 pub const Bytes = struct {
358 strings_index: u32,
359 len: u32,
360 };
361
362 pub const Record = struct {
363 elements_len: u32,
364 // trailing
365 // [elements_len]Ref
366 };
367};
368
369pub const PackedU64 = packed struct(u64) {
370 a: u32,
371 b: u32,
372
373 pub fn get(x: PackedU64) u64 {
374 return @bitCast(x);
375 }
376
377 pub fn init(x: u64) PackedU64 {
378 return @bitCast(x);
379 }
380};
381
382pub fn deinit(i: *Interner, gpa: Allocator) void {
383 i.map.deinit(gpa);
384 i.items.deinit(gpa);
385 i.extra.deinit(gpa);
386 i.limbs.deinit(gpa);
387 i.strings.deinit(gpa);
388}
389
390pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref {
391 if (key.toRef()) |some| return some;
392 const adapter: KeyAdapter = .{ .interner = i };
393 const gop = try i.map.getOrPutAdapted(gpa, key, adapter);
394 if (gop.found_existing) return @enumFromInt(gop.index);
395 try i.items.ensureUnusedCapacity(gpa, 1);
396
397 switch (key) {
398 .int_ty => |bits| {
399 i.items.appendAssumeCapacity(.{
400 .tag = .int_ty,
401 .data = bits,
402 });
403 },
404 .float_ty => |bits| {
405 i.items.appendAssumeCapacity(.{
406 .tag = .float_ty,
407 .data = bits,
408 });
409 },
410 .array_ty => |info| {
411 const split_len = PackedU64.init(info.len);
412 i.items.appendAssumeCapacity(.{
413 .tag = .array_ty,
414 .data = try i.addExtra(gpa, Tag.Array{
415 .len0 = split_len.a,
416 .len1 = split_len.b,
417 .child = info.child,
418 }),
419 });
420 },
421 .vector_ty => |info| {
422 i.items.appendAssumeCapacity(.{
423 .tag = .vector_ty,
424 .data = try i.addExtra(gpa, Tag.Vector{
425 .len = info.len,
426 .child = info.child,
427 }),
428 });
429 },
430 .int => |repr| int: {
431 var space: Tag.Int.BigIntSpace = undefined;
432 const big = repr.toBigInt(&space);
433 switch (repr) {
434 .u64 => |data| if (std.math.cast(u32, data)) |small| {
435 i.items.appendAssumeCapacity(.{
436 .tag = .u32,
437 .data = small,
438 });
439 break :int;
440 },
441 .i64 => |data| if (std.math.cast(i32, data)) |small| {
442 i.items.appendAssumeCapacity(.{
443 .tag = .i32,
444 .data = @bitCast(small),
445 });
446 break :int;
447 },
448 .big_int => |data| {
449 if (data.fitsInTwosComp(.unsigned, 32)) {
450 i.items.appendAssumeCapacity(.{
451 .tag = .u32,
452 .data = data.to(u32) catch unreachable,
453 });
454 break :int;
455 } else if (data.fitsInTwosComp(.signed, 32)) {
456 i.items.appendAssumeCapacity(.{
457 .tag = .i32,
458 .data = @bitCast(data.to(i32) catch unreachable),
459 });
460 break :int;
461 }
462 },
463 }
464 const limbs_index: u32 = @intCast(i.limbs.items.len);
465 try i.limbs.appendSlice(gpa, big.limbs);
466 i.items.appendAssumeCapacity(.{
467 .tag = if (big.positive) .int_positive else .int_negative,
468 .data = try i.addExtra(gpa, Tag.Int{
469 .limbs_index = limbs_index,
470 .limbs_len = @intCast(big.limbs.len),
471 }),
472 });
473 },
474 .float => |repr| switch (repr) {
475 .f16 => |data| i.items.appendAssumeCapacity(.{
476 .tag = .f16,
477 .data = @as(u16, @bitCast(data)),
478 }),
479 .f32 => |data| i.items.appendAssumeCapacity(.{
480 .tag = .f32,
481 .data = @as(u32, @bitCast(data)),
482 }),
483 .f64 => |data| i.items.appendAssumeCapacity(.{
484 .tag = .f64,
485 .data = try i.addExtra(gpa, Tag.F64.pack(data)),
486 }),
487 .f80 => |data| i.items.appendAssumeCapacity(.{
488 .tag = .f64,
489 .data = try i.addExtra(gpa, Tag.F80.pack(data)),
490 }),
491 .f128 => |data| i.items.appendAssumeCapacity(.{
492 .tag = .f64,
493 .data = try i.addExtra(gpa, Tag.F128.pack(data)),
494 }),
495 },
496 .bytes => |bytes| {
497 const strings_index: u32 = @intCast(i.strings.items.len);
498 try i.strings.appendSlice(gpa, bytes);
499 i.items.appendAssumeCapacity(.{
500 .tag = .bytes,
501 .data = try i.addExtra(gpa, Tag.Bytes{
502 .strings_index = strings_index,
503 .len = @intCast(bytes.len),
504 }),
505 });
506 },
507 .record_ty => |elems| {
508 try i.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.Record).Struct.fields.len +
509 elems.len);
510 i.items.appendAssumeCapacity(.{
511 .tag = .record_ty,
512 .data = i.addExtraAssumeCapacity(Tag.Record{
513 .elements_len = @intCast(elems.len),
514 }),
515 });
516 i.extra.appendSliceAssumeCapacity(@ptrCast(elems));
517 },
518 .ptr_ty,
519 .noreturn_ty,
520 .void_ty,
521 .func_ty,
522 .null,
523 => unreachable,
524 }
525
526 return @enumFromInt(gop.index);
527}
528
529fn addExtra(i: *Interner, gpa: Allocator, extra: anytype) Allocator.Error!u32 {
530 const fields = @typeInfo(@TypeOf(extra)).Struct.fields;
531 try i.extra.ensureUnusedCapacity(gpa, fields.len);
532 return i.addExtraAssumeCapacity(extra);
533}
534
535fn addExtraAssumeCapacity(i: *Interner, extra: anytype) u32 {
536 const result = @as(u32, @intCast(i.extra.items.len));
537 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {
538 i.extra.appendAssumeCapacity(switch (field.type) {
539 Ref => @intFromEnum(@field(extra, field.name)),
540 u32 => @field(extra, field.name),
541 else => @compileError("bad field type: " ++ @typeName(field.type)),
542 });
543 }
544 return result;
545}
546
547pub fn get(i: *const Interner, ref: Ref) Key {
548 switch (ref) {
549 .ptr => return .ptr_ty,
550 .func => return .func_ty,
551 .noreturn => return .noreturn_ty,
552 .void => return .void_ty,
553 .i1 => return .{ .int_ty = 1 },
554 .i8 => return .{ .int_ty = 8 },
555 .i16 => return .{ .int_ty = 16 },
556 .i32 => return .{ .int_ty = 32 },
557 .i64 => return .{ .int_ty = 64 },
558 .i128 => return .{ .int_ty = 128 },
559 .f16 => return .{ .float_ty = 16 },
560 .f32 => return .{ .float_ty = 32 },
561 .f64 => return .{ .float_ty = 64 },
562 .f80 => return .{ .float_ty = 80 },
563 .f128 => return .{ .float_ty = 128 },
564 .zero => return .{ .int = .{ .u64 = 0 } },
565 .one => return .{ .int = .{ .u64 = 1 } },
566 .null => return .null,
567 else => {},
568 }
569
570 const item = i.items.get(@intFromEnum(ref));
571 const data = item.data;
572 return switch (item.tag) {
573 .int_ty => .{ .int_ty = @intCast(data) },
574 .float_ty => .{ .float_ty = @intCast(data) },
575 .array_ty => {
576 const array_ty = i.extraData(Tag.Array, data);
577 return .{ .array_ty = .{
578 .len = array_ty.getLen(),
579 .child = array_ty.child,
580 } };
581 },
582 .vector_ty => {
583 const vector_ty = i.extraData(Tag.Vector, data);
584 return .{ .vector_ty = .{
585 .len = vector_ty.len,
586 .child = vector_ty.child,
587 } };
588 },
589 .u32 => .{ .int = .{ .u64 = data } },
590 .i32 => .{ .int = .{ .i64 = @as(i32, @bitCast(data)) } },
591 .int_positive, .int_negative => {
592 const int_info = i.extraData(Tag.Int, data);
593 const limbs = i.limbs.items[int_info.limbs_index..][0..int_info.limbs_len];
594 return .{ .int = .{
595 .big_int = .{
596 .positive = item.tag == .int_positive,
597 .limbs = limbs,
598 },
599 } };
600 },
601 .f16 => .{ .float = .{ .f16 = @bitCast(@as(u16, @intCast(data))) } },
602 .f32 => .{ .float = .{ .f32 = @bitCast(data) } },
603 .f64 => {
604 const float = i.extraData(Tag.F64, data);
605 return .{ .float = .{ .f64 = float.get() } };
606 },
607 .f80 => {
608 const float = i.extraData(Tag.F80, data);
609 return .{ .float = .{ .f80 = float.get() } };
610 },
611 .f128 => {
612 const float = i.extraData(Tag.F128, data);
613 return .{ .float = .{ .f128 = float.get() } };
614 },
615 .bytes => {
616 const bytes = i.extraData(Tag.Bytes, data);
617 return .{ .bytes = i.strings.items[bytes.strings_index..][0..bytes.len] };
618 },
619 .record_ty => {
620 const extra = i.extraDataTrail(Tag.Record, data);
621 return .{
622 .record_ty = @ptrCast(i.extra.items[extra.end..][0..extra.data.elements_len]),
623 };
624 },
625 };
626}
627
628fn extraData(i: *const Interner, comptime T: type, index: usize) T {
629 return i.extraDataTrail(T, index).data;
630}
631
632fn extraDataTrail(i: *const Interner, comptime T: type, index: usize) struct { data: T, end: u32 } {
633 var result: T = undefined;
634 const fields = @typeInfo(T).Struct.fields;
635 inline for (fields, 0..) |field, field_i| {
636 const int32 = i.extra.items[field_i + index];
637 @field(result, field.name) = switch (field.type) {
638 Ref => @enumFromInt(int32),
639 u32 => int32,
640 else => @compileError("bad field type: " ++ @typeName(field.type)),
641 };
642 }
643 return .{
644 .data = result,
645 .end = @intCast(index + fields.len),
646 };
647}
lib/compiler/aro/backend/Ir.zig created+696
......@@ -0,0 +1,696 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const Interner = @import("Interner.zig");
5const Object = @import("Object.zig");
6
7const Ir = @This();
8
9interner: *Interner,
10decls: std.StringArrayHashMapUnmanaged(Decl),
11
12pub const Decl = struct {
13 instructions: std.MultiArrayList(Inst),
14 body: std.ArrayListUnmanaged(Ref),
15 arena: std.heap.ArenaAllocator.State,
16
17 pub fn deinit(decl: *Decl, gpa: Allocator) void {
18 decl.instructions.deinit(gpa);
19 decl.body.deinit(gpa);
20 decl.arena.promote(gpa).deinit();
21 }
22};
23
24pub const Builder = struct {
25 gpa: Allocator,
26 arena: std.heap.ArenaAllocator,
27 interner: *Interner,
28
29 decls: std.StringArrayHashMapUnmanaged(Decl) = .{},
30 instructions: std.MultiArrayList(Ir.Inst) = .{},
31 body: std.ArrayListUnmanaged(Ref) = .{},
32 alloc_count: u32 = 0,
33 arg_count: u32 = 0,
34 current_label: Ref = undefined,
35
36 pub fn deinit(b: *Builder) void {
37 for (b.decls.values()) |*decl| {
38 decl.deinit(b.gpa);
39 }
40 b.arena.deinit();
41 b.instructions.deinit(b.gpa);
42 b.body.deinit(b.gpa);
43 b.* = undefined;
44 }
45
46 pub fn finish(b: *Builder) Ir {
47 return .{
48 .interner = b.interner,
49 .decls = b.decls.move(),
50 };
51 }
52
53 pub fn startFn(b: *Builder) Allocator.Error!void {
54 const entry = try b.makeLabel("entry");
55 try b.body.append(b.gpa, entry);
56 b.current_label = entry;
57 }
58
59 pub fn finishFn(b: *Builder, name: []const u8) !void {
60 var duped_instructions = try b.instructions.clone(b.gpa);
61 errdefer duped_instructions.deinit(b.gpa);
62 var duped_body = try b.body.clone(b.gpa);
63 errdefer duped_body.deinit(b.gpa);
64
65 try b.decls.put(b.gpa, name, .{
66 .instructions = duped_instructions,
67 .body = duped_body,
68 .arena = b.arena.state,
69 });
70 b.instructions.shrinkRetainingCapacity(0);
71 b.body.shrinkRetainingCapacity(0);
72 b.arena = std.heap.ArenaAllocator.init(b.gpa);
73 b.alloc_count = 0;
74 b.arg_count = 0;
75 }
76
77 pub fn startBlock(b: *Builder, label: Ref) !void {
78 try b.body.append(b.gpa, label);
79 b.current_label = label;
80 }
81
82 pub fn addArg(b: *Builder, ty: Interner.Ref) Allocator.Error!Ref {
83 const ref: Ref = @enumFromInt(b.instructions.len);
84 try b.instructions.append(b.gpa, .{ .tag = .arg, .data = .{ .none = {} }, .ty = ty });
85 try b.body.insert(b.gpa, b.arg_count, ref);
86 b.arg_count += 1;
87 return ref;
88 }
89
90 pub fn addAlloc(b: *Builder, size: u32, @"align": u32) Allocator.Error!Ref {
91 const ref: Ref = @enumFromInt(b.instructions.len);
92 try b.instructions.append(b.gpa, .{
93 .tag = .alloc,
94 .data = .{ .alloc = .{ .size = size, .@"align" = @"align" } },
95 .ty = .ptr,
96 });
97 try b.body.insert(b.gpa, b.alloc_count + b.arg_count + 1, ref);
98 b.alloc_count += 1;
99 return ref;
100 }
101
102 pub fn addInst(b: *Builder, tag: Ir.Inst.Tag, data: Ir.Inst.Data, ty: Interner.Ref) Allocator.Error!Ref {
103 const ref: Ref = @enumFromInt(b.instructions.len);
104 try b.instructions.append(b.gpa, .{ .tag = tag, .data = data, .ty = ty });
105 try b.body.append(b.gpa, ref);
106 return ref;
107 }
108
109 pub fn makeLabel(b: *Builder, name: [*:0]const u8) Allocator.Error!Ref {
110 const ref: Ref = @enumFromInt(b.instructions.len);
111 try b.instructions.append(b.gpa, .{ .tag = .label, .data = .{ .label = name }, .ty = .void });
112 return ref;
113 }
114
115 pub fn addJump(b: *Builder, label: Ref) Allocator.Error!void {
116 _ = try b.addInst(.jmp, .{ .un = label }, .noreturn);
117 }
118
119 pub fn addBranch(b: *Builder, cond: Ref, true_label: Ref, false_label: Ref) Allocator.Error!void {
120 const branch = try b.arena.allocator().create(Ir.Inst.Branch);
121 branch.* = .{
122 .cond = cond,
123 .then = true_label,
124 .@"else" = false_label,
125 };
126 _ = try b.addInst(.branch, .{ .branch = branch }, .noreturn);
127 }
128
129 pub fn addSwitch(b: *Builder, target: Ref, values: []Interner.Ref, labels: []Ref, default: Ref) Allocator.Error!void {
130 assert(values.len == labels.len);
131 const a = b.arena.allocator();
132 const @"switch" = try a.create(Ir.Inst.Switch);
133 @"switch".* = .{
134 .target = target,
135 .cases_len = @intCast(values.len),
136 .case_vals = (try a.dupe(Interner.Ref, values)).ptr,
137 .case_labels = (try a.dupe(Ref, labels)).ptr,
138 .default = default,
139 };
140 _ = try b.addInst(.@"switch", .{ .@"switch" = @"switch" }, .noreturn);
141 }
142
143 pub fn addStore(b: *Builder, ptr: Ref, val: Ref) Allocator.Error!void {
144 _ = try b.addInst(.store, .{ .bin = .{ .lhs = ptr, .rhs = val } }, .void);
145 }
146
147 pub fn addConstant(b: *Builder, val: Interner.Ref, ty: Interner.Ref) Allocator.Error!Ref {
148 const ref: Ref = @enumFromInt(b.instructions.len);
149 try b.instructions.append(b.gpa, .{
150 .tag = .constant,
151 .data = .{ .constant = val },
152 .ty = ty,
153 });
154 return ref;
155 }
156
157 pub fn addPhi(b: *Builder, inputs: []const Inst.Phi.Input, ty: Interner.Ref) Allocator.Error!Ref {
158 const a = b.arena.allocator();
159 const input_refs = try a.alloc(Ref, inputs.len * 2 + 1);
160 input_refs[0] = @enumFromInt(inputs.len);
161 @memcpy(input_refs[1..], std.mem.bytesAsSlice(Ref, std.mem.sliceAsBytes(inputs)));
162
163 return b.addInst(.phi, .{ .phi = .{ .ptr = input_refs.ptr } }, ty);
164 }
165
166 pub fn addSelect(b: *Builder, cond: Ref, then: Ref, @"else": Ref, ty: Interner.Ref) Allocator.Error!Ref {
167 const branch = try b.arena.allocator().create(Ir.Inst.Branch);
168 branch.* = .{
169 .cond = cond,
170 .then = then,
171 .@"else" = @"else",
172 };
173 return b.addInst(.select, .{ .branch = branch }, ty);
174 }
175};
176
177pub const Renderer = struct {
178 gpa: Allocator,
179 obj: *Object,
180 ir: *const Ir,
181 errors: ErrorList = .{},
182
183 pub const ErrorList = std.StringArrayHashMapUnmanaged([]const u8);
184
185 pub const Error = Allocator.Error || error{LowerFail};
186
187 pub fn deinit(r: *Renderer) void {
188 for (r.errors.values()) |msg| r.gpa.free(msg);
189 r.errors.deinit(r.gpa);
190 }
191
192 pub fn render(r: *Renderer) !void {
193 switch (r.obj.target.cpu.arch) {
194 .x86, .x86_64 => return @import("Ir/x86/Renderer.zig").render(r),
195 else => unreachable,
196 }
197 }
198
199 pub fn fail(
200 r: *Renderer,
201 name: []const u8,
202 comptime format: []const u8,
203 args: anytype,
204 ) Error {
205 try r.errors.ensureUnusedCapacity(r.gpa, 1);
206 r.errors.putAssumeCapacity(name, try std.fmt.allocPrint(r.gpa, format, args));
207 return error.LowerFail;
208 }
209};
210
211pub fn render(
212 ir: *const Ir,
213 gpa: Allocator,
214 target: std.Target,
215 errors: ?*Renderer.ErrorList,
216) !*Object {
217 const obj = try Object.create(gpa, target);
218 errdefer obj.deinit();
219
220 var renderer: Renderer = .{
221 .gpa = gpa,
222 .obj = obj,
223 .ir = ir,
224 };
225 defer {
226 if (errors) |some| {
227 some.* = renderer.errors.move();
228 }
229 renderer.deinit();
230 }
231
232 try renderer.render();
233 return obj;
234}
235
236pub const Ref = enum(u32) { none = std.math.maxInt(u32), _ };
237
238pub const Inst = struct {
239 tag: Tag,
240 data: Data,
241 ty: Interner.Ref,
242
243 pub const Tag = enum {
244 // data.constant
245 // not included in blocks
246 constant,
247
248 // data.arg
249 // not included in blocks
250 arg,
251 symbol,
252
253 // data.label
254 label,
255
256 // data.block
257 label_addr,
258 jmp,
259
260 // data.switch
261 @"switch",
262
263 // data.branch
264 branch,
265 select,
266
267 // data.un
268 jmp_val,
269
270 // data.call
271 call,
272
273 // data.alloc
274 alloc,
275
276 // data.phi
277 phi,
278
279 // data.bin
280 store,
281 bit_or,
282 bit_xor,
283 bit_and,
284 bit_shl,
285 bit_shr,
286 cmp_eq,
287 cmp_ne,
288 cmp_lt,
289 cmp_lte,
290 cmp_gt,
291 cmp_gte,
292 add,
293 sub,
294 mul,
295 div,
296 mod,
297
298 // data.un
299 ret,
300 load,
301 bit_not,
302 negate,
303 trunc,
304 zext,
305 sext,
306 };
307
308 pub const Data = union {
309 constant: Interner.Ref,
310 none: void,
311 bin: struct {
312 lhs: Ref,
313 rhs: Ref,
314 },
315 un: Ref,
316 arg: u32,
317 alloc: struct {
318 size: u32,
319 @"align": u32,
320 },
321 @"switch": *Switch,
322 call: *Call,
323 label: [*:0]const u8,
324 branch: *Branch,
325 phi: Phi,
326 };
327
328 pub const Branch = struct {
329 cond: Ref,
330 then: Ref,
331 @"else": Ref,
332 };
333
334 pub const Switch = struct {
335 target: Ref,
336 cases_len: u32,
337 default: Ref,
338 case_vals: [*]Interner.Ref,
339 case_labels: [*]Ref,
340 };
341
342 pub const Call = struct {
343 func: Ref,
344 args_len: u32,
345 args_ptr: [*]Ref,
346
347 pub fn args(c: Call) []Ref {
348 return c.args_ptr[0..c.args_len];
349 }
350 };
351
352 pub const Phi = struct {
353 ptr: [*]Ir.Ref,
354
355 pub const Input = struct {
356 label: Ir.Ref,
357 value: Ir.Ref,
358 };
359
360 pub fn inputs(p: Phi) []Input {
361 const len = @intFromEnum(p.ptr[0]) * 2;
362 const slice = (p.ptr + 1)[0..len];
363 return std.mem.bytesAsSlice(Input, std.mem.sliceAsBytes(slice));
364 }
365 };
366};
367
368pub fn deinit(ir: *Ir, gpa: std.mem.Allocator) void {
369 for (ir.decls.values()) |*decl| {
370 decl.deinit(gpa);
371 }
372 ir.decls.deinit(gpa);
373 ir.* = undefined;
374}
375
376const TYPE = std.io.tty.Color.bright_magenta;
377const INST = std.io.tty.Color.bright_cyan;
378const REF = std.io.tty.Color.bright_blue;
379const LITERAL = std.io.tty.Color.bright_green;
380const ATTRIBUTE = std.io.tty.Color.bright_yellow;
381
382const RefMap = std.AutoArrayHashMap(Ref, void);
383
384pub fn dump(ir: *const Ir, gpa: Allocator, config: std.io.tty.Config, w: anytype) !void {
385 for (ir.decls.keys(), ir.decls.values()) |name, *decl| {
386 try ir.dumpDecl(decl, gpa, name, config, w);
387 }
388}
389
390fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8, config: std.io.tty.Config, w: anytype) !void {
391 const tags = decl.instructions.items(.tag);
392 const data = decl.instructions.items(.data);
393
394 var ref_map = RefMap.init(gpa);
395 defer ref_map.deinit();
396
397 var label_map = RefMap.init(gpa);
398 defer label_map.deinit();
399
400 const ret_inst = decl.body.items[decl.body.items.len - 1];
401 const ret_operand = data[@intFromEnum(ret_inst)].un;
402 const ret_ty = decl.instructions.items(.ty)[@intFromEnum(ret_operand)];
403 try ir.writeType(ret_ty, config, w);
404 try config.setColor(w, REF);
405 try w.print(" @{s}", .{name});
406 try config.setColor(w, .reset);
407 try w.writeAll("(");
408
409 var arg_count: u32 = 0;
410 while (true) : (arg_count += 1) {
411 const ref = decl.body.items[arg_count];
412 if (tags[@intFromEnum(ref)] != .arg) break;
413 if (arg_count != 0) try w.writeAll(", ");
414 try ref_map.put(ref, {});
415 try ir.writeRef(decl, &ref_map, ref, config, w);
416 try config.setColor(w, .reset);
417 }
418 try w.writeAll(") {\n");
419 for (decl.body.items[arg_count..]) |ref| {
420 switch (tags[@intFromEnum(ref)]) {
421 .label => try label_map.put(ref, {}),
422 else => {},
423 }
424 }
425
426 for (decl.body.items[arg_count..]) |ref| {
427 const i = @intFromEnum(ref);
428 const tag = tags[i];
429 switch (tag) {
430 .arg, .constant, .symbol => unreachable,
431 .label => {
432 const label_index = label_map.getIndex(ref).?;
433 try config.setColor(w, REF);
434 try w.print("{s}.{d}:\n", .{ data[i].label, label_index });
435 },
436 // .label_val => {
437 // const un = data[i].un;
438 // try w.print(" %{d} = label.{d}\n", .{ i, @intFromEnum(un) });
439 // },
440 .jmp => {
441 const un = data[i].un;
442 try config.setColor(w, INST);
443 try w.writeAll(" jmp ");
444 try writeLabel(decl, &label_map, un, config, w);
445 try w.writeByte('\n');
446 },
447 .branch => {
448 const br = data[i].branch;
449 try config.setColor(w, INST);
450 try w.writeAll(" branch ");
451 try ir.writeRef(decl, &ref_map, br.cond, config, w);
452 try config.setColor(w, .reset);
453 try w.writeAll(", ");
454 try writeLabel(decl, &label_map, br.then, config, w);
455 try config.setColor(w, .reset);
456 try w.writeAll(", ");
457 try writeLabel(decl, &label_map, br.@"else", config, w);
458 try w.writeByte('\n');
459 },
460 .select => {
461 const br = data[i].branch;
462 try ir.writeNewRef(decl, &ref_map, ref, config, w);
463 try w.writeAll("select ");
464 try ir.writeRef(decl, &ref_map, br.cond, config, w);
465 try config.setColor(w, .reset);
466 try w.writeAll(", ");
467 try ir.writeRef(decl, &ref_map, br.then, config, w);
468 try config.setColor(w, .reset);
469 try w.writeAll(", ");
470 try ir.writeRef(decl, &ref_map, br.@"else", config, w);
471 try w.writeByte('\n');
472 },
473 // .jmp_val => {
474 // const bin = data[i].bin;
475 // try w.print(" %{s} %{d} label.{d}\n", .{ @tagName(tag), @intFromEnum(bin.lhs), @intFromEnum(bin.rhs) });
476 // },
477 .@"switch" => {
478 const @"switch" = data[i].@"switch";
479 try config.setColor(w, INST);
480 try w.writeAll(" switch ");
481 try ir.writeRef(decl, &ref_map, @"switch".target, config, w);
482 try config.setColor(w, .reset);
483 try w.writeAll(" {");
484 for (@"switch".case_vals[0..@"switch".cases_len], @"switch".case_labels) |val_ref, label_ref| {
485 try w.writeAll("\n ");
486 try ir.writeValue(val_ref, config, w);
487 try config.setColor(w, .reset);
488 try w.writeAll(" => ");
489 try writeLabel(decl, &label_map, label_ref, config, w);
490 try config.setColor(w, .reset);
491 }
492 try config.setColor(w, LITERAL);
493 try w.writeAll("\n default ");
494 try config.setColor(w, .reset);
495 try w.writeAll("=> ");
496 try writeLabel(decl, &label_map, @"switch".default, config, w);
497 try config.setColor(w, .reset);
498 try w.writeAll("\n }\n");
499 },
500 .call => {
501 const call = data[i].call;
502 try ir.writeNewRef(decl, &ref_map, ref, config, w);
503 try w.writeAll("call ");
504 try ir.writeRef(decl, &ref_map, call.func, config, w);
505 try config.setColor(w, .reset);
506 try w.writeAll("(");
507 for (call.args(), 0..) |arg, arg_i| {
508 if (arg_i != 0) try w.writeAll(", ");
509 try ir.writeRef(decl, &ref_map, arg, config, w);
510 try config.setColor(w, .reset);
511 }
512 try w.writeAll(")\n");
513 },
514 .alloc => {
515 const alloc = data[i].alloc;
516 try ir.writeNewRef(decl, &ref_map, ref, config, w);
517 try w.writeAll("alloc ");
518 try config.setColor(w, ATTRIBUTE);
519 try w.writeAll("size ");
520 try config.setColor(w, LITERAL);
521 try w.print("{d}", .{alloc.size});
522 try config.setColor(w, ATTRIBUTE);
523 try w.writeAll(" align ");
524 try config.setColor(w, LITERAL);
525 try w.print("{d}", .{alloc.@"align"});
526 try w.writeByte('\n');
527 },
528 .phi => {
529 try ir.writeNewRef(decl, &ref_map, ref, config, w);
530 try w.writeAll("phi");
531 try config.setColor(w, .reset);
532 try w.writeAll(" {");
533 for (data[i].phi.inputs()) |input| {
534 try w.writeAll("\n ");
535 try writeLabel(decl, &label_map, input.label, config, w);
536 try config.setColor(w, .reset);
537 try w.writeAll(" => ");
538 try ir.writeRef(decl, &ref_map, input.value, config, w);
539 try config.setColor(w, .reset);
540 }
541 try config.setColor(w, .reset);
542 try w.writeAll("\n }\n");
543 },
544 .store => {
545 const bin = data[i].bin;
546 try config.setColor(w, INST);
547 try w.writeAll(" store ");
548 try ir.writeRef(decl, &ref_map, bin.lhs, config, w);
549 try config.setColor(w, .reset);
550 try w.writeAll(", ");
551 try ir.writeRef(decl, &ref_map, bin.rhs, config, w);
552 try w.writeByte('\n');
553 },
554 .ret => {
555 try config.setColor(w, INST);
556 try w.writeAll(" ret ");
557 if (data[i].un != .none) try ir.writeRef(decl, &ref_map, data[i].un, config, w);
558 try w.writeByte('\n');
559 },
560 .load => {
561 try ir.writeNewRef(decl, &ref_map, ref, config, w);
562 try w.writeAll("load ");
563 try ir.writeRef(decl, &ref_map, data[i].un, config, w);
564 try w.writeByte('\n');
565 },
566 .bit_or,
567 .bit_xor,
568 .bit_and,
569 .bit_shl,
570 .bit_shr,
571 .cmp_eq,
572 .cmp_ne,
573 .cmp_lt,
574 .cmp_lte,
575 .cmp_gt,
576 .cmp_gte,
577 .add,
578 .sub,
579 .mul,
580 .div,
581 .mod,
582 => {
583 const bin = data[i].bin;
584 try ir.writeNewRef(decl, &ref_map, ref, config, w);
585 try w.print("{s} ", .{@tagName(tag)});
586 try ir.writeRef(decl, &ref_map, bin.lhs, config, w);
587 try config.setColor(w, .reset);
588 try w.writeAll(", ");
589 try ir.writeRef(decl, &ref_map, bin.rhs, config, w);
590 try w.writeByte('\n');
591 },
592 .bit_not,
593 .negate,
594 .trunc,
595 .zext,
596 .sext,
597 => {
598 const un = data[i].un;
599 try ir.writeNewRef(decl, &ref_map, ref, config, w);
600 try w.print("{s} ", .{@tagName(tag)});
601 try ir.writeRef(decl, &ref_map, un, config, w);
602 try w.writeByte('\n');
603 },
604 .label_addr, .jmp_val => {},
605 }
606 }
607 try config.setColor(w, .reset);
608 try w.writeAll("}\n\n");
609}
610
611fn writeType(ir: Ir, ty_ref: Interner.Ref, config: std.io.tty.Config, w: anytype) !void {
612 const ty = ir.interner.get(ty_ref);
613 try config.setColor(w, TYPE);
614 switch (ty) {
615 .ptr_ty, .noreturn_ty, .void_ty, .func_ty => try w.writeAll(@tagName(ty)),
616 .int_ty => |bits| try w.print("i{d}", .{bits}),
617 .float_ty => |bits| try w.print("f{d}", .{bits}),
618 .array_ty => |info| {
619 try w.print("[{d} * ", .{info.len});
620 try ir.writeType(info.child, .no_color, w);
621 try w.writeByte(']');
622 },
623 .vector_ty => |info| {
624 try w.print("<{d} * ", .{info.len});
625 try ir.writeType(info.child, .no_color, w);
626 try w.writeByte('>');
627 },
628 .record_ty => |elems| {
629 // TODO collect into buffer and only print once
630 try w.writeAll("{ ");
631 for (elems, 0..) |elem, i| {
632 if (i != 0) try w.writeAll(", ");
633 try ir.writeType(elem, config, w);
634 }
635 try w.writeAll(" }");
636 },
637 else => unreachable, // not a type
638 }
639}
640
641fn writeValue(ir: Ir, val: Interner.Ref, config: std.io.tty.Config, w: anytype) !void {
642 try config.setColor(w, LITERAL);
643 const key = ir.interner.get(val);
644 switch (key) {
645 .null => return w.writeAll("nullptr_t"),
646 .int => |repr| switch (repr) {
647 inline else => |x| return w.print("{d}", .{x}),
648 },
649 .float => |repr| switch (repr) {
650 inline else => |x| return w.print("{d}", .{@as(f64, @floatCast(x))}),
651 },
652 .bytes => |b| return std.zig.fmt.stringEscape(b, "", .{}, w),
653 else => unreachable, // not a value
654 }
655}
656
657fn writeRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void {
658 assert(ref != .none);
659 const index = @intFromEnum(ref);
660 const ty_ref = decl.instructions.items(.ty)[index];
661 if (decl.instructions.items(.tag)[index] == .constant) {
662 try ir.writeType(ty_ref, config, w);
663 const v_ref = decl.instructions.items(.data)[index].constant;
664 try w.writeByte(' ');
665 try ir.writeValue(v_ref, config, w);
666 return;
667 } else if (decl.instructions.items(.tag)[index] == .symbol) {
668 const name = decl.instructions.items(.data)[index].label;
669 try ir.writeType(ty_ref, config, w);
670 try config.setColor(w, REF);
671 try w.print(" @{s}", .{name});
672 return;
673 }
674 try ir.writeType(ty_ref, config, w);
675 try config.setColor(w, REF);
676 const ref_index = ref_map.getIndex(ref).?;
677 try w.print(" %{d}", .{ref_index});
678}
679
680fn writeNewRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void {
681 try ref_map.put(ref, {});
682 try w.writeAll(" ");
683 try ir.writeRef(decl, ref_map, ref, config, w);
684 try config.setColor(w, .reset);
685 try w.writeAll(" = ");
686 try config.setColor(w, INST);
687}
688
689fn writeLabel(decl: *const Decl, label_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void {
690 assert(ref != .none);
691 const index = @intFromEnum(ref);
692 const label = decl.instructions.items(.data)[index].label;
693 try config.setColor(w, REF);
694 const label_index = label_map.getIndex(ref).?;
695 try w.print("{s}.{d}", .{ label, label_index });
696}
lib/compiler/aro/backend/Ir/x86/Renderer.zig created+65
......@@ -0,0 +1,65 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const assert = std.debug.assert;
4const Interner = @import("../../Interner.zig");
5const Ir = @import("../../Ir.zig");
6const BaseRenderer = Ir.Renderer;
7const zig = @import("zig");
8const abi = zig.arch.x86_64.abi;
9const bits = zig.arch.x86_64.bits;
10
11const Condition = bits.Condition;
12const Immediate = bits.Immediate;
13const Memory = bits.Memory;
14const Register = bits.Register;
15const RegisterLock = RegisterManager.RegisterLock;
16const FrameIndex = bits.FrameIndex;
17
18const RegisterManager = zig.RegisterManager(Renderer, Register, Ir.Ref, abi.allocatable_regs);
19
20// Register classes
21const RegisterBitSet = RegisterManager.RegisterBitSet;
22const RegisterClass = struct {
23 const gp: RegisterBitSet = blk: {
24 var set = RegisterBitSet.initEmpty();
25 for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
26 break :blk set;
27 };
28 const x87: RegisterBitSet = blk: {
29 var set = RegisterBitSet.initEmpty();
30 for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
31 break :blk set;
32 };
33 const sse: RegisterBitSet = blk: {
34 var set = RegisterBitSet.initEmpty();
35 for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index);
36 break :blk set;
37 };
38};
39
40const Renderer = @This();
41
42base: *BaseRenderer,
43interner: *Interner,
44
45register_manager: RegisterManager = .{},
46
47pub fn render(base: *BaseRenderer) !void {
48 var renderer: Renderer = .{
49 .base = base,
50 .interner = base.ir.interner,
51 };
52
53 for (renderer.base.ir.decls.keys(), renderer.base.ir.decls.values()) |name, decl| {
54 renderer.renderFn(name, decl) catch |e| switch (e) {
55 error.OutOfMemory => return e,
56 error.LowerFail => continue,
57 };
58 }
59 if (renderer.base.errors.entries.len != 0) return error.LowerFail;
60}
61
62fn renderFn(r: *Renderer, name: []const u8, decl: Ir.Decl) !void {
63 _ = decl;
64 return r.base.fail(name, "TODO implement lowering functions", .{});
65}
lib/compiler/aro/backend/Object.zig created+73
......@@ -0,0 +1,73 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const Elf = @import("Object/Elf.zig");
4
5const Object = @This();
6
7format: std.Target.ObjectFormat,
8target: std.Target,
9
10pub fn create(gpa: Allocator, target: std.Target) !*Object {
11 switch (target.ofmt) {
12 .elf => return Elf.create(gpa, target),
13 else => unreachable,
14 }
15}
16
17pub fn deinit(obj: *Object) void {
18 switch (obj.format) {
19 .elf => @fieldParentPtr(Elf, "obj", obj).deinit(),
20 else => unreachable,
21 }
22}
23
24pub const Section = union(enum) {
25 undefined,
26 data,
27 read_only_data,
28 func,
29 strings,
30 custom: []const u8,
31};
32
33pub fn getSection(obj: *Object, section: Section) !*std.ArrayList(u8) {
34 switch (obj.format) {
35 .elf => return @fieldParentPtr(Elf, "obj", obj).getSection(section),
36 else => unreachable,
37 }
38}
39
40pub const SymbolType = enum {
41 func,
42 variable,
43 external,
44};
45
46pub fn declareSymbol(
47 obj: *Object,
48 section: Section,
49 name: ?[]const u8,
50 linkage: std.builtin.GlobalLinkage,
51 @"type": SymbolType,
52 offset: u64,
53 size: u64,
54) ![]const u8 {
55 switch (obj.format) {
56 .elf => return @fieldParentPtr(Elf, "obj", obj).declareSymbol(section, name, linkage, @"type", offset, size),
57 else => unreachable,
58 }
59}
60
61pub fn addRelocation(obj: *Object, name: []const u8, section: Section, address: u64, addend: i64) !void {
62 switch (obj.format) {
63 .elf => return @fieldParentPtr(Elf, "obj", obj).addRelocation(name, section, address, addend),
64 else => unreachable,
65 }
66}
67
68pub fn finish(obj: *Object, file: std.fs.File) !void {
69 switch (obj.format) {
70 .elf => return @fieldParentPtr(Elf, "obj", obj).finish(file),
71 else => unreachable,
72 }
73}
lib/compiler/aro/backend/Object/Elf.zig created+378
......@@ -0,0 +1,378 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3const Target = std.Target;
4const Object = @import("../Object.zig");
5
6const Section = struct {
7 data: std.ArrayList(u8),
8 relocations: std.ArrayListUnmanaged(Relocation) = .{},
9 flags: u64,
10 type: u32,
11 index: u16 = undefined,
12};
13
14const Symbol = struct {
15 section: ?*Section,
16 size: u64,
17 offset: u64,
18 index: u16 = undefined,
19 info: u8,
20};
21
22const Relocation = struct {
23 symbol: *Symbol,
24 addend: i64,
25 offset: u48,
26 type: u8,
27};
28
29const additional_sections = 3; // null section, strtab, symtab
30const strtab_index = 1;
31const symtab_index = 2;
32const strtab_default = "\x00.strtab\x00.symtab\x00";
33const strtab_name = 1;
34const symtab_name = "\x00.strtab\x00".len;
35
36const Elf = @This();
37
38obj: Object,
39/// The keys are owned by the Codegen.tree
40sections: std.StringHashMapUnmanaged(*Section) = .{},
41local_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
42global_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
43unnamed_symbol_mangle: u32 = 0,
44strtab_len: u64 = strtab_default.len,
45arena: std.heap.ArenaAllocator,
46
47pub fn create(gpa: Allocator, target: Target) !*Object {
48 const elf = try gpa.create(Elf);
49 elf.* = .{
50 .obj = .{ .format = .elf, .target = target },
51 .arena = std.heap.ArenaAllocator.init(gpa),
52 };
53 return &elf.obj;
54}
55
56pub fn deinit(elf: *Elf) void {
57 const gpa = elf.arena.child_allocator;
58 {
59 var it = elf.sections.valueIterator();
60 while (it.next()) |sect| {
61 sect.*.data.deinit();
62 sect.*.relocations.deinit(gpa);
63 }
64 }
65 elf.sections.deinit(gpa);
66 elf.local_symbols.deinit(gpa);
67 elf.global_symbols.deinit(gpa);
68 elf.arena.deinit();
69 gpa.destroy(elf);
70}
71
72fn sectionString(sec: Object.Section) []const u8 {
73 return switch (sec) {
74 .undefined => unreachable,
75 .data => "data",
76 .read_only_data => "rodata",
77 .func => "text",
78 .strings => "rodata.str",
79 .custom => |name| name,
80 };
81}
82
83pub fn getSection(elf: *Elf, section_kind: Object.Section) !*std.ArrayList(u8) {
84 const section_name = sectionString(section_kind);
85 const section = elf.sections.get(section_name) orelse blk: {
86 const section = try elf.arena.allocator().create(Section);
87 section.* = .{
88 .data = std.ArrayList(u8).init(elf.arena.child_allocator),
89 .type = std.elf.SHT_PROGBITS,
90 .flags = switch (section_kind) {
91 .func, .custom => std.elf.SHF_ALLOC + std.elf.SHF_EXECINSTR,
92 .strings => std.elf.SHF_ALLOC + std.elf.SHF_MERGE + std.elf.SHF_STRINGS,
93 .read_only_data => std.elf.SHF_ALLOC,
94 .data => std.elf.SHF_ALLOC + std.elf.SHF_WRITE,
95 .undefined => unreachable,
96 },
97 };
98 try elf.sections.putNoClobber(elf.arena.child_allocator, section_name, section);
99 elf.strtab_len += section_name.len + ".\x00".len;
100 break :blk section;
101 };
102 return &section.data;
103}
104
105pub fn declareSymbol(
106 elf: *Elf,
107 section_kind: Object.Section,
108 maybe_name: ?[]const u8,
109 linkage: std.builtin.GlobalLinkage,
110 @"type": Object.SymbolType,
111 offset: u64,
112 size: u64,
113) ![]const u8 {
114 const section = blk: {
115 if (section_kind == .undefined) break :blk null;
116 const section_name = sectionString(section_kind);
117 break :blk elf.sections.get(section_name);
118 };
119 const binding: u8 = switch (linkage) {
120 .Internal => std.elf.STB_LOCAL,
121 .Strong => std.elf.STB_GLOBAL,
122 .Weak => std.elf.STB_WEAK,
123 .LinkOnce => unreachable,
124 };
125 const sym_type: u8 = switch (@"type") {
126 .func => std.elf.STT_FUNC,
127 .variable => std.elf.STT_OBJECT,
128 .external => std.elf.STT_NOTYPE,
129 };
130 const name = if (maybe_name) |some| some else blk: {
131 defer elf.unnamed_symbol_mangle += 1;
132 break :blk try std.fmt.allocPrint(elf.arena.allocator(), ".L.{d}", .{elf.unnamed_symbol_mangle});
133 };
134
135 const gop = if (linkage == .Internal)
136 try elf.local_symbols.getOrPut(elf.arena.child_allocator, name)
137 else
138 try elf.global_symbols.getOrPut(elf.arena.child_allocator, name);
139
140 if (!gop.found_existing) {
141 gop.value_ptr.* = try elf.arena.allocator().create(Symbol);
142 elf.strtab_len += name.len + 1; // +1 for null byte
143 }
144 gop.value_ptr.*.* = .{
145 .section = section,
146 .size = size,
147 .offset = offset,
148 .info = (binding << 4) + sym_type,
149 };
150 return name;
151}
152
153pub fn addRelocation(elf: *Elf, name: []const u8, section_kind: Object.Section, address: u64, addend: i64) !void {
154 const section_name = sectionString(section_kind);
155 const symbol = elf.local_symbols.get(name) orelse elf.global_symbols.get(name).?; // reference to undeclared symbol
156 const section = elf.sections.get(section_name).?;
157 if (section.relocations.items.len == 0) elf.strtab_len += ".rela".len;
158
159 try section.relocations.append(elf.arena.child_allocator, .{
160 .symbol = symbol,
161 .offset = @intCast(address),
162 .addend = addend,
163 .type = if (symbol.section == null) 4 else 2, // TODO
164 });
165}
166
167/// elf header
168/// sections contents
169/// symbols
170/// relocations
171/// strtab
172/// section headers
173pub fn finish(elf: *Elf, file: std.fs.File) !void {
174 var buf_writer = std.io.bufferedWriter(file.writer());
175 const w = buf_writer.writer();
176
177 var num_sections: std.elf.Elf64_Half = additional_sections;
178 var relocations_len: std.elf.Elf64_Off = 0;
179 var sections_len: std.elf.Elf64_Off = 0;
180 {
181 var it = elf.sections.valueIterator();
182 while (it.next()) |sect| {
183 sections_len += sect.*.data.items.len;
184 relocations_len += sect.*.relocations.items.len * @sizeOf(std.elf.Elf64_Rela);
185 sect.*.index = num_sections;
186 num_sections += 1;
187 num_sections += @intFromBool(sect.*.relocations.items.len != 0);
188 }
189 }
190 const symtab_len = (elf.local_symbols.count() + elf.global_symbols.count() + 1) * @sizeOf(std.elf.Elf64_Sym);
191
192 const symtab_offset = @sizeOf(std.elf.Elf64_Ehdr) + sections_len;
193 const symtab_offset_aligned = std.mem.alignForward(u64, symtab_offset, 8);
194 const rela_offset = symtab_offset_aligned + symtab_len;
195 const strtab_offset = rela_offset + relocations_len;
196 const sh_offset = strtab_offset + elf.strtab_len;
197 const sh_offset_aligned = std.mem.alignForward(u64, sh_offset, 16);
198
199 const elf_header = std.elf.Elf64_Ehdr{
200 .e_ident = .{ 0x7F, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
201 .e_type = std.elf.ET.REL, // we only produce relocatables
202 .e_machine = elf.obj.target.cpu.arch.toElfMachine(),
203 .e_version = 1,
204 .e_entry = 0, // linker will handle this
205 .e_phoff = 0, // no program header
206 .e_shoff = sh_offset_aligned, // section headers offset
207 .e_flags = 0, // no flags
208 .e_ehsize = @sizeOf(std.elf.Elf64_Ehdr),
209 .e_phentsize = 0, // no program header
210 .e_phnum = 0, // no program header
211 .e_shentsize = @sizeOf(std.elf.Elf64_Shdr),
212 .e_shnum = num_sections,
213 .e_shstrndx = strtab_index,
214 };
215 try w.writeStruct(elf_header);
216
217 // write contents of sections
218 {
219 var it = elf.sections.valueIterator();
220 while (it.next()) |sect| try w.writeAll(sect.*.data.items);
221 }
222
223 // pad to 8 bytes
224 try w.writeByteNTimes(0, @intCast(symtab_offset_aligned - symtab_offset));
225
226 var name_offset: u32 = strtab_default.len;
227 // write symbols
228 {
229 // first symbol must be null
230 try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Sym));
231
232 var sym_index: u16 = 1;
233 var it = elf.local_symbols.iterator();
234 while (it.next()) |entry| {
235 const sym = entry.value_ptr.*;
236 try w.writeStruct(std.elf.Elf64_Sym{
237 .st_name = name_offset,
238 .st_info = sym.info,
239 .st_other = 0,
240 .st_shndx = if (sym.section) |some| some.index else 0,
241 .st_value = sym.offset,
242 .st_size = sym.size,
243 });
244 sym.index = sym_index;
245 sym_index += 1;
246 name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
247 }
248 it = elf.global_symbols.iterator();
249 while (it.next()) |entry| {
250 const sym = entry.value_ptr.*;
251 try w.writeStruct(std.elf.Elf64_Sym{
252 .st_name = name_offset,
253 .st_info = sym.info,
254 .st_other = 0,
255 .st_shndx = if (sym.section) |some| some.index else 0,
256 .st_value = sym.offset,
257 .st_size = sym.size,
258 });
259 sym.index = sym_index;
260 sym_index += 1;
261 name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte
262 }
263 }
264
265 // write relocations
266 {
267 var it = elf.sections.valueIterator();
268 while (it.next()) |sect| {
269 for (sect.*.relocations.items) |rela| {
270 try w.writeStruct(std.elf.Elf64_Rela{
271 .r_offset = rela.offset,
272 .r_addend = rela.addend,
273 .r_info = (@as(u64, rela.symbol.index) << 32) | rela.type,
274 });
275 }
276 }
277 }
278
279 // write strtab
280 try w.writeAll(strtab_default);
281 {
282 var it = elf.local_symbols.keyIterator();
283 while (it.next()) |key| try w.print("{s}\x00", .{key.*});
284 it = elf.global_symbols.keyIterator();
285 while (it.next()) |key| try w.print("{s}\x00", .{key.*});
286 }
287 {
288 var it = elf.sections.iterator();
289 while (it.next()) |entry| {
290 if (entry.value_ptr.*.relocations.items.len != 0) try w.writeAll(".rela");
291 try w.print(".{s}\x00", .{entry.key_ptr.*});
292 }
293 }
294
295 // pad to 16 bytes
296 try w.writeByteNTimes(0, @intCast(sh_offset_aligned - sh_offset));
297 // mandatory null header
298 try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Shdr));
299
300 // write strtab section header
301 {
302 const sect_header = std.elf.Elf64_Shdr{
303 .sh_name = strtab_name,
304 .sh_type = std.elf.SHT_STRTAB,
305 .sh_flags = 0,
306 .sh_addr = 0,
307 .sh_offset = strtab_offset,
308 .sh_size = elf.strtab_len,
309 .sh_link = 0,
310 .sh_info = 0,
311 .sh_addralign = 1,
312 .sh_entsize = 0,
313 };
314 try w.writeStruct(sect_header);
315 }
316
317 // write symtab section header
318 {
319 const sect_header = std.elf.Elf64_Shdr{
320 .sh_name = symtab_name,
321 .sh_type = std.elf.SHT_SYMTAB,
322 .sh_flags = 0,
323 .sh_addr = 0,
324 .sh_offset = symtab_offset_aligned,
325 .sh_size = symtab_len,
326 .sh_link = strtab_index,
327 .sh_info = elf.local_symbols.size + 1,
328 .sh_addralign = 8,
329 .sh_entsize = @sizeOf(std.elf.Elf64_Sym),
330 };
331 try w.writeStruct(sect_header);
332 }
333
334 // remaining section headers
335 {
336 var sect_offset: u64 = @sizeOf(std.elf.Elf64_Ehdr);
337 var rela_sect_offset: u64 = rela_offset;
338 var it = elf.sections.iterator();
339 while (it.next()) |entry| {
340 const sect = entry.value_ptr.*;
341 const rela_count = sect.relocations.items.len;
342 const rela_name_offset: u32 = if (rela_count != 0) @truncate(".rela".len) else 0;
343 try w.writeStruct(std.elf.Elf64_Shdr{
344 .sh_name = rela_name_offset + name_offset,
345 .sh_type = sect.type,
346 .sh_flags = sect.flags,
347 .sh_addr = 0,
348 .sh_offset = sect_offset,
349 .sh_size = sect.data.items.len,
350 .sh_link = 0,
351 .sh_info = 0,
352 .sh_addralign = if (sect.flags & std.elf.SHF_EXECINSTR != 0) 16 else 1,
353 .sh_entsize = 0,
354 });
355
356 if (rela_count != 0) {
357 const size = rela_count * @sizeOf(std.elf.Elf64_Rela);
358 try w.writeStruct(std.elf.Elf64_Shdr{
359 .sh_name = name_offset,
360 .sh_type = std.elf.SHT_RELA,
361 .sh_flags = 0,
362 .sh_addr = 0,
363 .sh_offset = rela_sect_offset,
364 .sh_size = rela_count * @sizeOf(std.elf.Elf64_Rela),
365 .sh_link = symtab_index,
366 .sh_info = sect.index,
367 .sh_addralign = 8,
368 .sh_entsize = @sizeOf(std.elf.Elf64_Rela),
369 });
370 rela_sect_offset += size;
371 }
372
373 sect_offset += sect.data.items.len;
374 name_offset += @as(u32, @intCast(entry.key_ptr.len + ".\x00".len)) + rela_name_offset;
375 }
376 }
377 try buf_writer.flush();
378}
lib/compiler/aro_translate_c.zig created+1298
......@@ -0,0 +1,1298 @@
1const std = @import("std");
2const mem = std.mem;
3const assert = std.debug.assert;
4const CallingConvention = std.builtin.CallingConvention;
5const aro = @import("aro");
6const CToken = aro.Tokenizer.Token;
7const Tree = aro.Tree;
8const NodeIndex = Tree.NodeIndex;
9const TokenIndex = Tree.TokenIndex;
10const Type = aro.Type;
11pub const ast = @import("aro_translate_c/ast.zig");
12const ZigNode = ast.Node;
13const ZigTag = ZigNode.Tag;
14const Scope = ScopeExtra(Context, Type);
15const Context = @This();
16
17gpa: mem.Allocator,
18arena: mem.Allocator,
19decl_table: std.AutoArrayHashMapUnmanaged(usize, []const u8) = .{},
20alias_list: AliasList,
21global_scope: *Scope.Root,
22mangle_count: u32 = 0,
23/// Table of record decls that have been demoted to opaques.
24opaque_demotes: std.AutoHashMapUnmanaged(usize, void) = .{},
25/// Table of unnamed enums and records that are child types of typedefs.
26unnamed_typedefs: std.AutoHashMapUnmanaged(usize, []const u8) = .{},
27/// Needed to decide if we are parsing a typename
28typedefs: std.StringArrayHashMapUnmanaged(void) = .{},
29
30/// This one is different than the root scope's name table. This contains
31/// a list of names that we found by visiting all the top level decls without
32/// translating them. The other maps are updated as we translate; this one is updated
33/// up front in a pre-processing step.
34global_names: std.StringArrayHashMapUnmanaged(void) = .{},
35
36/// This is similar to `global_names`, but contains names which we would
37/// *like* to use, but do not strictly *have* to if they are unavailable.
38/// These are relevant to types, which ideally we would name like
39/// 'struct_foo' with an alias 'foo', but if either of those names is taken,
40/// may be mangled.
41/// This is distinct from `global_names` so we can detect at a type
42/// declaration whether or not the name is available.
43weak_global_names: std.StringArrayHashMapUnmanaged(void) = .{},
44
45pattern_list: PatternList,
46tree: Tree,
47comp: *aro.Compilation,
48mapper: aro.TypeMapper,
49
50fn getMangle(c: *Context) u32 {
51 c.mangle_count += 1;
52 return c.mangle_count;
53}
54
55/// Convert a clang source location to a file:line:column string
56fn locStr(c: *Context, loc: TokenIndex) ![]const u8 {
57 _ = c;
58 _ = loc;
59 // const spelling_loc = c.source_manager.getSpellingLoc(loc);
60 // const filename_c = c.source_manager.getFilename(spelling_loc);
61 // const filename = if (filename_c) |s| try c.str(s) else @as([]const u8, "(no file)");
62
63 // const line = c.source_manager.getSpellingLineNumber(spelling_loc);
64 // const column = c.source_manager.getSpellingColumnNumber(spelling_loc);
65 // return std.fmt.allocPrint(c.arena, "{s}:{d}:{d}", .{ filename, line, column });
66 return "somewhere";
67}
68
69fn maybeSuppressResult(c: *Context, used: ResultUsed, result: ZigNode) TransError!ZigNode {
70 if (used == .used) return result;
71 return ZigTag.discard.create(c.arena, .{ .should_skip = false, .value = result });
72}
73
74fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: ZigNode) !void {
75 const gop = try c.global_scope.sym_table.getOrPut(name);
76 if (!gop.found_existing) {
77 gop.value_ptr.* = decl_node;
78 try c.global_scope.nodes.append(decl_node);
79 }
80}
81
82fn failDecl(c: *Context, loc: TokenIndex, name: []const u8, comptime format: []const u8, args: anytype) Error!void {
83 // location
84 // pub const name = @compileError(msg);
85 const fail_msg = try std.fmt.allocPrint(c.arena, format, args);
86 try addTopLevelDecl(c, name, try ZigTag.fail_decl.create(c.arena, .{ .actual = name, .mangled = fail_msg }));
87 const str = try c.locStr(loc);
88 const location_comment = try std.fmt.allocPrint(c.arena, "// {s}", .{str});
89 try c.global_scope.nodes.append(try ZigTag.warning.create(c.arena, location_comment));
90}
91
92fn warn(c: *Context, scope: *Scope, loc: TokenIndex, comptime format: []const u8, args: anytype) !void {
93 const str = try c.locStr(loc);
94 const value = try std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, .{str} ++ args);
95 try scope.appendNode(try ZigTag.warning.create(c.arena, value));
96}
97
98pub fn translate(
99 gpa: mem.Allocator,
100 comp: *aro.Compilation,
101 args: []const []const u8,
102) !std.zig.Ast {
103 try comp.addDefaultPragmaHandlers();
104 comp.langopts.setEmulatedCompiler(aro.target_util.systemCompiler(comp.target));
105
106 var driver: aro.Driver = .{ .comp = comp };
107 defer driver.deinit();
108
109 var macro_buf = std.ArrayList(u8).init(gpa);
110 defer macro_buf.deinit();
111
112 assert(!try driver.parseArgs(std.io.null_writer, macro_buf.writer(), args));
113 assert(driver.inputs.items.len == 1);
114 const source = driver.inputs.items[0];
115
116 const builtin_macros = try comp.generateBuiltinMacros(.include_system_defines);
117 const user_macros = try comp.addSourceFromBuffer("<command line>", macro_buf.items);
118
119 var pp = try aro.Preprocessor.initDefault(comp);
120 defer pp.deinit();
121
122 try pp.preprocessSources(&.{ source, builtin_macros, user_macros });
123
124 var tree = try pp.parse();
125 defer tree.deinit();
126
127 if (driver.comp.diagnostics.errors != 0) {
128 return error.SemanticAnalyzeFail;
129 }
130
131 const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper();
132 defer mapper.deinit(tree.comp.gpa);
133
134 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
135 defer arena_allocator.deinit();
136 const arena = arena_allocator.allocator();
137
138 var context = Context{
139 .gpa = gpa,
140 .arena = arena,
141 .alias_list = AliasList.init(gpa),
142 .global_scope = try arena.create(Scope.Root),
143 .pattern_list = try PatternList.init(gpa),
144 .comp = comp,
145 .mapper = mapper,
146 .tree = tree,
147 };
148 context.global_scope.* = Scope.Root.init(&context);
149 defer {
150 context.decl_table.deinit(gpa);
151 context.alias_list.deinit();
152 context.global_names.deinit(gpa);
153 context.opaque_demotes.deinit(gpa);
154 context.unnamed_typedefs.deinit(gpa);
155 context.typedefs.deinit(gpa);
156 context.global_scope.deinit();
157 context.pattern_list.deinit(gpa);
158 }
159
160 inline for (@typeInfo(std.zig.c_builtins).Struct.decls) |decl| {
161 const builtin_fn = try ZigTag.pub_var_simple.create(arena, .{
162 .name = decl.name,
163 .init = try ZigTag.import_c_builtin.create(arena, decl.name),
164 });
165 try addTopLevelDecl(&context, decl.name, builtin_fn);
166 }
167
168 try prepopulateGlobalNameTable(&context);
169 try transTopLevelDecls(&context);
170
171 for (context.alias_list.items) |alias| {
172 if (!context.global_scope.sym_table.contains(alias.alias)) {
173 const node = try ZigTag.alias.create(arena, .{ .actual = alias.alias, .mangled = alias.name });
174 try addTopLevelDecl(&context, alias.alias, node);
175 }
176 }
177
178 return ast.render(gpa, context.global_scope.nodes.items);
179}
180
181fn prepopulateGlobalNameTable(c: *Context) !void {
182 const node_tags = c.tree.nodes.items(.tag);
183 const node_types = c.tree.nodes.items(.ty);
184 const node_data = c.tree.nodes.items(.data);
185 for (c.tree.root_decls) |node| {
186 const data = node_data[@intFromEnum(node)];
187 const decl_name = switch (node_tags[@intFromEnum(node)]) {
188 .typedef => @panic("TODO"),
189
190 .static_assert,
191 .struct_decl_two,
192 .union_decl_two,
193 .struct_decl,
194 .union_decl,
195 => blk: {
196 const ty = node_types[@intFromEnum(node)];
197 const name_id = ty.data.record.name;
198 break :blk c.mapper.lookup(name_id);
199 },
200
201 .enum_decl_two,
202 .enum_decl,
203 => blk: {
204 const ty = node_types[@intFromEnum(node)];
205 const name_id = ty.data.@"enum".name;
206 break :blk c.mapper.lookup(name_id);
207 },
208
209 .fn_proto,
210 .static_fn_proto,
211 .inline_fn_proto,
212 .inline_static_fn_proto,
213 .fn_def,
214 .static_fn_def,
215 .inline_fn_def,
216 .inline_static_fn_def,
217 .@"var",
218 .static_var,
219 .threadlocal_var,
220 .threadlocal_static_var,
221 .extern_var,
222 .threadlocal_extern_var,
223 => c.tree.tokSlice(data.decl.name),
224 else => unreachable,
225 };
226 try c.global_names.put(c.gpa, decl_name, {});
227 }
228}
229
230fn transTopLevelDecls(c: *Context) !void {
231 const node_tags = c.tree.nodes.items(.tag);
232 const node_data = c.tree.nodes.items(.data);
233 for (c.tree.root_decls) |node| {
234 const data = node_data[@intFromEnum(node)];
235 switch (node_tags[@intFromEnum(node)]) {
236 .typedef => {
237 try transTypeDef(c, &c.global_scope.base, node);
238 },
239
240 .static_assert,
241 .struct_decl_two,
242 .union_decl_two,
243 .struct_decl,
244 .union_decl,
245 => {
246 try transRecordDecl(c, &c.global_scope.base, node);
247 },
248
249 .enum_decl_two => {
250 var fields = [2]NodeIndex{ data.bin.lhs, data.bin.rhs };
251 var field_count: u8 = 0;
252 if (fields[0] != .none) field_count += 1;
253 if (fields[1] != .none) field_count += 1;
254 try transEnumDecl(c, &c.global_scope.base, node, fields[0..field_count]);
255 },
256 .enum_decl => {
257 const fields = c.tree.data[data.range.start..data.range.end];
258 try transEnumDecl(c, &c.global_scope.base, node, fields);
259 },
260
261 .fn_proto,
262 .static_fn_proto,
263 .inline_fn_proto,
264 .inline_static_fn_proto,
265 .fn_def,
266 .static_fn_def,
267 .inline_fn_def,
268 .inline_static_fn_def,
269 => {
270 try transFnDecl(c, node);
271 },
272
273 .@"var",
274 .static_var,
275 .threadlocal_var,
276 .threadlocal_static_var,
277 .extern_var,
278 .threadlocal_extern_var,
279 => {
280 try transVarDecl(c, node, null);
281 },
282 else => unreachable,
283 }
284 }
285}
286
287fn transTypeDef(_: *Context, _: *Scope, _: NodeIndex) Error!void {
288 @panic("TODO");
289}
290fn transRecordDecl(_: *Context, _: *Scope, _: NodeIndex) Error!void {
291 @panic("TODO");
292}
293
294fn transFnDecl(c: *Context, fn_decl: NodeIndex) Error!void {
295 const raw_ty = c.tree.nodes.items(.ty)[@intFromEnum(fn_decl)];
296 const fn_ty = raw_ty.canonicalize(.standard);
297 const node_data = c.tree.nodes.items(.data)[@intFromEnum(fn_decl)];
298 if (c.decl_table.get(@intFromPtr(fn_ty.data.func))) |_|
299 return; // Avoid processing this decl twice
300
301 const fn_name = c.tree.tokSlice(node_data.decl.name);
302 if (c.global_scope.sym_table.contains(fn_name))
303 return; // Avoid processing this decl twice
304
305 const fn_decl_loc = 0; // TODO
306 const has_body = node_data.decl.node != .none;
307 const is_always_inline = has_body and raw_ty.getAttribute(.always_inline) != null;
308 const proto_ctx = FnProtoContext{
309 .fn_name = fn_name,
310 .is_inline = is_always_inline,
311 .is_extern = !has_body,
312 .is_export = switch (c.tree.nodes.items(.tag)[@intFromEnum(fn_decl)]) {
313 .fn_proto, .fn_def => has_body and !is_always_inline,
314
315 .inline_fn_proto, .inline_fn_def, .inline_static_fn_proto, .inline_static_fn_def, .static_fn_proto, .static_fn_def => false,
316
317 else => unreachable,
318 },
319 };
320
321 const proto_node = transFnType(c, &c.global_scope.base, raw_ty, fn_ty, fn_decl_loc, proto_ctx) catch |err| switch (err) {
322 error.UnsupportedType => {
323 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function", .{});
324 },
325 error.OutOfMemory => |e| return e,
326 };
327
328 if (!has_body) {
329 return addTopLevelDecl(c, fn_name, proto_node);
330 }
331 const proto_payload = proto_node.castTag(.func).?;
332
333 // actual function definition with body
334 const body_stmt = node_data.decl.node;
335 var block_scope = try Scope.Block.init(c, &c.global_scope.base, false);
336 block_scope.return_type = fn_ty.data.func.return_type;
337 defer block_scope.deinit();
338
339 var scope = &block_scope.base;
340 _ = &scope;
341
342 var param_id: c_uint = 0;
343 for (proto_payload.data.params, fn_ty.data.func.params) |*param, param_info| {
344 const param_name = param.name orelse {
345 proto_payload.data.is_extern = true;
346 proto_payload.data.is_export = false;
347 proto_payload.data.is_inline = false;
348 try warn(c, &c.global_scope.base, fn_decl_loc, "function {s} parameter has no name, demoted to extern", .{fn_name});
349 return addTopLevelDecl(c, fn_name, proto_node);
350 };
351
352 const is_const = param_info.ty.qual.@"const";
353
354 const mangled_param_name = try block_scope.makeMangledName(c, param_name);
355 param.name = mangled_param_name;
356
357 if (!is_const) {
358 const bare_arg_name = try std.fmt.allocPrint(c.arena, "arg_{s}", .{mangled_param_name});
359 const arg_name = try block_scope.makeMangledName(c, bare_arg_name);
360 param.name = arg_name;
361
362 const redecl_node = try ZigTag.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name });
363 try block_scope.statements.append(redecl_node);
364 }
365 try block_scope.discardVariable(c, mangled_param_name);
366
367 param_id += 1;
368 }
369
370 transCompoundStmtInline(c, body_stmt, &block_scope) catch |err| switch (err) {
371 error.OutOfMemory => |e| return e,
372 error.UnsupportedTranslation,
373 error.UnsupportedType,
374 => {
375 proto_payload.data.is_extern = true;
376 proto_payload.data.is_export = false;
377 proto_payload.data.is_inline = false;
378 try warn(c, &c.global_scope.base, fn_decl_loc, "unable to translate function, demoted to extern", .{});
379 return addTopLevelDecl(c, fn_name, proto_node);
380 },
381 };
382
383 proto_payload.data.body = try block_scope.complete(c);
384 return addTopLevelDecl(c, fn_name, proto_node);
385}
386
387fn transVarDecl(_: *Context, _: NodeIndex, _: ?usize) Error!void {
388 @panic("TODO");
389}
390
391fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes: []const NodeIndex) Error!void {
392 const node_types = c.tree.nodes.items(.ty);
393 const ty = node_types[@intFromEnum(enum_decl)];
394 if (c.decl_table.get(@intFromPtr(ty.data.@"enum"))) |_|
395 return; // Avoid processing this decl twice
396 const toplevel = scope.id == .root;
397 const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined;
398
399 var is_unnamed = false;
400 var bare_name: []const u8 = c.mapper.lookup(ty.data.@"enum".name);
401 var name = bare_name;
402 if (c.unnamed_typedefs.get(@intFromPtr(ty.data.@"enum"))) |typedef_name| {
403 bare_name = typedef_name;
404 name = typedef_name;
405 } else {
406 if (bare_name.len == 0) {
407 bare_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{c.getMangle()});
408 is_unnamed = true;
409 }
410 name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name});
411 }
412 if (!toplevel) name = try bs.makeMangledName(c, name);
413 try c.decl_table.putNoClobber(c.gpa, @intFromPtr(ty.data.@"enum"), name);
414
415 const enum_type_node = if (!ty.data.@"enum".isIncomplete()) blk: {
416 for (ty.data.@"enum".fields, field_nodes) |field, field_node| {
417 var enum_val_name: []const u8 = c.mapper.lookup(field.name);
418 if (!toplevel) {
419 enum_val_name = try bs.makeMangledName(c, enum_val_name);
420 }
421
422 const enum_const_type_node: ?ZigNode = transType(c, scope, field.ty, field.name_tok) catch |err| switch (err) {
423 error.UnsupportedType => null,
424 else => |e| return e,
425 };
426
427 const val = c.tree.value_map.get(field_node).?;
428 const enum_const_def = try ZigTag.enum_constant.create(c.arena, .{
429 .name = enum_val_name,
430 .is_public = toplevel,
431 .type = enum_const_type_node,
432 .value = try transCreateNodeAPInt(c, val),
433 });
434 if (toplevel)
435 try addTopLevelDecl(c, enum_val_name, enum_const_def)
436 else {
437 try scope.appendNode(enum_const_def);
438 try bs.discardVariable(c, enum_val_name);
439 }
440 }
441
442 break :blk transType(c, scope, ty.data.@"enum".tag_ty, 0) catch |err| switch (err) {
443 error.UnsupportedType => {
444 return failDecl(c, 0, name, "unable to translate enum integer type", .{});
445 },
446 else => |e| return e,
447 };
448 } else blk: {
449 try c.opaque_demotes.put(c.gpa, @intFromPtr(ty.data.@"enum"), {});
450 break :blk ZigTag.opaque_literal.init();
451 };
452
453 const is_pub = toplevel and !is_unnamed;
454 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
455 payload.* = .{
456 .base = .{ .tag = ([2]ZigTag{ .var_simple, .pub_var_simple })[@intFromBool(is_pub)] },
457 .data = .{
458 .init = enum_type_node,
459 .name = name,
460 },
461 };
462 const node = ZigNode.initPayload(&payload.base);
463 if (toplevel) {
464 try addTopLevelDecl(c, name, node);
465 if (!is_unnamed)
466 try c.alias_list.append(.{ .alias = bare_name, .name = name });
467 } else {
468 try scope.appendNode(node);
469 if (node.tag() != .pub_var_simple) {
470 try bs.discardVariable(c, name);
471 }
472 }
473}
474
475fn transType(c: *Context, scope: *Scope, raw_ty: Type, source_loc: TokenIndex) TypeError!ZigNode {
476 const ty = raw_ty.canonicalize(.standard);
477 switch (ty.specifier) {
478 .void => return ZigTag.type.create(c.arena, "anyopaque"),
479 .bool => return ZigTag.type.create(c.arena, "bool"),
480 .char => return ZigTag.type.create(c.arena, "c_char"),
481 .schar => return ZigTag.type.create(c.arena, "i8"),
482 .uchar => return ZigTag.type.create(c.arena, "u8"),
483 .short => return ZigTag.type.create(c.arena, "c_short"),
484 .ushort => return ZigTag.type.create(c.arena, "c_ushort"),
485 .int => return ZigTag.type.create(c.arena, "c_int"),
486 .uint => return ZigTag.type.create(c.arena, "c_uint"),
487 .long => return ZigTag.type.create(c.arena, "c_long"),
488 .ulong => return ZigTag.type.create(c.arena, "c_ulong"),
489 .long_long => return ZigTag.type.create(c.arena, "c_longlong"),
490 .ulong_long => return ZigTag.type.create(c.arena, "c_ulonglong"),
491 .int128 => return ZigTag.type.create(c.arena, "i128"),
492 .uint128 => return ZigTag.type.create(c.arena, "u128"),
493 .fp16, .float16 => return ZigTag.type.create(c.arena, "f16"),
494 .float => return ZigTag.type.create(c.arena, "f32"),
495 .double => return ZigTag.type.create(c.arena, "f64"),
496 .long_double => return ZigTag.type.create(c.arena, "c_longdouble"),
497 .float80 => return ZigTag.type.create(c.arena, "f80"),
498 .float128 => return ZigTag.type.create(c.arena, "f128"),
499 .func,
500 .var_args_func,
501 .old_style_func,
502 => return transFnType(c, scope, raw_ty, ty, source_loc, .{}),
503 else => return error.UnsupportedType,
504 }
505}
506
507fn zigAlignment(bit_alignment: u29) u32 {
508 return bit_alignment / 8;
509}
510
511const FnProtoContext = struct {
512 is_pub: bool = false,
513 is_export: bool = false,
514 is_extern: bool = false,
515 is_inline: bool = false,
516 fn_name: ?[]const u8 = null,
517};
518
519fn transFnType(
520 c: *Context,
521 scope: *Scope,
522 raw_ty: Type,
523 fn_ty: Type,
524 source_loc: TokenIndex,
525 ctx: FnProtoContext,
526) !ZigNode {
527 const param_count: usize = fn_ty.data.func.params.len;
528 const fn_params = try c.arena.alloc(ast.Payload.Param, param_count);
529
530 for (fn_ty.data.func.params, fn_params) |param_info, *param_node| {
531 const param_ty = param_info.ty;
532 const is_noalias = param_ty.qual.restrict;
533
534 const param_name: ?[]const u8 = if (param_info.name == .empty)
535 null
536 else
537 c.mapper.lookup(param_info.name);
538
539 const type_node = try transType(c, scope, param_ty, param_info.name_tok);
540 param_node.* = .{
541 .is_noalias = is_noalias,
542 .name = param_name,
543 .type = type_node,
544 };
545 }
546
547 const linksection_string = blk: {
548 if (raw_ty.getAttribute(.section)) |section| {
549 break :blk c.comp.interner.get(section.name.ref()).bytes;
550 }
551 break :blk null;
552 };
553
554 const alignment = if (raw_ty.requestedAlignment(c.comp)) |alignment| zigAlignment(alignment) else null;
555
556 const explicit_callconv = null;
557 // const explicit_callconv = if ((ctx.is_inline or ctx.is_export or ctx.is_extern) and ctx.cc == .C) null else ctx.cc;
558
559 const return_type_node = blk: {
560 if (raw_ty.getAttribute(.noreturn) != null) {
561 break :blk ZigTag.noreturn_type.init();
562 } else {
563 const return_ty = fn_ty.data.func.return_type;
564 if (return_ty.is(.void)) {
565 // convert primitive anyopaque to actual void (only for return type)
566 break :blk ZigTag.void_type.init();
567 } else {
568 break :blk transType(c, scope, return_ty, source_loc) catch |err| switch (err) {
569 error.UnsupportedType => {
570 try warn(c, scope, source_loc, "unsupported function proto return type", .{});
571 return err;
572 },
573 error.OutOfMemory => |e| return e,
574 };
575 }
576 }
577 };
578
579 const payload = try c.arena.create(ast.Payload.Func);
580 payload.* = .{
581 .base = .{ .tag = .func },
582 .data = .{
583 .is_pub = ctx.is_pub,
584 .is_extern = ctx.is_extern,
585 .is_export = ctx.is_export,
586 .is_inline = ctx.is_inline,
587 .is_var_args = switch (fn_ty.specifier) {
588 .func => false,
589 .var_args_func => true,
590 .old_style_func => !ctx.is_export and !ctx.is_inline,
591 else => unreachable,
592 },
593 .name = ctx.fn_name,
594 .linksection_string = linksection_string,
595 .explicit_callconv = explicit_callconv,
596 .params = fn_params,
597 .return_type = return_type_node,
598 .body = null,
599 .alignment = alignment,
600 },
601 };
602 return ZigNode.initPayload(&payload.base);
603}
604
605fn transStmt(c: *Context, node: NodeIndex) TransError!ZigNode {
606 return transExpr(c, node, .unused);
607}
608
609fn transCompoundStmtInline(c: *Context, compound: NodeIndex, block: *Scope.Block) TransError!void {
610 const data = c.tree.nodes.items(.data)[@intFromEnum(compound)];
611 var buf: [2]NodeIndex = undefined;
612 // TODO move these helpers to Aro
613 const stmts = switch (c.tree.nodes.items(.tag)[@intFromEnum(compound)]) {
614 .compound_stmt_two => blk: {
615 if (data.bin.lhs != .none) buf[0] = data.bin.lhs;
616 if (data.bin.rhs != .none) buf[1] = data.bin.rhs;
617 break :blk buf[0 .. @as(u32, @intFromBool(data.bin.lhs != .none)) + @intFromBool(data.bin.rhs != .none)];
618 },
619 .compound_stmt => c.tree.data[data.range.start..data.range.end],
620 else => unreachable,
621 };
622 for (stmts) |stmt| {
623 const result = try transStmt(c, stmt);
624 switch (result.tag()) {
625 .declaration, .empty_block => {},
626 else => try block.statements.append(result),
627 }
628 }
629}
630
631fn transCompoundStmt(c: *Context, scope: *Scope, compound: NodeIndex) TransError!ZigNode {
632 var block_scope = try Scope.Block.init(c, scope, false);
633 defer block_scope.deinit();
634 try transCompoundStmtInline(c, compound, &block_scope);
635 return try block_scope.complete(c);
636}
637
638fn transExpr(c: *Context, node: NodeIndex, result_used: ResultUsed) TransError!ZigNode {
639 std.debug.assert(node != .none);
640 const ty = c.tree.nodes.items(.ty)[@intFromEnum(node)];
641 if (c.tree.value_map.get(node)) |val| {
642 // TODO handle other values
643 const int = try transCreateNodeAPInt(c, val);
644 const as_node = try ZigTag.as.create(c.arena, .{
645 .lhs = try transType(c, undefined, ty, undefined),
646 .rhs = int,
647 });
648 return maybeSuppressResult(c, result_used, as_node);
649 }
650 const node_tags = c.tree.nodes.items(.tag);
651 switch (node_tags[@intFromEnum(node)]) {
652 else => unreachable, // Not an expression.
653 }
654 return .none;
655}
656
657fn transCreateNodeAPInt(c: *Context, int: aro.Value) !ZigNode {
658 var space: aro.Interner.Tag.Int.BigIntSpace = undefined;
659 var big = int.toBigInt(&space, c.comp);
660 const is_negative = !big.positive;
661 big.positive = true;
662
663 const str = big.toStringAlloc(c.arena, 10, .lower) catch |err| switch (err) {
664 error.OutOfMemory => return error.OutOfMemory,
665 };
666 const res = try ZigTag.integer_literal.create(c.arena, str);
667 if (is_negative) return ZigTag.negate.create(c.arena, res);
668 return res;
669}
670
671pub const PatternList = struct {
672 patterns: []Pattern,
673
674 /// Templates must be function-like macros
675 /// first element is macro source, second element is the name of the function
676 /// in std.lib.zig.c_translation.Macros which implements it
677 const templates = [_][2][]const u8{
678 [2][]const u8{ "f_SUFFIX(X) (X ## f)", "F_SUFFIX" },
679 [2][]const u8{ "F_SUFFIX(X) (X ## F)", "F_SUFFIX" },
680
681 [2][]const u8{ "u_SUFFIX(X) (X ## u)", "U_SUFFIX" },
682 [2][]const u8{ "U_SUFFIX(X) (X ## U)", "U_SUFFIX" },
683
684 [2][]const u8{ "l_SUFFIX(X) (X ## l)", "L_SUFFIX" },
685 [2][]const u8{ "L_SUFFIX(X) (X ## L)", "L_SUFFIX" },
686
687 [2][]const u8{ "ul_SUFFIX(X) (X ## ul)", "UL_SUFFIX" },
688 [2][]const u8{ "uL_SUFFIX(X) (X ## uL)", "UL_SUFFIX" },
689 [2][]const u8{ "Ul_SUFFIX(X) (X ## Ul)", "UL_SUFFIX" },
690 [2][]const u8{ "UL_SUFFIX(X) (X ## UL)", "UL_SUFFIX" },
691
692 [2][]const u8{ "ll_SUFFIX(X) (X ## ll)", "LL_SUFFIX" },
693 [2][]const u8{ "LL_SUFFIX(X) (X ## LL)", "LL_SUFFIX" },
694
695 [2][]const u8{ "ull_SUFFIX(X) (X ## ull)", "ULL_SUFFIX" },
696 [2][]const u8{ "uLL_SUFFIX(X) (X ## uLL)", "ULL_SUFFIX" },
697 [2][]const u8{ "Ull_SUFFIX(X) (X ## Ull)", "ULL_SUFFIX" },
698 [2][]const u8{ "ULL_SUFFIX(X) (X ## ULL)", "ULL_SUFFIX" },
699
700 [2][]const u8{ "f_SUFFIX(X) X ## f", "F_SUFFIX" },
701 [2][]const u8{ "F_SUFFIX(X) X ## F", "F_SUFFIX" },
702
703 [2][]const u8{ "u_SUFFIX(X) X ## u", "U_SUFFIX" },
704 [2][]const u8{ "U_SUFFIX(X) X ## U", "U_SUFFIX" },
705
706 [2][]const u8{ "l_SUFFIX(X) X ## l", "L_SUFFIX" },
707 [2][]const u8{ "L_SUFFIX(X) X ## L", "L_SUFFIX" },
708
709 [2][]const u8{ "ul_SUFFIX(X) X ## ul", "UL_SUFFIX" },
710 [2][]const u8{ "uL_SUFFIX(X) X ## uL", "UL_SUFFIX" },
711 [2][]const u8{ "Ul_SUFFIX(X) X ## Ul", "UL_SUFFIX" },
712 [2][]const u8{ "UL_SUFFIX(X) X ## UL", "UL_SUFFIX" },
713
714 [2][]const u8{ "ll_SUFFIX(X) X ## ll", "LL_SUFFIX" },
715 [2][]const u8{ "LL_SUFFIX(X) X ## LL", "LL_SUFFIX" },
716
717 [2][]const u8{ "ull_SUFFIX(X) X ## ull", "ULL_SUFFIX" },
718 [2][]const u8{ "uLL_SUFFIX(X) X ## uLL", "ULL_SUFFIX" },
719 [2][]const u8{ "Ull_SUFFIX(X) X ## Ull", "ULL_SUFFIX" },
720 [2][]const u8{ "ULL_SUFFIX(X) X ## ULL", "ULL_SUFFIX" },
721
722 [2][]const u8{ "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL" },
723 [2][]const u8{ "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL" },
724
725 [2][]const u8{
726 \\wl_container_of(ptr, sample, member) \
727 \\(__typeof__(sample))((char *)(ptr) - \
728 \\ offsetof(__typeof__(*sample), member))
729 ,
730 "WL_CONTAINER_OF",
731 },
732
733 [2][]const u8{ "IGNORE_ME(X) ((void)(X))", "DISCARD" },
734 [2][]const u8{ "IGNORE_ME(X) (void)(X)", "DISCARD" },
735 [2][]const u8{ "IGNORE_ME(X) ((const void)(X))", "DISCARD" },
736 [2][]const u8{ "IGNORE_ME(X) (const void)(X)", "DISCARD" },
737 [2][]const u8{ "IGNORE_ME(X) ((volatile void)(X))", "DISCARD" },
738 [2][]const u8{ "IGNORE_ME(X) (volatile void)(X)", "DISCARD" },
739 [2][]const u8{ "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD" },
740 [2][]const u8{ "IGNORE_ME(X) (const volatile void)(X)", "DISCARD" },
741 [2][]const u8{ "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD" },
742 [2][]const u8{ "IGNORE_ME(X) (volatile const void)(X)", "DISCARD" },
743 };
744
745 /// Assumes that `ms` represents a tokenized function-like macro.
746 fn buildArgsHash(allocator: mem.Allocator, ms: MacroSlicer, hash: *ArgsPositionMap) MacroProcessingError!void {
747 assert(ms.tokens.len > 2);
748 assert(ms.tokens[0].id == .identifier or ms.tokens[0].id == .extended_identifier);
749 assert(ms.tokens[1].id == .l_paren);
750
751 var i: usize = 2;
752 while (true) : (i += 1) {
753 const token = ms.tokens[i];
754 switch (token.id) {
755 .r_paren => break,
756 .comma => continue,
757 .identifier, .extended_identifier => {
758 const identifier = ms.slice(token);
759 try hash.put(allocator, identifier, i);
760 },
761 else => return error.UnexpectedMacroToken,
762 }
763 }
764 }
765
766 const Pattern = struct {
767 tokens: []const CToken,
768 source: []const u8,
769 impl: []const u8,
770 args_hash: ArgsPositionMap,
771
772 fn init(self: *Pattern, allocator: mem.Allocator, template: [2][]const u8) Error!void {
773 const source = template[0];
774 const impl = template[1];
775
776 var tok_list = std.ArrayList(CToken).init(allocator);
777 defer tok_list.deinit();
778 try tokenizeMacro(source, &tok_list);
779 const tokens = try allocator.dupe(CToken, tok_list.items);
780
781 self.* = .{
782 .tokens = tokens,
783 .source = source,
784 .impl = impl,
785 .args_hash = .{},
786 };
787 const ms = MacroSlicer{ .source = source, .tokens = tokens };
788 buildArgsHash(allocator, ms, &self.args_hash) catch |err| switch (err) {
789 error.UnexpectedMacroToken => unreachable,
790 else => |e| return e,
791 };
792 }
793
794 fn deinit(self: *Pattern, allocator: mem.Allocator) void {
795 self.args_hash.deinit(allocator);
796 allocator.free(self.tokens);
797 }
798
799 /// This function assumes that `ms` has already been validated to contain a function-like
800 /// macro, and that the parsed template macro in `self` also contains a function-like
801 /// macro. Please review this logic carefully if changing that assumption. Two
802 /// function-like macros are considered equivalent if and only if they contain the same
803 /// list of tokens, modulo parameter names.
804 pub fn isEquivalent(self: Pattern, ms: MacroSlicer, args_hash: ArgsPositionMap) bool {
805 if (self.tokens.len != ms.tokens.len) return false;
806 if (args_hash.count() != self.args_hash.count()) return false;
807
808 var i: usize = 2;
809 while (self.tokens[i].id != .r_paren) : (i += 1) {}
810
811 const pattern_slicer = MacroSlicer{ .source = self.source, .tokens = self.tokens };
812 while (i < self.tokens.len) : (i += 1) {
813 const pattern_token = self.tokens[i];
814 const macro_token = ms.tokens[i];
815 if (pattern_token.id != macro_token.id) return false;
816
817 const pattern_bytes = pattern_slicer.slice(pattern_token);
818 const macro_bytes = ms.slice(macro_token);
819 switch (pattern_token.id) {
820 .identifier, .extended_identifier => {
821 const pattern_arg_index = self.args_hash.get(pattern_bytes);
822 const macro_arg_index = args_hash.get(macro_bytes);
823
824 if (pattern_arg_index == null and macro_arg_index == null) {
825 if (!mem.eql(u8, pattern_bytes, macro_bytes)) return false;
826 } else if (pattern_arg_index != null and macro_arg_index != null) {
827 if (pattern_arg_index.? != macro_arg_index.?) return false;
828 } else {
829 return false;
830 }
831 },
832 .string_literal, .char_literal, .pp_num => {
833 if (!mem.eql(u8, pattern_bytes, macro_bytes)) return false;
834 },
835 else => {
836 // other tags correspond to keywords and operators that do not contain a "payload"
837 // that can vary
838 },
839 }
840 }
841 return true;
842 }
843 };
844
845 pub fn init(allocator: mem.Allocator) Error!PatternList {
846 const patterns = try allocator.alloc(Pattern, templates.len);
847 for (templates, 0..) |template, i| {
848 try patterns[i].init(allocator, template);
849 }
850 return PatternList{ .patterns = patterns };
851 }
852
853 pub fn deinit(self: *PatternList, allocator: mem.Allocator) void {
854 for (self.patterns) |*pattern| pattern.deinit(allocator);
855 allocator.free(self.patterns);
856 }
857
858 pub fn match(self: PatternList, allocator: mem.Allocator, ms: MacroSlicer) Error!?Pattern {
859 var args_hash: ArgsPositionMap = .{};
860 defer args_hash.deinit(allocator);
861
862 buildArgsHash(allocator, ms, &args_hash) catch |err| switch (err) {
863 error.UnexpectedMacroToken => return null,
864 else => |e| return e,
865 };
866
867 for (self.patterns) |pattern| if (pattern.isEquivalent(ms, args_hash)) return pattern;
868 return null;
869 }
870};
871
872pub const MacroSlicer = struct {
873 source: []const u8,
874 tokens: []const CToken,
875
876 pub fn slice(self: MacroSlicer, token: CToken) []const u8 {
877 return self.source[token.start..token.end];
878 }
879};
880
881// Maps macro parameter names to token position, for determining if different
882// identifiers refer to the same positional argument in different macros.
883pub const ArgsPositionMap = std.StringArrayHashMapUnmanaged(usize);
884
885pub const Error = std.mem.Allocator.Error;
886pub const MacroProcessingError = Error || error{UnexpectedMacroToken};
887pub const TypeError = Error || error{UnsupportedType};
888pub const TransError = TypeError || error{UnsupportedTranslation};
889
890pub const SymbolTable = std.StringArrayHashMap(ast.Node);
891pub const AliasList = std.ArrayList(struct {
892 alias: []const u8,
893 name: []const u8,
894});
895
896pub const ResultUsed = enum {
897 used,
898 unused,
899};
900
901pub fn ScopeExtra(comptime ScopeExtraContext: type, comptime ScopeExtraType: type) type {
902 return struct {
903 id: Id,
904 parent: ?*ScopeExtraScope,
905
906 const ScopeExtraScope = @This();
907
908 pub const Id = enum {
909 block,
910 root,
911 condition,
912 loop,
913 do_loop,
914 };
915
916 /// Used for the scope of condition expressions, for example `if (cond)`.
917 /// The block is lazily initialised because it is only needed for rare
918 /// cases of comma operators being used.
919 pub const Condition = struct {
920 base: ScopeExtraScope,
921 block: ?Block = null,
922
923 pub fn getBlockScope(self: *Condition, c: *ScopeExtraContext) !*Block {
924 if (self.block) |*b| return b;
925 self.block = try Block.init(c, &self.base, true);
926 return &self.block.?;
927 }
928
929 pub fn deinit(self: *Condition) void {
930 if (self.block) |*b| b.deinit();
931 }
932 };
933
934 /// Represents an in-progress Node.Block. This struct is stack-allocated.
935 /// When it is deinitialized, it produces an Node.Block which is allocated
936 /// into the main arena.
937 pub const Block = struct {
938 base: ScopeExtraScope,
939 statements: std.ArrayList(ast.Node),
940 variables: AliasList,
941 mangle_count: u32 = 0,
942 label: ?[]const u8 = null,
943
944 /// By default all variables are discarded, since we do not know in advance if they
945 /// will be used. This maps the variable's name to the Discard payload, so that if
946 /// the variable is subsequently referenced we can indicate that the discard should
947 /// be skipped during the intermediate AST -> Zig AST render step.
948 variable_discards: std.StringArrayHashMap(*ast.Payload.Discard),
949
950 /// When the block corresponds to a function, keep track of the return type
951 /// so that the return expression can be cast, if necessary
952 return_type: ?ScopeExtraType = null,
953
954 /// C static local variables are wrapped in a block-local struct. The struct
955 /// is named after the (mangled) variable name, the Zig variable within the
956 /// struct itself is given this name.
957 pub const static_inner_name = "static";
958
959 pub fn init(c: *ScopeExtraContext, parent: *ScopeExtraScope, labeled: bool) !Block {
960 var blk = Block{
961 .base = .{
962 .id = .block,
963 .parent = parent,
964 },
965 .statements = std.ArrayList(ast.Node).init(c.gpa),
966 .variables = AliasList.init(c.gpa),
967 .variable_discards = std.StringArrayHashMap(*ast.Payload.Discard).init(c.gpa),
968 };
969 if (labeled) {
970 blk.label = try blk.makeMangledName(c, "blk");
971 }
972 return blk;
973 }
974
975 pub fn deinit(self: *Block) void {
976 self.statements.deinit();
977 self.variables.deinit();
978 self.variable_discards.deinit();
979 self.* = undefined;
980 }
981
982 pub fn complete(self: *Block, c: *ScopeExtraContext) !ast.Node {
983 if (self.base.parent.?.id == .do_loop) {
984 // We reserve 1 extra statement if the parent is a do_loop. This is in case of
985 // do while, we want to put `if (cond) break;` at the end.
986 const alloc_len = self.statements.items.len + @intFromBool(self.base.parent.?.id == .do_loop);
987 var stmts = try c.arena.alloc(ast.Node, alloc_len);
988 stmts.len = self.statements.items.len;
989 @memcpy(stmts[0..self.statements.items.len], self.statements.items);
990 return ast.Node.Tag.block.create(c.arena, .{
991 .label = self.label,
992 .stmts = stmts,
993 });
994 }
995 if (self.statements.items.len == 0) return ast.Node.Tag.empty_block.init();
996 return ast.Node.Tag.block.create(c.arena, .{
997 .label = self.label,
998 .stmts = try c.arena.dupe(ast.Node, self.statements.items),
999 });
1000 }
1001
1002 /// Given the desired name, return a name that does not shadow anything from outer scopes.
1003 /// Inserts the returned name into the scope.
1004 /// The name will not be visible to callers of getAlias.
1005 pub fn reserveMangledName(scope: *Block, c: *ScopeExtraContext, name: []const u8) ![]const u8 {
1006 return scope.createMangledName(c, name, true);
1007 }
1008
1009 /// Same as reserveMangledName, but enables the alias immediately.
1010 pub fn makeMangledName(scope: *Block, c: *ScopeExtraContext, name: []const u8) ![]const u8 {
1011 return scope.createMangledName(c, name, false);
1012 }
1013
1014 pub fn createMangledName(scope: *Block, c: *ScopeExtraContext, name: []const u8, reservation: bool) ![]const u8 {
1015 const name_copy = try c.arena.dupe(u8, name);
1016 var proposed_name = name_copy;
1017 while (scope.contains(proposed_name)) {
1018 scope.mangle_count += 1;
1019 proposed_name = try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ name, scope.mangle_count });
1020 }
1021 const new_mangle = try scope.variables.addOne();
1022 if (reservation) {
1023 new_mangle.* = .{ .name = name_copy, .alias = name_copy };
1024 } else {
1025 new_mangle.* = .{ .name = name_copy, .alias = proposed_name };
1026 }
1027 return proposed_name;
1028 }
1029
1030 pub fn getAlias(scope: *Block, name: []const u8) []const u8 {
1031 for (scope.variables.items) |p| {
1032 if (std.mem.eql(u8, p.name, name))
1033 return p.alias;
1034 }
1035 return scope.base.parent.?.getAlias(name);
1036 }
1037
1038 pub fn localContains(scope: *Block, name: []const u8) bool {
1039 for (scope.variables.items) |p| {
1040 if (std.mem.eql(u8, p.alias, name))
1041 return true;
1042 }
1043 return false;
1044 }
1045
1046 pub fn contains(scope: *Block, name: []const u8) bool {
1047 if (scope.localContains(name))
1048 return true;
1049 return scope.base.parent.?.contains(name);
1050 }
1051
1052 pub fn discardVariable(scope: *Block, c: *ScopeExtraContext, name: []const u8) Error!void {
1053 const name_node = try ast.Node.Tag.identifier.create(c.arena, name);
1054 const discard = try ast.Node.Tag.discard.create(c.arena, .{ .should_skip = false, .value = name_node });
1055 try scope.statements.append(discard);
1056 try scope.variable_discards.putNoClobber(name, discard.castTag(.discard).?);
1057 }
1058 };
1059
1060 pub const Root = struct {
1061 base: ScopeExtraScope,
1062 sym_table: SymbolTable,
1063 macro_table: SymbolTable,
1064 blank_macros: std.StringArrayHashMap(void),
1065 context: *ScopeExtraContext,
1066 nodes: std.ArrayList(ast.Node),
1067
1068 pub fn init(c: *ScopeExtraContext) Root {
1069 return .{
1070 .base = .{
1071 .id = .root,
1072 .parent = null,
1073 },
1074 .sym_table = SymbolTable.init(c.gpa),
1075 .macro_table = SymbolTable.init(c.gpa),
1076 .blank_macros = std.StringArrayHashMap(void).init(c.gpa),
1077 .context = c,
1078 .nodes = std.ArrayList(ast.Node).init(c.gpa),
1079 };
1080 }
1081
1082 pub fn deinit(scope: *Root) void {
1083 scope.sym_table.deinit();
1084 scope.macro_table.deinit();
1085 scope.blank_macros.deinit();
1086 scope.nodes.deinit();
1087 }
1088
1089 /// Check if the global scope contains this name, without looking into the "future", e.g.
1090 /// ignore the preprocessed decl and macro names.
1091 pub fn containsNow(scope: *Root, name: []const u8) bool {
1092 return scope.sym_table.contains(name) or scope.macro_table.contains(name);
1093 }
1094
1095 /// Check if the global scope contains the name, includes all decls that haven't been translated yet.
1096 pub fn contains(scope: *Root, name: []const u8) bool {
1097 return scope.containsNow(name) or scope.context.global_names.contains(name) or scope.context.weak_global_names.contains(name);
1098 }
1099 };
1100
1101 pub fn findBlockScope(inner: *ScopeExtraScope, c: *ScopeExtraContext) !*ScopeExtraScope.Block {
1102 var scope = inner;
1103 while (true) {
1104 switch (scope.id) {
1105 .root => unreachable,
1106 .block => return @fieldParentPtr(Block, "base", scope),
1107 .condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c),
1108 else => scope = scope.parent.?,
1109 }
1110 }
1111 }
1112
1113 pub fn findBlockReturnType(inner: *ScopeExtraScope) ScopeExtraType {
1114 var scope = inner;
1115 while (true) {
1116 switch (scope.id) {
1117 .root => unreachable,
1118 .block => {
1119 const block = @fieldParentPtr(Block, "base", scope);
1120 if (block.return_type) |ty| return ty;
1121 scope = scope.parent.?;
1122 },
1123 else => scope = scope.parent.?,
1124 }
1125 }
1126 }
1127
1128 pub fn getAlias(scope: *ScopeExtraScope, name: []const u8) []const u8 {
1129 return switch (scope.id) {
1130 .root => return name,
1131 .block => @fieldParentPtr(Block, "base", scope).getAlias(name),
1132 .loop, .do_loop, .condition => scope.parent.?.getAlias(name),
1133 };
1134 }
1135
1136 pub fn contains(scope: *ScopeExtraScope, name: []const u8) bool {
1137 return switch (scope.id) {
1138 .root => @fieldParentPtr(Root, "base", scope).contains(name),
1139 .block => @fieldParentPtr(Block, "base", scope).contains(name),
1140 .loop, .do_loop, .condition => scope.parent.?.contains(name),
1141 };
1142 }
1143
1144 pub fn getBreakableScope(inner: *ScopeExtraScope) *ScopeExtraScope {
1145 var scope = inner;
1146 while (true) {
1147 switch (scope.id) {
1148 .root => unreachable,
1149 .loop, .do_loop => return scope,
1150 else => scope = scope.parent.?,
1151 }
1152 }
1153 }
1154
1155 /// Appends a node to the first block scope if inside a function, or to the root tree if not.
1156 pub fn appendNode(inner: *ScopeExtraScope, node: ast.Node) !void {
1157 var scope = inner;
1158 while (true) {
1159 switch (scope.id) {
1160 .root => {
1161 const root = @fieldParentPtr(Root, "base", scope);
1162 return root.nodes.append(node);
1163 },
1164 .block => {
1165 const block = @fieldParentPtr(Block, "base", scope);
1166 return block.statements.append(node);
1167 },
1168 else => scope = scope.parent.?,
1169 }
1170 }
1171 }
1172
1173 pub fn skipVariableDiscard(inner: *ScopeExtraScope, name: []const u8) void {
1174 if (true) {
1175 // TODO: due to 'local variable is never mutated' errors, we can
1176 // only skip discards if a variable is used as an lvalue, which
1177 // we don't currently have detection for in translate-c.
1178 // Once #17584 is completed, perhaps we can do away with this
1179 // logic entirely, and instead rely on render to fixup code.
1180 return;
1181 }
1182 var scope = inner;
1183 while (true) {
1184 switch (scope.id) {
1185 .root => return,
1186 .block => {
1187 const block = @fieldParentPtr(Block, "base", scope);
1188 if (block.variable_discards.get(name)) |discard| {
1189 discard.data.should_skip = true;
1190 return;
1191 }
1192 },
1193 else => {},
1194 }
1195 scope = scope.parent.?;
1196 }
1197 }
1198 };
1199}
1200
1201pub fn tokenizeMacro(source: []const u8, tok_list: *std.ArrayList(CToken)) Error!void {
1202 var tokenizer: aro.Tokenizer = .{
1203 .buf = source,
1204 .source = .unused,
1205 .langopts = .{},
1206 };
1207 while (true) {
1208 const tok = tokenizer.next();
1209 switch (tok.id) {
1210 .whitespace => continue,
1211 .nl, .eof => {
1212 try tok_list.append(tok);
1213 break;
1214 },
1215 else => {},
1216 }
1217 try tok_list.append(tok);
1218 }
1219}
1220
1221// Testing here instead of test/translate_c.zig allows us to also test that the
1222// mapped function exists in `std.zig.c_translation.Macros`
1223test "Macro matching" {
1224 const testing = std.testing;
1225 const helper = struct {
1226 const MacroFunctions = std.zig.c_translation.Macros;
1227 fn checkMacro(allocator: mem.Allocator, pattern_list: PatternList, source: []const u8, comptime expected_match: ?[]const u8) !void {
1228 var tok_list = std.ArrayList(CToken).init(allocator);
1229 defer tok_list.deinit();
1230 try tokenizeMacro(source, &tok_list);
1231 const macro_slicer: MacroSlicer = .{ .source = source, .tokens = tok_list.items };
1232 const matched = try pattern_list.match(allocator, macro_slicer);
1233 if (expected_match) |expected| {
1234 try testing.expectEqualStrings(expected, matched.?.impl);
1235 try testing.expect(@hasDecl(MacroFunctions, expected));
1236 } else {
1237 try testing.expectEqual(@as(@TypeOf(matched), null), matched);
1238 }
1239 }
1240 };
1241 const allocator = std.testing.allocator;
1242 var pattern_list = try PatternList.init(allocator);
1243 defer pattern_list.deinit(allocator);
1244
1245 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## F)", "F_SUFFIX");
1246 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## U)", "U_SUFFIX");
1247 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## L)", "L_SUFFIX");
1248 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## LL)", "LL_SUFFIX");
1249 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## UL)", "UL_SUFFIX");
1250 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## ULL)", "ULL_SUFFIX");
1251 try helper.checkMacro(allocator, pattern_list,
1252 \\container_of(a, b, c) \
1253 \\(__typeof__(b))((char *)(a) - \
1254 \\ offsetof(__typeof__(*b), c))
1255 , "WL_CONTAINER_OF");
1256
1257 try helper.checkMacro(allocator, pattern_list, "NO_MATCH(X, Y) (X + Y)", null);
1258 try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL");
1259 try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL");
1260 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (void)(X)", "DISCARD");
1261 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((void)(X))", "DISCARD");
1262 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const void)(X)", "DISCARD");
1263 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const void)(X))", "DISCARD");
1264 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile void)(X)", "DISCARD");
1265 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile void)(X))", "DISCARD");
1266 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const volatile void)(X)", "DISCARD");
1267 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD");
1268 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile const void)(X)", "DISCARD");
1269 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD");
1270}
1271
1272pub fn main() !void {
1273 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
1274 defer arena_instance.deinit();
1275 const arena = arena_instance.allocator();
1276
1277 var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .{};
1278 const gpa = general_purpose_allocator.allocator();
1279
1280 const args = try std.process.argsAlloc(arena);
1281
1282 var aro_comp = aro.Compilation.init(gpa);
1283 defer aro_comp.deinit();
1284
1285 var tree = translate(gpa, &aro_comp, args) catch |err| switch (err) {
1286 error.SemanticAnalyzeFail, error.FatalError => {
1287 aro.Diagnostics.render(&aro_comp, std.io.tty.detectConfig(std.io.getStdErr()));
1288 std.process.exit(1);
1289 },
1290 error.OutOfMemory => return error.OutOfMemory,
1291 error.StreamTooLong => std.zig.fatal("StreamTooLong?", .{}),
1292 };
1293 defer tree.deinit(gpa);
1294
1295 const formatted = try tree.render(arena);
1296 try std.io.getStdOut().writeAll(formatted);
1297 return std.process.cleanExit();
1298}
lib/compiler/aro_translate_c/ast.zig created+2941
......@@ -0,0 +1,2941 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3
4pub const Node = extern union {
5 /// If the tag value is less than Tag.no_payload_count, then no pointer
6 /// dereference is needed.
7 tag_if_small_enough: usize,
8 ptr_otherwise: *Payload,
9
10 pub const Tag = enum {
11 /// Declarations add themselves to the correct scopes and should not be emitted as this tag.
12 declaration,
13 null_literal,
14 undefined_literal,
15 /// opaque {}
16 opaque_literal,
17 true_literal,
18 false_literal,
19 empty_block,
20 return_void,
21 zero_literal,
22 one_literal,
23 void_type,
24 noreturn_type,
25 @"anytype",
26 @"continue",
27 @"break",
28 // After this, the tag requires a payload.
29
30 integer_literal,
31 float_literal,
32 string_literal,
33 char_literal,
34 enum_literal,
35 /// "string"[0..end]
36 string_slice,
37 identifier,
38 fn_identifier,
39 @"if",
40 /// if (!operand) break;
41 if_not_break,
42 @"while",
43 /// while (true) operand
44 while_true,
45 @"switch",
46 /// else => operand,
47 switch_else,
48 /// items => body,
49 switch_prong,
50 break_val,
51 @"return",
52 field_access,
53 array_access,
54 call,
55 var_decl,
56 /// const name = struct { init }
57 static_local_var,
58 /// var name = init.*
59 mut_str,
60 func,
61 warning,
62 @"struct",
63 @"union",
64 @"comptime",
65 @"defer",
66 array_init,
67 tuple,
68 container_init,
69 container_init_dot,
70 helpers_cast,
71 /// _ = operand;
72 discard,
73
74 // a + b
75 add,
76 // a = b
77 add_assign,
78 // c = (a = b)
79 add_wrap,
80 add_wrap_assign,
81 sub,
82 sub_assign,
83 sub_wrap,
84 sub_wrap_assign,
85 mul,
86 mul_assign,
87 mul_wrap,
88 mul_wrap_assign,
89 div,
90 div_assign,
91 shl,
92 shl_assign,
93 shr,
94 shr_assign,
95 mod,
96 mod_assign,
97 @"and",
98 @"or",
99 less_than,
100 less_than_equal,
101 greater_than,
102 greater_than_equal,
103 equal,
104 not_equal,
105 bit_and,
106 bit_and_assign,
107 bit_or,
108 bit_or_assign,
109 bit_xor,
110 bit_xor_assign,
111 array_cat,
112 ellipsis3,
113 assign,
114
115 /// @import("std").zig.c_builtins.<name>
116 import_c_builtin,
117 /// @intCast(operand)
118 int_cast,
119 /// @constCast(operand)
120 const_cast,
121 /// @volatileCast(operand)
122 volatile_cast,
123 /// @import("std").zig.c_translation.promoteIntLiteral(value, type, base)
124 helpers_promoteIntLiteral,
125 /// @import("std").zig.c_translation.signedRemainder(lhs, rhs)
126 signed_remainder,
127 /// @divTrunc(lhs, rhs)
128 div_trunc,
129 /// @intFromBool(operand)
130 int_from_bool,
131 /// @as(lhs, rhs)
132 as,
133 /// @truncate(operand)
134 truncate,
135 /// @bitCast(operand)
136 bit_cast,
137 /// @floatCast(operand)
138 float_cast,
139 /// @intFromFloat(operand)
140 int_from_float,
141 /// @floatFromInt(operand)
142 float_from_int,
143 /// @ptrFromInt(operand)
144 ptr_from_int,
145 /// @intFromPtr(operand)
146 int_from_ptr,
147 /// @alignCast(operand)
148 align_cast,
149 /// @ptrCast(operand)
150 ptr_cast,
151 /// @divExact(lhs, rhs)
152 div_exact,
153 /// @offsetOf(lhs, rhs)
154 offset_of,
155 /// @splat(operand)
156 vector_zero_init,
157 /// @shuffle(type, a, b, mask)
158 shuffle,
159 /// @extern(ty, .{ .name = n })
160 builtin_extern,
161
162 /// @import("std").zig.c_translation.MacroArithmetic.<op>(lhs, rhs)
163 macro_arithmetic,
164
165 asm_simple,
166
167 negate,
168 negate_wrap,
169 bit_not,
170 not,
171 address_of,
172 /// .?
173 unwrap,
174 /// .*
175 deref,
176
177 block,
178 /// { operand }
179 block_single,
180
181 sizeof,
182 alignof,
183 typeof,
184 typeinfo,
185 type,
186
187 optional_type,
188 c_pointer,
189 single_pointer,
190 array_type,
191 null_sentinel_array_type,
192
193 /// @import("std").zig.c_translation.sizeof(operand)
194 helpers_sizeof,
195 /// @import("std").zig.c_translation.FlexibleArrayType(lhs, rhs)
196 helpers_flexible_array_type,
197 /// @import("std").zig.c_translation.shuffleVectorIndex(lhs, rhs)
198 helpers_shuffle_vector_index,
199 /// @import("std").zig.c_translation.Macro.<operand>
200 helpers_macro,
201 /// @Vector(lhs, rhs)
202 vector,
203 /// @import("std").mem.zeroes(operand)
204 std_mem_zeroes,
205 /// @import("std").mem.zeroInit(lhs, rhs)
206 std_mem_zeroinit,
207 // pub const name = @compileError(msg);
208 fail_decl,
209 // var actual = mangled;
210 arg_redecl,
211 /// pub const alias = actual;
212 alias,
213 /// const name = init;
214 var_simple,
215 /// pub const name = init;
216 pub_var_simple,
217 /// pub? const name (: type)? = value
218 enum_constant,
219
220 /// pub inline fn name(params) return_type body
221 pub_inline_fn,
222
223 /// [0]type{}
224 empty_array,
225 /// [1]type{val} ** count
226 array_filler,
227
228 pub const last_no_payload_tag = Tag.@"break";
229 pub const no_payload_count = @intFromEnum(last_no_payload_tag) + 1;
230
231 pub fn Type(comptime t: Tag) type {
232 return switch (t) {
233 .declaration,
234 .null_literal,
235 .undefined_literal,
236 .opaque_literal,
237 .true_literal,
238 .false_literal,
239 .empty_block,
240 .return_void,
241 .zero_literal,
242 .one_literal,
243 .void_type,
244 .noreturn_type,
245 .@"anytype",
246 .@"continue",
247 .@"break",
248 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
249
250 .std_mem_zeroes,
251 .@"return",
252 .@"comptime",
253 .@"defer",
254 .asm_simple,
255 .negate,
256 .negate_wrap,
257 .bit_not,
258 .not,
259 .optional_type,
260 .address_of,
261 .unwrap,
262 .deref,
263 .int_from_ptr,
264 .empty_array,
265 .while_true,
266 .if_not_break,
267 .switch_else,
268 .block_single,
269 .helpers_sizeof,
270 .int_from_bool,
271 .sizeof,
272 .alignof,
273 .typeof,
274 .typeinfo,
275 .align_cast,
276 .truncate,
277 .bit_cast,
278 .float_cast,
279 .int_from_float,
280 .float_from_int,
281 .ptr_from_int,
282 .ptr_cast,
283 .int_cast,
284 .const_cast,
285 .volatile_cast,
286 .vector_zero_init,
287 => Payload.UnOp,
288
289 .add,
290 .add_assign,
291 .add_wrap,
292 .add_wrap_assign,
293 .sub,
294 .sub_assign,
295 .sub_wrap,
296 .sub_wrap_assign,
297 .mul,
298 .mul_assign,
299 .mul_wrap,
300 .mul_wrap_assign,
301 .div,
302 .div_assign,
303 .shl,
304 .shl_assign,
305 .shr,
306 .shr_assign,
307 .mod,
308 .mod_assign,
309 .@"and",
310 .@"or",
311 .less_than,
312 .less_than_equal,
313 .greater_than,
314 .greater_than_equal,
315 .equal,
316 .not_equal,
317 .bit_and,
318 .bit_and_assign,
319 .bit_or,
320 .bit_or_assign,
321 .bit_xor,
322 .bit_xor_assign,
323 .div_trunc,
324 .signed_remainder,
325 .as,
326 .array_cat,
327 .ellipsis3,
328 .assign,
329 .array_access,
330 .std_mem_zeroinit,
331 .helpers_flexible_array_type,
332 .helpers_shuffle_vector_index,
333 .vector,
334 .div_exact,
335 .offset_of,
336 .helpers_cast,
337 => Payload.BinOp,
338
339 .integer_literal,
340 .float_literal,
341 .string_literal,
342 .char_literal,
343 .enum_literal,
344 .identifier,
345 .fn_identifier,
346 .warning,
347 .type,
348 .helpers_macro,
349 .import_c_builtin,
350 => Payload.Value,
351 .discard => Payload.Discard,
352 .@"if" => Payload.If,
353 .@"while" => Payload.While,
354 .@"switch", .array_init, .switch_prong => Payload.Switch,
355 .break_val => Payload.BreakVal,
356 .call => Payload.Call,
357 .var_decl => Payload.VarDecl,
358 .func => Payload.Func,
359 .@"struct", .@"union" => Payload.Record,
360 .tuple => Payload.TupleInit,
361 .container_init => Payload.ContainerInit,
362 .container_init_dot => Payload.ContainerInitDot,
363 .helpers_promoteIntLiteral => Payload.PromoteIntLiteral,
364 .block => Payload.Block,
365 .c_pointer, .single_pointer => Payload.Pointer,
366 .array_type, .null_sentinel_array_type => Payload.Array,
367 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
368 .var_simple, .pub_var_simple, .static_local_var, .mut_str => Payload.SimpleVarDecl,
369 .enum_constant => Payload.EnumConstant,
370 .array_filler => Payload.ArrayFiller,
371 .pub_inline_fn => Payload.PubInlineFn,
372 .field_access => Payload.FieldAccess,
373 .string_slice => Payload.StringSlice,
374 .shuffle => Payload.Shuffle,
375 .builtin_extern => Payload.Extern,
376 .macro_arithmetic => Payload.MacroArithmetic,
377 };
378 }
379
380 pub fn init(comptime t: Tag) Node {
381 comptime std.debug.assert(@intFromEnum(t) < Tag.no_payload_count);
382 return .{ .tag_if_small_enough = @intFromEnum(t) };
383 }
384
385 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Node {
386 const ptr = try ally.create(t.Type());
387 ptr.* = .{
388 .base = .{ .tag = t },
389 .data = data,
390 };
391 return Node{ .ptr_otherwise = &ptr.base };
392 }
393
394 pub fn Data(comptime t: Tag) type {
395 return std.meta.fieldInfo(t.Type(), .data).type;
396 }
397 };
398
399 pub fn tag(self: Node) Tag {
400 if (self.tag_if_small_enough < Tag.no_payload_count) {
401 return @as(Tag, @enumFromInt(@as(std.meta.Tag(Tag), @intCast(self.tag_if_small_enough))));
402 } else {
403 return self.ptr_otherwise.tag;
404 }
405 }
406
407 pub fn castTag(self: Node, comptime t: Tag) ?*t.Type() {
408 if (self.tag_if_small_enough < Tag.no_payload_count)
409 return null;
410
411 if (self.ptr_otherwise.tag == t)
412 return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);
413
414 return null;
415 }
416
417 pub fn initPayload(payload: *Payload) Node {
418 std.debug.assert(@intFromEnum(payload.tag) >= Tag.no_payload_count);
419 return .{ .ptr_otherwise = payload };
420 }
421
422 pub fn isNoreturn(node: Node, break_counts: bool) bool {
423 switch (node.tag()) {
424 .block => {
425 const block_node = node.castTag(.block).?;
426 if (block_node.data.stmts.len == 0) return false;
427
428 const last = block_node.data.stmts[block_node.data.stmts.len - 1];
429 return last.isNoreturn(break_counts);
430 },
431 .@"switch" => {
432 const switch_node = node.castTag(.@"switch").?;
433
434 for (switch_node.data.cases) |case| {
435 const body = if (case.castTag(.switch_else)) |some|
436 some.data
437 else if (case.castTag(.switch_prong)) |some|
438 some.data.cond
439 else
440 unreachable;
441
442 if (!body.isNoreturn(break_counts)) return false;
443 }
444 return true;
445 },
446 .@"return", .return_void => return true,
447 .@"break" => if (break_counts) return true,
448 else => {},
449 }
450 return false;
451 }
452};
453
454pub const Payload = struct {
455 tag: Node.Tag,
456
457 pub const Value = struct {
458 base: Payload,
459 data: []const u8,
460 };
461
462 pub const UnOp = struct {
463 base: Payload,
464 data: Node,
465 };
466
467 pub const BinOp = struct {
468 base: Payload,
469 data: struct {
470 lhs: Node,
471 rhs: Node,
472 },
473 };
474
475 pub const Discard = struct {
476 base: Payload,
477 data: struct {
478 should_skip: bool,
479 value: Node,
480 },
481 };
482
483 pub const If = struct {
484 base: Payload,
485 data: struct {
486 cond: Node,
487 then: Node,
488 @"else": ?Node,
489 },
490 };
491
492 pub const While = struct {
493 base: Payload,
494 data: struct {
495 cond: Node,
496 body: Node,
497 cont_expr: ?Node,
498 },
499 };
500
501 pub const Switch = struct {
502 base: Payload,
503 data: struct {
504 cond: Node,
505 cases: []Node,
506 },
507 };
508
509 pub const BreakVal = struct {
510 base: Payload,
511 data: struct {
512 label: ?[]const u8,
513 val: Node,
514 },
515 };
516
517 pub const Call = struct {
518 base: Payload,
519 data: struct {
520 lhs: Node,
521 args: []Node,
522 },
523 };
524
525 pub const VarDecl = struct {
526 base: Payload,
527 data: struct {
528 is_pub: bool,
529 is_const: bool,
530 is_extern: bool,
531 is_export: bool,
532 is_threadlocal: bool,
533 alignment: ?c_uint,
534 linksection_string: ?[]const u8,
535 name: []const u8,
536 type: Node,
537 init: ?Node,
538 },
539 };
540
541 pub const Func = struct {
542 base: Payload,
543 data: struct {
544 is_pub: bool,
545 is_extern: bool,
546 is_export: bool,
547 is_inline: bool,
548 is_var_args: bool,
549 name: ?[]const u8,
550 linksection_string: ?[]const u8,
551 explicit_callconv: ?std.builtin.CallingConvention,
552 params: []Param,
553 return_type: Node,
554 body: ?Node,
555 alignment: ?c_uint,
556 },
557 };
558
559 pub const Param = struct {
560 is_noalias: bool,
561 name: ?[]const u8,
562 type: Node,
563 };
564
565 pub const Record = struct {
566 base: Payload,
567 data: struct {
568 layout: enum { @"packed", @"extern", none },
569 fields: []Field,
570 functions: []Node,
571 variables: []Node,
572 },
573
574 pub const Field = struct {
575 name: []const u8,
576 type: Node,
577 alignment: ?c_uint,
578 default_value: ?Node,
579 };
580 };
581
582 pub const TupleInit = struct {
583 base: Payload,
584 data: []Node,
585 };
586
587 pub const ContainerInit = struct {
588 base: Payload,
589 data: struct {
590 lhs: Node,
591 inits: []Initializer,
592 },
593
594 pub const Initializer = struct {
595 name: []const u8,
596 value: Node,
597 };
598 };
599
600 pub const ContainerInitDot = struct {
601 base: Payload,
602 data: []Initializer,
603
604 pub const Initializer = struct {
605 name: []const u8,
606 value: Node,
607 };
608 };
609
610 pub const Block = struct {
611 base: Payload,
612 data: struct {
613 label: ?[]const u8,
614 stmts: []Node,
615 },
616 };
617
618 pub const Array = struct {
619 base: Payload,
620 data: ArrayTypeInfo,
621
622 pub const ArrayTypeInfo = struct {
623 elem_type: Node,
624 len: usize,
625 };
626 };
627
628 pub const Pointer = struct {
629 base: Payload,
630 data: struct {
631 elem_type: Node,
632 is_const: bool,
633 is_volatile: bool,
634 },
635 };
636
637 pub const ArgRedecl = struct {
638 base: Payload,
639 data: struct {
640 actual: []const u8,
641 mangled: []const u8,
642 },
643 };
644
645 pub const SimpleVarDecl = struct {
646 base: Payload,
647 data: struct {
648 name: []const u8,
649 init: Node,
650 },
651 };
652
653 pub const EnumConstant = struct {
654 base: Payload,
655 data: struct {
656 name: []const u8,
657 is_public: bool,
658 type: ?Node,
659 value: Node,
660 },
661 };
662
663 pub const ArrayFiller = struct {
664 base: Payload,
665 data: struct {
666 type: Node,
667 filler: Node,
668 count: usize,
669 },
670 };
671
672 pub const PubInlineFn = struct {
673 base: Payload,
674 data: struct {
675 name: []const u8,
676 params: []Param,
677 return_type: Node,
678 body: Node,
679 },
680 };
681
682 pub const FieldAccess = struct {
683 base: Payload,
684 data: struct {
685 lhs: Node,
686 field_name: []const u8,
687 },
688 };
689
690 pub const PromoteIntLiteral = struct {
691 base: Payload,
692 data: struct {
693 value: Node,
694 type: Node,
695 base: Node,
696 },
697 };
698
699 pub const StringSlice = struct {
700 base: Payload,
701 data: struct {
702 string: Node,
703 end: usize,
704 },
705 };
706
707 pub const Shuffle = struct {
708 base: Payload,
709 data: struct {
710 element_type: Node,
711 a: Node,
712 b: Node,
713 mask_vector: Node,
714 },
715 };
716
717 pub const Extern = struct {
718 base: Payload,
719 data: struct {
720 type: Node,
721 name: Node,
722 },
723 };
724
725 pub const MacroArithmetic = struct {
726 base: Payload,
727 data: struct {
728 op: Operator,
729 lhs: Node,
730 rhs: Node,
731 },
732
733 pub const Operator = enum { div, rem };
734 };
735};
736
737/// Converts the nodes into a Zig Ast.
738/// Caller must free the source slice.
739pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
740 var ctx = Context{
741 .gpa = gpa,
742 .buf = std.ArrayList(u8).init(gpa),
743 };
744 defer ctx.buf.deinit();
745 defer ctx.nodes.deinit(gpa);
746 defer ctx.extra_data.deinit(gpa);
747 defer ctx.tokens.deinit(gpa);
748
749 // Estimate that each top level node has 10 child nodes.
750 const estimated_node_count = nodes.len * 10;
751 try ctx.nodes.ensureTotalCapacity(gpa, estimated_node_count);
752 // Estimate that each each node has 2 tokens.
753 const estimated_tokens_count = estimated_node_count * 2;
754 try ctx.tokens.ensureTotalCapacity(gpa, estimated_tokens_count);
755 // Estimate that each each token is 3 bytes long.
756 const estimated_buf_len = estimated_tokens_count * 3;
757 try ctx.buf.ensureTotalCapacity(estimated_buf_len);
758
759 ctx.nodes.appendAssumeCapacity(.{
760 .tag = .root,
761 .main_token = 0,
762 .data = .{
763 .lhs = undefined,
764 .rhs = undefined,
765 },
766 });
767
768 const root_members = blk: {
769 var result = std.ArrayList(NodeIndex).init(gpa);
770 defer result.deinit();
771
772 for (nodes) |node| {
773 const res = try renderNode(&ctx, node);
774 if (node.tag() == .warning) continue;
775 try result.append(res);
776 }
777 break :blk try ctx.listToSpan(result.items);
778 };
779
780 ctx.nodes.items(.data)[0] = .{
781 .lhs = root_members.start,
782 .rhs = root_members.end,
783 };
784
785 try ctx.tokens.append(gpa, .{
786 .tag = .eof,
787 .start = @as(u32, @intCast(ctx.buf.items.len)),
788 });
789
790 return std.zig.Ast{
791 .source = try ctx.buf.toOwnedSliceSentinel(0),
792 .tokens = ctx.tokens.toOwnedSlice(),
793 .nodes = ctx.nodes.toOwnedSlice(),
794 .extra_data = try ctx.extra_data.toOwnedSlice(gpa),
795 .errors = &.{},
796 .mode = .zig,
797 };
798}
799
800const NodeIndex = std.zig.Ast.Node.Index;
801const NodeSubRange = std.zig.Ast.Node.SubRange;
802const TokenIndex = std.zig.Ast.TokenIndex;
803const TokenTag = std.zig.Token.Tag;
804
805const Context = struct {
806 gpa: Allocator,
807 buf: std.ArrayList(u8),
808 nodes: std.zig.Ast.NodeList = .{},
809 extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
810 tokens: std.zig.Ast.TokenList = .{},
811
812 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
813 const start_index = c.buf.items.len;
814 try c.buf.writer().print(format ++ " ", args);
815
816 try c.tokens.append(c.gpa, .{
817 .tag = tag,
818 .start = @as(u32, @intCast(start_index)),
819 });
820
821 return @as(u32, @intCast(c.tokens.len - 1));
822 }
823
824 fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
825 return c.addTokenFmt(tag, "{s}", .{bytes});
826 }
827
828 fn addIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex {
829 if (std.zig.primitives.isPrimitive(bytes))
830 return c.addTokenFmt(.identifier, "@\"{s}\"", .{bytes});
831 return c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(bytes)});
832 }
833
834 fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange {
835 try c.extra_data.appendSlice(c.gpa, list);
836 return NodeSubRange{
837 .start = @as(NodeIndex, @intCast(c.extra_data.items.len - list.len)),
838 .end = @as(NodeIndex, @intCast(c.extra_data.items.len)),
839 };
840 }
841
842 fn addNode(c: *Context, elem: std.zig.Ast.Node) Allocator.Error!NodeIndex {
843 const result = @as(NodeIndex, @intCast(c.nodes.len));
844 try c.nodes.append(c.gpa, elem);
845 return result;
846 }
847
848 fn addExtra(c: *Context, extra: anytype) Allocator.Error!NodeIndex {
849 const fields = std.meta.fields(@TypeOf(extra));
850 try c.extra_data.ensureUnusedCapacity(c.gpa, fields.len);
851 const result = @as(u32, @intCast(c.extra_data.items.len));
852 inline for (fields) |field| {
853 comptime std.debug.assert(field.type == NodeIndex);
854 c.extra_data.appendAssumeCapacity(@field(extra, field.name));
855 }
856 return result;
857 }
858};
859
860fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
861 var result = std.ArrayList(NodeIndex).init(c.gpa);
862 defer result.deinit();
863
864 for (nodes) |node| {
865 const res = try renderNode(c, node);
866 if (node.tag() == .warning) continue;
867 try result.append(res);
868 }
869
870 return try c.listToSpan(result.items);
871}
872
873fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
874 switch (node.tag()) {
875 .declaration => unreachable,
876 .warning => {
877 const payload = node.castTag(.warning).?.data;
878 try c.buf.appendSlice(payload);
879 try c.buf.append('\n');
880 return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
881 },
882 .helpers_cast => {
883 const payload = node.castTag(.helpers_cast).?.data;
884 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "cast" });
885 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
886 },
887 .helpers_promoteIntLiteral => {
888 const payload = node.castTag(.helpers_promoteIntLiteral).?.data;
889 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "promoteIntLiteral" });
890 return renderCall(c, import_node, &.{ payload.type, payload.value, payload.base });
891 },
892 .helpers_sizeof => {
893 const payload = node.castTag(.helpers_sizeof).?.data;
894 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "sizeof" });
895 return renderCall(c, import_node, &.{payload});
896 },
897 .std_mem_zeroes => {
898 const payload = node.castTag(.std_mem_zeroes).?.data;
899 const import_node = try renderStdImport(c, &.{ "mem", "zeroes" });
900 return renderCall(c, import_node, &.{payload});
901 },
902 .std_mem_zeroinit => {
903 const payload = node.castTag(.std_mem_zeroinit).?.data;
904 const import_node = try renderStdImport(c, &.{ "mem", "zeroInit" });
905 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
906 },
907 .helpers_flexible_array_type => {
908 const payload = node.castTag(.helpers_flexible_array_type).?.data;
909 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "FlexibleArrayType" });
910 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
911 },
912 .helpers_shuffle_vector_index => {
913 const payload = node.castTag(.helpers_shuffle_vector_index).?.data;
914 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "shuffleVectorIndex" });
915 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
916 },
917 .vector => {
918 const payload = node.castTag(.vector).?.data;
919 return renderBuiltinCall(c, "@Vector", &.{ payload.lhs, payload.rhs });
920 },
921 .call => {
922 const payload = node.castTag(.call).?.data;
923 // Cosmetic: avoids an unnecesary address_of on most function calls.
924 const lhs = if (payload.lhs.tag() == .fn_identifier)
925 try c.addNode(.{
926 .tag = .identifier,
927 .main_token = try c.addIdentifier(payload.lhs.castTag(.fn_identifier).?.data),
928 .data = undefined,
929 })
930 else
931 try renderNodeGrouped(c, payload.lhs);
932 return renderCall(c, lhs, payload.args);
933 },
934 .null_literal => return c.addNode(.{
935 .tag = .identifier,
936 .main_token = try c.addToken(.identifier, "null"),
937 .data = undefined,
938 }),
939 .undefined_literal => return c.addNode(.{
940 .tag = .identifier,
941 .main_token = try c.addToken(.identifier, "undefined"),
942 .data = undefined,
943 }),
944 .true_literal => return c.addNode(.{
945 .tag = .identifier,
946 .main_token = try c.addToken(.identifier, "true"),
947 .data = undefined,
948 }),
949 .false_literal => return c.addNode(.{
950 .tag = .identifier,
951 .main_token = try c.addToken(.identifier, "false"),
952 .data = undefined,
953 }),
954 .zero_literal => return c.addNode(.{
955 .tag = .number_literal,
956 .main_token = try c.addToken(.number_literal, "0"),
957 .data = undefined,
958 }),
959 .one_literal => return c.addNode(.{
960 .tag = .number_literal,
961 .main_token = try c.addToken(.number_literal, "1"),
962 .data = undefined,
963 }),
964 .void_type => return c.addNode(.{
965 .tag = .identifier,
966 .main_token = try c.addToken(.identifier, "void"),
967 .data = undefined,
968 }),
969 .noreturn_type => return c.addNode(.{
970 .tag = .identifier,
971 .main_token = try c.addToken(.identifier, "noreturn"),
972 .data = undefined,
973 }),
974 .@"continue" => return c.addNode(.{
975 .tag = .@"continue",
976 .main_token = try c.addToken(.keyword_continue, "continue"),
977 .data = .{
978 .lhs = 0,
979 .rhs = undefined,
980 },
981 }),
982 .return_void => return c.addNode(.{
983 .tag = .@"return",
984 .main_token = try c.addToken(.keyword_return, "return"),
985 .data = .{
986 .lhs = 0,
987 .rhs = undefined,
988 },
989 }),
990 .@"break" => return c.addNode(.{
991 .tag = .@"break",
992 .main_token = try c.addToken(.keyword_break, "break"),
993 .data = .{
994 .lhs = 0,
995 .rhs = 0,
996 },
997 }),
998 .break_val => {
999 const payload = node.castTag(.break_val).?.data;
1000 const tok = try c.addToken(.keyword_break, "break");
1001 const break_label = if (payload.label) |some| blk: {
1002 _ = try c.addToken(.colon, ":");
1003 break :blk try c.addIdentifier(some);
1004 } else 0;
1005 return c.addNode(.{
1006 .tag = .@"break",
1007 .main_token = tok,
1008 .data = .{
1009 .lhs = break_label,
1010 .rhs = try renderNode(c, payload.val),
1011 },
1012 });
1013 },
1014 .@"return" => {
1015 const payload = node.castTag(.@"return").?.data;
1016 return c.addNode(.{
1017 .tag = .@"return",
1018 .main_token = try c.addToken(.keyword_return, "return"),
1019 .data = .{
1020 .lhs = try renderNode(c, payload),
1021 .rhs = undefined,
1022 },
1023 });
1024 },
1025 .@"comptime" => {
1026 const payload = node.castTag(.@"comptime").?.data;
1027 return c.addNode(.{
1028 .tag = .@"comptime",
1029 .main_token = try c.addToken(.keyword_comptime, "comptime"),
1030 .data = .{
1031 .lhs = try renderNode(c, payload),
1032 .rhs = undefined,
1033 },
1034 });
1035 },
1036 .@"defer" => {
1037 const payload = node.castTag(.@"defer").?.data;
1038 return c.addNode(.{
1039 .tag = .@"defer",
1040 .main_token = try c.addToken(.keyword_defer, "defer"),
1041 .data = .{
1042 .lhs = undefined,
1043 .rhs = try renderNode(c, payload),
1044 },
1045 });
1046 },
1047 .asm_simple => {
1048 const payload = node.castTag(.asm_simple).?.data;
1049 const asm_token = try c.addToken(.keyword_asm, "asm");
1050 _ = try c.addToken(.l_paren, "(");
1051 return c.addNode(.{
1052 .tag = .asm_simple,
1053 .main_token = asm_token,
1054 .data = .{
1055 .lhs = try renderNode(c, payload),
1056 .rhs = try c.addToken(.r_paren, ")"),
1057 },
1058 });
1059 },
1060 .type => {
1061 const payload = node.castTag(.type).?.data;
1062 return c.addNode(.{
1063 .tag = .identifier,
1064 .main_token = try c.addToken(.identifier, payload),
1065 .data = undefined,
1066 });
1067 },
1068 .identifier => {
1069 const payload = node.castTag(.identifier).?.data;
1070 return c.addNode(.{
1071 .tag = .identifier,
1072 .main_token = try c.addIdentifier(payload),
1073 .data = undefined,
1074 });
1075 },
1076 .fn_identifier => {
1077 // C semantics are that a function identifier has address
1078 // value (implicit in stage1, explicit in stage2), except in
1079 // the context of an address_of, which is handled there.
1080 const payload = node.castTag(.fn_identifier).?.data;
1081 const tok = try c.addToken(.ampersand, "&");
1082 const arg = try c.addNode(.{
1083 .tag = .identifier,
1084 .main_token = try c.addIdentifier(payload),
1085 .data = undefined,
1086 });
1087 return c.addNode(.{
1088 .tag = .address_of,
1089 .main_token = tok,
1090 .data = .{
1091 .lhs = arg,
1092 .rhs = undefined,
1093 },
1094 });
1095 },
1096 .float_literal => {
1097 const payload = node.castTag(.float_literal).?.data;
1098 return c.addNode(.{
1099 .tag = .number_literal,
1100 .main_token = try c.addToken(.number_literal, payload),
1101 .data = undefined,
1102 });
1103 },
1104 .integer_literal => {
1105 const payload = node.castTag(.integer_literal).?.data;
1106 return c.addNode(.{
1107 .tag = .number_literal,
1108 .main_token = try c.addToken(.number_literal, payload),
1109 .data = undefined,
1110 });
1111 },
1112 .string_literal => {
1113 const payload = node.castTag(.string_literal).?.data;
1114 return c.addNode(.{
1115 .tag = .string_literal,
1116 .main_token = try c.addToken(.string_literal, payload),
1117 .data = undefined,
1118 });
1119 },
1120 .char_literal => {
1121 const payload = node.castTag(.char_literal).?.data;
1122 return c.addNode(.{
1123 .tag = .char_literal,
1124 .main_token = try c.addToken(.char_literal, payload),
1125 .data = undefined,
1126 });
1127 },
1128 .enum_literal => {
1129 const payload = node.castTag(.enum_literal).?.data;
1130 _ = try c.addToken(.period, ".");
1131 return c.addNode(.{
1132 .tag = .enum_literal,
1133 .main_token = try c.addToken(.identifier, payload),
1134 .data = undefined,
1135 });
1136 },
1137 .helpers_macro => {
1138 const payload = node.castTag(.helpers_macro).?.data;
1139 const chain = [_][]const u8{
1140 "zig",
1141 "c_translation",
1142 "Macros",
1143 payload,
1144 };
1145 return renderStdImport(c, &chain);
1146 },
1147 .import_c_builtin => {
1148 const payload = node.castTag(.import_c_builtin).?.data;
1149 const chain = [_][]const u8{
1150 "zig",
1151 "c_builtins",
1152 payload,
1153 };
1154 return renderStdImport(c, &chain);
1155 },
1156 .string_slice => {
1157 const payload = node.castTag(.string_slice).?.data;
1158
1159 const string = try renderNode(c, payload.string);
1160 const l_bracket = try c.addToken(.l_bracket, "[");
1161 const start = try c.addNode(.{
1162 .tag = .number_literal,
1163 .main_token = try c.addToken(.number_literal, "0"),
1164 .data = undefined,
1165 });
1166 _ = try c.addToken(.ellipsis2, "..");
1167 const end = try c.addNode(.{
1168 .tag = .number_literal,
1169 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.end}),
1170 .data = undefined,
1171 });
1172 _ = try c.addToken(.r_bracket, "]");
1173
1174 return c.addNode(.{
1175 .tag = .slice,
1176 .main_token = l_bracket,
1177 .data = .{
1178 .lhs = string,
1179 .rhs = try c.addExtra(std.zig.Ast.Node.Slice{
1180 .start = start,
1181 .end = end,
1182 }),
1183 },
1184 });
1185 },
1186 .fail_decl => {
1187 const payload = node.castTag(.fail_decl).?.data;
1188 // pub const name = @compileError(msg);
1189 _ = try c.addToken(.keyword_pub, "pub");
1190 const const_tok = try c.addToken(.keyword_const, "const");
1191 _ = try c.addIdentifier(payload.actual);
1192 _ = try c.addToken(.equal, "=");
1193
1194 const compile_error_tok = try c.addToken(.builtin, "@compileError");
1195 _ = try c.addToken(.l_paren, "(");
1196 const err_msg_tok = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(payload.mangled)});
1197 const err_msg = try c.addNode(.{
1198 .tag = .string_literal,
1199 .main_token = err_msg_tok,
1200 .data = undefined,
1201 });
1202 _ = try c.addToken(.r_paren, ")");
1203 const compile_error = try c.addNode(.{
1204 .tag = .builtin_call_two,
1205 .main_token = compile_error_tok,
1206 .data = .{
1207 .lhs = err_msg,
1208 .rhs = 0,
1209 },
1210 });
1211 _ = try c.addToken(.semicolon, ";");
1212
1213 return c.addNode(.{
1214 .tag = .simple_var_decl,
1215 .main_token = const_tok,
1216 .data = .{
1217 .lhs = 0,
1218 .rhs = compile_error,
1219 },
1220 });
1221 },
1222 .pub_var_simple, .var_simple => {
1223 const payload = @fieldParentPtr(Payload.SimpleVarDecl, "base", node.ptr_otherwise).data;
1224 if (node.tag() == .pub_var_simple) _ = try c.addToken(.keyword_pub, "pub");
1225 const const_tok = try c.addToken(.keyword_const, "const");
1226 _ = try c.addIdentifier(payload.name);
1227 _ = try c.addToken(.equal, "=");
1228
1229 const init = try renderNode(c, payload.init);
1230 _ = try c.addToken(.semicolon, ";");
1231
1232 return c.addNode(.{
1233 .tag = .simple_var_decl,
1234 .main_token = const_tok,
1235 .data = .{
1236 .lhs = 0,
1237 .rhs = init,
1238 },
1239 });
1240 },
1241 .static_local_var => {
1242 const payload = node.castTag(.static_local_var).?.data;
1243
1244 const const_tok = try c.addToken(.keyword_const, "const");
1245 _ = try c.addIdentifier(payload.name);
1246 _ = try c.addToken(.equal, "=");
1247
1248 const kind_tok = try c.addToken(.keyword_struct, "struct");
1249 _ = try c.addToken(.l_brace, "{");
1250
1251 const container_def = try c.addNode(.{
1252 .tag = .container_decl_two_trailing,
1253 .main_token = kind_tok,
1254 .data = .{
1255 .lhs = try renderNode(c, payload.init),
1256 .rhs = 0,
1257 },
1258 });
1259 _ = try c.addToken(.r_brace, "}");
1260 _ = try c.addToken(.semicolon, ";");
1261
1262 return c.addNode(.{
1263 .tag = .simple_var_decl,
1264 .main_token = const_tok,
1265 .data = .{
1266 .lhs = 0,
1267 .rhs = container_def,
1268 },
1269 });
1270 },
1271 .mut_str => {
1272 const payload = node.castTag(.mut_str).?.data;
1273
1274 const var_tok = try c.addToken(.keyword_var, "var");
1275 _ = try c.addIdentifier(payload.name);
1276 _ = try c.addToken(.equal, "=");
1277
1278 const deref = try c.addNode(.{
1279 .tag = .deref,
1280 .data = .{
1281 .lhs = try renderNodeGrouped(c, payload.init),
1282 .rhs = undefined,
1283 },
1284 .main_token = try c.addToken(.period_asterisk, ".*"),
1285 });
1286 _ = try c.addToken(.semicolon, ";");
1287
1288 return c.addNode(.{
1289 .tag = .simple_var_decl,
1290 .main_token = var_tok,
1291 .data = .{ .lhs = 0, .rhs = deref },
1292 });
1293 },
1294 .var_decl => return renderVar(c, node),
1295 .arg_redecl, .alias => {
1296 const payload = @fieldParentPtr(Payload.ArgRedecl, "base", node.ptr_otherwise).data;
1297 if (node.tag() == .alias) _ = try c.addToken(.keyword_pub, "pub");
1298 const mut_tok = if (node.tag() == .alias)
1299 try c.addToken(.keyword_const, "const")
1300 else
1301 try c.addToken(.keyword_var, "var");
1302 _ = try c.addIdentifier(payload.actual);
1303 _ = try c.addToken(.equal, "=");
1304
1305 const init = try c.addNode(.{
1306 .tag = .identifier,
1307 .main_token = try c.addIdentifier(payload.mangled),
1308 .data = undefined,
1309 });
1310 _ = try c.addToken(.semicolon, ";");
1311
1312 return c.addNode(.{
1313 .tag = .simple_var_decl,
1314 .main_token = mut_tok,
1315 .data = .{
1316 .lhs = 0,
1317 .rhs = init,
1318 },
1319 });
1320 },
1321 .int_cast => {
1322 const payload = node.castTag(.int_cast).?.data;
1323 return renderBuiltinCall(c, "@intCast", &.{payload});
1324 },
1325 .const_cast => {
1326 const payload = node.castTag(.const_cast).?.data;
1327 return renderBuiltinCall(c, "@constCast", &.{payload});
1328 },
1329 .volatile_cast => {
1330 const payload = node.castTag(.volatile_cast).?.data;
1331 return renderBuiltinCall(c, "@volatileCast", &.{payload});
1332 },
1333 .signed_remainder => {
1334 const payload = node.castTag(.signed_remainder).?.data;
1335 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "signedRemainder" });
1336 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
1337 },
1338 .div_trunc => {
1339 const payload = node.castTag(.div_trunc).?.data;
1340 return renderBuiltinCall(c, "@divTrunc", &.{ payload.lhs, payload.rhs });
1341 },
1342 .int_from_bool => {
1343 const payload = node.castTag(.int_from_bool).?.data;
1344 return renderBuiltinCall(c, "@intFromBool", &.{payload});
1345 },
1346 .as => {
1347 const payload = node.castTag(.as).?.data;
1348 return renderBuiltinCall(c, "@as", &.{ payload.lhs, payload.rhs });
1349 },
1350 .truncate => {
1351 const payload = node.castTag(.truncate).?.data;
1352 return renderBuiltinCall(c, "@truncate", &.{payload});
1353 },
1354 .bit_cast => {
1355 const payload = node.castTag(.bit_cast).?.data;
1356 return renderBuiltinCall(c, "@bitCast", &.{payload});
1357 },
1358 .float_cast => {
1359 const payload = node.castTag(.float_cast).?.data;
1360 return renderBuiltinCall(c, "@floatCast", &.{payload});
1361 },
1362 .int_from_float => {
1363 const payload = node.castTag(.int_from_float).?.data;
1364 return renderBuiltinCall(c, "@intFromFloat", &.{payload});
1365 },
1366 .float_from_int => {
1367 const payload = node.castTag(.float_from_int).?.data;
1368 return renderBuiltinCall(c, "@floatFromInt", &.{payload});
1369 },
1370 .ptr_from_int => {
1371 const payload = node.castTag(.ptr_from_int).?.data;
1372 return renderBuiltinCall(c, "@ptrFromInt", &.{payload});
1373 },
1374 .int_from_ptr => {
1375 const payload = node.castTag(.int_from_ptr).?.data;
1376 return renderBuiltinCall(c, "@intFromPtr", &.{payload});
1377 },
1378 .align_cast => {
1379 const payload = node.castTag(.align_cast).?.data;
1380 return renderBuiltinCall(c, "@alignCast", &.{payload});
1381 },
1382 .ptr_cast => {
1383 const payload = node.castTag(.ptr_cast).?.data;
1384 return renderBuiltinCall(c, "@ptrCast", &.{payload});
1385 },
1386 .div_exact => {
1387 const payload = node.castTag(.div_exact).?.data;
1388 return renderBuiltinCall(c, "@divExact", &.{ payload.lhs, payload.rhs });
1389 },
1390 .offset_of => {
1391 const payload = node.castTag(.offset_of).?.data;
1392 return renderBuiltinCall(c, "@offsetOf", &.{ payload.lhs, payload.rhs });
1393 },
1394 .sizeof => {
1395 const payload = node.castTag(.sizeof).?.data;
1396 return renderBuiltinCall(c, "@sizeOf", &.{payload});
1397 },
1398 .shuffle => {
1399 const payload = node.castTag(.shuffle).?.data;
1400 return renderBuiltinCall(c, "@shuffle", &.{
1401 payload.element_type,
1402 payload.a,
1403 payload.b,
1404 payload.mask_vector,
1405 });
1406 },
1407 .builtin_extern => {
1408 const payload = node.castTag(.builtin_extern).?.data;
1409
1410 var info_inits: [1]Payload.ContainerInitDot.Initializer = .{
1411 .{ .name = "name", .value = payload.name },
1412 };
1413 var info_payload: Payload.ContainerInitDot = .{
1414 .base = .{ .tag = .container_init_dot },
1415 .data = &info_inits,
1416 };
1417
1418 return renderBuiltinCall(c, "@extern", &.{
1419 payload.type,
1420 .{ .ptr_otherwise = &info_payload.base },
1421 });
1422 },
1423 .macro_arithmetic => {
1424 const payload = node.castTag(.macro_arithmetic).?.data;
1425 const op = @tagName(payload.op);
1426 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "MacroArithmetic", op });
1427 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
1428 },
1429 .alignof => {
1430 const payload = node.castTag(.alignof).?.data;
1431 return renderBuiltinCall(c, "@alignOf", &.{payload});
1432 },
1433 .typeof => {
1434 const payload = node.castTag(.typeof).?.data;
1435 return renderBuiltinCall(c, "@TypeOf", &.{payload});
1436 },
1437 .typeinfo => {
1438 const payload = node.castTag(.typeinfo).?.data;
1439 return renderBuiltinCall(c, "@typeInfo", &.{payload});
1440 },
1441 .negate => return renderPrefixOp(c, node, .negation, .minus, "-"),
1442 .negate_wrap => return renderPrefixOp(c, node, .negation_wrap, .minus_percent, "-%"),
1443 .bit_not => return renderPrefixOp(c, node, .bit_not, .tilde, "~"),
1444 .not => return renderPrefixOp(c, node, .bool_not, .bang, "!"),
1445 .optional_type => return renderPrefixOp(c, node, .optional_type, .question_mark, "?"),
1446 .address_of => {
1447 const payload = node.castTag(.address_of).?.data;
1448
1449 const ampersand = try c.addToken(.ampersand, "&");
1450 const base = if (payload.tag() == .fn_identifier)
1451 try c.addNode(.{
1452 .tag = .identifier,
1453 .main_token = try c.addIdentifier(payload.castTag(.fn_identifier).?.data),
1454 .data = undefined,
1455 })
1456 else
1457 try renderNodeGrouped(c, payload);
1458 return c.addNode(.{
1459 .tag = .address_of,
1460 .main_token = ampersand,
1461 .data = .{
1462 .lhs = base,
1463 .rhs = undefined,
1464 },
1465 });
1466 },
1467 .deref => {
1468 const payload = node.castTag(.deref).?.data;
1469 const operand = try renderNodeGrouped(c, payload);
1470 const deref_tok = try c.addToken(.period_asterisk, ".*");
1471 return c.addNode(.{
1472 .tag = .deref,
1473 .main_token = deref_tok,
1474 .data = .{
1475 .lhs = operand,
1476 .rhs = undefined,
1477 },
1478 });
1479 },
1480 .unwrap => {
1481 const payload = node.castTag(.unwrap).?.data;
1482 const operand = try renderNodeGrouped(c, payload);
1483 const period = try c.addToken(.period, ".");
1484 const question_mark = try c.addToken(.question_mark, "?");
1485 return c.addNode(.{
1486 .tag = .unwrap_optional,
1487 .main_token = period,
1488 .data = .{
1489 .lhs = operand,
1490 .rhs = question_mark,
1491 },
1492 });
1493 },
1494 .c_pointer, .single_pointer => {
1495 const payload = @fieldParentPtr(Payload.Pointer, "base", node.ptr_otherwise).data;
1496
1497 const asterisk = if (node.tag() == .single_pointer)
1498 try c.addToken(.asterisk, "*")
1499 else blk: {
1500 _ = try c.addToken(.l_bracket, "[");
1501 const res = try c.addToken(.asterisk, "*");
1502 _ = try c.addIdentifier("c");
1503 _ = try c.addToken(.r_bracket, "]");
1504 break :blk res;
1505 };
1506 if (payload.is_const) _ = try c.addToken(.keyword_const, "const");
1507 if (payload.is_volatile) _ = try c.addToken(.keyword_volatile, "volatile");
1508 const elem_type = try renderNodeGrouped(c, payload.elem_type);
1509
1510 return c.addNode(.{
1511 .tag = .ptr_type_aligned,
1512 .main_token = asterisk,
1513 .data = .{
1514 .lhs = 0,
1515 .rhs = elem_type,
1516 },
1517 });
1518 },
1519 .add => return renderBinOpGrouped(c, node, .add, .plus, "+"),
1520 .add_assign => return renderBinOp(c, node, .assign_add, .plus_equal, "+="),
1521 .add_wrap => return renderBinOpGrouped(c, node, .add_wrap, .plus_percent, "+%"),
1522 .add_wrap_assign => return renderBinOp(c, node, .assign_add_wrap, .plus_percent_equal, "+%="),
1523 .sub => return renderBinOpGrouped(c, node, .sub, .minus, "-"),
1524 .sub_assign => return renderBinOp(c, node, .assign_sub, .minus_equal, "-="),
1525 .sub_wrap => return renderBinOpGrouped(c, node, .sub_wrap, .minus_percent, "-%"),
1526 .sub_wrap_assign => return renderBinOp(c, node, .assign_sub_wrap, .minus_percent_equal, "-%="),
1527 .mul => return renderBinOpGrouped(c, node, .mul, .asterisk, "*"),
1528 .mul_assign => return renderBinOp(c, node, .assign_mul, .asterisk_equal, "*="),
1529 .mul_wrap => return renderBinOpGrouped(c, node, .mul_wrap, .asterisk_percent, "*%"),
1530 .mul_wrap_assign => return renderBinOp(c, node, .assign_mul_wrap, .asterisk_percent_equal, "*%="),
1531 .div => return renderBinOpGrouped(c, node, .div, .slash, "/"),
1532 .div_assign => return renderBinOp(c, node, .assign_div, .slash_equal, "/="),
1533 .shl => return renderBinOpGrouped(c, node, .shl, .angle_bracket_angle_bracket_left, "<<"),
1534 .shl_assign => return renderBinOp(c, node, .assign_shl, .angle_bracket_angle_bracket_left_equal, "<<="),
1535 .shr => return renderBinOpGrouped(c, node, .shr, .angle_bracket_angle_bracket_right, ">>"),
1536 .shr_assign => return renderBinOp(c, node, .assign_shr, .angle_bracket_angle_bracket_right_equal, ">>="),
1537 .mod => return renderBinOpGrouped(c, node, .mod, .percent, "%"),
1538 .mod_assign => return renderBinOp(c, node, .assign_mod, .percent_equal, "%="),
1539 .@"and" => return renderBinOpGrouped(c, node, .bool_and, .keyword_and, "and"),
1540 .@"or" => return renderBinOpGrouped(c, node, .bool_or, .keyword_or, "or"),
1541 .less_than => return renderBinOpGrouped(c, node, .less_than, .angle_bracket_left, "<"),
1542 .less_than_equal => return renderBinOpGrouped(c, node, .less_or_equal, .angle_bracket_left_equal, "<="),
1543 .greater_than => return renderBinOpGrouped(c, node, .greater_than, .angle_bracket_right, ">="),
1544 .greater_than_equal => return renderBinOpGrouped(c, node, .greater_or_equal, .angle_bracket_right_equal, ">="),
1545 .equal => return renderBinOpGrouped(c, node, .equal_equal, .equal_equal, "=="),
1546 .not_equal => return renderBinOpGrouped(c, node, .bang_equal, .bang_equal, "!="),
1547 .bit_and => return renderBinOpGrouped(c, node, .bit_and, .ampersand, "&"),
1548 .bit_and_assign => return renderBinOp(c, node, .assign_bit_and, .ampersand_equal, "&="),
1549 .bit_or => return renderBinOpGrouped(c, node, .bit_or, .pipe, "|"),
1550 .bit_or_assign => return renderBinOp(c, node, .assign_bit_or, .pipe_equal, "|="),
1551 .bit_xor => return renderBinOpGrouped(c, node, .bit_xor, .caret, "^"),
1552 .bit_xor_assign => return renderBinOp(c, node, .assign_bit_xor, .caret_equal, "^="),
1553 .array_cat => return renderBinOp(c, node, .array_cat, .plus_plus, "++"),
1554 .ellipsis3 => return renderBinOpGrouped(c, node, .switch_range, .ellipsis3, "..."),
1555 .assign => return renderBinOp(c, node, .assign, .equal, "="),
1556 .empty_block => {
1557 const l_brace = try c.addToken(.l_brace, "{");
1558 _ = try c.addToken(.r_brace, "}");
1559 return c.addNode(.{
1560 .tag = .block_two,
1561 .main_token = l_brace,
1562 .data = .{
1563 .lhs = 0,
1564 .rhs = 0,
1565 },
1566 });
1567 },
1568 .block_single => {
1569 const payload = node.castTag(.block_single).?.data;
1570 const l_brace = try c.addToken(.l_brace, "{");
1571
1572 const stmt = try renderNode(c, payload);
1573 try addSemicolonIfNeeded(c, payload);
1574
1575 _ = try c.addToken(.r_brace, "}");
1576 return c.addNode(.{
1577 .tag = .block_two_semicolon,
1578 .main_token = l_brace,
1579 .data = .{
1580 .lhs = stmt,
1581 .rhs = 0,
1582 },
1583 });
1584 },
1585 .block => {
1586 const payload = node.castTag(.block).?.data;
1587 if (payload.label) |some| {
1588 _ = try c.addIdentifier(some);
1589 _ = try c.addToken(.colon, ":");
1590 }
1591 const l_brace = try c.addToken(.l_brace, "{");
1592
1593 var stmts = std.ArrayList(NodeIndex).init(c.gpa);
1594 defer stmts.deinit();
1595 for (payload.stmts) |stmt| {
1596 const res = try renderNode(c, stmt);
1597 if (res == 0) continue;
1598 try addSemicolonIfNeeded(c, stmt);
1599 try stmts.append(res);
1600 }
1601 const span = try c.listToSpan(stmts.items);
1602 _ = try c.addToken(.r_brace, "}");
1603
1604 const semicolon = c.tokens.items(.tag)[c.tokens.len - 2] == .semicolon;
1605 return c.addNode(.{
1606 .tag = if (semicolon) .block_semicolon else .block,
1607 .main_token = l_brace,
1608 .data = .{
1609 .lhs = span.start,
1610 .rhs = span.end,
1611 },
1612 });
1613 },
1614 .func => return renderFunc(c, node),
1615 .pub_inline_fn => return renderMacroFunc(c, node),
1616 .discard => {
1617 const payload = node.castTag(.discard).?.data;
1618 if (payload.should_skip) return @as(NodeIndex, 0);
1619
1620 const lhs = try c.addNode(.{
1621 .tag = .identifier,
1622 .main_token = try c.addToken(.identifier, "_"),
1623 .data = undefined,
1624 });
1625 const main_token = try c.addToken(.equal, "=");
1626 if (payload.value.tag() == .identifier) {
1627 // Render as `_ = &foo;` to avoid tripping "pointless discard" and "local variable never mutated" errors.
1628 var addr_of_pl: Payload.UnOp = .{
1629 .base = .{ .tag = .address_of },
1630 .data = payload.value,
1631 };
1632 const addr_of: Node = .{ .ptr_otherwise = &addr_of_pl.base };
1633 return c.addNode(.{
1634 .tag = .assign,
1635 .main_token = main_token,
1636 .data = .{
1637 .lhs = lhs,
1638 .rhs = try renderNode(c, addr_of),
1639 },
1640 });
1641 } else {
1642 return c.addNode(.{
1643 .tag = .assign,
1644 .main_token = main_token,
1645 .data = .{
1646 .lhs = lhs,
1647 .rhs = try renderNode(c, payload.value),
1648 },
1649 });
1650 }
1651 },
1652 .@"while" => {
1653 const payload = node.castTag(.@"while").?.data;
1654 const while_tok = try c.addToken(.keyword_while, "while");
1655 _ = try c.addToken(.l_paren, "(");
1656 const cond = try renderNode(c, payload.cond);
1657 _ = try c.addToken(.r_paren, ")");
1658
1659 const cont_expr = if (payload.cont_expr) |some| blk: {
1660 _ = try c.addToken(.colon, ":");
1661 _ = try c.addToken(.l_paren, "(");
1662 const res = try renderNode(c, some);
1663 _ = try c.addToken(.r_paren, ")");
1664 break :blk res;
1665 } else 0;
1666 const body = try renderNode(c, payload.body);
1667
1668 if (cont_expr == 0) {
1669 return c.addNode(.{
1670 .tag = .while_simple,
1671 .main_token = while_tok,
1672 .data = .{
1673 .lhs = cond,
1674 .rhs = body,
1675 },
1676 });
1677 } else {
1678 return c.addNode(.{
1679 .tag = .while_cont,
1680 .main_token = while_tok,
1681 .data = .{
1682 .lhs = cond,
1683 .rhs = try c.addExtra(std.zig.Ast.Node.WhileCont{
1684 .cont_expr = cont_expr,
1685 .then_expr = body,
1686 }),
1687 },
1688 });
1689 }
1690 },
1691 .while_true => {
1692 const payload = node.castTag(.while_true).?.data;
1693 const while_tok = try c.addToken(.keyword_while, "while");
1694 _ = try c.addToken(.l_paren, "(");
1695 const cond = try c.addNode(.{
1696 .tag = .identifier,
1697 .main_token = try c.addToken(.identifier, "true"),
1698 .data = undefined,
1699 });
1700 _ = try c.addToken(.r_paren, ")");
1701 const body = try renderNode(c, payload);
1702
1703 return c.addNode(.{
1704 .tag = .while_simple,
1705 .main_token = while_tok,
1706 .data = .{
1707 .lhs = cond,
1708 .rhs = body,
1709 },
1710 });
1711 },
1712 .@"if" => {
1713 const payload = node.castTag(.@"if").?.data;
1714 const if_tok = try c.addToken(.keyword_if, "if");
1715 _ = try c.addToken(.l_paren, "(");
1716 const cond = try renderNode(c, payload.cond);
1717 _ = try c.addToken(.r_paren, ")");
1718
1719 const then_expr = try renderNode(c, payload.then);
1720 const else_node = payload.@"else" orelse return c.addNode(.{
1721 .tag = .if_simple,
1722 .main_token = if_tok,
1723 .data = .{
1724 .lhs = cond,
1725 .rhs = then_expr,
1726 },
1727 });
1728 _ = try c.addToken(.keyword_else, "else");
1729 const else_expr = try renderNode(c, else_node);
1730
1731 return c.addNode(.{
1732 .tag = .@"if",
1733 .main_token = if_tok,
1734 .data = .{
1735 .lhs = cond,
1736 .rhs = try c.addExtra(std.zig.Ast.Node.If{
1737 .then_expr = then_expr,
1738 .else_expr = else_expr,
1739 }),
1740 },
1741 });
1742 },
1743 .if_not_break => {
1744 const payload = node.castTag(.if_not_break).?.data;
1745 const if_tok = try c.addToken(.keyword_if, "if");
1746 _ = try c.addToken(.l_paren, "(");
1747 const cond = try c.addNode(.{
1748 .tag = .bool_not,
1749 .main_token = try c.addToken(.bang, "!"),
1750 .data = .{
1751 .lhs = try renderNodeGrouped(c, payload),
1752 .rhs = undefined,
1753 },
1754 });
1755 _ = try c.addToken(.r_paren, ")");
1756 const then_expr = try c.addNode(.{
1757 .tag = .@"break",
1758 .main_token = try c.addToken(.keyword_break, "break"),
1759 .data = .{
1760 .lhs = 0,
1761 .rhs = 0,
1762 },
1763 });
1764
1765 return c.addNode(.{
1766 .tag = .if_simple,
1767 .main_token = if_tok,
1768 .data = .{
1769 .lhs = cond,
1770 .rhs = then_expr,
1771 },
1772 });
1773 },
1774 .@"switch" => {
1775 const payload = node.castTag(.@"switch").?.data;
1776 const switch_tok = try c.addToken(.keyword_switch, "switch");
1777 _ = try c.addToken(.l_paren, "(");
1778 const cond = try renderNode(c, payload.cond);
1779 _ = try c.addToken(.r_paren, ")");
1780
1781 _ = try c.addToken(.l_brace, "{");
1782 var cases = try c.gpa.alloc(NodeIndex, payload.cases.len);
1783 defer c.gpa.free(cases);
1784 for (payload.cases, 0..) |case, i| {
1785 cases[i] = try renderNode(c, case);
1786 _ = try c.addToken(.comma, ",");
1787 }
1788 const span = try c.listToSpan(cases);
1789 _ = try c.addToken(.r_brace, "}");
1790 return c.addNode(.{
1791 .tag = .switch_comma,
1792 .main_token = switch_tok,
1793 .data = .{
1794 .lhs = cond,
1795 .rhs = try c.addExtra(NodeSubRange{
1796 .start = span.start,
1797 .end = span.end,
1798 }),
1799 },
1800 });
1801 },
1802 .switch_else => {
1803 const payload = node.castTag(.switch_else).?.data;
1804 _ = try c.addToken(.keyword_else, "else");
1805 return c.addNode(.{
1806 .tag = .switch_case_one,
1807 .main_token = try c.addToken(.equal_angle_bracket_right, "=>"),
1808 .data = .{
1809 .lhs = 0,
1810 .rhs = try renderNode(c, payload),
1811 },
1812 });
1813 },
1814 .switch_prong => {
1815 const payload = node.castTag(.switch_prong).?.data;
1816 var items = try c.gpa.alloc(NodeIndex, @max(payload.cases.len, 1));
1817 defer c.gpa.free(items);
1818 items[0] = 0;
1819 for (payload.cases, 0..) |item, i| {
1820 if (i != 0) _ = try c.addToken(.comma, ",");
1821 items[i] = try renderNode(c, item);
1822 }
1823 _ = try c.addToken(.r_brace, "}");
1824 if (items.len < 2) {
1825 return c.addNode(.{
1826 .tag = .switch_case_one,
1827 .main_token = try c.addToken(.equal_angle_bracket_right, "=>"),
1828 .data = .{
1829 .lhs = items[0],
1830 .rhs = try renderNode(c, payload.cond),
1831 },
1832 });
1833 } else {
1834 const span = try c.listToSpan(items);
1835 return c.addNode(.{
1836 .tag = .switch_case,
1837 .main_token = try c.addToken(.equal_angle_bracket_right, "=>"),
1838 .data = .{
1839 .lhs = try c.addExtra(NodeSubRange{
1840 .start = span.start,
1841 .end = span.end,
1842 }),
1843 .rhs = try renderNode(c, payload.cond),
1844 },
1845 });
1846 }
1847 },
1848 .opaque_literal => {
1849 const opaque_tok = try c.addToken(.keyword_opaque, "opaque");
1850 _ = try c.addToken(.l_brace, "{");
1851 _ = try c.addToken(.r_brace, "}");
1852
1853 return c.addNode(.{
1854 .tag = .container_decl_two,
1855 .main_token = opaque_tok,
1856 .data = .{
1857 .lhs = 0,
1858 .rhs = 0,
1859 },
1860 });
1861 },
1862 .array_access => {
1863 const payload = node.castTag(.array_access).?.data;
1864 const lhs = try renderNodeGrouped(c, payload.lhs);
1865 const l_bracket = try c.addToken(.l_bracket, "[");
1866 const index_expr = try renderNode(c, payload.rhs);
1867 _ = try c.addToken(.r_bracket, "]");
1868 return c.addNode(.{
1869 .tag = .array_access,
1870 .main_token = l_bracket,
1871 .data = .{
1872 .lhs = lhs,
1873 .rhs = index_expr,
1874 },
1875 });
1876 },
1877 .array_type => {
1878 const payload = node.castTag(.array_type).?.data;
1879 return renderArrayType(c, payload.len, payload.elem_type);
1880 },
1881 .null_sentinel_array_type => {
1882 const payload = node.castTag(.null_sentinel_array_type).?.data;
1883 return renderNullSentinelArrayType(c, payload.len, payload.elem_type);
1884 },
1885 .array_filler => {
1886 const payload = node.castTag(.array_filler).?.data;
1887
1888 const type_expr = try renderArrayType(c, 1, payload.type);
1889 const l_brace = try c.addToken(.l_brace, "{");
1890 const val = try renderNode(c, payload.filler);
1891 _ = try c.addToken(.r_brace, "}");
1892
1893 const init = try c.addNode(.{
1894 .tag = .array_init_one,
1895 .main_token = l_brace,
1896 .data = .{
1897 .lhs = type_expr,
1898 .rhs = val,
1899 },
1900 });
1901 return c.addNode(.{
1902 .tag = .array_cat,
1903 .main_token = try c.addToken(.asterisk_asterisk, "**"),
1904 .data = .{
1905 .lhs = init,
1906 .rhs = try c.addNode(.{
1907 .tag = .number_literal,
1908 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.count}),
1909 .data = undefined,
1910 }),
1911 },
1912 });
1913 },
1914 .empty_array => {
1915 const payload = node.castTag(.empty_array).?.data;
1916
1917 const type_expr = try renderArrayType(c, 0, payload);
1918 return renderArrayInit(c, type_expr, &.{});
1919 },
1920 .array_init => {
1921 const payload = node.castTag(.array_init).?.data;
1922 const type_expr = try renderNode(c, payload.cond);
1923 return renderArrayInit(c, type_expr, payload.cases);
1924 },
1925 .vector_zero_init => {
1926 const payload = node.castTag(.vector_zero_init).?.data;
1927 return renderBuiltinCall(c, "@splat", &.{payload});
1928 },
1929 .field_access => {
1930 const payload = node.castTag(.field_access).?.data;
1931 const lhs = try renderNodeGrouped(c, payload.lhs);
1932 return renderFieldAccess(c, lhs, payload.field_name);
1933 },
1934 .@"struct", .@"union" => return renderRecord(c, node),
1935 .enum_constant => {
1936 const payload = node.castTag(.enum_constant).?.data;
1937
1938 if (payload.is_public) _ = try c.addToken(.keyword_pub, "pub");
1939 const const_tok = try c.addToken(.keyword_const, "const");
1940 _ = try c.addIdentifier(payload.name);
1941
1942 const type_node = if (payload.type) |enum_const_type| blk: {
1943 _ = try c.addToken(.colon, ":");
1944 break :blk try renderNode(c, enum_const_type);
1945 } else 0;
1946
1947 _ = try c.addToken(.equal, "=");
1948
1949 const init_node = try renderNode(c, payload.value);
1950 _ = try c.addToken(.semicolon, ";");
1951
1952 return c.addNode(.{
1953 .tag = .simple_var_decl,
1954 .main_token = const_tok,
1955 .data = .{
1956 .lhs = type_node,
1957 .rhs = init_node,
1958 },
1959 });
1960 },
1961 .tuple => {
1962 const payload = node.castTag(.tuple).?.data;
1963 _ = try c.addToken(.period, ".");
1964 const l_brace = try c.addToken(.l_brace, "{");
1965 var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2));
1966 defer c.gpa.free(inits);
1967 inits[0] = 0;
1968 inits[1] = 0;
1969 for (payload, 0..) |init, i| {
1970 if (i != 0) _ = try c.addToken(.comma, ",");
1971 inits[i] = try renderNode(c, init);
1972 }
1973 _ = try c.addToken(.r_brace, "}");
1974 if (payload.len < 3) {
1975 return c.addNode(.{
1976 .tag = .array_init_dot_two,
1977 .main_token = l_brace,
1978 .data = .{
1979 .lhs = inits[0],
1980 .rhs = inits[1],
1981 },
1982 });
1983 } else {
1984 const span = try c.listToSpan(inits);
1985 return c.addNode(.{
1986 .tag = .array_init_dot,
1987 .main_token = l_brace,
1988 .data = .{
1989 .lhs = span.start,
1990 .rhs = span.end,
1991 },
1992 });
1993 }
1994 },
1995 .container_init_dot => {
1996 const payload = node.castTag(.container_init_dot).?.data;
1997 _ = try c.addToken(.period, ".");
1998 const l_brace = try c.addToken(.l_brace, "{");
1999 var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2));
2000 defer c.gpa.free(inits);
2001 inits[0] = 0;
2002 inits[1] = 0;
2003 for (payload, 0..) |init, i| {
2004 _ = try c.addToken(.period, ".");
2005 _ = try c.addIdentifier(init.name);
2006 _ = try c.addToken(.equal, "=");
2007 inits[i] = try renderNode(c, init.value);
2008 _ = try c.addToken(.comma, ",");
2009 }
2010 _ = try c.addToken(.r_brace, "}");
2011
2012 if (payload.len < 3) {
2013 return c.addNode(.{
2014 .tag = .struct_init_dot_two_comma,
2015 .main_token = l_brace,
2016 .data = .{
2017 .lhs = inits[0],
2018 .rhs = inits[1],
2019 },
2020 });
2021 } else {
2022 const span = try c.listToSpan(inits);
2023 return c.addNode(.{
2024 .tag = .struct_init_dot_comma,
2025 .main_token = l_brace,
2026 .data = .{
2027 .lhs = span.start,
2028 .rhs = span.end,
2029 },
2030 });
2031 }
2032 },
2033 .container_init => {
2034 const payload = node.castTag(.container_init).?.data;
2035 const lhs = try renderNode(c, payload.lhs);
2036
2037 const l_brace = try c.addToken(.l_brace, "{");
2038 var inits = try c.gpa.alloc(NodeIndex, @max(payload.inits.len, 1));
2039 defer c.gpa.free(inits);
2040 inits[0] = 0;
2041 for (payload.inits, 0..) |init, i| {
2042 _ = try c.addToken(.period, ".");
2043 _ = try c.addIdentifier(init.name);
2044 _ = try c.addToken(.equal, "=");
2045 inits[i] = try renderNode(c, init.value);
2046 _ = try c.addToken(.comma, ",");
2047 }
2048 _ = try c.addToken(.r_brace, "}");
2049
2050 return switch (payload.inits.len) {
2051 0 => c.addNode(.{
2052 .tag = .struct_init_one,
2053 .main_token = l_brace,
2054 .data = .{
2055 .lhs = lhs,
2056 .rhs = 0,
2057 },
2058 }),
2059 1 => c.addNode(.{
2060 .tag = .struct_init_one_comma,
2061 .main_token = l_brace,
2062 .data = .{
2063 .lhs = lhs,
2064 .rhs = inits[0],
2065 },
2066 }),
2067 else => blk: {
2068 const span = try c.listToSpan(inits);
2069 break :blk c.addNode(.{
2070 .tag = .struct_init_comma,
2071 .main_token = l_brace,
2072 .data = .{
2073 .lhs = lhs,
2074 .rhs = try c.addExtra(NodeSubRange{
2075 .start = span.start,
2076 .end = span.end,
2077 }),
2078 },
2079 });
2080 },
2081 };
2082 },
2083 .@"anytype" => unreachable, // Handled in renderParams
2084 }
2085}
2086
2087fn renderRecord(c: *Context, node: Node) !NodeIndex {
2088 const payload = @fieldParentPtr(Payload.Record, "base", node.ptr_otherwise).data;
2089 if (payload.layout == .@"packed")
2090 _ = try c.addToken(.keyword_packed, "packed")
2091 else if (payload.layout == .@"extern")
2092 _ = try c.addToken(.keyword_extern, "extern");
2093 const kind_tok = if (node.tag() == .@"struct")
2094 try c.addToken(.keyword_struct, "struct")
2095 else
2096 try c.addToken(.keyword_union, "union");
2097
2098 _ = try c.addToken(.l_brace, "{");
2099
2100 const num_vars = payload.variables.len;
2101 const num_funcs = payload.functions.len;
2102 const total_members = payload.fields.len + num_vars + num_funcs;
2103 const members = try c.gpa.alloc(NodeIndex, @max(total_members, 2));
2104 defer c.gpa.free(members);
2105 members[0] = 0;
2106 members[1] = 0;
2107
2108 for (payload.fields, 0..) |field, i| {
2109 const name_tok = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field.name)});
2110 _ = try c.addToken(.colon, ":");
2111 const type_expr = try renderNode(c, field.type);
2112
2113 const align_expr = if (field.alignment) |alignment| blk: {
2114 _ = try c.addToken(.keyword_align, "align");
2115 _ = try c.addToken(.l_paren, "(");
2116 const align_expr = try c.addNode(.{
2117 .tag = .number_literal,
2118 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{alignment}),
2119 .data = undefined,
2120 });
2121 _ = try c.addToken(.r_paren, ")");
2122 break :blk align_expr;
2123 } else 0;
2124
2125 const value_expr = if (field.default_value) |value| blk: {
2126 _ = try c.addToken(.equal, "=");
2127 break :blk try renderNode(c, value);
2128 } else 0;
2129
2130 members[i] = try c.addNode(if (align_expr == 0) .{
2131 .tag = .container_field_init,
2132 .main_token = name_tok,
2133 .data = .{
2134 .lhs = type_expr,
2135 .rhs = value_expr,
2136 },
2137 } else if (value_expr == 0) .{
2138 .tag = .container_field_align,
2139 .main_token = name_tok,
2140 .data = .{
2141 .lhs = type_expr,
2142 .rhs = align_expr,
2143 },
2144 } else .{
2145 .tag = .container_field,
2146 .main_token = name_tok,
2147 .data = .{
2148 .lhs = type_expr,
2149 .rhs = try c.addExtra(std.zig.Ast.Node.ContainerField{
2150 .align_expr = align_expr,
2151 .value_expr = value_expr,
2152 }),
2153 },
2154 });
2155 _ = try c.addToken(.comma, ",");
2156 }
2157 for (payload.variables, 0..) |variable, i| {
2158 members[payload.fields.len + i] = try renderNode(c, variable);
2159 }
2160 for (payload.functions, 0..) |function, i| {
2161 members[payload.fields.len + num_vars + i] = try renderNode(c, function);
2162 }
2163 _ = try c.addToken(.r_brace, "}");
2164
2165 if (total_members == 0) {
2166 return c.addNode(.{
2167 .tag = .container_decl_two,
2168 .main_token = kind_tok,
2169 .data = .{
2170 .lhs = 0,
2171 .rhs = 0,
2172 },
2173 });
2174 } else if (total_members <= 2) {
2175 return c.addNode(.{
2176 .tag = if (num_funcs == 0) .container_decl_two_trailing else .container_decl_two,
2177 .main_token = kind_tok,
2178 .data = .{
2179 .lhs = members[0],
2180 .rhs = members[1],
2181 },
2182 });
2183 } else {
2184 const span = try c.listToSpan(members);
2185 return c.addNode(.{
2186 .tag = if (num_funcs == 0) .container_decl_trailing else .container_decl,
2187 .main_token = kind_tok,
2188 .data = .{
2189 .lhs = span.start,
2190 .rhs = span.end,
2191 },
2192 });
2193 }
2194}
2195
2196fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeIndex {
2197 return c.addNode(.{
2198 .tag = .field_access,
2199 .main_token = try c.addToken(.period, "."),
2200 .data = .{
2201 .lhs = lhs,
2202 .rhs = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field_name)}),
2203 },
2204 });
2205}
2206
2207fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex {
2208 const l_brace = try c.addToken(.l_brace, "{");
2209 var rendered = try c.gpa.alloc(NodeIndex, @max(inits.len, 1));
2210 defer c.gpa.free(rendered);
2211 rendered[0] = 0;
2212 for (inits, 0..) |init, i| {
2213 rendered[i] = try renderNode(c, init);
2214 _ = try c.addToken(.comma, ",");
2215 }
2216 _ = try c.addToken(.r_brace, "}");
2217 if (inits.len < 2) {
2218 return c.addNode(.{
2219 .tag = .array_init_one_comma,
2220 .main_token = l_brace,
2221 .data = .{
2222 .lhs = lhs,
2223 .rhs = rendered[0],
2224 },
2225 });
2226 } else {
2227 const span = try c.listToSpan(rendered);
2228 return c.addNode(.{
2229 .tag = .array_init_comma,
2230 .main_token = l_brace,
2231 .data = .{
2232 .lhs = lhs,
2233 .rhs = try c.addExtra(NodeSubRange{
2234 .start = span.start,
2235 .end = span.end,
2236 }),
2237 },
2238 });
2239 }
2240}
2241
2242fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
2243 const l_bracket = try c.addToken(.l_bracket, "[");
2244 const len_expr = try c.addNode(.{
2245 .tag = .number_literal,
2246 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{len}),
2247 .data = undefined,
2248 });
2249 _ = try c.addToken(.r_bracket, "]");
2250 const elem_type_expr = try renderNode(c, elem_type);
2251 return c.addNode(.{
2252 .tag = .array_type,
2253 .main_token = l_bracket,
2254 .data = .{
2255 .lhs = len_expr,
2256 .rhs = elem_type_expr,
2257 },
2258 });
2259}
2260
2261fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
2262 const l_bracket = try c.addToken(.l_bracket, "[");
2263 const len_expr = try c.addNode(.{
2264 .tag = .number_literal,
2265 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{len}),
2266 .data = undefined,
2267 });
2268 _ = try c.addToken(.colon, ":");
2269
2270 const sentinel_expr = try c.addNode(.{
2271 .tag = .number_literal,
2272 .main_token = try c.addToken(.number_literal, "0"),
2273 .data = undefined,
2274 });
2275
2276 _ = try c.addToken(.r_bracket, "]");
2277 const elem_type_expr = try renderNode(c, elem_type);
2278 return c.addNode(.{
2279 .tag = .array_type_sentinel,
2280 .main_token = l_bracket,
2281 .data = .{
2282 .lhs = len_expr,
2283 .rhs = try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{
2284 .sentinel = sentinel_expr,
2285 .elem_type = elem_type_expr,
2286 }),
2287 },
2288 });
2289}
2290
2291fn addSemicolonIfNeeded(c: *Context, node: Node) !void {
2292 switch (node.tag()) {
2293 .warning => unreachable,
2294 .var_decl, .var_simple, .arg_redecl, .alias, .block, .empty_block, .block_single, .@"switch", .static_local_var, .mut_str => {},
2295 .while_true => {
2296 const payload = node.castTag(.while_true).?.data;
2297 return addSemicolonIfNotBlock(c, payload);
2298 },
2299 .@"while" => {
2300 const payload = node.castTag(.@"while").?.data;
2301 return addSemicolonIfNotBlock(c, payload.body);
2302 },
2303 .@"if" => {
2304 const payload = node.castTag(.@"if").?.data;
2305 if (payload.@"else") |some|
2306 return addSemicolonIfNeeded(c, some);
2307 return addSemicolonIfNotBlock(c, payload.then);
2308 },
2309 else => _ = try c.addToken(.semicolon, ";"),
2310 }
2311}
2312
2313fn addSemicolonIfNotBlock(c: *Context, node: Node) !void {
2314 switch (node.tag()) {
2315 .block, .empty_block, .block_single => {},
2316 else => _ = try c.addToken(.semicolon, ";"),
2317 }
2318}
2319
2320fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2321 switch (node.tag()) {
2322 .declaration => unreachable,
2323 .null_literal,
2324 .undefined_literal,
2325 .true_literal,
2326 .false_literal,
2327 .return_void,
2328 .zero_literal,
2329 .one_literal,
2330 .void_type,
2331 .noreturn_type,
2332 .@"anytype",
2333 .div_trunc,
2334 .signed_remainder,
2335 .int_cast,
2336 .const_cast,
2337 .volatile_cast,
2338 .as,
2339 .truncate,
2340 .bit_cast,
2341 .float_cast,
2342 .int_from_float,
2343 .float_from_int,
2344 .ptr_from_int,
2345 .std_mem_zeroes,
2346 .int_from_ptr,
2347 .sizeof,
2348 .alignof,
2349 .typeof,
2350 .typeinfo,
2351 .vector,
2352 .helpers_sizeof,
2353 .helpers_cast,
2354 .helpers_promoteIntLiteral,
2355 .helpers_shuffle_vector_index,
2356 .helpers_flexible_array_type,
2357 .std_mem_zeroinit,
2358 .integer_literal,
2359 .float_literal,
2360 .string_literal,
2361 .string_slice,
2362 .char_literal,
2363 .enum_literal,
2364 .identifier,
2365 .fn_identifier,
2366 .field_access,
2367 .ptr_cast,
2368 .type,
2369 .array_access,
2370 .align_cast,
2371 .optional_type,
2372 .c_pointer,
2373 .single_pointer,
2374 .unwrap,
2375 .deref,
2376 .not,
2377 .negate,
2378 .negate_wrap,
2379 .bit_not,
2380 .func,
2381 .call,
2382 .array_type,
2383 .null_sentinel_array_type,
2384 .int_from_bool,
2385 .div_exact,
2386 .offset_of,
2387 .shuffle,
2388 .builtin_extern,
2389 .static_local_var,
2390 .mut_str,
2391 .macro_arithmetic,
2392 => {
2393 // no grouping needed
2394 return renderNode(c, node);
2395 },
2396
2397 .opaque_literal,
2398 .empty_array,
2399 .block_single,
2400 .add,
2401 .add_wrap,
2402 .sub,
2403 .sub_wrap,
2404 .mul,
2405 .mul_wrap,
2406 .div,
2407 .shl,
2408 .shr,
2409 .mod,
2410 .@"and",
2411 .@"or",
2412 .less_than,
2413 .less_than_equal,
2414 .greater_than,
2415 .greater_than_equal,
2416 .equal,
2417 .not_equal,
2418 .bit_and,
2419 .bit_or,
2420 .bit_xor,
2421 .empty_block,
2422 .array_cat,
2423 .array_filler,
2424 .@"if",
2425 .@"struct",
2426 .@"union",
2427 .array_init,
2428 .vector_zero_init,
2429 .tuple,
2430 .container_init,
2431 .container_init_dot,
2432 .block,
2433 .address_of,
2434 => return c.addNode(.{
2435 .tag = .grouped_expression,
2436 .main_token = try c.addToken(.l_paren, "("),
2437 .data = .{
2438 .lhs = try renderNode(c, node),
2439 .rhs = try c.addToken(.r_paren, ")"),
2440 },
2441 }),
2442 .ellipsis3,
2443 .switch_prong,
2444 .warning,
2445 .var_decl,
2446 .fail_decl,
2447 .arg_redecl,
2448 .alias,
2449 .var_simple,
2450 .pub_var_simple,
2451 .enum_constant,
2452 .@"while",
2453 .@"switch",
2454 .@"break",
2455 .break_val,
2456 .pub_inline_fn,
2457 .discard,
2458 .@"continue",
2459 .@"return",
2460 .@"comptime",
2461 .@"defer",
2462 .asm_simple,
2463 .while_true,
2464 .if_not_break,
2465 .switch_else,
2466 .add_assign,
2467 .add_wrap_assign,
2468 .sub_assign,
2469 .sub_wrap_assign,
2470 .mul_assign,
2471 .mul_wrap_assign,
2472 .div_assign,
2473 .shl_assign,
2474 .shr_assign,
2475 .mod_assign,
2476 .bit_and_assign,
2477 .bit_or_assign,
2478 .bit_xor_assign,
2479 .assign,
2480 .helpers_macro,
2481 .import_c_builtin,
2482 => {
2483 // these should never appear in places where grouping might be needed.
2484 unreachable;
2485 },
2486 }
2487}
2488
2489fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2490 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;
2491 return c.addNode(.{
2492 .tag = tag,
2493 .main_token = try c.addToken(tok_tag, bytes),
2494 .data = .{
2495 .lhs = try renderNodeGrouped(c, payload),
2496 .rhs = undefined,
2497 },
2498 });
2499}
2500
2501fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2502 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2503 const lhs = try renderNodeGrouped(c, payload.lhs);
2504 return c.addNode(.{
2505 .tag = tag,
2506 .main_token = try c.addToken(tok_tag, bytes),
2507 .data = .{
2508 .lhs = lhs,
2509 .rhs = try renderNodeGrouped(c, payload.rhs),
2510 },
2511 });
2512}
2513
2514fn renderBinOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2515 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2516 const lhs = try renderNode(c, payload.lhs);
2517 return c.addNode(.{
2518 .tag = tag,
2519 .main_token = try c.addToken(tok_tag, bytes),
2520 .data = .{
2521 .lhs = lhs,
2522 .rhs = try renderNode(c, payload.rhs),
2523 },
2524 });
2525}
2526
2527fn renderStdImport(c: *Context, parts: []const []const u8) !NodeIndex {
2528 const import_tok = try c.addToken(.builtin, "@import");
2529 _ = try c.addToken(.l_paren, "(");
2530 const std_tok = try c.addToken(.string_literal, "\"std\"");
2531 const std_node = try c.addNode(.{
2532 .tag = .string_literal,
2533 .main_token = std_tok,
2534 .data = undefined,
2535 });
2536 _ = try c.addToken(.r_paren, ")");
2537
2538 const import_node = try c.addNode(.{
2539 .tag = .builtin_call_two,
2540 .main_token = import_tok,
2541 .data = .{
2542 .lhs = std_node,
2543 .rhs = 0,
2544 },
2545 });
2546
2547 var access_chain = import_node;
2548 for (parts) |part| {
2549 access_chain = try renderFieldAccess(c, access_chain, part);
2550 }
2551 return access_chain;
2552}
2553
2554fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {
2555 const lparen = try c.addToken(.l_paren, "(");
2556 const res = switch (args.len) {
2557 0 => try c.addNode(.{
2558 .tag = .call_one,
2559 .main_token = lparen,
2560 .data = .{
2561 .lhs = lhs,
2562 .rhs = 0,
2563 },
2564 }),
2565 1 => blk: {
2566 const arg = try renderNode(c, args[0]);
2567 break :blk try c.addNode(.{
2568 .tag = .call_one,
2569 .main_token = lparen,
2570 .data = .{
2571 .lhs = lhs,
2572 .rhs = arg,
2573 },
2574 });
2575 },
2576 else => blk: {
2577 var rendered = try c.gpa.alloc(NodeIndex, args.len);
2578 defer c.gpa.free(rendered);
2579
2580 for (args, 0..) |arg, i| {
2581 if (i != 0) _ = try c.addToken(.comma, ",");
2582 rendered[i] = try renderNode(c, arg);
2583 }
2584 const span = try c.listToSpan(rendered);
2585 break :blk try c.addNode(.{
2586 .tag = .call,
2587 .main_token = lparen,
2588 .data = .{
2589 .lhs = lhs,
2590 .rhs = try c.addExtra(NodeSubRange{
2591 .start = span.start,
2592 .end = span.end,
2593 }),
2594 },
2595 });
2596 },
2597 };
2598 _ = try c.addToken(.r_paren, ")");
2599 return res;
2600}
2601
2602fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !NodeIndex {
2603 const builtin_tok = try c.addToken(.builtin, builtin);
2604 _ = try c.addToken(.l_paren, "(");
2605 var arg_1: NodeIndex = 0;
2606 var arg_2: NodeIndex = 0;
2607 var arg_3: NodeIndex = 0;
2608 var arg_4: NodeIndex = 0;
2609 switch (args.len) {
2610 0 => {},
2611 1 => {
2612 arg_1 = try renderNode(c, args[0]);
2613 },
2614 2 => {
2615 arg_1 = try renderNode(c, args[0]);
2616 _ = try c.addToken(.comma, ",");
2617 arg_2 = try renderNode(c, args[1]);
2618 },
2619 4 => {
2620 arg_1 = try renderNode(c, args[0]);
2621 _ = try c.addToken(.comma, ",");
2622 arg_2 = try renderNode(c, args[1]);
2623 _ = try c.addToken(.comma, ",");
2624 arg_3 = try renderNode(c, args[2]);
2625 _ = try c.addToken(.comma, ",");
2626 arg_4 = try renderNode(c, args[3]);
2627 },
2628 else => unreachable, // expand this function as needed.
2629 }
2630
2631 _ = try c.addToken(.r_paren, ")");
2632 if (args.len <= 2) {
2633 return c.addNode(.{
2634 .tag = .builtin_call_two,
2635 .main_token = builtin_tok,
2636 .data = .{
2637 .lhs = arg_1,
2638 .rhs = arg_2,
2639 },
2640 });
2641 } else {
2642 std.debug.assert(args.len == 4);
2643
2644 const params = try c.listToSpan(&.{ arg_1, arg_2, arg_3, arg_4 });
2645 return c.addNode(.{
2646 .tag = .builtin_call,
2647 .main_token = builtin_tok,
2648 .data = .{
2649 .lhs = params.start,
2650 .rhs = params.end,
2651 },
2652 });
2653 }
2654}
2655
2656fn renderVar(c: *Context, node: Node) !NodeIndex {
2657 const payload = node.castTag(.var_decl).?.data;
2658 if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
2659 if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
2660 if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
2661 if (payload.is_threadlocal) _ = try c.addToken(.keyword_threadlocal, "threadlocal");
2662 const mut_tok = if (payload.is_const)
2663 try c.addToken(.keyword_const, "const")
2664 else
2665 try c.addToken(.keyword_var, "var");
2666 _ = try c.addIdentifier(payload.name);
2667 _ = try c.addToken(.colon, ":");
2668 const type_node = try renderNode(c, payload.type);
2669
2670 const align_node = if (payload.alignment) |some| blk: {
2671 _ = try c.addToken(.keyword_align, "align");
2672 _ = try c.addToken(.l_paren, "(");
2673 const res = try c.addNode(.{
2674 .tag = .number_literal,
2675 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{some}),
2676 .data = undefined,
2677 });
2678 _ = try c.addToken(.r_paren, ")");
2679 break :blk res;
2680 } else 0;
2681
2682 const section_node = if (payload.linksection_string) |some| blk: {
2683 _ = try c.addToken(.keyword_linksection, "linksection");
2684 _ = try c.addToken(.l_paren, "(");
2685 const res = try c.addNode(.{
2686 .tag = .string_literal,
2687 .main_token = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(some)}),
2688 .data = undefined,
2689 });
2690 _ = try c.addToken(.r_paren, ")");
2691 break :blk res;
2692 } else 0;
2693
2694 const init_node = if (payload.init) |some| blk: {
2695 _ = try c.addToken(.equal, "=");
2696 break :blk try renderNode(c, some);
2697 } else 0;
2698 _ = try c.addToken(.semicolon, ";");
2699
2700 if (section_node == 0) {
2701 if (align_node == 0) {
2702 return c.addNode(.{
2703 .tag = .simple_var_decl,
2704 .main_token = mut_tok,
2705 .data = .{
2706 .lhs = type_node,
2707 .rhs = init_node,
2708 },
2709 });
2710 } else {
2711 return c.addNode(.{
2712 .tag = .local_var_decl,
2713 .main_token = mut_tok,
2714 .data = .{
2715 .lhs = try c.addExtra(std.zig.Ast.Node.LocalVarDecl{
2716 .type_node = type_node,
2717 .align_node = align_node,
2718 }),
2719 .rhs = init_node,
2720 },
2721 });
2722 }
2723 } else {
2724 return c.addNode(.{
2725 .tag = .global_var_decl,
2726 .main_token = mut_tok,
2727 .data = .{
2728 .lhs = try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{
2729 .type_node = type_node,
2730 .align_node = align_node,
2731 .section_node = section_node,
2732 .addrspace_node = 0,
2733 }),
2734 .rhs = init_node,
2735 },
2736 });
2737 }
2738}
2739
2740fn renderFunc(c: *Context, node: Node) !NodeIndex {
2741 const payload = node.castTag(.func).?.data;
2742 if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
2743 if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
2744 if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
2745 if (payload.is_inline) _ = try c.addToken(.keyword_inline, "inline");
2746 const fn_token = try c.addToken(.keyword_fn, "fn");
2747 if (payload.name) |some| _ = try c.addIdentifier(some);
2748
2749 const params = try renderParams(c, payload.params, payload.is_var_args);
2750 defer params.deinit();
2751 var span: NodeSubRange = undefined;
2752 if (params.items.len > 1) span = try c.listToSpan(params.items);
2753
2754 const align_expr = if (payload.alignment) |some| blk: {
2755 _ = try c.addToken(.keyword_align, "align");
2756 _ = try c.addToken(.l_paren, "(");
2757 const res = try c.addNode(.{
2758 .tag = .number_literal,
2759 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{some}),
2760 .data = undefined,
2761 });
2762 _ = try c.addToken(.r_paren, ")");
2763 break :blk res;
2764 } else 0;
2765
2766 const section_expr = if (payload.linksection_string) |some| blk: {
2767 _ = try c.addToken(.keyword_linksection, "linksection");
2768 _ = try c.addToken(.l_paren, "(");
2769 const res = try c.addNode(.{
2770 .tag = .string_literal,
2771 .main_token = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(some)}),
2772 .data = undefined,
2773 });
2774 _ = try c.addToken(.r_paren, ")");
2775 break :blk res;
2776 } else 0;
2777
2778 const callconv_expr = if (payload.explicit_callconv) |some| blk: {
2779 _ = try c.addToken(.keyword_callconv, "callconv");
2780 _ = try c.addToken(.l_paren, "(");
2781 _ = try c.addToken(.period, ".");
2782 const res = try c.addNode(.{
2783 .tag = .enum_literal,
2784 .main_token = try c.addTokenFmt(.identifier, "{s}", .{@tagName(some)}),
2785 .data = undefined,
2786 });
2787 _ = try c.addToken(.r_paren, ")");
2788 break :blk res;
2789 } else 0;
2790
2791 const return_type_expr = try renderNode(c, payload.return_type);
2792
2793 const fn_proto = try blk: {
2794 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {
2795 if (params.items.len < 2)
2796 break :blk c.addNode(.{
2797 .tag = .fn_proto_simple,
2798 .main_token = fn_token,
2799 .data = .{
2800 .lhs = params.items[0],
2801 .rhs = return_type_expr,
2802 },
2803 })
2804 else
2805 break :blk c.addNode(.{
2806 .tag = .fn_proto_multi,
2807 .main_token = fn_token,
2808 .data = .{
2809 .lhs = try c.addExtra(NodeSubRange{
2810 .start = span.start,
2811 .end = span.end,
2812 }),
2813 .rhs = return_type_expr,
2814 },
2815 });
2816 }
2817 if (params.items.len < 2)
2818 break :blk c.addNode(.{
2819 .tag = .fn_proto_one,
2820 .main_token = fn_token,
2821 .data = .{
2822 .lhs = try c.addExtra(std.zig.Ast.Node.FnProtoOne{
2823 .param = params.items[0],
2824 .align_expr = align_expr,
2825 .addrspace_expr = 0, // TODO
2826 .section_expr = section_expr,
2827 .callconv_expr = callconv_expr,
2828 }),
2829 .rhs = return_type_expr,
2830 },
2831 })
2832 else
2833 break :blk c.addNode(.{
2834 .tag = .fn_proto,
2835 .main_token = fn_token,
2836 .data = .{
2837 .lhs = try c.addExtra(std.zig.Ast.Node.FnProto{
2838 .params_start = span.start,
2839 .params_end = span.end,
2840 .align_expr = align_expr,
2841 .addrspace_expr = 0, // TODO
2842 .section_expr = section_expr,
2843 .callconv_expr = callconv_expr,
2844 }),
2845 .rhs = return_type_expr,
2846 },
2847 });
2848 };
2849
2850 const payload_body = payload.body orelse {
2851 if (payload.is_extern) {
2852 _ = try c.addToken(.semicolon, ";");
2853 }
2854 return fn_proto;
2855 };
2856 const body = try renderNode(c, payload_body);
2857 return c.addNode(.{
2858 .tag = .fn_decl,
2859 .main_token = fn_token,
2860 .data = .{
2861 .lhs = fn_proto,
2862 .rhs = body,
2863 },
2864 });
2865}
2866
2867fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2868 const payload = node.castTag(.pub_inline_fn).?.data;
2869 _ = try c.addToken(.keyword_pub, "pub");
2870 _ = try c.addToken(.keyword_inline, "inline");
2871 const fn_token = try c.addToken(.keyword_fn, "fn");
2872 _ = try c.addIdentifier(payload.name);
2873
2874 const params = try renderParams(c, payload.params, false);
2875 defer params.deinit();
2876 var span: NodeSubRange = undefined;
2877 if (params.items.len > 1) span = try c.listToSpan(params.items);
2878
2879 const return_type_expr = try renderNodeGrouped(c, payload.return_type);
2880
2881 const fn_proto = blk: {
2882 if (params.items.len < 2) {
2883 break :blk try c.addNode(.{
2884 .tag = .fn_proto_simple,
2885 .main_token = fn_token,
2886 .data = .{
2887 .lhs = params.items[0],
2888 .rhs = return_type_expr,
2889 },
2890 });
2891 } else {
2892 break :blk try c.addNode(.{
2893 .tag = .fn_proto_multi,
2894 .main_token = fn_token,
2895 .data = .{
2896 .lhs = try c.addExtra(std.zig.Ast.Node.SubRange{
2897 .start = span.start,
2898 .end = span.end,
2899 }),
2900 .rhs = return_type_expr,
2901 },
2902 });
2903 }
2904 };
2905 return c.addNode(.{
2906 .tag = .fn_decl,
2907 .main_token = fn_token,
2908 .data = .{
2909 .lhs = fn_proto,
2910 .rhs = try renderNode(c, payload.body),
2911 },
2912 });
2913}
2914
2915fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) {
2916 _ = try c.addToken(.l_paren, "(");
2917 var rendered = try std.ArrayList(NodeIndex).initCapacity(c.gpa, @max(params.len, 1));
2918 errdefer rendered.deinit();
2919
2920 for (params, 0..) |param, i| {
2921 if (i != 0) _ = try c.addToken(.comma, ",");
2922 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
2923 if (param.name) |some| {
2924 _ = try c.addIdentifier(some);
2925 _ = try c.addToken(.colon, ":");
2926 }
2927 if (param.type.tag() == .@"anytype") {
2928 _ = try c.addToken(.keyword_anytype, "anytype");
2929 continue;
2930 }
2931 rendered.appendAssumeCapacity(try renderNode(c, param.type));
2932 }
2933 if (is_var_args) {
2934 if (params.len != 0) _ = try c.addToken(.comma, ",");
2935 _ = try c.addToken(.ellipsis3, "...");
2936 }
2937 _ = try c.addToken(.r_paren, ")");
2938
2939 if (rendered.items.len == 0) rendered.appendAssumeCapacity(0);
2940 return rendered;
2941}
src/Compilation.zig-2
......@@ -4007,8 +4007,6 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module
40074007 }
40084008 var tree = switch (comp.config.c_frontend) {
40094009 .aro => tree: {
4010 const translate_c = @import("aro_translate_c.zig");
4011 _ = translate_c;
40124010 if (true) @panic("TODO");
40134011 break :tree undefined;
40144012 },
src/aro_translate_c.zig deleted-678
......@@ -1,678 +0,0 @@
1const std = @import("std");
2const mem = std.mem;
3const assert = std.debug.assert;
4const CallingConvention = std.builtin.CallingConvention;
5const translate_c = @import("translate_c.zig");
6const aro = @import("aro");
7const Tree = aro.Tree;
8const NodeIndex = Tree.NodeIndex;
9const TokenIndex = Tree.TokenIndex;
10const Type = aro.Type;
11const ast = @import("translate_c/ast.zig");
12const ZigNode = ast.Node;
13const ZigTag = ZigNode.Tag;
14const common = @import("translate_c/common.zig");
15const Error = common.Error;
16const MacroProcessingError = common.MacroProcessingError;
17const TypeError = common.TypeError;
18const TransError = common.TransError;
19const SymbolTable = common.SymbolTable;
20const AliasList = common.AliasList;
21const ResultUsed = common.ResultUsed;
22const Scope = common.ScopeExtra(Context, Type);
23
24const Context = struct {
25 gpa: mem.Allocator,
26 arena: mem.Allocator,
27 decl_table: std.AutoArrayHashMapUnmanaged(usize, []const u8) = .{},
28 alias_list: AliasList,
29 global_scope: *Scope.Root,
30 mangle_count: u32 = 0,
31 /// Table of record decls that have been demoted to opaques.
32 opaque_demotes: std.AutoHashMapUnmanaged(usize, void) = .{},
33 /// Table of unnamed enums and records that are child types of typedefs.
34 unnamed_typedefs: std.AutoHashMapUnmanaged(usize, []const u8) = .{},
35 /// Needed to decide if we are parsing a typename
36 typedefs: std.StringArrayHashMapUnmanaged(void) = .{},
37
38 /// This one is different than the root scope's name table. This contains
39 /// a list of names that we found by visiting all the top level decls without
40 /// translating them. The other maps are updated as we translate; this one is updated
41 /// up front in a pre-processing step.
42 global_names: std.StringArrayHashMapUnmanaged(void) = .{},
43
44 /// This is similar to `global_names`, but contains names which we would
45 /// *like* to use, but do not strictly *have* to if they are unavailable.
46 /// These are relevant to types, which ideally we would name like
47 /// 'struct_foo' with an alias 'foo', but if either of those names is taken,
48 /// may be mangled.
49 /// This is distinct from `global_names` so we can detect at a type
50 /// declaration whether or not the name is available.
51 weak_global_names: std.StringArrayHashMapUnmanaged(void) = .{},
52
53 pattern_list: translate_c.PatternList,
54 tree: Tree,
55 comp: *aro.Compilation,
56 mapper: aro.TypeMapper,
57
58 fn getMangle(c: *Context) u32 {
59 c.mangle_count += 1;
60 return c.mangle_count;
61 }
62
63 /// Convert a clang source location to a file:line:column string
64 fn locStr(c: *Context, loc: TokenIndex) ![]const u8 {
65 _ = c;
66 _ = loc;
67 // const spelling_loc = c.source_manager.getSpellingLoc(loc);
68 // const filename_c = c.source_manager.getFilename(spelling_loc);
69 // const filename = if (filename_c) |s| try c.str(s) else @as([]const u8, "(no file)");
70
71 // const line = c.source_manager.getSpellingLineNumber(spelling_loc);
72 // const column = c.source_manager.getSpellingColumnNumber(spelling_loc);
73 // return std.fmt.allocPrint(c.arena, "{s}:{d}:{d}", .{ filename, line, column });
74 return "somewhere";
75 }
76};
77
78fn maybeSuppressResult(c: *Context, used: ResultUsed, result: ZigNode) TransError!ZigNode {
79 if (used == .used) return result;
80 return ZigTag.discard.create(c.arena, .{ .should_skip = false, .value = result });
81}
82
83fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: ZigNode) !void {
84 const gop = try c.global_scope.sym_table.getOrPut(name);
85 if (!gop.found_existing) {
86 gop.value_ptr.* = decl_node;
87 try c.global_scope.nodes.append(decl_node);
88 }
89}
90
91fn failDecl(c: *Context, loc: TokenIndex, name: []const u8, comptime format: []const u8, args: anytype) Error!void {
92 // location
93 // pub const name = @compileError(msg);
94 const fail_msg = try std.fmt.allocPrint(c.arena, format, args);
95 try addTopLevelDecl(c, name, try ZigTag.fail_decl.create(c.arena, .{ .actual = name, .mangled = fail_msg }));
96 const str = try c.locStr(loc);
97 const location_comment = try std.fmt.allocPrint(c.arena, "// {s}", .{str});
98 try c.global_scope.nodes.append(try ZigTag.warning.create(c.arena, location_comment));
99}
100
101fn warn(c: *Context, scope: *Scope, loc: TokenIndex, comptime format: []const u8, args: anytype) !void {
102 const str = try c.locStr(loc);
103 const value = try std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, .{str} ++ args);
104 try scope.appendNode(try ZigTag.warning.create(c.arena, value));
105}
106
107pub fn translate(
108 gpa: mem.Allocator,
109 comp: *aro.Compilation,
110 args: []const []const u8,
111) !std.zig.Ast {
112 try comp.addDefaultPragmaHandlers();
113 comp.langopts.setEmulatedCompiler(aro.target_util.systemCompiler(comp.target));
114
115 var driver: aro.Driver = .{ .comp = comp };
116 defer driver.deinit();
117
118 var macro_buf = std.ArrayList(u8).init(gpa);
119 defer macro_buf.deinit();
120
121 assert(!try driver.parseArgs(std.io.null_writer, macro_buf.writer(), args));
122 assert(driver.inputs.items.len == 1);
123 const source = driver.inputs.items[0];
124
125 const builtin_macros = try comp.generateBuiltinMacros(.include_system_defines);
126 const user_macros = try comp.addSourceFromBuffer("<command line>", macro_buf.items);
127
128 var pp = try aro.Preprocessor.initDefault(comp);
129 defer pp.deinit();
130
131 try pp.preprocessSources(&.{ source, builtin_macros, user_macros });
132
133 var tree = try pp.parse();
134 defer tree.deinit();
135
136 if (driver.comp.diagnostics.errors != 0) {
137 return error.SemanticAnalyzeFail;
138 }
139
140 const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper();
141 defer mapper.deinit(tree.comp.gpa);
142
143 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
144 defer arena_allocator.deinit();
145 const arena = arena_allocator.allocator();
146
147 var context = Context{
148 .gpa = gpa,
149 .arena = arena,
150 .alias_list = AliasList.init(gpa),
151 .global_scope = try arena.create(Scope.Root),
152 .pattern_list = try translate_c.PatternList.init(gpa),
153 .comp = comp,
154 .mapper = mapper,
155 .tree = tree,
156 };
157 context.global_scope.* = Scope.Root.init(&context);
158 defer {
159 context.decl_table.deinit(gpa);
160 context.alias_list.deinit();
161 context.global_names.deinit(gpa);
162 context.opaque_demotes.deinit(gpa);
163 context.unnamed_typedefs.deinit(gpa);
164 context.typedefs.deinit(gpa);
165 context.global_scope.deinit();
166 context.pattern_list.deinit(gpa);
167 }
168
169 inline for (@typeInfo(std.zig.c_builtins).Struct.decls) |decl| {
170 const builtin_fn = try ZigTag.pub_var_simple.create(arena, .{
171 .name = decl.name,
172 .init = try ZigTag.import_c_builtin.create(arena, decl.name),
173 });
174 try addTopLevelDecl(&context, decl.name, builtin_fn);
175 }
176
177 try prepopulateGlobalNameTable(&context);
178 try transTopLevelDecls(&context);
179
180 for (context.alias_list.items) |alias| {
181 if (!context.global_scope.sym_table.contains(alias.alias)) {
182 const node = try ZigTag.alias.create(arena, .{ .actual = alias.alias, .mangled = alias.name });
183 try addTopLevelDecl(&context, alias.alias, node);
184 }
185 }
186
187 return ast.render(gpa, context.global_scope.nodes.items);
188}
189
190fn prepopulateGlobalNameTable(c: *Context) !void {
191 const node_tags = c.tree.nodes.items(.tag);
192 const node_types = c.tree.nodes.items(.ty);
193 const node_data = c.tree.nodes.items(.data);
194 for (c.tree.root_decls) |node| {
195 const data = node_data[@intFromEnum(node)];
196 const decl_name = switch (node_tags[@intFromEnum(node)]) {
197 .typedef => @panic("TODO"),
198
199 .static_assert,
200 .struct_decl_two,
201 .union_decl_two,
202 .struct_decl,
203 .union_decl,
204 => blk: {
205 const ty = node_types[@intFromEnum(node)];
206 const name_id = ty.data.record.name;
207 break :blk c.mapper.lookup(name_id);
208 },
209
210 .enum_decl_two,
211 .enum_decl,
212 => blk: {
213 const ty = node_types[@intFromEnum(node)];
214 const name_id = ty.data.@"enum".name;
215 break :blk c.mapper.lookup(name_id);
216 },
217
218 .fn_proto,
219 .static_fn_proto,
220 .inline_fn_proto,
221 .inline_static_fn_proto,
222 .fn_def,
223 .static_fn_def,
224 .inline_fn_def,
225 .inline_static_fn_def,
226 .@"var",
227 .static_var,
228 .threadlocal_var,
229 .threadlocal_static_var,
230 .extern_var,
231 .threadlocal_extern_var,
232 => c.tree.tokSlice(data.decl.name),
233 else => unreachable,
234 };
235 try c.global_names.put(c.gpa, decl_name, {});
236 }
237}
238
239fn transTopLevelDecls(c: *Context) !void {
240 const node_tags = c.tree.nodes.items(.tag);
241 const node_data = c.tree.nodes.items(.data);
242 for (c.tree.root_decls) |node| {
243 const data = node_data[@intFromEnum(node)];
244 switch (node_tags[@intFromEnum(node)]) {
245 .typedef => {
246 try transTypeDef(c, &c.global_scope.base, node);
247 },
248
249 .static_assert,
250 .struct_decl_two,
251 .union_decl_two,
252 .struct_decl,
253 .union_decl,
254 => {
255 try transRecordDecl(c, &c.global_scope.base, node);
256 },
257
258 .enum_decl_two => {
259 var fields = [2]NodeIndex{ data.bin.lhs, data.bin.rhs };
260 var field_count: u8 = 0;
261 if (fields[0] != .none) field_count += 1;
262 if (fields[1] != .none) field_count += 1;
263 try transEnumDecl(c, &c.global_scope.base, node, fields[0..field_count]);
264 },
265 .enum_decl => {
266 const fields = c.tree.data[data.range.start..data.range.end];
267 try transEnumDecl(c, &c.global_scope.base, node, fields);
268 },
269
270 .fn_proto,
271 .static_fn_proto,
272 .inline_fn_proto,
273 .inline_static_fn_proto,
274 .fn_def,
275 .static_fn_def,
276 .inline_fn_def,
277 .inline_static_fn_def,
278 => {
279 try transFnDecl(c, node);
280 },
281
282 .@"var",
283 .static_var,
284 .threadlocal_var,
285 .threadlocal_static_var,
286 .extern_var,
287 .threadlocal_extern_var,
288 => {
289 try transVarDecl(c, node, null);
290 },
291 else => unreachable,
292 }
293 }
294}
295
296fn transTypeDef(_: *Context, _: *Scope, _: NodeIndex) Error!void {
297 @panic("TODO");
298}
299fn transRecordDecl(_: *Context, _: *Scope, _: NodeIndex) Error!void {
300 @panic("TODO");
301}
302
303fn transFnDecl(c: *Context, fn_decl: NodeIndex) Error!void {
304 const raw_ty = c.tree.nodes.items(.ty)[@intFromEnum(fn_decl)];
305 const fn_ty = raw_ty.canonicalize(.standard);
306 const node_data = c.tree.nodes.items(.data)[@intFromEnum(fn_decl)];
307 if (c.decl_table.get(@intFromPtr(fn_ty.data.func))) |_|
308 return; // Avoid processing this decl twice
309
310 const fn_name = c.tree.tokSlice(node_data.decl.name);
311 if (c.global_scope.sym_table.contains(fn_name))
312 return; // Avoid processing this decl twice
313
314 const fn_decl_loc = 0; // TODO
315 const has_body = node_data.decl.node != .none;
316 const is_always_inline = has_body and raw_ty.getAttribute(.always_inline) != null;
317 const proto_ctx = FnProtoContext{
318 .fn_name = fn_name,
319 .is_inline = is_always_inline,
320 .is_extern = !has_body,
321 .is_export = switch (c.tree.nodes.items(.tag)[@intFromEnum(fn_decl)]) {
322 .fn_proto, .fn_def => has_body and !is_always_inline,
323
324 .inline_fn_proto, .inline_fn_def, .inline_static_fn_proto, .inline_static_fn_def, .static_fn_proto, .static_fn_def => false,
325
326 else => unreachable,
327 },
328 };
329
330 const proto_node = transFnType(c, &c.global_scope.base, raw_ty, fn_ty, fn_decl_loc, proto_ctx) catch |err| switch (err) {
331 error.UnsupportedType => {
332 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function", .{});
333 },
334 error.OutOfMemory => |e| return e,
335 };
336
337 if (!has_body) {
338 return addTopLevelDecl(c, fn_name, proto_node);
339 }
340 const proto_payload = proto_node.castTag(.func).?;
341
342 // actual function definition with body
343 const body_stmt = node_data.decl.node;
344 var block_scope = try Scope.Block.init(c, &c.global_scope.base, false);
345 block_scope.return_type = fn_ty.data.func.return_type;
346 defer block_scope.deinit();
347
348 var scope = &block_scope.base;
349 _ = &scope;
350
351 var param_id: c_uint = 0;
352 for (proto_payload.data.params, fn_ty.data.func.params) |*param, param_info| {
353 const param_name = param.name orelse {
354 proto_payload.data.is_extern = true;
355 proto_payload.data.is_export = false;
356 proto_payload.data.is_inline = false;
357 try warn(c, &c.global_scope.base, fn_decl_loc, "function {s} parameter has no name, demoted to extern", .{fn_name});
358 return addTopLevelDecl(c, fn_name, proto_node);
359 };
360
361 const is_const = param_info.ty.qual.@"const";
362
363 const mangled_param_name = try block_scope.makeMangledName(c, param_name);
364 param.name = mangled_param_name;
365
366 if (!is_const) {
367 const bare_arg_name = try std.fmt.allocPrint(c.arena, "arg_{s}", .{mangled_param_name});
368 const arg_name = try block_scope.makeMangledName(c, bare_arg_name);
369 param.name = arg_name;
370
371 const redecl_node = try ZigTag.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name });
372 try block_scope.statements.append(redecl_node);
373 }
374 try block_scope.discardVariable(c, mangled_param_name);
375
376 param_id += 1;
377 }
378
379 transCompoundStmtInline(c, body_stmt, &block_scope) catch |err| switch (err) {
380 error.OutOfMemory => |e| return e,
381 error.UnsupportedTranslation,
382 error.UnsupportedType,
383 => {
384 proto_payload.data.is_extern = true;
385 proto_payload.data.is_export = false;
386 proto_payload.data.is_inline = false;
387 try warn(c, &c.global_scope.base, fn_decl_loc, "unable to translate function, demoted to extern", .{});
388 return addTopLevelDecl(c, fn_name, proto_node);
389 },
390 };
391
392 proto_payload.data.body = try block_scope.complete(c);
393 return addTopLevelDecl(c, fn_name, proto_node);
394}
395
396fn transVarDecl(_: *Context, _: NodeIndex, _: ?usize) Error!void {
397 @panic("TODO");
398}
399
400fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes: []const NodeIndex) Error!void {
401 const node_types = c.tree.nodes.items(.ty);
402 const ty = node_types[@intFromEnum(enum_decl)];
403 if (c.decl_table.get(@intFromPtr(ty.data.@"enum"))) |_|
404 return; // Avoid processing this decl twice
405 const toplevel = scope.id == .root;
406 const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined;
407
408 var is_unnamed = false;
409 var bare_name: []const u8 = c.mapper.lookup(ty.data.@"enum".name);
410 var name = bare_name;
411 if (c.unnamed_typedefs.get(@intFromPtr(ty.data.@"enum"))) |typedef_name| {
412 bare_name = typedef_name;
413 name = typedef_name;
414 } else {
415 if (bare_name.len == 0) {
416 bare_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{c.getMangle()});
417 is_unnamed = true;
418 }
419 name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name});
420 }
421 if (!toplevel) name = try bs.makeMangledName(c, name);
422 try c.decl_table.putNoClobber(c.gpa, @intFromPtr(ty.data.@"enum"), name);
423
424 const enum_type_node = if (!ty.data.@"enum".isIncomplete()) blk: {
425 for (ty.data.@"enum".fields, field_nodes) |field, field_node| {
426 var enum_val_name: []const u8 = c.mapper.lookup(field.name);
427 if (!toplevel) {
428 enum_val_name = try bs.makeMangledName(c, enum_val_name);
429 }
430
431 const enum_const_type_node: ?ZigNode = transType(c, scope, field.ty, field.name_tok) catch |err| switch (err) {
432 error.UnsupportedType => null,
433 else => |e| return e,
434 };
435
436 const val = c.tree.value_map.get(field_node).?;
437 const enum_const_def = try ZigTag.enum_constant.create(c.arena, .{
438 .name = enum_val_name,
439 .is_public = toplevel,
440 .type = enum_const_type_node,
441 .value = try transCreateNodeAPInt(c, val),
442 });
443 if (toplevel)
444 try addTopLevelDecl(c, enum_val_name, enum_const_def)
445 else {
446 try scope.appendNode(enum_const_def);
447 try bs.discardVariable(c, enum_val_name);
448 }
449 }
450
451 break :blk transType(c, scope, ty.data.@"enum".tag_ty, 0) catch |err| switch (err) {
452 error.UnsupportedType => {
453 return failDecl(c, 0, name, "unable to translate enum integer type", .{});
454 },
455 else => |e| return e,
456 };
457 } else blk: {
458 try c.opaque_demotes.put(c.gpa, @intFromPtr(ty.data.@"enum"), {});
459 break :blk ZigTag.opaque_literal.init();
460 };
461
462 const is_pub = toplevel and !is_unnamed;
463 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
464 payload.* = .{
465 .base = .{ .tag = ([2]ZigTag{ .var_simple, .pub_var_simple })[@intFromBool(is_pub)] },
466 .data = .{
467 .init = enum_type_node,
468 .name = name,
469 },
470 };
471 const node = ZigNode.initPayload(&payload.base);
472 if (toplevel) {
473 try addTopLevelDecl(c, name, node);
474 if (!is_unnamed)
475 try c.alias_list.append(.{ .alias = bare_name, .name = name });
476 } else {
477 try scope.appendNode(node);
478 if (node.tag() != .pub_var_simple) {
479 try bs.discardVariable(c, name);
480 }
481 }
482}
483
484fn transType(c: *Context, scope: *Scope, raw_ty: Type, source_loc: TokenIndex) TypeError!ZigNode {
485 const ty = raw_ty.canonicalize(.standard);
486 switch (ty.specifier) {
487 .void => return ZigTag.type.create(c.arena, "anyopaque"),
488 .bool => return ZigTag.type.create(c.arena, "bool"),
489 .char => return ZigTag.type.create(c.arena, "c_char"),
490 .schar => return ZigTag.type.create(c.arena, "i8"),
491 .uchar => return ZigTag.type.create(c.arena, "u8"),
492 .short => return ZigTag.type.create(c.arena, "c_short"),
493 .ushort => return ZigTag.type.create(c.arena, "c_ushort"),
494 .int => return ZigTag.type.create(c.arena, "c_int"),
495 .uint => return ZigTag.type.create(c.arena, "c_uint"),
496 .long => return ZigTag.type.create(c.arena, "c_long"),
497 .ulong => return ZigTag.type.create(c.arena, "c_ulong"),
498 .long_long => return ZigTag.type.create(c.arena, "c_longlong"),
499 .ulong_long => return ZigTag.type.create(c.arena, "c_ulonglong"),
500 .int128 => return ZigTag.type.create(c.arena, "i128"),
501 .uint128 => return ZigTag.type.create(c.arena, "u128"),
502 .fp16, .float16 => return ZigTag.type.create(c.arena, "f16"),
503 .float => return ZigTag.type.create(c.arena, "f32"),
504 .double => return ZigTag.type.create(c.arena, "f64"),
505 .long_double => return ZigTag.type.create(c.arena, "c_longdouble"),
506 .float80 => return ZigTag.type.create(c.arena, "f80"),
507 .float128 => return ZigTag.type.create(c.arena, "f128"),
508 .func,
509 .var_args_func,
510 .old_style_func,
511 => return transFnType(c, scope, raw_ty, ty, source_loc, .{}),
512 else => return error.UnsupportedType,
513 }
514}
515
516fn zigAlignment(bit_alignment: u29) u32 {
517 return bit_alignment / 8;
518}
519
520const FnProtoContext = struct {
521 is_pub: bool = false,
522 is_export: bool = false,
523 is_extern: bool = false,
524 is_inline: bool = false,
525 fn_name: ?[]const u8 = null,
526};
527
528fn transFnType(
529 c: *Context,
530 scope: *Scope,
531 raw_ty: Type,
532 fn_ty: Type,
533 source_loc: TokenIndex,
534 ctx: FnProtoContext,
535) !ZigNode {
536 const param_count: usize = fn_ty.data.func.params.len;
537 const fn_params = try c.arena.alloc(ast.Payload.Param, param_count);
538
539 for (fn_ty.data.func.params, fn_params) |param_info, *param_node| {
540 const param_ty = param_info.ty;
541 const is_noalias = param_ty.qual.restrict;
542
543 const param_name: ?[]const u8 = if (param_info.name == .empty)
544 null
545 else
546 c.mapper.lookup(param_info.name);
547
548 const type_node = try transType(c, scope, param_ty, param_info.name_tok);
549 param_node.* = .{
550 .is_noalias = is_noalias,
551 .name = param_name,
552 .type = type_node,
553 };
554 }
555
556 const linksection_string = blk: {
557 if (raw_ty.getAttribute(.section)) |section| {
558 break :blk c.comp.interner.get(section.name.ref()).bytes;
559 }
560 break :blk null;
561 };
562
563 const alignment = if (raw_ty.requestedAlignment(c.comp)) |alignment| zigAlignment(alignment) else null;
564
565 const explicit_callconv = null;
566 // const explicit_callconv = if ((ctx.is_inline or ctx.is_export or ctx.is_extern) and ctx.cc == .C) null else ctx.cc;
567
568 const return_type_node = blk: {
569 if (raw_ty.getAttribute(.noreturn) != null) {
570 break :blk ZigTag.noreturn_type.init();
571 } else {
572 const return_ty = fn_ty.data.func.return_type;
573 if (return_ty.is(.void)) {
574 // convert primitive anyopaque to actual void (only for return type)
575 break :blk ZigTag.void_type.init();
576 } else {
577 break :blk transType(c, scope, return_ty, source_loc) catch |err| switch (err) {
578 error.UnsupportedType => {
579 try warn(c, scope, source_loc, "unsupported function proto return type", .{});
580 return err;
581 },
582 error.OutOfMemory => |e| return e,
583 };
584 }
585 }
586 };
587
588 const payload = try c.arena.create(ast.Payload.Func);
589 payload.* = .{
590 .base = .{ .tag = .func },
591 .data = .{
592 .is_pub = ctx.is_pub,
593 .is_extern = ctx.is_extern,
594 .is_export = ctx.is_export,
595 .is_inline = ctx.is_inline,
596 .is_var_args = switch (fn_ty.specifier) {
597 .func => false,
598 .var_args_func => true,
599 .old_style_func => !ctx.is_export and !ctx.is_inline,
600 else => unreachable,
601 },
602 .name = ctx.fn_name,
603 .linksection_string = linksection_string,
604 .explicit_callconv = explicit_callconv,
605 .params = fn_params,
606 .return_type = return_type_node,
607 .body = null,
608 .alignment = alignment,
609 },
610 };
611 return ZigNode.initPayload(&payload.base);
612}
613
614fn transStmt(c: *Context, node: NodeIndex) TransError!ZigNode {
615 return transExpr(c, node, .unused);
616}
617
618fn transCompoundStmtInline(c: *Context, compound: NodeIndex, block: *Scope.Block) TransError!void {
619 const data = c.tree.nodes.items(.data)[@intFromEnum(compound)];
620 var buf: [2]NodeIndex = undefined;
621 // TODO move these helpers to Aro
622 const stmts = switch (c.tree.nodes.items(.tag)[@intFromEnum(compound)]) {
623 .compound_stmt_two => blk: {
624 if (data.bin.lhs != .none) buf[0] = data.bin.lhs;
625 if (data.bin.rhs != .none) buf[1] = data.bin.rhs;
626 break :blk buf[0 .. @as(u32, @intFromBool(data.bin.lhs != .none)) + @intFromBool(data.bin.rhs != .none)];
627 },
628 .compound_stmt => c.tree.data[data.range.start..data.range.end],
629 else => unreachable,
630 };
631 for (stmts) |stmt| {
632 const result = try transStmt(c, stmt);
633 switch (result.tag()) {
634 .declaration, .empty_block => {},
635 else => try block.statements.append(result),
636 }
637 }
638}
639
640fn transCompoundStmt(c: *Context, scope: *Scope, compound: NodeIndex) TransError!ZigNode {
641 var block_scope = try Scope.Block.init(c, scope, false);
642 defer block_scope.deinit();
643 try transCompoundStmtInline(c, compound, &block_scope);
644 return try block_scope.complete(c);
645}
646
647fn transExpr(c: *Context, node: NodeIndex, result_used: ResultUsed) TransError!ZigNode {
648 std.debug.assert(node != .none);
649 const ty = c.tree.nodes.items(.ty)[@intFromEnum(node)];
650 if (c.tree.value_map.get(node)) |val| {
651 // TODO handle other values
652 const int = try transCreateNodeAPInt(c, val);
653 const as_node = try ZigTag.as.create(c.arena, .{
654 .lhs = try transType(c, undefined, ty, undefined),
655 .rhs = int,
656 });
657 return maybeSuppressResult(c, result_used, as_node);
658 }
659 const node_tags = c.tree.nodes.items(.tag);
660 switch (node_tags[@intFromEnum(node)]) {
661 else => unreachable, // Not an expression.
662 }
663 return .none;
664}
665
666fn transCreateNodeAPInt(c: *Context, int: aro.Value) !ZigNode {
667 var space: aro.Interner.Tag.Int.BigIntSpace = undefined;
668 var big = int.toBigInt(&space, c.comp);
669 const is_negative = !big.positive;
670 big.positive = true;
671
672 const str = big.toStringAlloc(c.arena, 10, .lower) catch |err| switch (err) {
673 error.OutOfMemory => return error.OutOfMemory,
674 };
675 const res = try ZigTag.integer_literal.create(c.arena, str);
676 if (is_negative) return ZigTag.negate.create(c.arena, res);
677 return res;
678}
src/main.zig+84-37
......@@ -294,13 +294,20 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
294294 } else if (mem.eql(u8, cmd, "rc")) {
295295 return cmdRc(gpa, arena, args[1..]);
296296 } else if (mem.eql(u8, cmd, "fmt")) {
297 return jitCmd(gpa, arena, cmd_args, "fmt", "fmt.zig", false);
297 return jitCmd(gpa, arena, cmd_args, .{
298 .cmd_name = "fmt",
299 .root_src_path = "fmt.zig",
300 });
298301 } else if (mem.eql(u8, cmd, "objcopy")) {
299302 return @import("objcopy.zig").cmdObjCopy(gpa, arena, cmd_args);
300303 } else if (mem.eql(u8, cmd, "fetch")) {
301304 return cmdFetch(gpa, arena, cmd_args);
302305 } else if (mem.eql(u8, cmd, "libc")) {
303 return jitCmd(gpa, arena, cmd_args, "libc", "libc.zig", true);
306 return jitCmd(gpa, arena, cmd_args, .{
307 .cmd_name = "libc",
308 .root_src_path = "libc.zig",
309 .prepend_zig_lib_dir_path = true,
310 });
304311 } else if (mem.eql(u8, cmd, "init")) {
305312 return cmdInit(gpa, arena, cmd_args);
306313 } else if (mem.eql(u8, cmd, "targets")) {
......@@ -317,7 +324,10 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
317324 verifyLibcxxCorrectlyLinked();
318325 return @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().writer());
319326 } else if (mem.eql(u8, cmd, "reduce")) {
320 return jitCmd(gpa, arena, cmd_args, "reduce", "reduce.zig", false);
327 return jitCmd(gpa, arena, cmd_args, .{
328 .cmd_name = "reduce",
329 .root_src_path = "reduce.zig",
330 });
321331 } else if (mem.eql(u8, cmd, "zen")) {
322332 return io.getStdOut().writeAll(info_zen);
323333 } else if (mem.eql(u8, cmd, "help") or mem.eql(u8, cmd, "-h") or mem.eql(u8, cmd, "--help")) {
......@@ -4459,7 +4469,13 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
44594469 const digest = if (try man.hit()) man.final() else digest: {
44604470 if (fancy_output) |p| p.cache_hit = false;
44614471 var argv = std.ArrayList([]const u8).init(arena);
4462 try argv.append(@tagName(comp.config.c_frontend)); // argv[0] is program name, actual args start at [1]
4472 switch (comp.config.c_frontend) {
4473 .aro => {},
4474 .clang => {
4475 // argv[0] is program name, actual args start at [1]
4476 try argv.append(@tagName(comp.config.c_frontend));
4477 },
4478 }
44634479
44644480 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});
44654481 defer zig_cache_tmp_dir.close();
......@@ -4484,24 +4500,18 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
44844500 Compilation.dump_argv(argv.items);
44854501 }
44864502
4487 var tree = switch (comp.config.c_frontend) {
4488 .aro => tree: {
4489 const aro = @import("aro");
4490 const translate_c = @import("aro_translate_c.zig");
4491 var aro_comp = aro.Compilation.init(comp.gpa);
4492 defer aro_comp.deinit();
4493
4494 break :tree translate_c.translate(comp.gpa, &aro_comp, argv.items) catch |err| switch (err) {
4495 error.SemanticAnalyzeFail, error.FatalError => {
4496 // TODO convert these to zig errors
4497 aro.Diagnostics.render(&aro_comp, std.io.tty.detectConfig(std.io.getStdErr()));
4498 process.exit(1);
4499 },
4500 error.OutOfMemory => return error.OutOfMemory,
4501 error.StreamTooLong => fatal("StreamTooLong?", .{}),
4502 };
4503 const formatted = switch (comp.config.c_frontend) {
4504 .aro => f: {
4505 var stdout: []u8 = undefined;
4506 try jitCmd(comp.gpa, arena, argv.items, .{
4507 .cmd_name = "aro_translate_c",
4508 .root_src_path = "aro_translate_c.zig",
4509 .depend_on_aro = true,
4510 .capture = &stdout,
4511 });
4512 break :f stdout;
45034513 },
4504 .clang => tree: {
4514 .clang => f: {
45054515 if (!build_options.have_llvm) unreachable;
45064516 const translate_c = @import("translate_c.zig");
45074517
......@@ -4519,7 +4529,7 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
45194529
45204530 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
45214531 var errors = std.zig.ErrorBundle.empty;
4522 break :tree translate_c.translate(
4532 var tree = translate_c.translate(
45234533 comp.gpa,
45244534 new_argv.ptr,
45254535 new_argv.ptr + new_argv.len,
......@@ -4537,9 +4547,10 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
45374547 }
45384548 },
45394549 };
4550 defer tree.deinit(comp.gpa);
4551 break :f try tree.render(arena);
45404552 },
45414553 };
4542 defer tree.deinit(comp.gpa);
45434554
45444555 if (out_dep_path) |dep_file_path| {
45454556 const dep_basename = fs.path.basename(dep_file_path);
......@@ -4560,9 +4571,6 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
45604571 var zig_file = try o_dir.createFile(translated_zig_basename, .{});
45614572 defer zig_file.close();
45624573
4563 const formatted = try tree.render(comp.gpa);
4564 defer comp.gpa.free(formatted);
4565
45664574 try zig_file.writeAll(formatted);
45674575
45684576 man.writeManifest() catch |err| warn("failed to write cache manifest: {s}", .{
......@@ -5522,13 +5530,19 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
55225530 }
55235531}
55245532
5533const JitCmdOptions = struct {
5534 cmd_name: []const u8,
5535 root_src_path: []const u8,
5536 prepend_zig_lib_dir_path: bool = false,
5537 depend_on_aro: bool = false,
5538 capture: ?*[]u8 = null,
5539};
5540
55255541fn jitCmd(
55265542 gpa: Allocator,
55275543 arena: Allocator,
55285544 args: []const []const u8,
5529 cmd_name: []const u8,
5530 root_src_path: []const u8,
5531 prepend_zig_lib_dir_path: bool,
5545 options: JitCmdOptions,
55325546) !void {
55335547 const color: Color = .auto;
55345548
......@@ -5540,7 +5554,7 @@ fn jitCmd(
55405554 };
55415555
55425556 const exe_basename = try std.zig.binNameAlloc(arena, .{
5543 .root_name = cmd_name,
5557 .root_name = options.cmd_name,
55445558 .target = resolved_target.result,
55455559 .output_mode = .Exe,
55465560 });
......@@ -5595,7 +5609,7 @@ fn jitCmd(
55955609 .root_dir = zig_lib_directory,
55965610 .sub_path = "compiler",
55975611 },
5598 .root_src_path = root_src_path,
5612 .root_src_path = options.root_src_path,
55995613 };
56005614
56015615 const config = try Compilation.Config.resolve(.{
......@@ -5623,11 +5637,35 @@ fn jitCmd(
56235637 .builtin_mod = null,
56245638 });
56255639
5640 if (options.depend_on_aro) {
5641 const aro_mod = try Package.Module.create(arena, .{
5642 .global_cache_directory = global_cache_directory,
5643 .paths = .{
5644 .root = .{
5645 .root_dir = zig_lib_directory,
5646 .sub_path = "compiler/aro",
5647 },
5648 .root_src_path = "aro.zig",
5649 },
5650 .fully_qualified_name = "aro",
5651 .cc_argv = &.{},
5652 .inherited = .{
5653 .resolved_target = resolved_target,
5654 .optimize_mode = optimize_mode,
5655 .strip = strip,
5656 },
5657 .global = config,
5658 .parent = null,
5659 .builtin_mod = root_mod.getBuiltinDependency(),
5660 });
5661 try root_mod.deps.put(arena, "aro", aro_mod);
5662 }
5663
56265664 const comp = Compilation.create(gpa, arena, .{
56275665 .zig_lib_directory = zig_lib_directory,
56285666 .local_cache_directory = global_cache_directory,
56295667 .global_cache_directory = global_cache_directory,
5630 .root_name = cmd_name,
5668 .root_name = options.cmd_name,
56315669 .config = config,
56325670 .root_mod = root_mod,
56335671 .main_mod = root_mod,
......@@ -5650,12 +5688,12 @@ fn jitCmd(
56505688 child_argv.appendAssumeCapacity(exe_path);
56515689 }
56525690
5653 if (prepend_zig_lib_dir_path)
5691 if (options.prepend_zig_lib_dir_path)
56545692 child_argv.appendAssumeCapacity(zig_lib_directory.path.?);
56555693
56565694 child_argv.appendSliceAssumeCapacity(args);
56575695
5658 if (process.can_execv) {
5696 if (process.can_execv and options.capture == null) {
56595697 const err = process.execv(gpa, child_argv.items);
56605698 const cmd = try std.mem.join(arena, " ", child_argv.items);
56615699 fatal("the following command failed to execve with '{s}':\n{s}", .{
......@@ -5673,13 +5711,22 @@ fn jitCmd(
56735711
56745712 var child = std.ChildProcess.init(child_argv.items, gpa);
56755713 child.stdin_behavior = .Inherit;
5676 child.stdout_behavior = .Inherit;
5714 child.stdout_behavior = if (options.capture == null) .Inherit else .Pipe;
56775715 child.stderr_behavior = .Inherit;
56785716
5679 const term = try child.spawnAndWait();
5717 try child.spawn();
5718
5719 if (options.capture) |ptr| {
5720 ptr.* = try child.stdout.?.readToEndAlloc(arena, std.math.maxInt(u32));
5721 }
5722
5723 const term = try child.wait();
56805724 switch (term) {
56815725 .Exited => |code| {
5682 if (code == 0) return cleanExit();
5726 if (code == 0) {
5727 if (options.capture != null) return;
5728 return cleanExit();
5729 }
56835730 const cmd = try std.mem.join(arena, " ", child_argv.items);
56845731 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
56855732 },
src/stubs/aro_builtins.zig deleted-35
......@@ -1,35 +0,0 @@
1//! Stub implementation only used when bootstrapping stage2
2//! Keep in sync with deps/aro/build/GenerateDef.zig
3
4pub fn with(comptime Properties: type) type {
5 return struct {
6 tag: Tag = @enumFromInt(0),
7 properties: Properties = undefined,
8 pub const max_param_count = 1;
9 pub const longest_name = 0;
10 pub const data = [_]@This(){.{}};
11 pub inline fn fromName(_: []const u8) ?@This() {
12 return .{};
13 }
14 pub fn nameFromUniqueIndex(_: u16, _: []u8) []u8 {
15 return "";
16 }
17 pub fn uniqueIndex(_: []const u8) ?u16 {
18 return null;
19 }
20 pub const Tag = enum(u16) { _ };
21 pub fn nameFromTag(_: Tag) NameBuf {
22 return .{};
23 }
24 pub fn tagFromName(name: []const u8) ?Tag {
25 var res: u16 = 0;
26 for (name) |c| res +%= c;
27 return @enumFromInt(res);
28 }
29 pub const NameBuf = struct {
30 pub fn span(_: *const NameBuf) []const u8 {
31 return "";
32 }
33 };
34 };
35}
src/stubs/aro_messages.zig deleted-508
......@@ -1,508 +0,0 @@
1//! Stub implementation only used when bootstrapping stage2
2//! Keep in sync with deps/aro/build/GenerateDef.zig
3
4pub fn with(comptime Properties: type) type {
5 return struct {
6 pub const Tag = enum {
7 todo,
8 error_directive,
9 warning_directive,
10 elif_without_if,
11 elif_after_else,
12 elifdef_without_if,
13 elifdef_after_else,
14 elifndef_without_if,
15 elifndef_after_else,
16 else_without_if,
17 else_after_else,
18 endif_without_if,
19 unknown_pragma,
20 line_simple_digit,
21 line_invalid_filename,
22 unterminated_conditional_directive,
23 invalid_preprocessing_directive,
24 macro_name_missing,
25 extra_tokens_directive_end,
26 expected_value_in_expr,
27 closing_paren,
28 to_match_paren,
29 to_match_brace,
30 to_match_bracket,
31 header_str_closing,
32 header_str_match,
33 string_literal_in_pp_expr,
34 float_literal_in_pp_expr,
35 defined_as_macro_name,
36 macro_name_must_be_identifier,
37 whitespace_after_macro_name,
38 hash_hash_at_start,
39 hash_hash_at_end,
40 pasting_formed_invalid,
41 missing_paren_param_list,
42 unterminated_macro_param_list,
43 invalid_token_param_list,
44 expected_comma_param_list,
45 hash_not_followed_param,
46 expected_filename,
47 empty_filename,
48 expected_invalid,
49 expected_eof,
50 expected_token,
51 expected_expr,
52 expected_integer_constant_expr,
53 missing_type_specifier,
54 missing_type_specifier_c23,
55 multiple_storage_class,
56 static_assert_failure,
57 static_assert_failure_message,
58 expected_type,
59 cannot_combine_spec,
60 duplicate_decl_spec,
61 restrict_non_pointer,
62 expected_external_decl,
63 expected_ident_or_l_paren,
64 missing_declaration,
65 func_not_in_root,
66 illegal_initializer,
67 extern_initializer,
68 spec_from_typedef,
69 param_before_var_args,
70 void_only_param,
71 void_param_qualified,
72 void_must_be_first_param,
73 invalid_storage_on_param,
74 threadlocal_non_var,
75 func_spec_non_func,
76 illegal_storage_on_func,
77 illegal_storage_on_global,
78 expected_stmt,
79 func_cannot_return_func,
80 func_cannot_return_array,
81 undeclared_identifier,
82 not_callable,
83 unsupported_str_cat,
84 static_func_not_global,
85 implicit_func_decl,
86 unknown_builtin,
87 implicit_builtin,
88 implicit_builtin_header_note,
89 expected_param_decl,
90 invalid_old_style_params,
91 expected_fn_body,
92 invalid_void_param,
93 unused_value,
94 continue_not_in_loop,
95 break_not_in_loop_or_switch,
96 unreachable_code,
97 duplicate_label,
98 previous_label,
99 undeclared_label,
100 case_not_in_switch,
101 duplicate_switch_case,
102 multiple_default,
103 previous_case,
104 expected_arguments,
105 expected_arguments_old,
106 expected_at_least_arguments,
107 invalid_static_star,
108 static_non_param,
109 array_qualifiers,
110 star_non_param,
111 variable_len_array_file_scope,
112 useless_static,
113 negative_array_size,
114 array_incomplete_elem,
115 array_func_elem,
116 static_non_outermost_array,
117 qualifier_non_outermost_array,
118 unterminated_macro_arg_list,
119 unknown_warning,
120 overflow,
121 int_literal_too_big,
122 indirection_ptr,
123 addr_of_rvalue,
124 addr_of_bitfield,
125 not_assignable,
126 ident_or_l_brace,
127 empty_enum,
128 redefinition,
129 previous_definition,
130 expected_identifier,
131 expected_str_literal,
132 expected_str_literal_in,
133 parameter_missing,
134 empty_record,
135 empty_record_size,
136 wrong_tag,
137 expected_parens_around_typename,
138 alignof_expr,
139 invalid_alignof,
140 invalid_sizeof,
141 macro_redefined,
142 generic_qual_type,
143 generic_array_type,
144 generic_func_type,
145 generic_duplicate,
146 generic_duplicate_here,
147 generic_duplicate_default,
148 generic_no_match,
149 escape_sequence_overflow,
150 invalid_universal_character,
151 incomplete_universal_character,
152 multichar_literal_warning,
153 invalid_multichar_literal,
154 wide_multichar_literal,
155 char_lit_too_wide,
156 char_too_large,
157 must_use_struct,
158 must_use_union,
159 must_use_enum,
160 redefinition_different_sym,
161 redefinition_incompatible,
162 redefinition_of_parameter,
163 invalid_bin_types,
164 comparison_ptr_int,
165 comparison_distinct_ptr,
166 incompatible_pointers,
167 invalid_argument_un,
168 incompatible_assign,
169 implicit_ptr_to_int,
170 invalid_cast_to_float,
171 invalid_cast_to_pointer,
172 invalid_cast_type,
173 qual_cast,
174 invalid_index,
175 invalid_subscript,
176 array_after,
177 array_before,
178 statement_int,
179 statement_scalar,
180 func_should_return,
181 incompatible_return,
182 incompatible_return_sign,
183 implicit_int_to_ptr,
184 func_does_not_return,
185 void_func_returns_value,
186 incompatible_arg,
187 incompatible_ptr_arg,
188 incompatible_ptr_arg_sign,
189 parameter_here,
190 atomic_array,
191 atomic_func,
192 atomic_incomplete,
193 addr_of_register,
194 variable_incomplete_ty,
195 parameter_incomplete_ty,
196 tentative_array,
197 deref_incomplete_ty_ptr,
198 alignas_on_func,
199 alignas_on_param,
200 minimum_alignment,
201 maximum_alignment,
202 negative_alignment,
203 align_ignored,
204 zero_align_ignored,
205 non_pow2_align,
206 pointer_mismatch,
207 static_assert_not_constant,
208 static_assert_missing_message,
209 pre_c23_compat,
210 unbound_vla,
211 array_too_large,
212 incompatible_ptr_init,
213 incompatible_ptr_init_sign,
214 incompatible_ptr_assign,
215 incompatible_ptr_assign_sign,
216 vla_init,
217 func_init,
218 incompatible_init,
219 empty_scalar_init,
220 excess_scalar_init,
221 excess_str_init,
222 excess_struct_init,
223 excess_array_init,
224 str_init_too_long,
225 arr_init_too_long,
226 invalid_typeof,
227 division_by_zero,
228 division_by_zero_macro,
229 builtin_choose_cond,
230 alignas_unavailable,
231 case_val_unavailable,
232 enum_val_unavailable,
233 incompatible_array_init,
234 array_init_str,
235 initializer_overrides,
236 previous_initializer,
237 invalid_array_designator,
238 negative_array_designator,
239 oob_array_designator,
240 invalid_field_designator,
241 no_such_field_designator,
242 empty_aggregate_init_braces,
243 ptr_init_discards_quals,
244 ptr_assign_discards_quals,
245 ptr_ret_discards_quals,
246 ptr_arg_discards_quals,
247 unknown_attribute,
248 ignored_attribute,
249 invalid_fallthrough,
250 cannot_apply_attribute_to_statement,
251 builtin_macro_redefined,
252 feature_check_requires_identifier,
253 missing_tok_builtin,
254 gnu_label_as_value,
255 expected_record_ty,
256 member_expr_not_ptr,
257 member_expr_ptr,
258 no_such_member,
259 malformed_warning_check,
260 invalid_computed_goto,
261 pragma_warning_message,
262 pragma_error_message,
263 pragma_message,
264 pragma_requires_string_literal,
265 poisoned_identifier,
266 pragma_poison_identifier,
267 pragma_poison_macro,
268 newline_eof,
269 empty_translation_unit,
270 omitting_parameter_name,
271 non_int_bitfield,
272 negative_bitwidth,
273 zero_width_named_field,
274 bitfield_too_big,
275 invalid_utf8,
276 implicitly_unsigned_literal,
277 invalid_preproc_operator,
278 invalid_preproc_expr_start,
279 c99_compat,
280 unexpected_character,
281 invalid_identifier_start_char,
282 unicode_zero_width,
283 unicode_homoglyph,
284 meaningless_asm_qual,
285 duplicate_asm_qual,
286 invalid_asm_str,
287 dollar_in_identifier_extension,
288 dollars_in_identifiers,
289 expanded_from_here,
290 skipping_macro_backtrace,
291 pragma_operator_string_literal,
292 unknown_gcc_pragma,
293 unknown_gcc_pragma_directive,
294 predefined_top_level,
295 incompatible_va_arg,
296 too_many_scalar_init_braces,
297 uninitialized_in_own_init,
298 gnu_statement_expression,
299 stmt_expr_not_allowed_file_scope,
300 gnu_imaginary_constant,
301 plain_complex,
302 complex_int,
303 qual_on_ret_type,
304 cli_invalid_standard,
305 cli_invalid_target,
306 cli_invalid_emulate,
307 cli_unknown_arg,
308 cli_error,
309 cli_unused_link_object,
310 cli_unknown_linker,
311 extra_semi,
312 func_field,
313 vla_field,
314 field_incomplete_ty,
315 flexible_in_union,
316 flexible_non_final,
317 flexible_in_empty,
318 duplicate_member,
319 binary_integer_literal,
320 gnu_va_macro,
321 builtin_must_be_called,
322 va_start_not_in_func,
323 va_start_fixed_args,
324 va_start_not_last_param,
325 attribute_not_enough_args,
326 attribute_too_many_args,
327 attribute_arg_invalid,
328 unknown_attr_enum,
329 attribute_requires_identifier,
330 declspec_not_enabled,
331 declspec_attr_not_supported,
332 deprecated_declarations,
333 deprecated_note,
334 unavailable,
335 unavailable_note,
336 warning_attribute,
337 error_attribute,
338 ignored_record_attr,
339 backslash_newline_escape,
340 array_size_non_int,
341 cast_to_smaller_int,
342 gnu_switch_range,
343 empty_case_range,
344 non_standard_escape_char,
345 invalid_pp_stringify_escape,
346 vla,
347 float_overflow_conversion,
348 float_out_of_range,
349 float_zero_conversion,
350 float_value_changed,
351 float_to_int,
352 const_decl_folded,
353 const_decl_folded_vla,
354 redefinition_of_typedef,
355 undefined_macro,
356 fn_macro_undefined,
357 preprocessing_directive_only,
358 missing_lparen_after_builtin,
359 offsetof_ty,
360 offsetof_incomplete,
361 offsetof_array,
362 pragma_pack_lparen,
363 pragma_pack_rparen,
364 pragma_pack_unknown_action,
365 pragma_pack_show,
366 pragma_pack_int,
367 pragma_pack_int_ident,
368 pragma_pack_undefined_pop,
369 pragma_pack_empty_stack,
370 cond_expr_type,
371 too_many_includes,
372 enumerator_too_small,
373 enumerator_too_large,
374 include_next,
375 include_next_outside_header,
376 enumerator_overflow,
377 enum_not_representable,
378 enum_too_large,
379 enum_fixed,
380 enum_prev_nonfixed,
381 enum_prev_fixed,
382 enum_different_explicit_ty,
383 enum_not_representable_fixed,
384 transparent_union_wrong_type,
385 transparent_union_one_field,
386 transparent_union_size,
387 transparent_union_size_note,
388 designated_init_invalid,
389 designated_init_needed,
390 ignore_common,
391 ignore_nocommon,
392 non_string_ignored,
393 local_variable_attribute,
394 ignore_cold,
395 ignore_hot,
396 ignore_noinline,
397 ignore_always_inline,
398 invalid_noreturn,
399 nodiscard_unused,
400 warn_unused_result,
401 invalid_vec_elem_ty,
402 vec_size_not_multiple,
403 invalid_imag,
404 invalid_real,
405 zero_length_array,
406 old_style_flexible_struct,
407 comma_deletion_va_args,
408 main_return_type,
409 expansion_to_defined,
410 invalid_int_suffix,
411 invalid_float_suffix,
412 invalid_octal_digit,
413 invalid_binary_digit,
414 exponent_has_no_digits,
415 hex_floating_constant_requires_exponent,
416 sizeof_returns_zero,
417 declspec_not_allowed_after_declarator,
418 declarator_name_tok,
419 type_not_supported_on_target,
420 bit_int,
421 unsigned_bit_int_too_small,
422 signed_bit_int_too_small,
423 bit_int_too_big,
424 keyword_macro,
425 ptr_arithmetic_incomplete,
426 callconv_not_supported,
427 pointer_arith_void,
428 sizeof_array_arg,
429 array_address_to_bool,
430 string_literal_to_bool,
431 constant_expression_conversion_not_allowed,
432 invalid_object_cast,
433 cli_invalid_fp_eval_method,
434 suggest_pointer_for_invalid_fp16,
435 bitint_suffix,
436 auto_type_extension,
437 auto_type_not_allowed,
438 auto_type_requires_initializer,
439 auto_type_requires_single_declarator,
440 auto_type_requires_plain_declarator,
441 invalid_cast_to_auto_type,
442 auto_type_from_bitfield,
443 array_of_auto_type,
444 auto_type_with_init_list,
445 missing_semicolon,
446 tentative_definition_incomplete,
447 forward_declaration_here,
448 gnu_union_cast,
449 invalid_union_cast,
450 cast_to_incomplete_type,
451 invalid_source_epoch,
452 fuse_ld_path,
453 invalid_rtlib,
454 unsupported_rtlib_gcc,
455 invalid_unwindlib,
456 incompatible_unwindlib,
457 gnu_asm_disabled,
458 extension_token_used,
459 complex_component_init,
460 complex_prefix_postfix_op,
461 not_floating_type,
462 argument_types_differ,
463 ms_search_rule,
464 ctrl_z_eof,
465 illegal_char_encoding_warning,
466 illegal_char_encoding_error,
467 ucn_basic_char_error,
468 ucn_basic_char_warning,
469 ucn_control_char_error,
470 ucn_control_char_warning,
471 c89_ucn_in_literal,
472 four_char_char_literal,
473 multi_char_char_literal,
474 missing_hex_escape,
475 unknown_escape_sequence,
476 attribute_requires_string,
477 unterminated_string_literal_warning,
478 unterminated_string_literal_error,
479 empty_char_literal_warning,
480 empty_char_literal_error,
481 unterminated_char_literal_warning,
482 unterminated_char_literal_error,
483 unterminated_comment,
484 def_no_proto_deprecated,
485 passing_args_to_kr,
486 unknown_type_name,
487 label_compound_end,
488 u8_char_lit,
489 malformed_embed_param,
490 malformed_embed_limit,
491 duplicate_embed_param,
492 unsupported_embed_param,
493 invalid_compound_literal_storage_class,
494 va_opt_lparen,
495 va_opt_rparen,
496 attribute_int_out_of_range,
497 identifier_not_normalized,
498 c23_auto_plain_declarator,
499 c23_auto_single_declarator,
500 c32_auto_requires_initializer,
501 c23_auto_scalar_init,
502
503 pub fn property(_: Tag) Properties {
504 return undefined;
505 }
506 };
507 };
508}
src/stubs/aro_names.zig deleted-10
......@@ -1,10 +0,0 @@
1//! Stub implementation only used when bootstrapping stage2
2//! Keep in sync with deps/aro/build/GenerateDef.zig
3
4pub fn with(comptime _: type) type {
5 return struct {
6 pub inline fn fromName(_: []const u8) ?@This() {
7 return null;
8 }
9 };
10}
src/stubs/aro_options.zig deleted-1
......@@ -1 +0,0 @@
1pub const version_str: []const u8 = "bootstrap-stub";
src/translate_c.zig+6-287
......@@ -8,10 +8,10 @@ const CallingConvention = std.builtin.CallingConvention;
88const clang = @import("clang.zig");
99const aro = @import("aro");
1010const CToken = aro.Tokenizer.Token;
11const ast = @import("translate_c/ast.zig");
1211const Node = ast.Node;
1312const Tag = Node.Tag;
14const common = @import("translate_c/common.zig");
13const common = @import("aro_translate_c");
14const ast = common.ast;
1515const Error = common.Error;
1616const MacroProcessingError = common.MacroProcessingError;
1717const TypeError = common.TypeError;
......@@ -20,10 +20,8 @@ const SymbolTable = common.SymbolTable;
2020const AliasList = common.AliasList;
2121const ResultUsed = common.ResultUsed;
2222const Scope = common.ScopeExtra(Context, clang.QualType);
23
24// Maps macro parameter names to token position, for determining if different
25// identifiers refer to the same positional argument in different macros.
26const ArgsPositionMap = std.StringArrayHashMapUnmanaged(usize);
23const PatternList = common.PatternList;
24const MacroSlicer = common.MacroSlicer;
2725
2826pub const Context = struct {
2927 gpa: mem.Allocator,
......@@ -5093,265 +5091,6 @@ pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, compti
50935091 try c.global_scope.nodes.append(try Tag.warning.create(c.arena, location_comment));
50945092}
50955093
5096pub const PatternList = struct {
5097 patterns: []Pattern,
5098
5099 /// Templates must be function-like macros
5100 /// first element is macro source, second element is the name of the function
5101 /// in std.lib.zig.c_translation.Macros which implements it
5102 const templates = [_][2][]const u8{
5103 [2][]const u8{ "f_SUFFIX(X) (X ## f)", "F_SUFFIX" },
5104 [2][]const u8{ "F_SUFFIX(X) (X ## F)", "F_SUFFIX" },
5105
5106 [2][]const u8{ "u_SUFFIX(X) (X ## u)", "U_SUFFIX" },
5107 [2][]const u8{ "U_SUFFIX(X) (X ## U)", "U_SUFFIX" },
5108
5109 [2][]const u8{ "l_SUFFIX(X) (X ## l)", "L_SUFFIX" },
5110 [2][]const u8{ "L_SUFFIX(X) (X ## L)", "L_SUFFIX" },
5111
5112 [2][]const u8{ "ul_SUFFIX(X) (X ## ul)", "UL_SUFFIX" },
5113 [2][]const u8{ "uL_SUFFIX(X) (X ## uL)", "UL_SUFFIX" },
5114 [2][]const u8{ "Ul_SUFFIX(X) (X ## Ul)", "UL_SUFFIX" },
5115 [2][]const u8{ "UL_SUFFIX(X) (X ## UL)", "UL_SUFFIX" },
5116
5117 [2][]const u8{ "ll_SUFFIX(X) (X ## ll)", "LL_SUFFIX" },
5118 [2][]const u8{ "LL_SUFFIX(X) (X ## LL)", "LL_SUFFIX" },
5119
5120 [2][]const u8{ "ull_SUFFIX(X) (X ## ull)", "ULL_SUFFIX" },
5121 [2][]const u8{ "uLL_SUFFIX(X) (X ## uLL)", "ULL_SUFFIX" },
5122 [2][]const u8{ "Ull_SUFFIX(X) (X ## Ull)", "ULL_SUFFIX" },
5123 [2][]const u8{ "ULL_SUFFIX(X) (X ## ULL)", "ULL_SUFFIX" },
5124
5125 [2][]const u8{ "f_SUFFIX(X) X ## f", "F_SUFFIX" },
5126 [2][]const u8{ "F_SUFFIX(X) X ## F", "F_SUFFIX" },
5127
5128 [2][]const u8{ "u_SUFFIX(X) X ## u", "U_SUFFIX" },
5129 [2][]const u8{ "U_SUFFIX(X) X ## U", "U_SUFFIX" },
5130
5131 [2][]const u8{ "l_SUFFIX(X) X ## l", "L_SUFFIX" },
5132 [2][]const u8{ "L_SUFFIX(X) X ## L", "L_SUFFIX" },
5133
5134 [2][]const u8{ "ul_SUFFIX(X) X ## ul", "UL_SUFFIX" },
5135 [2][]const u8{ "uL_SUFFIX(X) X ## uL", "UL_SUFFIX" },
5136 [2][]const u8{ "Ul_SUFFIX(X) X ## Ul", "UL_SUFFIX" },
5137 [2][]const u8{ "UL_SUFFIX(X) X ## UL", "UL_SUFFIX" },
5138
5139 [2][]const u8{ "ll_SUFFIX(X) X ## ll", "LL_SUFFIX" },
5140 [2][]const u8{ "LL_SUFFIX(X) X ## LL", "LL_SUFFIX" },
5141
5142 [2][]const u8{ "ull_SUFFIX(X) X ## ull", "ULL_SUFFIX" },
5143 [2][]const u8{ "uLL_SUFFIX(X) X ## uLL", "ULL_SUFFIX" },
5144 [2][]const u8{ "Ull_SUFFIX(X) X ## Ull", "ULL_SUFFIX" },
5145 [2][]const u8{ "ULL_SUFFIX(X) X ## ULL", "ULL_SUFFIX" },
5146
5147 [2][]const u8{ "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL" },
5148 [2][]const u8{ "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL" },
5149
5150 [2][]const u8{
5151 \\wl_container_of(ptr, sample, member) \
5152 \\(__typeof__(sample))((char *)(ptr) - \
5153 \\ offsetof(__typeof__(*sample), member))
5154 ,
5155 "WL_CONTAINER_OF",
5156 },
5157
5158 [2][]const u8{ "IGNORE_ME(X) ((void)(X))", "DISCARD" },
5159 [2][]const u8{ "IGNORE_ME(X) (void)(X)", "DISCARD" },
5160 [2][]const u8{ "IGNORE_ME(X) ((const void)(X))", "DISCARD" },
5161 [2][]const u8{ "IGNORE_ME(X) (const void)(X)", "DISCARD" },
5162 [2][]const u8{ "IGNORE_ME(X) ((volatile void)(X))", "DISCARD" },
5163 [2][]const u8{ "IGNORE_ME(X) (volatile void)(X)", "DISCARD" },
5164 [2][]const u8{ "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD" },
5165 [2][]const u8{ "IGNORE_ME(X) (const volatile void)(X)", "DISCARD" },
5166 [2][]const u8{ "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD" },
5167 [2][]const u8{ "IGNORE_ME(X) (volatile const void)(X)", "DISCARD" },
5168 };
5169
5170 /// Assumes that `ms` represents a tokenized function-like macro.
5171 fn buildArgsHash(allocator: mem.Allocator, ms: MacroSlicer, hash: *ArgsPositionMap) MacroProcessingError!void {
5172 assert(ms.tokens.len > 2);
5173 assert(ms.tokens[0].id == .identifier or ms.tokens[0].id == .extended_identifier);
5174 assert(ms.tokens[1].id == .l_paren);
5175
5176 var i: usize = 2;
5177 while (true) : (i += 1) {
5178 const token = ms.tokens[i];
5179 switch (token.id) {
5180 .r_paren => break,
5181 .comma => continue,
5182 .identifier, .extended_identifier => {
5183 const identifier = ms.slice(token);
5184 try hash.put(allocator, identifier, i);
5185 },
5186 else => return error.UnexpectedMacroToken,
5187 }
5188 }
5189 }
5190
5191 const Pattern = struct {
5192 tokens: []const CToken,
5193 source: []const u8,
5194 impl: []const u8,
5195 args_hash: ArgsPositionMap,
5196
5197 fn init(self: *Pattern, allocator: mem.Allocator, template: [2][]const u8) Error!void {
5198 const source = template[0];
5199 const impl = template[1];
5200
5201 var tok_list = std.ArrayList(CToken).init(allocator);
5202 defer tok_list.deinit();
5203 try tokenizeMacro(source, &tok_list);
5204 const tokens = try allocator.dupe(CToken, tok_list.items);
5205
5206 self.* = .{
5207 .tokens = tokens,
5208 .source = source,
5209 .impl = impl,
5210 .args_hash = .{},
5211 };
5212 const ms = MacroSlicer{ .source = source, .tokens = tokens };
5213 buildArgsHash(allocator, ms, &self.args_hash) catch |err| switch (err) {
5214 error.UnexpectedMacroToken => unreachable,
5215 else => |e| return e,
5216 };
5217 }
5218
5219 fn deinit(self: *Pattern, allocator: mem.Allocator) void {
5220 self.args_hash.deinit(allocator);
5221 allocator.free(self.tokens);
5222 }
5223
5224 /// This function assumes that `ms` has already been validated to contain a function-like
5225 /// macro, and that the parsed template macro in `self` also contains a function-like
5226 /// macro. Please review this logic carefully if changing that assumption. Two
5227 /// function-like macros are considered equivalent if and only if they contain the same
5228 /// list of tokens, modulo parameter names.
5229 pub fn isEquivalent(self: Pattern, ms: MacroSlicer, args_hash: ArgsPositionMap) bool {
5230 if (self.tokens.len != ms.tokens.len) return false;
5231 if (args_hash.count() != self.args_hash.count()) return false;
5232
5233 var i: usize = 2;
5234 while (self.tokens[i].id != .r_paren) : (i += 1) {}
5235
5236 const pattern_slicer = MacroSlicer{ .source = self.source, .tokens = self.tokens };
5237 while (i < self.tokens.len) : (i += 1) {
5238 const pattern_token = self.tokens[i];
5239 const macro_token = ms.tokens[i];
5240 if (pattern_token.id != macro_token.id) return false;
5241
5242 const pattern_bytes = pattern_slicer.slice(pattern_token);
5243 const macro_bytes = ms.slice(macro_token);
5244 switch (pattern_token.id) {
5245 .identifier, .extended_identifier => {
5246 const pattern_arg_index = self.args_hash.get(pattern_bytes);
5247 const macro_arg_index = args_hash.get(macro_bytes);
5248
5249 if (pattern_arg_index == null and macro_arg_index == null) {
5250 if (!mem.eql(u8, pattern_bytes, macro_bytes)) return false;
5251 } else if (pattern_arg_index != null and macro_arg_index != null) {
5252 if (pattern_arg_index.? != macro_arg_index.?) return false;
5253 } else {
5254 return false;
5255 }
5256 },
5257 .string_literal, .char_literal, .pp_num => {
5258 if (!mem.eql(u8, pattern_bytes, macro_bytes)) return false;
5259 },
5260 else => {
5261 // other tags correspond to keywords and operators that do not contain a "payload"
5262 // that can vary
5263 },
5264 }
5265 }
5266 return true;
5267 }
5268 };
5269
5270 pub fn init(allocator: mem.Allocator) Error!PatternList {
5271 const patterns = try allocator.alloc(Pattern, templates.len);
5272 for (templates, 0..) |template, i| {
5273 try patterns[i].init(allocator, template);
5274 }
5275 return PatternList{ .patterns = patterns };
5276 }
5277
5278 pub fn deinit(self: *PatternList, allocator: mem.Allocator) void {
5279 for (self.patterns) |*pattern| pattern.deinit(allocator);
5280 allocator.free(self.patterns);
5281 }
5282
5283 pub fn match(self: PatternList, allocator: mem.Allocator, ms: MacroSlicer) Error!?Pattern {
5284 var args_hash: ArgsPositionMap = .{};
5285 defer args_hash.deinit(allocator);
5286
5287 buildArgsHash(allocator, ms, &args_hash) catch |err| switch (err) {
5288 error.UnexpectedMacroToken => return null,
5289 else => |e| return e,
5290 };
5291
5292 for (self.patterns) |pattern| if (pattern.isEquivalent(ms, args_hash)) return pattern;
5293 return null;
5294 }
5295};
5296
5297const MacroSlicer = struct {
5298 source: []const u8,
5299 tokens: []const CToken,
5300 fn slice(self: MacroSlicer, token: CToken) []const u8 {
5301 return self.source[token.start..token.end];
5302 }
5303};
5304
5305// Testing here instead of test/translate_c.zig allows us to also test that the
5306// mapped function exists in `std.zig.c_translation.Macros`
5307test "Macro matching" {
5308 const helper = struct {
5309 const MacroFunctions = std.zig.c_translation.Macros;
5310 fn checkMacro(allocator: mem.Allocator, pattern_list: PatternList, source: []const u8, comptime expected_match: ?[]const u8) !void {
5311 var tok_list = std.ArrayList(CToken).init(allocator);
5312 defer tok_list.deinit();
5313 try tokenizeMacro(source, &tok_list);
5314 const macro_slicer = MacroSlicer{ .source = source, .tokens = tok_list.items };
5315 const matched = try pattern_list.match(allocator, macro_slicer);
5316 if (expected_match) |expected| {
5317 try testing.expectEqualStrings(expected, matched.?.impl);
5318 try testing.expect(@hasDecl(MacroFunctions, expected));
5319 } else {
5320 try testing.expectEqual(@as(@TypeOf(matched), null), matched);
5321 }
5322 }
5323 };
5324 const allocator = std.testing.allocator;
5325 var pattern_list = try PatternList.init(allocator);
5326 defer pattern_list.deinit(allocator);
5327
5328 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## F)", "F_SUFFIX");
5329 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## U)", "U_SUFFIX");
5330 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## L)", "L_SUFFIX");
5331 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## LL)", "LL_SUFFIX");
5332 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## UL)", "UL_SUFFIX");
5333 try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## ULL)", "ULL_SUFFIX");
5334 try helper.checkMacro(allocator, pattern_list,
5335 \\container_of(a, b, c) \
5336 \\(__typeof__(b))((char *)(a) - \
5337 \\ offsetof(__typeof__(*b), c))
5338 , "WL_CONTAINER_OF");
5339
5340 try helper.checkMacro(allocator, pattern_list, "NO_MATCH(X, Y) (X + Y)", null);
5341 try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL");
5342 try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL");
5343 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (void)(X)", "DISCARD");
5344 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((void)(X))", "DISCARD");
5345 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const void)(X)", "DISCARD");
5346 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const void)(X))", "DISCARD");
5347 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile void)(X)", "DISCARD");
5348 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile void)(X))", "DISCARD");
5349 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const volatile void)(X)", "DISCARD");
5350 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD");
5351 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile const void)(X)", "DISCARD");
5352 try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD");
5353}
5354
53555094const MacroCtx = struct {
53565095 source: []const u8,
53575096 list: []const CToken,
......@@ -5392,7 +5131,7 @@ const MacroCtx = struct {
53925131 }
53935132
53945133 fn makeSlicer(self: *const MacroCtx) MacroSlicer {
5395 return MacroSlicer{ .source = self.source, .tokens = self.list };
5134 return .{ .source = self.source, .tokens = self.list };
53965135 }
53975136
53985137 const MacroTranslateError = union(enum) {
......@@ -5432,26 +5171,6 @@ const MacroCtx = struct {
54325171 }
54335172};
54345173
5435fn tokenizeMacro(source: []const u8, tok_list: *std.ArrayList(CToken)) Error!void {
5436 var tokenizer: aro.Tokenizer = .{
5437 .buf = source,
5438 .source = .unused,
5439 .langopts = .{},
5440 };
5441 while (true) {
5442 const tok = tokenizer.next();
5443 switch (tok.id) {
5444 .whitespace => continue,
5445 .nl, .eof => {
5446 try tok_list.append(tok);
5447 break;
5448 },
5449 else => {},
5450 }
5451 try tok_list.append(tok);
5452 }
5453}
5454
54555174fn getMacroText(unit: *const clang.ASTUnit, c: *const Context, macro: *const clang.MacroDefinitionRecord) ![]const u8 {
54565175 const begin_loc = macro.getSourceRange_getBegin();
54575176 const end_loc = clang.Lexer.getLocForEndOfToken(macro.getSourceRange_getEnd(), c.source_manager, unit);
......@@ -5491,7 +5210,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
54915210
54925211 const source = try getMacroText(unit, c, macro);
54935212
5494 try tokenizeMacro(source, &tok_list);
5213 try common.tokenizeMacro(source, &tok_list);
54955214
54965215 var macro_ctx = MacroCtx{
54975216 .source = source,
src/translate_c/ast.zig deleted-2942
......@@ -1,2942 +0,0 @@
1const std = @import("std");
2const Type = @import("../type.zig").Type;
3const Allocator = std.mem.Allocator;
4
5pub const Node = extern union {
6 /// If the tag value is less than Tag.no_payload_count, then no pointer
7 /// dereference is needed.
8 tag_if_small_enough: usize,
9 ptr_otherwise: *Payload,
10
11 pub const Tag = enum {
12 /// Declarations add themselves to the correct scopes and should not be emitted as this tag.
13 declaration,
14 null_literal,
15 undefined_literal,
16 /// opaque {}
17 opaque_literal,
18 true_literal,
19 false_literal,
20 empty_block,
21 return_void,
22 zero_literal,
23 one_literal,
24 void_type,
25 noreturn_type,
26 @"anytype",
27 @"continue",
28 @"break",
29 // After this, the tag requires a payload.
30
31 integer_literal,
32 float_literal,
33 string_literal,
34 char_literal,
35 enum_literal,
36 /// "string"[0..end]
37 string_slice,
38 identifier,
39 fn_identifier,
40 @"if",
41 /// if (!operand) break;
42 if_not_break,
43 @"while",
44 /// while (true) operand
45 while_true,
46 @"switch",
47 /// else => operand,
48 switch_else,
49 /// items => body,
50 switch_prong,
51 break_val,
52 @"return",
53 field_access,
54 array_access,
55 call,
56 var_decl,
57 /// const name = struct { init }
58 static_local_var,
59 /// var name = init.*
60 mut_str,
61 func,
62 warning,
63 @"struct",
64 @"union",
65 @"comptime",
66 @"defer",
67 array_init,
68 tuple,
69 container_init,
70 container_init_dot,
71 helpers_cast,
72 /// _ = operand;
73 discard,
74
75 // a + b
76 add,
77 // a = b
78 add_assign,
79 // c = (a = b)
80 add_wrap,
81 add_wrap_assign,
82 sub,
83 sub_assign,
84 sub_wrap,
85 sub_wrap_assign,
86 mul,
87 mul_assign,
88 mul_wrap,
89 mul_wrap_assign,
90 div,
91 div_assign,
92 shl,
93 shl_assign,
94 shr,
95 shr_assign,
96 mod,
97 mod_assign,
98 @"and",
99 @"or",
100 less_than,
101 less_than_equal,
102 greater_than,
103 greater_than_equal,
104 equal,
105 not_equal,
106 bit_and,
107 bit_and_assign,
108 bit_or,
109 bit_or_assign,
110 bit_xor,
111 bit_xor_assign,
112 array_cat,
113 ellipsis3,
114 assign,
115
116 /// @import("std").zig.c_builtins.<name>
117 import_c_builtin,
118 /// @intCast(operand)
119 int_cast,
120 /// @constCast(operand)
121 const_cast,
122 /// @volatileCast(operand)
123 volatile_cast,
124 /// @import("std").zig.c_translation.promoteIntLiteral(value, type, base)
125 helpers_promoteIntLiteral,
126 /// @import("std").zig.c_translation.signedRemainder(lhs, rhs)
127 signed_remainder,
128 /// @divTrunc(lhs, rhs)
129 div_trunc,
130 /// @intFromBool(operand)
131 int_from_bool,
132 /// @as(lhs, rhs)
133 as,
134 /// @truncate(operand)
135 truncate,
136 /// @bitCast(operand)
137 bit_cast,
138 /// @floatCast(operand)
139 float_cast,
140 /// @intFromFloat(operand)
141 int_from_float,
142 /// @floatFromInt(operand)
143 float_from_int,
144 /// @ptrFromInt(operand)
145 ptr_from_int,
146 /// @intFromPtr(operand)
147 int_from_ptr,
148 /// @alignCast(operand)
149 align_cast,
150 /// @ptrCast(operand)
151 ptr_cast,
152 /// @divExact(lhs, rhs)
153 div_exact,
154 /// @offsetOf(lhs, rhs)
155 offset_of,
156 /// @splat(operand)
157 vector_zero_init,
158 /// @shuffle(type, a, b, mask)
159 shuffle,
160 /// @extern(ty, .{ .name = n })
161 builtin_extern,
162
163 /// @import("std").zig.c_translation.MacroArithmetic.<op>(lhs, rhs)
164 macro_arithmetic,
165
166 asm_simple,
167
168 negate,
169 negate_wrap,
170 bit_not,
171 not,
172 address_of,
173 /// .?
174 unwrap,
175 /// .*
176 deref,
177
178 block,
179 /// { operand }
180 block_single,
181
182 sizeof,
183 alignof,
184 typeof,
185 typeinfo,
186 type,
187
188 optional_type,
189 c_pointer,
190 single_pointer,
191 array_type,
192 null_sentinel_array_type,
193
194 /// @import("std").zig.c_translation.sizeof(operand)
195 helpers_sizeof,
196 /// @import("std").zig.c_translation.FlexibleArrayType(lhs, rhs)
197 helpers_flexible_array_type,
198 /// @import("std").zig.c_translation.shuffleVectorIndex(lhs, rhs)
199 helpers_shuffle_vector_index,
200 /// @import("std").zig.c_translation.Macro.<operand>
201 helpers_macro,
202 /// @Vector(lhs, rhs)
203 vector,
204 /// @import("std").mem.zeroes(operand)
205 std_mem_zeroes,
206 /// @import("std").mem.zeroInit(lhs, rhs)
207 std_mem_zeroinit,
208 // pub const name = @compileError(msg);
209 fail_decl,
210 // var actual = mangled;
211 arg_redecl,
212 /// pub const alias = actual;
213 alias,
214 /// const name = init;
215 var_simple,
216 /// pub const name = init;
217 pub_var_simple,
218 /// pub? const name (: type)? = value
219 enum_constant,
220
221 /// pub inline fn name(params) return_type body
222 pub_inline_fn,
223
224 /// [0]type{}
225 empty_array,
226 /// [1]type{val} ** count
227 array_filler,
228
229 pub const last_no_payload_tag = Tag.@"break";
230 pub const no_payload_count = @intFromEnum(last_no_payload_tag) + 1;
231
232 pub fn Type(comptime t: Tag) type {
233 return switch (t) {
234 .declaration,
235 .null_literal,
236 .undefined_literal,
237 .opaque_literal,
238 .true_literal,
239 .false_literal,
240 .empty_block,
241 .return_void,
242 .zero_literal,
243 .one_literal,
244 .void_type,
245 .noreturn_type,
246 .@"anytype",
247 .@"continue",
248 .@"break",
249 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
250
251 .std_mem_zeroes,
252 .@"return",
253 .@"comptime",
254 .@"defer",
255 .asm_simple,
256 .negate,
257 .negate_wrap,
258 .bit_not,
259 .not,
260 .optional_type,
261 .address_of,
262 .unwrap,
263 .deref,
264 .int_from_ptr,
265 .empty_array,
266 .while_true,
267 .if_not_break,
268 .switch_else,
269 .block_single,
270 .helpers_sizeof,
271 .int_from_bool,
272 .sizeof,
273 .alignof,
274 .typeof,
275 .typeinfo,
276 .align_cast,
277 .truncate,
278 .bit_cast,
279 .float_cast,
280 .int_from_float,
281 .float_from_int,
282 .ptr_from_int,
283 .ptr_cast,
284 .int_cast,
285 .const_cast,
286 .volatile_cast,
287 .vector_zero_init,
288 => Payload.UnOp,
289
290 .add,
291 .add_assign,
292 .add_wrap,
293 .add_wrap_assign,
294 .sub,
295 .sub_assign,
296 .sub_wrap,
297 .sub_wrap_assign,
298 .mul,
299 .mul_assign,
300 .mul_wrap,
301 .mul_wrap_assign,
302 .div,
303 .div_assign,
304 .shl,
305 .shl_assign,
306 .shr,
307 .shr_assign,
308 .mod,
309 .mod_assign,
310 .@"and",
311 .@"or",
312 .less_than,
313 .less_than_equal,
314 .greater_than,
315 .greater_than_equal,
316 .equal,
317 .not_equal,
318 .bit_and,
319 .bit_and_assign,
320 .bit_or,
321 .bit_or_assign,
322 .bit_xor,
323 .bit_xor_assign,
324 .div_trunc,
325 .signed_remainder,
326 .as,
327 .array_cat,
328 .ellipsis3,
329 .assign,
330 .array_access,
331 .std_mem_zeroinit,
332 .helpers_flexible_array_type,
333 .helpers_shuffle_vector_index,
334 .vector,
335 .div_exact,
336 .offset_of,
337 .helpers_cast,
338 => Payload.BinOp,
339
340 .integer_literal,
341 .float_literal,
342 .string_literal,
343 .char_literal,
344 .enum_literal,
345 .identifier,
346 .fn_identifier,
347 .warning,
348 .type,
349 .helpers_macro,
350 .import_c_builtin,
351 => Payload.Value,
352 .discard => Payload.Discard,
353 .@"if" => Payload.If,
354 .@"while" => Payload.While,
355 .@"switch", .array_init, .switch_prong => Payload.Switch,
356 .break_val => Payload.BreakVal,
357 .call => Payload.Call,
358 .var_decl => Payload.VarDecl,
359 .func => Payload.Func,
360 .@"struct", .@"union" => Payload.Record,
361 .tuple => Payload.TupleInit,
362 .container_init => Payload.ContainerInit,
363 .container_init_dot => Payload.ContainerInitDot,
364 .helpers_promoteIntLiteral => Payload.PromoteIntLiteral,
365 .block => Payload.Block,
366 .c_pointer, .single_pointer => Payload.Pointer,
367 .array_type, .null_sentinel_array_type => Payload.Array,
368 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
369 .var_simple, .pub_var_simple, .static_local_var, .mut_str => Payload.SimpleVarDecl,
370 .enum_constant => Payload.EnumConstant,
371 .array_filler => Payload.ArrayFiller,
372 .pub_inline_fn => Payload.PubInlineFn,
373 .field_access => Payload.FieldAccess,
374 .string_slice => Payload.StringSlice,
375 .shuffle => Payload.Shuffle,
376 .builtin_extern => Payload.Extern,
377 .macro_arithmetic => Payload.MacroArithmetic,
378 };
379 }
380
381 pub fn init(comptime t: Tag) Node {
382 comptime std.debug.assert(@intFromEnum(t) < Tag.no_payload_count);
383 return .{ .tag_if_small_enough = @intFromEnum(t) };
384 }
385
386 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Node {
387 const ptr = try ally.create(t.Type());
388 ptr.* = .{
389 .base = .{ .tag = t },
390 .data = data,
391 };
392 return Node{ .ptr_otherwise = &ptr.base };
393 }
394
395 pub fn Data(comptime t: Tag) type {
396 return std.meta.fieldInfo(t.Type(), .data).type;
397 }
398 };
399
400 pub fn tag(self: Node) Tag {
401 if (self.tag_if_small_enough < Tag.no_payload_count) {
402 return @as(Tag, @enumFromInt(@as(std.meta.Tag(Tag), @intCast(self.tag_if_small_enough))));
403 } else {
404 return self.ptr_otherwise.tag;
405 }
406 }
407
408 pub fn castTag(self: Node, comptime t: Tag) ?*t.Type() {
409 if (self.tag_if_small_enough < Tag.no_payload_count)
410 return null;
411
412 if (self.ptr_otherwise.tag == t)
413 return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);
414
415 return null;
416 }
417
418 pub fn initPayload(payload: *Payload) Node {
419 std.debug.assert(@intFromEnum(payload.tag) >= Tag.no_payload_count);
420 return .{ .ptr_otherwise = payload };
421 }
422
423 pub fn isNoreturn(node: Node, break_counts: bool) bool {
424 switch (node.tag()) {
425 .block => {
426 const block_node = node.castTag(.block).?;
427 if (block_node.data.stmts.len == 0) return false;
428
429 const last = block_node.data.stmts[block_node.data.stmts.len - 1];
430 return last.isNoreturn(break_counts);
431 },
432 .@"switch" => {
433 const switch_node = node.castTag(.@"switch").?;
434
435 for (switch_node.data.cases) |case| {
436 const body = if (case.castTag(.switch_else)) |some|
437 some.data
438 else if (case.castTag(.switch_prong)) |some|
439 some.data.cond
440 else
441 unreachable;
442
443 if (!body.isNoreturn(break_counts)) return false;
444 }
445 return true;
446 },
447 .@"return", .return_void => return true,
448 .@"break" => if (break_counts) return true,
449 else => {},
450 }
451 return false;
452 }
453};
454
455pub const Payload = struct {
456 tag: Node.Tag,
457
458 pub const Value = struct {
459 base: Payload,
460 data: []const u8,
461 };
462
463 pub const UnOp = struct {
464 base: Payload,
465 data: Node,
466 };
467
468 pub const BinOp = struct {
469 base: Payload,
470 data: struct {
471 lhs: Node,
472 rhs: Node,
473 },
474 };
475
476 pub const Discard = struct {
477 base: Payload,
478 data: struct {
479 should_skip: bool,
480 value: Node,
481 },
482 };
483
484 pub const If = struct {
485 base: Payload,
486 data: struct {
487 cond: Node,
488 then: Node,
489 @"else": ?Node,
490 },
491 };
492
493 pub const While = struct {
494 base: Payload,
495 data: struct {
496 cond: Node,
497 body: Node,
498 cont_expr: ?Node,
499 },
500 };
501
502 pub const Switch = struct {
503 base: Payload,
504 data: struct {
505 cond: Node,
506 cases: []Node,
507 },
508 };
509
510 pub const BreakVal = struct {
511 base: Payload,
512 data: struct {
513 label: ?[]const u8,
514 val: Node,
515 },
516 };
517
518 pub const Call = struct {
519 base: Payload,
520 data: struct {
521 lhs: Node,
522 args: []Node,
523 },
524 };
525
526 pub const VarDecl = struct {
527 base: Payload,
528 data: struct {
529 is_pub: bool,
530 is_const: bool,
531 is_extern: bool,
532 is_export: bool,
533 is_threadlocal: bool,
534 alignment: ?c_uint,
535 linksection_string: ?[]const u8,
536 name: []const u8,
537 type: Node,
538 init: ?Node,
539 },
540 };
541
542 pub const Func = struct {
543 base: Payload,
544 data: struct {
545 is_pub: bool,
546 is_extern: bool,
547 is_export: bool,
548 is_inline: bool,
549 is_var_args: bool,
550 name: ?[]const u8,
551 linksection_string: ?[]const u8,
552 explicit_callconv: ?std.builtin.CallingConvention,
553 params: []Param,
554 return_type: Node,
555 body: ?Node,
556 alignment: ?c_uint,
557 },
558 };
559
560 pub const Param = struct {
561 is_noalias: bool,
562 name: ?[]const u8,
563 type: Node,
564 };
565
566 pub const Record = struct {
567 base: Payload,
568 data: struct {
569 layout: enum { @"packed", @"extern", none },
570 fields: []Field,
571 functions: []Node,
572 variables: []Node,
573 },
574
575 pub const Field = struct {
576 name: []const u8,
577 type: Node,
578 alignment: ?c_uint,
579 default_value: ?Node,
580 };
581 };
582
583 pub const TupleInit = struct {
584 base: Payload,
585 data: []Node,
586 };
587
588 pub const ContainerInit = struct {
589 base: Payload,
590 data: struct {
591 lhs: Node,
592 inits: []Initializer,
593 },
594
595 pub const Initializer = struct {
596 name: []const u8,
597 value: Node,
598 };
599 };
600
601 pub const ContainerInitDot = struct {
602 base: Payload,
603 data: []Initializer,
604
605 pub const Initializer = struct {
606 name: []const u8,
607 value: Node,
608 };
609 };
610
611 pub const Block = struct {
612 base: Payload,
613 data: struct {
614 label: ?[]const u8,
615 stmts: []Node,
616 },
617 };
618
619 pub const Array = struct {
620 base: Payload,
621 data: ArrayTypeInfo,
622
623 pub const ArrayTypeInfo = struct {
624 elem_type: Node,
625 len: usize,
626 };
627 };
628
629 pub const Pointer = struct {
630 base: Payload,
631 data: struct {
632 elem_type: Node,
633 is_const: bool,
634 is_volatile: bool,
635 },
636 };
637
638 pub const ArgRedecl = struct {
639 base: Payload,
640 data: struct {
641 actual: []const u8,
642 mangled: []const u8,
643 },
644 };
645
646 pub const SimpleVarDecl = struct {
647 base: Payload,
648 data: struct {
649 name: []const u8,
650 init: Node,
651 },
652 };
653
654 pub const EnumConstant = struct {
655 base: Payload,
656 data: struct {
657 name: []const u8,
658 is_public: bool,
659 type: ?Node,
660 value: Node,
661 },
662 };
663
664 pub const ArrayFiller = struct {
665 base: Payload,
666 data: struct {
667 type: Node,
668 filler: Node,
669 count: usize,
670 },
671 };
672
673 pub const PubInlineFn = struct {
674 base: Payload,
675 data: struct {
676 name: []const u8,
677 params: []Param,
678 return_type: Node,
679 body: Node,
680 },
681 };
682
683 pub const FieldAccess = struct {
684 base: Payload,
685 data: struct {
686 lhs: Node,
687 field_name: []const u8,
688 },
689 };
690
691 pub const PromoteIntLiteral = struct {
692 base: Payload,
693 data: struct {
694 value: Node,
695 type: Node,
696 base: Node,
697 },
698 };
699
700 pub const StringSlice = struct {
701 base: Payload,
702 data: struct {
703 string: Node,
704 end: usize,
705 },
706 };
707
708 pub const Shuffle = struct {
709 base: Payload,
710 data: struct {
711 element_type: Node,
712 a: Node,
713 b: Node,
714 mask_vector: Node,
715 },
716 };
717
718 pub const Extern = struct {
719 base: Payload,
720 data: struct {
721 type: Node,
722 name: Node,
723 },
724 };
725
726 pub const MacroArithmetic = struct {
727 base: Payload,
728 data: struct {
729 op: Operator,
730 lhs: Node,
731 rhs: Node,
732 },
733
734 pub const Operator = enum { div, rem };
735 };
736};
737
738/// Converts the nodes into a Zig Ast.
739/// Caller must free the source slice.
740pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
741 var ctx = Context{
742 .gpa = gpa,
743 .buf = std.ArrayList(u8).init(gpa),
744 };
745 defer ctx.buf.deinit();
746 defer ctx.nodes.deinit(gpa);
747 defer ctx.extra_data.deinit(gpa);
748 defer ctx.tokens.deinit(gpa);
749
750 // Estimate that each top level node has 10 child nodes.
751 const estimated_node_count = nodes.len * 10;
752 try ctx.nodes.ensureTotalCapacity(gpa, estimated_node_count);
753 // Estimate that each each node has 2 tokens.
754 const estimated_tokens_count = estimated_node_count * 2;
755 try ctx.tokens.ensureTotalCapacity(gpa, estimated_tokens_count);
756 // Estimate that each each token is 3 bytes long.
757 const estimated_buf_len = estimated_tokens_count * 3;
758 try ctx.buf.ensureTotalCapacity(estimated_buf_len);
759
760 ctx.nodes.appendAssumeCapacity(.{
761 .tag = .root,
762 .main_token = 0,
763 .data = .{
764 .lhs = undefined,
765 .rhs = undefined,
766 },
767 });
768
769 const root_members = blk: {
770 var result = std.ArrayList(NodeIndex).init(gpa);
771 defer result.deinit();
772
773 for (nodes) |node| {
774 const res = try renderNode(&ctx, node);
775 if (node.tag() == .warning) continue;
776 try result.append(res);
777 }
778 break :blk try ctx.listToSpan(result.items);
779 };
780
781 ctx.nodes.items(.data)[0] = .{
782 .lhs = root_members.start,
783 .rhs = root_members.end,
784 };
785
786 try ctx.tokens.append(gpa, .{
787 .tag = .eof,
788 .start = @as(u32, @intCast(ctx.buf.items.len)),
789 });
790
791 return std.zig.Ast{
792 .source = try ctx.buf.toOwnedSliceSentinel(0),
793 .tokens = ctx.tokens.toOwnedSlice(),
794 .nodes = ctx.nodes.toOwnedSlice(),
795 .extra_data = try ctx.extra_data.toOwnedSlice(gpa),
796 .errors = &.{},
797 .mode = .zig,
798 };
799}
800
801const NodeIndex = std.zig.Ast.Node.Index;
802const NodeSubRange = std.zig.Ast.Node.SubRange;
803const TokenIndex = std.zig.Ast.TokenIndex;
804const TokenTag = std.zig.Token.Tag;
805
806const Context = struct {
807 gpa: Allocator,
808 buf: std.ArrayList(u8),
809 nodes: std.zig.Ast.NodeList = .{},
810 extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
811 tokens: std.zig.Ast.TokenList = .{},
812
813 fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
814 const start_index = c.buf.items.len;
815 try c.buf.writer().print(format ++ " ", args);
816
817 try c.tokens.append(c.gpa, .{
818 .tag = tag,
819 .start = @as(u32, @intCast(start_index)),
820 });
821
822 return @as(u32, @intCast(c.tokens.len - 1));
823 }
824
825 fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
826 return c.addTokenFmt(tag, "{s}", .{bytes});
827 }
828
829 fn addIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex {
830 if (std.zig.primitives.isPrimitive(bytes))
831 return c.addTokenFmt(.identifier, "@\"{s}\"", .{bytes});
832 return c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(bytes)});
833 }
834
835 fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange {
836 try c.extra_data.appendSlice(c.gpa, list);
837 return NodeSubRange{
838 .start = @as(NodeIndex, @intCast(c.extra_data.items.len - list.len)),
839 .end = @as(NodeIndex, @intCast(c.extra_data.items.len)),
840 };
841 }
842
843 fn addNode(c: *Context, elem: std.zig.Ast.Node) Allocator.Error!NodeIndex {
844 const result = @as(NodeIndex, @intCast(c.nodes.len));
845 try c.nodes.append(c.gpa, elem);
846 return result;
847 }
848
849 fn addExtra(c: *Context, extra: anytype) Allocator.Error!NodeIndex {
850 const fields = std.meta.fields(@TypeOf(extra));
851 try c.extra_data.ensureUnusedCapacity(c.gpa, fields.len);
852 const result = @as(u32, @intCast(c.extra_data.items.len));
853 inline for (fields) |field| {
854 comptime std.debug.assert(field.type == NodeIndex);
855 c.extra_data.appendAssumeCapacity(@field(extra, field.name));
856 }
857 return result;
858 }
859};
860
861fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
862 var result = std.ArrayList(NodeIndex).init(c.gpa);
863 defer result.deinit();
864
865 for (nodes) |node| {
866 const res = try renderNode(c, node);
867 if (node.tag() == .warning) continue;
868 try result.append(res);
869 }
870
871 return try c.listToSpan(result.items);
872}
873
874fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
875 switch (node.tag()) {
876 .declaration => unreachable,
877 .warning => {
878 const payload = node.castTag(.warning).?.data;
879 try c.buf.appendSlice(payload);
880 try c.buf.append('\n');
881 return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
882 },
883 .helpers_cast => {
884 const payload = node.castTag(.helpers_cast).?.data;
885 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "cast" });
886 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
887 },
888 .helpers_promoteIntLiteral => {
889 const payload = node.castTag(.helpers_promoteIntLiteral).?.data;
890 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "promoteIntLiteral" });
891 return renderCall(c, import_node, &.{ payload.type, payload.value, payload.base });
892 },
893 .helpers_sizeof => {
894 const payload = node.castTag(.helpers_sizeof).?.data;
895 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "sizeof" });
896 return renderCall(c, import_node, &.{payload});
897 },
898 .std_mem_zeroes => {
899 const payload = node.castTag(.std_mem_zeroes).?.data;
900 const import_node = try renderStdImport(c, &.{ "mem", "zeroes" });
901 return renderCall(c, import_node, &.{payload});
902 },
903 .std_mem_zeroinit => {
904 const payload = node.castTag(.std_mem_zeroinit).?.data;
905 const import_node = try renderStdImport(c, &.{ "mem", "zeroInit" });
906 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
907 },
908 .helpers_flexible_array_type => {
909 const payload = node.castTag(.helpers_flexible_array_type).?.data;
910 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "FlexibleArrayType" });
911 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
912 },
913 .helpers_shuffle_vector_index => {
914 const payload = node.castTag(.helpers_shuffle_vector_index).?.data;
915 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "shuffleVectorIndex" });
916 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
917 },
918 .vector => {
919 const payload = node.castTag(.vector).?.data;
920 return renderBuiltinCall(c, "@Vector", &.{ payload.lhs, payload.rhs });
921 },
922 .call => {
923 const payload = node.castTag(.call).?.data;
924 // Cosmetic: avoids an unnecesary address_of on most function calls.
925 const lhs = if (payload.lhs.tag() == .fn_identifier)
926 try c.addNode(.{
927 .tag = .identifier,
928 .main_token = try c.addIdentifier(payload.lhs.castTag(.fn_identifier).?.data),
929 .data = undefined,
930 })
931 else
932 try renderNodeGrouped(c, payload.lhs);
933 return renderCall(c, lhs, payload.args);
934 },
935 .null_literal => return c.addNode(.{
936 .tag = .identifier,
937 .main_token = try c.addToken(.identifier, "null"),
938 .data = undefined,
939 }),
940 .undefined_literal => return c.addNode(.{
941 .tag = .identifier,
942 .main_token = try c.addToken(.identifier, "undefined"),
943 .data = undefined,
944 }),
945 .true_literal => return c.addNode(.{
946 .tag = .identifier,
947 .main_token = try c.addToken(.identifier, "true"),
948 .data = undefined,
949 }),
950 .false_literal => return c.addNode(.{
951 .tag = .identifier,
952 .main_token = try c.addToken(.identifier, "false"),
953 .data = undefined,
954 }),
955 .zero_literal => return c.addNode(.{
956 .tag = .number_literal,
957 .main_token = try c.addToken(.number_literal, "0"),
958 .data = undefined,
959 }),
960 .one_literal => return c.addNode(.{
961 .tag = .number_literal,
962 .main_token = try c.addToken(.number_literal, "1"),
963 .data = undefined,
964 }),
965 .void_type => return c.addNode(.{
966 .tag = .identifier,
967 .main_token = try c.addToken(.identifier, "void"),
968 .data = undefined,
969 }),
970 .noreturn_type => return c.addNode(.{
971 .tag = .identifier,
972 .main_token = try c.addToken(.identifier, "noreturn"),
973 .data = undefined,
974 }),
975 .@"continue" => return c.addNode(.{
976 .tag = .@"continue",
977 .main_token = try c.addToken(.keyword_continue, "continue"),
978 .data = .{
979 .lhs = 0,
980 .rhs = undefined,
981 },
982 }),
983 .return_void => return c.addNode(.{
984 .tag = .@"return",
985 .main_token = try c.addToken(.keyword_return, "return"),
986 .data = .{
987 .lhs = 0,
988 .rhs = undefined,
989 },
990 }),
991 .@"break" => return c.addNode(.{
992 .tag = .@"break",
993 .main_token = try c.addToken(.keyword_break, "break"),
994 .data = .{
995 .lhs = 0,
996 .rhs = 0,
997 },
998 }),
999 .break_val => {
1000 const payload = node.castTag(.break_val).?.data;
1001 const tok = try c.addToken(.keyword_break, "break");
1002 const break_label = if (payload.label) |some| blk: {
1003 _ = try c.addToken(.colon, ":");
1004 break :blk try c.addIdentifier(some);
1005 } else 0;
1006 return c.addNode(.{
1007 .tag = .@"break",
1008 .main_token = tok,
1009 .data = .{
1010 .lhs = break_label,
1011 .rhs = try renderNode(c, payload.val),
1012 },
1013 });
1014 },
1015 .@"return" => {
1016 const payload = node.castTag(.@"return").?.data;
1017 return c.addNode(.{
1018 .tag = .@"return",
1019 .main_token = try c.addToken(.keyword_return, "return"),
1020 .data = .{
1021 .lhs = try renderNode(c, payload),
1022 .rhs = undefined,
1023 },
1024 });
1025 },
1026 .@"comptime" => {
1027 const payload = node.castTag(.@"comptime").?.data;
1028 return c.addNode(.{
1029 .tag = .@"comptime",
1030 .main_token = try c.addToken(.keyword_comptime, "comptime"),
1031 .data = .{
1032 .lhs = try renderNode(c, payload),
1033 .rhs = undefined,
1034 },
1035 });
1036 },
1037 .@"defer" => {
1038 const payload = node.castTag(.@"defer").?.data;
1039 return c.addNode(.{
1040 .tag = .@"defer",
1041 .main_token = try c.addToken(.keyword_defer, "defer"),
1042 .data = .{
1043 .lhs = undefined,
1044 .rhs = try renderNode(c, payload),
1045 },
1046 });
1047 },
1048 .asm_simple => {
1049 const payload = node.castTag(.asm_simple).?.data;
1050 const asm_token = try c.addToken(.keyword_asm, "asm");
1051 _ = try c.addToken(.l_paren, "(");
1052 return c.addNode(.{
1053 .tag = .asm_simple,
1054 .main_token = asm_token,
1055 .data = .{
1056 .lhs = try renderNode(c, payload),
1057 .rhs = try c.addToken(.r_paren, ")"),
1058 },
1059 });
1060 },
1061 .type => {
1062 const payload = node.castTag(.type).?.data;
1063 return c.addNode(.{
1064 .tag = .identifier,
1065 .main_token = try c.addToken(.identifier, payload),
1066 .data = undefined,
1067 });
1068 },
1069 .identifier => {
1070 const payload = node.castTag(.identifier).?.data;
1071 return c.addNode(.{
1072 .tag = .identifier,
1073 .main_token = try c.addIdentifier(payload),
1074 .data = undefined,
1075 });
1076 },
1077 .fn_identifier => {
1078 // C semantics are that a function identifier has address
1079 // value (implicit in stage1, explicit in stage2), except in
1080 // the context of an address_of, which is handled there.
1081 const payload = node.castTag(.fn_identifier).?.data;
1082 const tok = try c.addToken(.ampersand, "&");
1083 const arg = try c.addNode(.{
1084 .tag = .identifier,
1085 .main_token = try c.addIdentifier(payload),
1086 .data = undefined,
1087 });
1088 return c.addNode(.{
1089 .tag = .address_of,
1090 .main_token = tok,
1091 .data = .{
1092 .lhs = arg,
1093 .rhs = undefined,
1094 },
1095 });
1096 },
1097 .float_literal => {
1098 const payload = node.castTag(.float_literal).?.data;
1099 return c.addNode(.{
1100 .tag = .number_literal,
1101 .main_token = try c.addToken(.number_literal, payload),
1102 .data = undefined,
1103 });
1104 },
1105 .integer_literal => {
1106 const payload = node.castTag(.integer_literal).?.data;
1107 return c.addNode(.{
1108 .tag = .number_literal,
1109 .main_token = try c.addToken(.number_literal, payload),
1110 .data = undefined,
1111 });
1112 },
1113 .string_literal => {
1114 const payload = node.castTag(.string_literal).?.data;
1115 return c.addNode(.{
1116 .tag = .string_literal,
1117 .main_token = try c.addToken(.string_literal, payload),
1118 .data = undefined,
1119 });
1120 },
1121 .char_literal => {
1122 const payload = node.castTag(.char_literal).?.data;
1123 return c.addNode(.{
1124 .tag = .char_literal,
1125 .main_token = try c.addToken(.char_literal, payload),
1126 .data = undefined,
1127 });
1128 },
1129 .enum_literal => {
1130 const payload = node.castTag(.enum_literal).?.data;
1131 _ = try c.addToken(.period, ".");
1132 return c.addNode(.{
1133 .tag = .enum_literal,
1134 .main_token = try c.addToken(.identifier, payload),
1135 .data = undefined,
1136 });
1137 },
1138 .helpers_macro => {
1139 const payload = node.castTag(.helpers_macro).?.data;
1140 const chain = [_][]const u8{
1141 "zig",
1142 "c_translation",
1143 "Macros",
1144 payload,
1145 };
1146 return renderStdImport(c, &chain);
1147 },
1148 .import_c_builtin => {
1149 const payload = node.castTag(.import_c_builtin).?.data;
1150 const chain = [_][]const u8{
1151 "zig",
1152 "c_builtins",
1153 payload,
1154 };
1155 return renderStdImport(c, &chain);
1156 },
1157 .string_slice => {
1158 const payload = node.castTag(.string_slice).?.data;
1159
1160 const string = try renderNode(c, payload.string);
1161 const l_bracket = try c.addToken(.l_bracket, "[");
1162 const start = try c.addNode(.{
1163 .tag = .number_literal,
1164 .main_token = try c.addToken(.number_literal, "0"),
1165 .data = undefined,
1166 });
1167 _ = try c.addToken(.ellipsis2, "..");
1168 const end = try c.addNode(.{
1169 .tag = .number_literal,
1170 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.end}),
1171 .data = undefined,
1172 });
1173 _ = try c.addToken(.r_bracket, "]");
1174
1175 return c.addNode(.{
1176 .tag = .slice,
1177 .main_token = l_bracket,
1178 .data = .{
1179 .lhs = string,
1180 .rhs = try c.addExtra(std.zig.Ast.Node.Slice{
1181 .start = start,
1182 .end = end,
1183 }),
1184 },
1185 });
1186 },
1187 .fail_decl => {
1188 const payload = node.castTag(.fail_decl).?.data;
1189 // pub const name = @compileError(msg);
1190 _ = try c.addToken(.keyword_pub, "pub");
1191 const const_tok = try c.addToken(.keyword_const, "const");
1192 _ = try c.addIdentifier(payload.actual);
1193 _ = try c.addToken(.equal, "=");
1194
1195 const compile_error_tok = try c.addToken(.builtin, "@compileError");
1196 _ = try c.addToken(.l_paren, "(");
1197 const err_msg_tok = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(payload.mangled)});
1198 const err_msg = try c.addNode(.{
1199 .tag = .string_literal,
1200 .main_token = err_msg_tok,
1201 .data = undefined,
1202 });
1203 _ = try c.addToken(.r_paren, ")");
1204 const compile_error = try c.addNode(.{
1205 .tag = .builtin_call_two,
1206 .main_token = compile_error_tok,
1207 .data = .{
1208 .lhs = err_msg,
1209 .rhs = 0,
1210 },
1211 });
1212 _ = try c.addToken(.semicolon, ";");
1213
1214 return c.addNode(.{
1215 .tag = .simple_var_decl,
1216 .main_token = const_tok,
1217 .data = .{
1218 .lhs = 0,
1219 .rhs = compile_error,
1220 },
1221 });
1222 },
1223 .pub_var_simple, .var_simple => {
1224 const payload = @fieldParentPtr(Payload.SimpleVarDecl, "base", node.ptr_otherwise).data;
1225 if (node.tag() == .pub_var_simple) _ = try c.addToken(.keyword_pub, "pub");
1226 const const_tok = try c.addToken(.keyword_const, "const");
1227 _ = try c.addIdentifier(payload.name);
1228 _ = try c.addToken(.equal, "=");
1229
1230 const init = try renderNode(c, payload.init);
1231 _ = try c.addToken(.semicolon, ";");
1232
1233 return c.addNode(.{
1234 .tag = .simple_var_decl,
1235 .main_token = const_tok,
1236 .data = .{
1237 .lhs = 0,
1238 .rhs = init,
1239 },
1240 });
1241 },
1242 .static_local_var => {
1243 const payload = node.castTag(.static_local_var).?.data;
1244
1245 const const_tok = try c.addToken(.keyword_const, "const");
1246 _ = try c.addIdentifier(payload.name);
1247 _ = try c.addToken(.equal, "=");
1248
1249 const kind_tok = try c.addToken(.keyword_struct, "struct");
1250 _ = try c.addToken(.l_brace, "{");
1251
1252 const container_def = try c.addNode(.{
1253 .tag = .container_decl_two_trailing,
1254 .main_token = kind_tok,
1255 .data = .{
1256 .lhs = try renderNode(c, payload.init),
1257 .rhs = 0,
1258 },
1259 });
1260 _ = try c.addToken(.r_brace, "}");
1261 _ = try c.addToken(.semicolon, ";");
1262
1263 return c.addNode(.{
1264 .tag = .simple_var_decl,
1265 .main_token = const_tok,
1266 .data = .{
1267 .lhs = 0,
1268 .rhs = container_def,
1269 },
1270 });
1271 },
1272 .mut_str => {
1273 const payload = node.castTag(.mut_str).?.data;
1274
1275 const var_tok = try c.addToken(.keyword_var, "var");
1276 _ = try c.addIdentifier(payload.name);
1277 _ = try c.addToken(.equal, "=");
1278
1279 const deref = try c.addNode(.{
1280 .tag = .deref,
1281 .data = .{
1282 .lhs = try renderNodeGrouped(c, payload.init),
1283 .rhs = undefined,
1284 },
1285 .main_token = try c.addToken(.period_asterisk, ".*"),
1286 });
1287 _ = try c.addToken(.semicolon, ";");
1288
1289 return c.addNode(.{
1290 .tag = .simple_var_decl,
1291 .main_token = var_tok,
1292 .data = .{ .lhs = 0, .rhs = deref },
1293 });
1294 },
1295 .var_decl => return renderVar(c, node),
1296 .arg_redecl, .alias => {
1297 const payload = @fieldParentPtr(Payload.ArgRedecl, "base", node.ptr_otherwise).data;
1298 if (node.tag() == .alias) _ = try c.addToken(.keyword_pub, "pub");
1299 const mut_tok = if (node.tag() == .alias)
1300 try c.addToken(.keyword_const, "const")
1301 else
1302 try c.addToken(.keyword_var, "var");
1303 _ = try c.addIdentifier(payload.actual);
1304 _ = try c.addToken(.equal, "=");
1305
1306 const init = try c.addNode(.{
1307 .tag = .identifier,
1308 .main_token = try c.addIdentifier(payload.mangled),
1309 .data = undefined,
1310 });
1311 _ = try c.addToken(.semicolon, ";");
1312
1313 return c.addNode(.{
1314 .tag = .simple_var_decl,
1315 .main_token = mut_tok,
1316 .data = .{
1317 .lhs = 0,
1318 .rhs = init,
1319 },
1320 });
1321 },
1322 .int_cast => {
1323 const payload = node.castTag(.int_cast).?.data;
1324 return renderBuiltinCall(c, "@intCast", &.{payload});
1325 },
1326 .const_cast => {
1327 const payload = node.castTag(.const_cast).?.data;
1328 return renderBuiltinCall(c, "@constCast", &.{payload});
1329 },
1330 .volatile_cast => {
1331 const payload = node.castTag(.volatile_cast).?.data;
1332 return renderBuiltinCall(c, "@volatileCast", &.{payload});
1333 },
1334 .signed_remainder => {
1335 const payload = node.castTag(.signed_remainder).?.data;
1336 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "signedRemainder" });
1337 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
1338 },
1339 .div_trunc => {
1340 const payload = node.castTag(.div_trunc).?.data;
1341 return renderBuiltinCall(c, "@divTrunc", &.{ payload.lhs, payload.rhs });
1342 },
1343 .int_from_bool => {
1344 const payload = node.castTag(.int_from_bool).?.data;
1345 return renderBuiltinCall(c, "@intFromBool", &.{payload});
1346 },
1347 .as => {
1348 const payload = node.castTag(.as).?.data;
1349 return renderBuiltinCall(c, "@as", &.{ payload.lhs, payload.rhs });
1350 },
1351 .truncate => {
1352 const payload = node.castTag(.truncate).?.data;
1353 return renderBuiltinCall(c, "@truncate", &.{payload});
1354 },
1355 .bit_cast => {
1356 const payload = node.castTag(.bit_cast).?.data;
1357 return renderBuiltinCall(c, "@bitCast", &.{payload});
1358 },
1359 .float_cast => {
1360 const payload = node.castTag(.float_cast).?.data;
1361 return renderBuiltinCall(c, "@floatCast", &.{payload});
1362 },
1363 .int_from_float => {
1364 const payload = node.castTag(.int_from_float).?.data;
1365 return renderBuiltinCall(c, "@intFromFloat", &.{payload});
1366 },
1367 .float_from_int => {
1368 const payload = node.castTag(.float_from_int).?.data;
1369 return renderBuiltinCall(c, "@floatFromInt", &.{payload});
1370 },
1371 .ptr_from_int => {
1372 const payload = node.castTag(.ptr_from_int).?.data;
1373 return renderBuiltinCall(c, "@ptrFromInt", &.{payload});
1374 },
1375 .int_from_ptr => {
1376 const payload = node.castTag(.int_from_ptr).?.data;
1377 return renderBuiltinCall(c, "@intFromPtr", &.{payload});
1378 },
1379 .align_cast => {
1380 const payload = node.castTag(.align_cast).?.data;
1381 return renderBuiltinCall(c, "@alignCast", &.{payload});
1382 },
1383 .ptr_cast => {
1384 const payload = node.castTag(.ptr_cast).?.data;
1385 return renderBuiltinCall(c, "@ptrCast", &.{payload});
1386 },
1387 .div_exact => {
1388 const payload = node.castTag(.div_exact).?.data;
1389 return renderBuiltinCall(c, "@divExact", &.{ payload.lhs, payload.rhs });
1390 },
1391 .offset_of => {
1392 const payload = node.castTag(.offset_of).?.data;
1393 return renderBuiltinCall(c, "@offsetOf", &.{ payload.lhs, payload.rhs });
1394 },
1395 .sizeof => {
1396 const payload = node.castTag(.sizeof).?.data;
1397 return renderBuiltinCall(c, "@sizeOf", &.{payload});
1398 },
1399 .shuffle => {
1400 const payload = node.castTag(.shuffle).?.data;
1401 return renderBuiltinCall(c, "@shuffle", &.{
1402 payload.element_type,
1403 payload.a,
1404 payload.b,
1405 payload.mask_vector,
1406 });
1407 },
1408 .builtin_extern => {
1409 const payload = node.castTag(.builtin_extern).?.data;
1410
1411 var info_inits: [1]Payload.ContainerInitDot.Initializer = .{
1412 .{ .name = "name", .value = payload.name },
1413 };
1414 var info_payload: Payload.ContainerInitDot = .{
1415 .base = .{ .tag = .container_init_dot },
1416 .data = &info_inits,
1417 };
1418
1419 return renderBuiltinCall(c, "@extern", &.{
1420 payload.type,
1421 .{ .ptr_otherwise = &info_payload.base },
1422 });
1423 },
1424 .macro_arithmetic => {
1425 const payload = node.castTag(.macro_arithmetic).?.data;
1426 const op = @tagName(payload.op);
1427 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "MacroArithmetic", op });
1428 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
1429 },
1430 .alignof => {
1431 const payload = node.castTag(.alignof).?.data;
1432 return renderBuiltinCall(c, "@alignOf", &.{payload});
1433 },
1434 .typeof => {
1435 const payload = node.castTag(.typeof).?.data;
1436 return renderBuiltinCall(c, "@TypeOf", &.{payload});
1437 },
1438 .typeinfo => {
1439 const payload = node.castTag(.typeinfo).?.data;
1440 return renderBuiltinCall(c, "@typeInfo", &.{payload});
1441 },
1442 .negate => return renderPrefixOp(c, node, .negation, .minus, "-"),
1443 .negate_wrap => return renderPrefixOp(c, node, .negation_wrap, .minus_percent, "-%"),
1444 .bit_not => return renderPrefixOp(c, node, .bit_not, .tilde, "~"),
1445 .not => return renderPrefixOp(c, node, .bool_not, .bang, "!"),
1446 .optional_type => return renderPrefixOp(c, node, .optional_type, .question_mark, "?"),
1447 .address_of => {
1448 const payload = node.castTag(.address_of).?.data;
1449
1450 const ampersand = try c.addToken(.ampersand, "&");
1451 const base = if (payload.tag() == .fn_identifier)
1452 try c.addNode(.{
1453 .tag = .identifier,
1454 .main_token = try c.addIdentifier(payload.castTag(.fn_identifier).?.data),
1455 .data = undefined,
1456 })
1457 else
1458 try renderNodeGrouped(c, payload);
1459 return c.addNode(.{
1460 .tag = .address_of,
1461 .main_token = ampersand,
1462 .data = .{
1463 .lhs = base,
1464 .rhs = undefined,
1465 },
1466 });
1467 },
1468 .deref => {
1469 const payload = node.castTag(.deref).?.data;
1470 const operand = try renderNodeGrouped(c, payload);
1471 const deref_tok = try c.addToken(.period_asterisk, ".*");
1472 return c.addNode(.{
1473 .tag = .deref,
1474 .main_token = deref_tok,
1475 .data = .{
1476 .lhs = operand,
1477 .rhs = undefined,
1478 },
1479 });
1480 },
1481 .unwrap => {
1482 const payload = node.castTag(.unwrap).?.data;
1483 const operand = try renderNodeGrouped(c, payload);
1484 const period = try c.addToken(.period, ".");
1485 const question_mark = try c.addToken(.question_mark, "?");
1486 return c.addNode(.{
1487 .tag = .unwrap_optional,
1488 .main_token = period,
1489 .data = .{
1490 .lhs = operand,
1491 .rhs = question_mark,
1492 },
1493 });
1494 },
1495 .c_pointer, .single_pointer => {
1496 const payload = @fieldParentPtr(Payload.Pointer, "base", node.ptr_otherwise).data;
1497
1498 const asterisk = if (node.tag() == .single_pointer)
1499 try c.addToken(.asterisk, "*")
1500 else blk: {
1501 _ = try c.addToken(.l_bracket, "[");
1502 const res = try c.addToken(.asterisk, "*");
1503 _ = try c.addIdentifier("c");
1504 _ = try c.addToken(.r_bracket, "]");
1505 break :blk res;
1506 };
1507 if (payload.is_const) _ = try c.addToken(.keyword_const, "const");
1508 if (payload.is_volatile) _ = try c.addToken(.keyword_volatile, "volatile");
1509 const elem_type = try renderNodeGrouped(c, payload.elem_type);
1510
1511 return c.addNode(.{
1512 .tag = .ptr_type_aligned,
1513 .main_token = asterisk,
1514 .data = .{
1515 .lhs = 0,
1516 .rhs = elem_type,
1517 },
1518 });
1519 },
1520 .add => return renderBinOpGrouped(c, node, .add, .plus, "+"),
1521 .add_assign => return renderBinOp(c, node, .assign_add, .plus_equal, "+="),
1522 .add_wrap => return renderBinOpGrouped(c, node, .add_wrap, .plus_percent, "+%"),
1523 .add_wrap_assign => return renderBinOp(c, node, .assign_add_wrap, .plus_percent_equal, "+%="),
1524 .sub => return renderBinOpGrouped(c, node, .sub, .minus, "-"),
1525 .sub_assign => return renderBinOp(c, node, .assign_sub, .minus_equal, "-="),
1526 .sub_wrap => return renderBinOpGrouped(c, node, .sub_wrap, .minus_percent, "-%"),
1527 .sub_wrap_assign => return renderBinOp(c, node, .assign_sub_wrap, .minus_percent_equal, "-%="),
1528 .mul => return renderBinOpGrouped(c, node, .mul, .asterisk, "*"),
1529 .mul_assign => return renderBinOp(c, node, .assign_mul, .asterisk_equal, "*="),
1530 .mul_wrap => return renderBinOpGrouped(c, node, .mul_wrap, .asterisk_percent, "*%"),
1531 .mul_wrap_assign => return renderBinOp(c, node, .assign_mul_wrap, .asterisk_percent_equal, "*%="),
1532 .div => return renderBinOpGrouped(c, node, .div, .slash, "/"),
1533 .div_assign => return renderBinOp(c, node, .assign_div, .slash_equal, "/="),
1534 .shl => return renderBinOpGrouped(c, node, .shl, .angle_bracket_angle_bracket_left, "<<"),
1535 .shl_assign => return renderBinOp(c, node, .assign_shl, .angle_bracket_angle_bracket_left_equal, "<<="),
1536 .shr => return renderBinOpGrouped(c, node, .shr, .angle_bracket_angle_bracket_right, ">>"),
1537 .shr_assign => return renderBinOp(c, node, .assign_shr, .angle_bracket_angle_bracket_right_equal, ">>="),
1538 .mod => return renderBinOpGrouped(c, node, .mod, .percent, "%"),
1539 .mod_assign => return renderBinOp(c, node, .assign_mod, .percent_equal, "%="),
1540 .@"and" => return renderBinOpGrouped(c, node, .bool_and, .keyword_and, "and"),
1541 .@"or" => return renderBinOpGrouped(c, node, .bool_or, .keyword_or, "or"),
1542 .less_than => return renderBinOpGrouped(c, node, .less_than, .angle_bracket_left, "<"),
1543 .less_than_equal => return renderBinOpGrouped(c, node, .less_or_equal, .angle_bracket_left_equal, "<="),
1544 .greater_than => return renderBinOpGrouped(c, node, .greater_than, .angle_bracket_right, ">="),
1545 .greater_than_equal => return renderBinOpGrouped(c, node, .greater_or_equal, .angle_bracket_right_equal, ">="),
1546 .equal => return renderBinOpGrouped(c, node, .equal_equal, .equal_equal, "=="),
1547 .not_equal => return renderBinOpGrouped(c, node, .bang_equal, .bang_equal, "!="),
1548 .bit_and => return renderBinOpGrouped(c, node, .bit_and, .ampersand, "&"),
1549 .bit_and_assign => return renderBinOp(c, node, .assign_bit_and, .ampersand_equal, "&="),
1550 .bit_or => return renderBinOpGrouped(c, node, .bit_or, .pipe, "|"),
1551 .bit_or_assign => return renderBinOp(c, node, .assign_bit_or, .pipe_equal, "|="),
1552 .bit_xor => return renderBinOpGrouped(c, node, .bit_xor, .caret, "^"),
1553 .bit_xor_assign => return renderBinOp(c, node, .assign_bit_xor, .caret_equal, "^="),
1554 .array_cat => return renderBinOp(c, node, .array_cat, .plus_plus, "++"),
1555 .ellipsis3 => return renderBinOpGrouped(c, node, .switch_range, .ellipsis3, "..."),
1556 .assign => return renderBinOp(c, node, .assign, .equal, "="),
1557 .empty_block => {
1558 const l_brace = try c.addToken(.l_brace, "{");
1559 _ = try c.addToken(.r_brace, "}");
1560 return c.addNode(.{
1561 .tag = .block_two,
1562 .main_token = l_brace,
1563 .data = .{
1564 .lhs = 0,
1565 .rhs = 0,
1566 },
1567 });
1568 },
1569 .block_single => {
1570 const payload = node.castTag(.block_single).?.data;
1571 const l_brace = try c.addToken(.l_brace, "{");
1572
1573 const stmt = try renderNode(c, payload);
1574 try addSemicolonIfNeeded(c, payload);
1575
1576 _ = try c.addToken(.r_brace, "}");
1577 return c.addNode(.{
1578 .tag = .block_two_semicolon,
1579 .main_token = l_brace,
1580 .data = .{
1581 .lhs = stmt,
1582 .rhs = 0,
1583 },
1584 });
1585 },
1586 .block => {
1587 const payload = node.castTag(.block).?.data;
1588 if (payload.label) |some| {
1589 _ = try c.addIdentifier(some);
1590 _ = try c.addToken(.colon, ":");
1591 }
1592 const l_brace = try c.addToken(.l_brace, "{");
1593
1594 var stmts = std.ArrayList(NodeIndex).init(c.gpa);
1595 defer stmts.deinit();
1596 for (payload.stmts) |stmt| {
1597 const res = try renderNode(c, stmt);
1598 if (res == 0) continue;
1599 try addSemicolonIfNeeded(c, stmt);
1600 try stmts.append(res);
1601 }
1602 const span = try c.listToSpan(stmts.items);
1603 _ = try c.addToken(.r_brace, "}");
1604
1605 const semicolon = c.tokens.items(.tag)[c.tokens.len - 2] == .semicolon;
1606 return c.addNode(.{
1607 .tag = if (semicolon) .block_semicolon else .block,
1608 .main_token = l_brace,
1609 .data = .{
1610 .lhs = span.start,
1611 .rhs = span.end,
1612 },
1613 });
1614 },
1615 .func => return renderFunc(c, node),
1616 .pub_inline_fn => return renderMacroFunc(c, node),
1617 .discard => {
1618 const payload = node.castTag(.discard).?.data;
1619 if (payload.should_skip) return @as(NodeIndex, 0);
1620
1621 const lhs = try c.addNode(.{
1622 .tag = .identifier,
1623 .main_token = try c.addToken(.identifier, "_"),
1624 .data = undefined,
1625 });
1626 const main_token = try c.addToken(.equal, "=");
1627 if (payload.value.tag() == .identifier) {
1628 // Render as `_ = &foo;` to avoid tripping "pointless discard" and "local variable never mutated" errors.
1629 var addr_of_pl: Payload.UnOp = .{
1630 .base = .{ .tag = .address_of },
1631 .data = payload.value,
1632 };
1633 const addr_of: Node = .{ .ptr_otherwise = &addr_of_pl.base };
1634 return c.addNode(.{
1635 .tag = .assign,
1636 .main_token = main_token,
1637 .data = .{
1638 .lhs = lhs,
1639 .rhs = try renderNode(c, addr_of),
1640 },
1641 });
1642 } else {
1643 return c.addNode(.{
1644 .tag = .assign,
1645 .main_token = main_token,
1646 .data = .{
1647 .lhs = lhs,
1648 .rhs = try renderNode(c, payload.value),
1649 },
1650 });
1651 }
1652 },
1653 .@"while" => {
1654 const payload = node.castTag(.@"while").?.data;
1655 const while_tok = try c.addToken(.keyword_while, "while");
1656 _ = try c.addToken(.l_paren, "(");
1657 const cond = try renderNode(c, payload.cond);
1658 _ = try c.addToken(.r_paren, ")");
1659
1660 const cont_expr = if (payload.cont_expr) |some| blk: {
1661 _ = try c.addToken(.colon, ":");
1662 _ = try c.addToken(.l_paren, "(");
1663 const res = try renderNode(c, some);
1664 _ = try c.addToken(.r_paren, ")");
1665 break :blk res;
1666 } else 0;
1667 const body = try renderNode(c, payload.body);
1668
1669 if (cont_expr == 0) {
1670 return c.addNode(.{
1671 .tag = .while_simple,
1672 .main_token = while_tok,
1673 .data = .{
1674 .lhs = cond,
1675 .rhs = body,
1676 },
1677 });
1678 } else {
1679 return c.addNode(.{
1680 .tag = .while_cont,
1681 .main_token = while_tok,
1682 .data = .{
1683 .lhs = cond,
1684 .rhs = try c.addExtra(std.zig.Ast.Node.WhileCont{
1685 .cont_expr = cont_expr,
1686 .then_expr = body,
1687 }),
1688 },
1689 });
1690 }
1691 },
1692 .while_true => {
1693 const payload = node.castTag(.while_true).?.data;
1694 const while_tok = try c.addToken(.keyword_while, "while");
1695 _ = try c.addToken(.l_paren, "(");
1696 const cond = try c.addNode(.{
1697 .tag = .identifier,
1698 .main_token = try c.addToken(.identifier, "true"),
1699 .data = undefined,
1700 });
1701 _ = try c.addToken(.r_paren, ")");
1702 const body = try renderNode(c, payload);
1703
1704 return c.addNode(.{
1705 .tag = .while_simple,
1706 .main_token = while_tok,
1707 .data = .{
1708 .lhs = cond,
1709 .rhs = body,
1710 },
1711 });
1712 },
1713 .@"if" => {
1714 const payload = node.castTag(.@"if").?.data;
1715 const if_tok = try c.addToken(.keyword_if, "if");
1716 _ = try c.addToken(.l_paren, "(");
1717 const cond = try renderNode(c, payload.cond);
1718 _ = try c.addToken(.r_paren, ")");
1719
1720 const then_expr = try renderNode(c, payload.then);
1721 const else_node = payload.@"else" orelse return c.addNode(.{
1722 .tag = .if_simple,
1723 .main_token = if_tok,
1724 .data = .{
1725 .lhs = cond,
1726 .rhs = then_expr,
1727 },
1728 });
1729 _ = try c.addToken(.keyword_else, "else");
1730 const else_expr = try renderNode(c, else_node);
1731
1732 return c.addNode(.{
1733 .tag = .@"if",
1734 .main_token = if_tok,
1735 .data = .{
1736 .lhs = cond,
1737 .rhs = try c.addExtra(std.zig.Ast.Node.If{
1738 .then_expr = then_expr,
1739 .else_expr = else_expr,
1740 }),
1741 },
1742 });
1743 },
1744 .if_not_break => {
1745 const payload = node.castTag(.if_not_break).?.data;
1746 const if_tok = try c.addToken(.keyword_if, "if");
1747 _ = try c.addToken(.l_paren, "(");
1748 const cond = try c.addNode(.{
1749 .tag = .bool_not,
1750 .main_token = try c.addToken(.bang, "!"),
1751 .data = .{
1752 .lhs = try renderNodeGrouped(c, payload),
1753 .rhs = undefined,
1754 },
1755 });
1756 _ = try c.addToken(.r_paren, ")");
1757 const then_expr = try c.addNode(.{
1758 .tag = .@"break",
1759 .main_token = try c.addToken(.keyword_break, "break"),
1760 .data = .{
1761 .lhs = 0,
1762 .rhs = 0,
1763 },
1764 });
1765
1766 return c.addNode(.{
1767 .tag = .if_simple,
1768 .main_token = if_tok,
1769 .data = .{
1770 .lhs = cond,
1771 .rhs = then_expr,
1772 },
1773 });
1774 },
1775 .@"switch" => {
1776 const payload = node.castTag(.@"switch").?.data;
1777 const switch_tok = try c.addToken(.keyword_switch, "switch");
1778 _ = try c.addToken(.l_paren, "(");
1779 const cond = try renderNode(c, payload.cond);
1780 _ = try c.addToken(.r_paren, ")");
1781
1782 _ = try c.addToken(.l_brace, "{");
1783 var cases = try c.gpa.alloc(NodeIndex, payload.cases.len);
1784 defer c.gpa.free(cases);
1785 for (payload.cases, 0..) |case, i| {
1786 cases[i] = try renderNode(c, case);
1787 _ = try c.addToken(.comma, ",");
1788 }
1789 const span = try c.listToSpan(cases);
1790 _ = try c.addToken(.r_brace, "}");
1791 return c.addNode(.{
1792 .tag = .switch_comma,
1793 .main_token = switch_tok,
1794 .data = .{
1795 .lhs = cond,
1796 .rhs = try c.addExtra(NodeSubRange{
1797 .start = span.start,
1798 .end = span.end,
1799 }),
1800 },
1801 });
1802 },
1803 .switch_else => {
1804 const payload = node.castTag(.switch_else).?.data;
1805 _ = try c.addToken(.keyword_else, "else");
1806 return c.addNode(.{
1807 .tag = .switch_case_one,
1808 .main_token = try c.addToken(.equal_angle_bracket_right, "=>"),
1809 .data = .{
1810 .lhs = 0,
1811 .rhs = try renderNode(c, payload),
1812 },
1813 });
1814 },
1815 .switch_prong => {
1816 const payload = node.castTag(.switch_prong).?.data;
1817 var items = try c.gpa.alloc(NodeIndex, @max(payload.cases.len, 1));
1818 defer c.gpa.free(items);
1819 items[0] = 0;
1820 for (payload.cases, 0..) |item, i| {
1821 if (i != 0) _ = try c.addToken(.comma, ",");
1822 items[i] = try renderNode(c, item);
1823 }
1824 _ = try c.addToken(.r_brace, "}");
1825 if (items.len < 2) {
1826 return c.addNode(.{
1827 .tag = .switch_case_one,
1828 .main_token = try c.addToken(.equal_angle_bracket_right, "=>"),
1829 .data = .{
1830 .lhs = items[0],
1831 .rhs = try renderNode(c, payload.cond),
1832 },
1833 });
1834 } else {
1835 const span = try c.listToSpan(items);
1836 return c.addNode(.{
1837 .tag = .switch_case,
1838 .main_token = try c.addToken(.equal_angle_bracket_right, "=>"),
1839 .data = .{
1840 .lhs = try c.addExtra(NodeSubRange{
1841 .start = span.start,
1842 .end = span.end,
1843 }),
1844 .rhs = try renderNode(c, payload.cond),
1845 },
1846 });
1847 }
1848 },
1849 .opaque_literal => {
1850 const opaque_tok = try c.addToken(.keyword_opaque, "opaque");
1851 _ = try c.addToken(.l_brace, "{");
1852 _ = try c.addToken(.r_brace, "}");
1853
1854 return c.addNode(.{
1855 .tag = .container_decl_two,
1856 .main_token = opaque_tok,
1857 .data = .{
1858 .lhs = 0,
1859 .rhs = 0,
1860 },
1861 });
1862 },
1863 .array_access => {
1864 const payload = node.castTag(.array_access).?.data;
1865 const lhs = try renderNodeGrouped(c, payload.lhs);
1866 const l_bracket = try c.addToken(.l_bracket, "[");
1867 const index_expr = try renderNode(c, payload.rhs);
1868 _ = try c.addToken(.r_bracket, "]");
1869 return c.addNode(.{
1870 .tag = .array_access,
1871 .main_token = l_bracket,
1872 .data = .{
1873 .lhs = lhs,
1874 .rhs = index_expr,
1875 },
1876 });
1877 },
1878 .array_type => {
1879 const payload = node.castTag(.array_type).?.data;
1880 return renderArrayType(c, payload.len, payload.elem_type);
1881 },
1882 .null_sentinel_array_type => {
1883 const payload = node.castTag(.null_sentinel_array_type).?.data;
1884 return renderNullSentinelArrayType(c, payload.len, payload.elem_type);
1885 },
1886 .array_filler => {
1887 const payload = node.castTag(.array_filler).?.data;
1888
1889 const type_expr = try renderArrayType(c, 1, payload.type);
1890 const l_brace = try c.addToken(.l_brace, "{");
1891 const val = try renderNode(c, payload.filler);
1892 _ = try c.addToken(.r_brace, "}");
1893
1894 const init = try c.addNode(.{
1895 .tag = .array_init_one,
1896 .main_token = l_brace,
1897 .data = .{
1898 .lhs = type_expr,
1899 .rhs = val,
1900 },
1901 });
1902 return c.addNode(.{
1903 .tag = .array_cat,
1904 .main_token = try c.addToken(.asterisk_asterisk, "**"),
1905 .data = .{
1906 .lhs = init,
1907 .rhs = try c.addNode(.{
1908 .tag = .number_literal,
1909 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.count}),
1910 .data = undefined,
1911 }),
1912 },
1913 });
1914 },
1915 .empty_array => {
1916 const payload = node.castTag(.empty_array).?.data;
1917
1918 const type_expr = try renderArrayType(c, 0, payload);
1919 return renderArrayInit(c, type_expr, &.{});
1920 },
1921 .array_init => {
1922 const payload = node.castTag(.array_init).?.data;
1923 const type_expr = try renderNode(c, payload.cond);
1924 return renderArrayInit(c, type_expr, payload.cases);
1925 },
1926 .vector_zero_init => {
1927 const payload = node.castTag(.vector_zero_init).?.data;
1928 return renderBuiltinCall(c, "@splat", &.{payload});
1929 },
1930 .field_access => {
1931 const payload = node.castTag(.field_access).?.data;
1932 const lhs = try renderNodeGrouped(c, payload.lhs);
1933 return renderFieldAccess(c, lhs, payload.field_name);
1934 },
1935 .@"struct", .@"union" => return renderRecord(c, node),
1936 .enum_constant => {
1937 const payload = node.castTag(.enum_constant).?.data;
1938
1939 if (payload.is_public) _ = try c.addToken(.keyword_pub, "pub");
1940 const const_tok = try c.addToken(.keyword_const, "const");
1941 _ = try c.addIdentifier(payload.name);
1942
1943 const type_node = if (payload.type) |enum_const_type| blk: {
1944 _ = try c.addToken(.colon, ":");
1945 break :blk try renderNode(c, enum_const_type);
1946 } else 0;
1947
1948 _ = try c.addToken(.equal, "=");
1949
1950 const init_node = try renderNode(c, payload.value);
1951 _ = try c.addToken(.semicolon, ";");
1952
1953 return c.addNode(.{
1954 .tag = .simple_var_decl,
1955 .main_token = const_tok,
1956 .data = .{
1957 .lhs = type_node,
1958 .rhs = init_node,
1959 },
1960 });
1961 },
1962 .tuple => {
1963 const payload = node.castTag(.tuple).?.data;
1964 _ = try c.addToken(.period, ".");
1965 const l_brace = try c.addToken(.l_brace, "{");
1966 var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2));
1967 defer c.gpa.free(inits);
1968 inits[0] = 0;
1969 inits[1] = 0;
1970 for (payload, 0..) |init, i| {
1971 if (i != 0) _ = try c.addToken(.comma, ",");
1972 inits[i] = try renderNode(c, init);
1973 }
1974 _ = try c.addToken(.r_brace, "}");
1975 if (payload.len < 3) {
1976 return c.addNode(.{
1977 .tag = .array_init_dot_two,
1978 .main_token = l_brace,
1979 .data = .{
1980 .lhs = inits[0],
1981 .rhs = inits[1],
1982 },
1983 });
1984 } else {
1985 const span = try c.listToSpan(inits);
1986 return c.addNode(.{
1987 .tag = .array_init_dot,
1988 .main_token = l_brace,
1989 .data = .{
1990 .lhs = span.start,
1991 .rhs = span.end,
1992 },
1993 });
1994 }
1995 },
1996 .container_init_dot => {
1997 const payload = node.castTag(.container_init_dot).?.data;
1998 _ = try c.addToken(.period, ".");
1999 const l_brace = try c.addToken(.l_brace, "{");
2000 var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2));
2001 defer c.gpa.free(inits);
2002 inits[0] = 0;
2003 inits[1] = 0;
2004 for (payload, 0..) |init, i| {
2005 _ = try c.addToken(.period, ".");
2006 _ = try c.addIdentifier(init.name);
2007 _ = try c.addToken(.equal, "=");
2008 inits[i] = try renderNode(c, init.value);
2009 _ = try c.addToken(.comma, ",");
2010 }
2011 _ = try c.addToken(.r_brace, "}");
2012
2013 if (payload.len < 3) {
2014 return c.addNode(.{
2015 .tag = .struct_init_dot_two_comma,
2016 .main_token = l_brace,
2017 .data = .{
2018 .lhs = inits[0],
2019 .rhs = inits[1],
2020 },
2021 });
2022 } else {
2023 const span = try c.listToSpan(inits);
2024 return c.addNode(.{
2025 .tag = .struct_init_dot_comma,
2026 .main_token = l_brace,
2027 .data = .{
2028 .lhs = span.start,
2029 .rhs = span.end,
2030 },
2031 });
2032 }
2033 },
2034 .container_init => {
2035 const payload = node.castTag(.container_init).?.data;
2036 const lhs = try renderNode(c, payload.lhs);
2037
2038 const l_brace = try c.addToken(.l_brace, "{");
2039 var inits = try c.gpa.alloc(NodeIndex, @max(payload.inits.len, 1));
2040 defer c.gpa.free(inits);
2041 inits[0] = 0;
2042 for (payload.inits, 0..) |init, i| {
2043 _ = try c.addToken(.period, ".");
2044 _ = try c.addIdentifier(init.name);
2045 _ = try c.addToken(.equal, "=");
2046 inits[i] = try renderNode(c, init.value);
2047 _ = try c.addToken(.comma, ",");
2048 }
2049 _ = try c.addToken(.r_brace, "}");
2050
2051 return switch (payload.inits.len) {
2052 0 => c.addNode(.{
2053 .tag = .struct_init_one,
2054 .main_token = l_brace,
2055 .data = .{
2056 .lhs = lhs,
2057 .rhs = 0,
2058 },
2059 }),
2060 1 => c.addNode(.{
2061 .tag = .struct_init_one_comma,
2062 .main_token = l_brace,
2063 .data = .{
2064 .lhs = lhs,
2065 .rhs = inits[0],
2066 },
2067 }),
2068 else => blk: {
2069 const span = try c.listToSpan(inits);
2070 break :blk c.addNode(.{
2071 .tag = .struct_init_comma,
2072 .main_token = l_brace,
2073 .data = .{
2074 .lhs = lhs,
2075 .rhs = try c.addExtra(NodeSubRange{
2076 .start = span.start,
2077 .end = span.end,
2078 }),
2079 },
2080 });
2081 },
2082 };
2083 },
2084 .@"anytype" => unreachable, // Handled in renderParams
2085 }
2086}
2087
2088fn renderRecord(c: *Context, node: Node) !NodeIndex {
2089 const payload = @fieldParentPtr(Payload.Record, "base", node.ptr_otherwise).data;
2090 if (payload.layout == .@"packed")
2091 _ = try c.addToken(.keyword_packed, "packed")
2092 else if (payload.layout == .@"extern")
2093 _ = try c.addToken(.keyword_extern, "extern");
2094 const kind_tok = if (node.tag() == .@"struct")
2095 try c.addToken(.keyword_struct, "struct")
2096 else
2097 try c.addToken(.keyword_union, "union");
2098
2099 _ = try c.addToken(.l_brace, "{");
2100
2101 const num_vars = payload.variables.len;
2102 const num_funcs = payload.functions.len;
2103 const total_members = payload.fields.len + num_vars + num_funcs;
2104 const members = try c.gpa.alloc(NodeIndex, @max(total_members, 2));
2105 defer c.gpa.free(members);
2106 members[0] = 0;
2107 members[1] = 0;
2108
2109 for (payload.fields, 0..) |field, i| {
2110 const name_tok = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field.name)});
2111 _ = try c.addToken(.colon, ":");
2112 const type_expr = try renderNode(c, field.type);
2113
2114 const align_expr = if (field.alignment) |alignment| blk: {
2115 _ = try c.addToken(.keyword_align, "align");
2116 _ = try c.addToken(.l_paren, "(");
2117 const align_expr = try c.addNode(.{
2118 .tag = .number_literal,
2119 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{alignment}),
2120 .data = undefined,
2121 });
2122 _ = try c.addToken(.r_paren, ")");
2123 break :blk align_expr;
2124 } else 0;
2125
2126 const value_expr = if (field.default_value) |value| blk: {
2127 _ = try c.addToken(.equal, "=");
2128 break :blk try renderNode(c, value);
2129 } else 0;
2130
2131 members[i] = try c.addNode(if (align_expr == 0) .{
2132 .tag = .container_field_init,
2133 .main_token = name_tok,
2134 .data = .{
2135 .lhs = type_expr,
2136 .rhs = value_expr,
2137 },
2138 } else if (value_expr == 0) .{
2139 .tag = .container_field_align,
2140 .main_token = name_tok,
2141 .data = .{
2142 .lhs = type_expr,
2143 .rhs = align_expr,
2144 },
2145 } else .{
2146 .tag = .container_field,
2147 .main_token = name_tok,
2148 .data = .{
2149 .lhs = type_expr,
2150 .rhs = try c.addExtra(std.zig.Ast.Node.ContainerField{
2151 .align_expr = align_expr,
2152 .value_expr = value_expr,
2153 }),
2154 },
2155 });
2156 _ = try c.addToken(.comma, ",");
2157 }
2158 for (payload.variables, 0..) |variable, i| {
2159 members[payload.fields.len + i] = try renderNode(c, variable);
2160 }
2161 for (payload.functions, 0..) |function, i| {
2162 members[payload.fields.len + num_vars + i] = try renderNode(c, function);
2163 }
2164 _ = try c.addToken(.r_brace, "}");
2165
2166 if (total_members == 0) {
2167 return c.addNode(.{
2168 .tag = .container_decl_two,
2169 .main_token = kind_tok,
2170 .data = .{
2171 .lhs = 0,
2172 .rhs = 0,
2173 },
2174 });
2175 } else if (total_members <= 2) {
2176 return c.addNode(.{
2177 .tag = if (num_funcs == 0) .container_decl_two_trailing else .container_decl_two,
2178 .main_token = kind_tok,
2179 .data = .{
2180 .lhs = members[0],
2181 .rhs = members[1],
2182 },
2183 });
2184 } else {
2185 const span = try c.listToSpan(members);
2186 return c.addNode(.{
2187 .tag = if (num_funcs == 0) .container_decl_trailing else .container_decl,
2188 .main_token = kind_tok,
2189 .data = .{
2190 .lhs = span.start,
2191 .rhs = span.end,
2192 },
2193 });
2194 }
2195}
2196
2197fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeIndex {
2198 return c.addNode(.{
2199 .tag = .field_access,
2200 .main_token = try c.addToken(.period, "."),
2201 .data = .{
2202 .lhs = lhs,
2203 .rhs = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field_name)}),
2204 },
2205 });
2206}
2207
2208fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex {
2209 const l_brace = try c.addToken(.l_brace, "{");
2210 var rendered = try c.gpa.alloc(NodeIndex, @max(inits.len, 1));
2211 defer c.gpa.free(rendered);
2212 rendered[0] = 0;
2213 for (inits, 0..) |init, i| {
2214 rendered[i] = try renderNode(c, init);
2215 _ = try c.addToken(.comma, ",");
2216 }
2217 _ = try c.addToken(.r_brace, "}");
2218 if (inits.len < 2) {
2219 return c.addNode(.{
2220 .tag = .array_init_one_comma,
2221 .main_token = l_brace,
2222 .data = .{
2223 .lhs = lhs,
2224 .rhs = rendered[0],
2225 },
2226 });
2227 } else {
2228 const span = try c.listToSpan(rendered);
2229 return c.addNode(.{
2230 .tag = .array_init_comma,
2231 .main_token = l_brace,
2232 .data = .{
2233 .lhs = lhs,
2234 .rhs = try c.addExtra(NodeSubRange{
2235 .start = span.start,
2236 .end = span.end,
2237 }),
2238 },
2239 });
2240 }
2241}
2242
2243fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
2244 const l_bracket = try c.addToken(.l_bracket, "[");
2245 const len_expr = try c.addNode(.{
2246 .tag = .number_literal,
2247 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{len}),
2248 .data = undefined,
2249 });
2250 _ = try c.addToken(.r_bracket, "]");
2251 const elem_type_expr = try renderNode(c, elem_type);
2252 return c.addNode(.{
2253 .tag = .array_type,
2254 .main_token = l_bracket,
2255 .data = .{
2256 .lhs = len_expr,
2257 .rhs = elem_type_expr,
2258 },
2259 });
2260}
2261
2262fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
2263 const l_bracket = try c.addToken(.l_bracket, "[");
2264 const len_expr = try c.addNode(.{
2265 .tag = .number_literal,
2266 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{len}),
2267 .data = undefined,
2268 });
2269 _ = try c.addToken(.colon, ":");
2270
2271 const sentinel_expr = try c.addNode(.{
2272 .tag = .number_literal,
2273 .main_token = try c.addToken(.number_literal, "0"),
2274 .data = undefined,
2275 });
2276
2277 _ = try c.addToken(.r_bracket, "]");
2278 const elem_type_expr = try renderNode(c, elem_type);
2279 return c.addNode(.{
2280 .tag = .array_type_sentinel,
2281 .main_token = l_bracket,
2282 .data = .{
2283 .lhs = len_expr,
2284 .rhs = try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{
2285 .sentinel = sentinel_expr,
2286 .elem_type = elem_type_expr,
2287 }),
2288 },
2289 });
2290}
2291
2292fn addSemicolonIfNeeded(c: *Context, node: Node) !void {
2293 switch (node.tag()) {
2294 .warning => unreachable,
2295 .var_decl, .var_simple, .arg_redecl, .alias, .block, .empty_block, .block_single, .@"switch", .static_local_var, .mut_str => {},
2296 .while_true => {
2297 const payload = node.castTag(.while_true).?.data;
2298 return addSemicolonIfNotBlock(c, payload);
2299 },
2300 .@"while" => {
2301 const payload = node.castTag(.@"while").?.data;
2302 return addSemicolonIfNotBlock(c, payload.body);
2303 },
2304 .@"if" => {
2305 const payload = node.castTag(.@"if").?.data;
2306 if (payload.@"else") |some|
2307 return addSemicolonIfNeeded(c, some);
2308 return addSemicolonIfNotBlock(c, payload.then);
2309 },
2310 else => _ = try c.addToken(.semicolon, ";"),
2311 }
2312}
2313
2314fn addSemicolonIfNotBlock(c: *Context, node: Node) !void {
2315 switch (node.tag()) {
2316 .block, .empty_block, .block_single => {},
2317 else => _ = try c.addToken(.semicolon, ";"),
2318 }
2319}
2320
2321fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2322 switch (node.tag()) {
2323 .declaration => unreachable,
2324 .null_literal,
2325 .undefined_literal,
2326 .true_literal,
2327 .false_literal,
2328 .return_void,
2329 .zero_literal,
2330 .one_literal,
2331 .void_type,
2332 .noreturn_type,
2333 .@"anytype",
2334 .div_trunc,
2335 .signed_remainder,
2336 .int_cast,
2337 .const_cast,
2338 .volatile_cast,
2339 .as,
2340 .truncate,
2341 .bit_cast,
2342 .float_cast,
2343 .int_from_float,
2344 .float_from_int,
2345 .ptr_from_int,
2346 .std_mem_zeroes,
2347 .int_from_ptr,
2348 .sizeof,
2349 .alignof,
2350 .typeof,
2351 .typeinfo,
2352 .vector,
2353 .helpers_sizeof,
2354 .helpers_cast,
2355 .helpers_promoteIntLiteral,
2356 .helpers_shuffle_vector_index,
2357 .helpers_flexible_array_type,
2358 .std_mem_zeroinit,
2359 .integer_literal,
2360 .float_literal,
2361 .string_literal,
2362 .string_slice,
2363 .char_literal,
2364 .enum_literal,
2365 .identifier,
2366 .fn_identifier,
2367 .field_access,
2368 .ptr_cast,
2369 .type,
2370 .array_access,
2371 .align_cast,
2372 .optional_type,
2373 .c_pointer,
2374 .single_pointer,
2375 .unwrap,
2376 .deref,
2377 .not,
2378 .negate,
2379 .negate_wrap,
2380 .bit_not,
2381 .func,
2382 .call,
2383 .array_type,
2384 .null_sentinel_array_type,
2385 .int_from_bool,
2386 .div_exact,
2387 .offset_of,
2388 .shuffle,
2389 .builtin_extern,
2390 .static_local_var,
2391 .mut_str,
2392 .macro_arithmetic,
2393 => {
2394 // no grouping needed
2395 return renderNode(c, node);
2396 },
2397
2398 .opaque_literal,
2399 .empty_array,
2400 .block_single,
2401 .add,
2402 .add_wrap,
2403 .sub,
2404 .sub_wrap,
2405 .mul,
2406 .mul_wrap,
2407 .div,
2408 .shl,
2409 .shr,
2410 .mod,
2411 .@"and",
2412 .@"or",
2413 .less_than,
2414 .less_than_equal,
2415 .greater_than,
2416 .greater_than_equal,
2417 .equal,
2418 .not_equal,
2419 .bit_and,
2420 .bit_or,
2421 .bit_xor,
2422 .empty_block,
2423 .array_cat,
2424 .array_filler,
2425 .@"if",
2426 .@"struct",
2427 .@"union",
2428 .array_init,
2429 .vector_zero_init,
2430 .tuple,
2431 .container_init,
2432 .container_init_dot,
2433 .block,
2434 .address_of,
2435 => return c.addNode(.{
2436 .tag = .grouped_expression,
2437 .main_token = try c.addToken(.l_paren, "("),
2438 .data = .{
2439 .lhs = try renderNode(c, node),
2440 .rhs = try c.addToken(.r_paren, ")"),
2441 },
2442 }),
2443 .ellipsis3,
2444 .switch_prong,
2445 .warning,
2446 .var_decl,
2447 .fail_decl,
2448 .arg_redecl,
2449 .alias,
2450 .var_simple,
2451 .pub_var_simple,
2452 .enum_constant,
2453 .@"while",
2454 .@"switch",
2455 .@"break",
2456 .break_val,
2457 .pub_inline_fn,
2458 .discard,
2459 .@"continue",
2460 .@"return",
2461 .@"comptime",
2462 .@"defer",
2463 .asm_simple,
2464 .while_true,
2465 .if_not_break,
2466 .switch_else,
2467 .add_assign,
2468 .add_wrap_assign,
2469 .sub_assign,
2470 .sub_wrap_assign,
2471 .mul_assign,
2472 .mul_wrap_assign,
2473 .div_assign,
2474 .shl_assign,
2475 .shr_assign,
2476 .mod_assign,
2477 .bit_and_assign,
2478 .bit_or_assign,
2479 .bit_xor_assign,
2480 .assign,
2481 .helpers_macro,
2482 .import_c_builtin,
2483 => {
2484 // these should never appear in places where grouping might be needed.
2485 unreachable;
2486 },
2487 }
2488}
2489
2490fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2491 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;
2492 return c.addNode(.{
2493 .tag = tag,
2494 .main_token = try c.addToken(tok_tag, bytes),
2495 .data = .{
2496 .lhs = try renderNodeGrouped(c, payload),
2497 .rhs = undefined,
2498 },
2499 });
2500}
2501
2502fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2503 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2504 const lhs = try renderNodeGrouped(c, payload.lhs);
2505 return c.addNode(.{
2506 .tag = tag,
2507 .main_token = try c.addToken(tok_tag, bytes),
2508 .data = .{
2509 .lhs = lhs,
2510 .rhs = try renderNodeGrouped(c, payload.rhs),
2511 },
2512 });
2513}
2514
2515fn renderBinOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2516 const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2517 const lhs = try renderNode(c, payload.lhs);
2518 return c.addNode(.{
2519 .tag = tag,
2520 .main_token = try c.addToken(tok_tag, bytes),
2521 .data = .{
2522 .lhs = lhs,
2523 .rhs = try renderNode(c, payload.rhs),
2524 },
2525 });
2526}
2527
2528fn renderStdImport(c: *Context, parts: []const []const u8) !NodeIndex {
2529 const import_tok = try c.addToken(.builtin, "@import");
2530 _ = try c.addToken(.l_paren, "(");
2531 const std_tok = try c.addToken(.string_literal, "\"std\"");
2532 const std_node = try c.addNode(.{
2533 .tag = .string_literal,
2534 .main_token = std_tok,
2535 .data = undefined,
2536 });
2537 _ = try c.addToken(.r_paren, ")");
2538
2539 const import_node = try c.addNode(.{
2540 .tag = .builtin_call_two,
2541 .main_token = import_tok,
2542 .data = .{
2543 .lhs = std_node,
2544 .rhs = 0,
2545 },
2546 });
2547
2548 var access_chain = import_node;
2549 for (parts) |part| {
2550 access_chain = try renderFieldAccess(c, access_chain, part);
2551 }
2552 return access_chain;
2553}
2554
2555fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {
2556 const lparen = try c.addToken(.l_paren, "(");
2557 const res = switch (args.len) {
2558 0 => try c.addNode(.{
2559 .tag = .call_one,
2560 .main_token = lparen,
2561 .data = .{
2562 .lhs = lhs,
2563 .rhs = 0,
2564 },
2565 }),
2566 1 => blk: {
2567 const arg = try renderNode(c, args[0]);
2568 break :blk try c.addNode(.{
2569 .tag = .call_one,
2570 .main_token = lparen,
2571 .data = .{
2572 .lhs = lhs,
2573 .rhs = arg,
2574 },
2575 });
2576 },
2577 else => blk: {
2578 var rendered = try c.gpa.alloc(NodeIndex, args.len);
2579 defer c.gpa.free(rendered);
2580
2581 for (args, 0..) |arg, i| {
2582 if (i != 0) _ = try c.addToken(.comma, ",");
2583 rendered[i] = try renderNode(c, arg);
2584 }
2585 const span = try c.listToSpan(rendered);
2586 break :blk try c.addNode(.{
2587 .tag = .call,
2588 .main_token = lparen,
2589 .data = .{
2590 .lhs = lhs,
2591 .rhs = try c.addExtra(NodeSubRange{
2592 .start = span.start,
2593 .end = span.end,
2594 }),
2595 },
2596 });
2597 },
2598 };
2599 _ = try c.addToken(.r_paren, ")");
2600 return res;
2601}
2602
2603fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !NodeIndex {
2604 const builtin_tok = try c.addToken(.builtin, builtin);
2605 _ = try c.addToken(.l_paren, "(");
2606 var arg_1: NodeIndex = 0;
2607 var arg_2: NodeIndex = 0;
2608 var arg_3: NodeIndex = 0;
2609 var arg_4: NodeIndex = 0;
2610 switch (args.len) {
2611 0 => {},
2612 1 => {
2613 arg_1 = try renderNode(c, args[0]);
2614 },
2615 2 => {
2616 arg_1 = try renderNode(c, args[0]);
2617 _ = try c.addToken(.comma, ",");
2618 arg_2 = try renderNode(c, args[1]);
2619 },
2620 4 => {
2621 arg_1 = try renderNode(c, args[0]);
2622 _ = try c.addToken(.comma, ",");
2623 arg_2 = try renderNode(c, args[1]);
2624 _ = try c.addToken(.comma, ",");
2625 arg_3 = try renderNode(c, args[2]);
2626 _ = try c.addToken(.comma, ",");
2627 arg_4 = try renderNode(c, args[3]);
2628 },
2629 else => unreachable, // expand this function as needed.
2630 }
2631
2632 _ = try c.addToken(.r_paren, ")");
2633 if (args.len <= 2) {
2634 return c.addNode(.{
2635 .tag = .builtin_call_two,
2636 .main_token = builtin_tok,
2637 .data = .{
2638 .lhs = arg_1,
2639 .rhs = arg_2,
2640 },
2641 });
2642 } else {
2643 std.debug.assert(args.len == 4);
2644
2645 const params = try c.listToSpan(&.{ arg_1, arg_2, arg_3, arg_4 });
2646 return c.addNode(.{
2647 .tag = .builtin_call,
2648 .main_token = builtin_tok,
2649 .data = .{
2650 .lhs = params.start,
2651 .rhs = params.end,
2652 },
2653 });
2654 }
2655}
2656
2657fn renderVar(c: *Context, node: Node) !NodeIndex {
2658 const payload = node.castTag(.var_decl).?.data;
2659 if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
2660 if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
2661 if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
2662 if (payload.is_threadlocal) _ = try c.addToken(.keyword_threadlocal, "threadlocal");
2663 const mut_tok = if (payload.is_const)
2664 try c.addToken(.keyword_const, "const")
2665 else
2666 try c.addToken(.keyword_var, "var");
2667 _ = try c.addIdentifier(payload.name);
2668 _ = try c.addToken(.colon, ":");
2669 const type_node = try renderNode(c, payload.type);
2670
2671 const align_node = if (payload.alignment) |some| blk: {
2672 _ = try c.addToken(.keyword_align, "align");
2673 _ = try c.addToken(.l_paren, "(");
2674 const res = try c.addNode(.{
2675 .tag = .number_literal,
2676 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{some}),
2677 .data = undefined,
2678 });
2679 _ = try c.addToken(.r_paren, ")");
2680 break :blk res;
2681 } else 0;
2682
2683 const section_node = if (payload.linksection_string) |some| blk: {
2684 _ = try c.addToken(.keyword_linksection, "linksection");
2685 _ = try c.addToken(.l_paren, "(");
2686 const res = try c.addNode(.{
2687 .tag = .string_literal,
2688 .main_token = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(some)}),
2689 .data = undefined,
2690 });
2691 _ = try c.addToken(.r_paren, ")");
2692 break :blk res;
2693 } else 0;
2694
2695 const init_node = if (payload.init) |some| blk: {
2696 _ = try c.addToken(.equal, "=");
2697 break :blk try renderNode(c, some);
2698 } else 0;
2699 _ = try c.addToken(.semicolon, ";");
2700
2701 if (section_node == 0) {
2702 if (align_node == 0) {
2703 return c.addNode(.{
2704 .tag = .simple_var_decl,
2705 .main_token = mut_tok,
2706 .data = .{
2707 .lhs = type_node,
2708 .rhs = init_node,
2709 },
2710 });
2711 } else {
2712 return c.addNode(.{
2713 .tag = .local_var_decl,
2714 .main_token = mut_tok,
2715 .data = .{
2716 .lhs = try c.addExtra(std.zig.Ast.Node.LocalVarDecl{
2717 .type_node = type_node,
2718 .align_node = align_node,
2719 }),
2720 .rhs = init_node,
2721 },
2722 });
2723 }
2724 } else {
2725 return c.addNode(.{
2726 .tag = .global_var_decl,
2727 .main_token = mut_tok,
2728 .data = .{
2729 .lhs = try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{
2730 .type_node = type_node,
2731 .align_node = align_node,
2732 .section_node = section_node,
2733 .addrspace_node = 0,
2734 }),
2735 .rhs = init_node,
2736 },
2737 });
2738 }
2739}
2740
2741fn renderFunc(c: *Context, node: Node) !NodeIndex {
2742 const payload = node.castTag(.func).?.data;
2743 if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
2744 if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
2745 if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
2746 if (payload.is_inline) _ = try c.addToken(.keyword_inline, "inline");
2747 const fn_token = try c.addToken(.keyword_fn, "fn");
2748 if (payload.name) |some| _ = try c.addIdentifier(some);
2749
2750 const params = try renderParams(c, payload.params, payload.is_var_args);
2751 defer params.deinit();
2752 var span: NodeSubRange = undefined;
2753 if (params.items.len > 1) span = try c.listToSpan(params.items);
2754
2755 const align_expr = if (payload.alignment) |some| blk: {
2756 _ = try c.addToken(.keyword_align, "align");
2757 _ = try c.addToken(.l_paren, "(");
2758 const res = try c.addNode(.{
2759 .tag = .number_literal,
2760 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{some}),
2761 .data = undefined,
2762 });
2763 _ = try c.addToken(.r_paren, ")");
2764 break :blk res;
2765 } else 0;
2766
2767 const section_expr = if (payload.linksection_string) |some| blk: {
2768 _ = try c.addToken(.keyword_linksection, "linksection");
2769 _ = try c.addToken(.l_paren, "(");
2770 const res = try c.addNode(.{
2771 .tag = .string_literal,
2772 .main_token = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(some)}),
2773 .data = undefined,
2774 });
2775 _ = try c.addToken(.r_paren, ")");
2776 break :blk res;
2777 } else 0;
2778
2779 const callconv_expr = if (payload.explicit_callconv) |some| blk: {
2780 _ = try c.addToken(.keyword_callconv, "callconv");
2781 _ = try c.addToken(.l_paren, "(");
2782 _ = try c.addToken(.period, ".");
2783 const res = try c.addNode(.{
2784 .tag = .enum_literal,
2785 .main_token = try c.addTokenFmt(.identifier, "{s}", .{@tagName(some)}),
2786 .data = undefined,
2787 });
2788 _ = try c.addToken(.r_paren, ")");
2789 break :blk res;
2790 } else 0;
2791
2792 const return_type_expr = try renderNode(c, payload.return_type);
2793
2794 const fn_proto = try blk: {
2795 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {
2796 if (params.items.len < 2)
2797 break :blk c.addNode(.{
2798 .tag = .fn_proto_simple,
2799 .main_token = fn_token,
2800 .data = .{
2801 .lhs = params.items[0],
2802 .rhs = return_type_expr,
2803 },
2804 })
2805 else
2806 break :blk c.addNode(.{
2807 .tag = .fn_proto_multi,
2808 .main_token = fn_token,
2809 .data = .{
2810 .lhs = try c.addExtra(NodeSubRange{
2811 .start = span.start,
2812 .end = span.end,
2813 }),
2814 .rhs = return_type_expr,
2815 },
2816 });
2817 }
2818 if (params.items.len < 2)
2819 break :blk c.addNode(.{
2820 .tag = .fn_proto_one,
2821 .main_token = fn_token,
2822 .data = .{
2823 .lhs = try c.addExtra(std.zig.Ast.Node.FnProtoOne{
2824 .param = params.items[0],
2825 .align_expr = align_expr,
2826 .addrspace_expr = 0, // TODO
2827 .section_expr = section_expr,
2828 .callconv_expr = callconv_expr,
2829 }),
2830 .rhs = return_type_expr,
2831 },
2832 })
2833 else
2834 break :blk c.addNode(.{
2835 .tag = .fn_proto,
2836 .main_token = fn_token,
2837 .data = .{
2838 .lhs = try c.addExtra(std.zig.Ast.Node.FnProto{
2839 .params_start = span.start,
2840 .params_end = span.end,
2841 .align_expr = align_expr,
2842 .addrspace_expr = 0, // TODO
2843 .section_expr = section_expr,
2844 .callconv_expr = callconv_expr,
2845 }),
2846 .rhs = return_type_expr,
2847 },
2848 });
2849 };
2850
2851 const payload_body = payload.body orelse {
2852 if (payload.is_extern) {
2853 _ = try c.addToken(.semicolon, ";");
2854 }
2855 return fn_proto;
2856 };
2857 const body = try renderNode(c, payload_body);
2858 return c.addNode(.{
2859 .tag = .fn_decl,
2860 .main_token = fn_token,
2861 .data = .{
2862 .lhs = fn_proto,
2863 .rhs = body,
2864 },
2865 });
2866}
2867
2868fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2869 const payload = node.castTag(.pub_inline_fn).?.data;
2870 _ = try c.addToken(.keyword_pub, "pub");
2871 _ = try c.addToken(.keyword_inline, "inline");
2872 const fn_token = try c.addToken(.keyword_fn, "fn");
2873 _ = try c.addIdentifier(payload.name);
2874
2875 const params = try renderParams(c, payload.params, false);
2876 defer params.deinit();
2877 var span: NodeSubRange = undefined;
2878 if (params.items.len > 1) span = try c.listToSpan(params.items);
2879
2880 const return_type_expr = try renderNodeGrouped(c, payload.return_type);
2881
2882 const fn_proto = blk: {
2883 if (params.items.len < 2) {
2884 break :blk try c.addNode(.{
2885 .tag = .fn_proto_simple,
2886 .main_token = fn_token,
2887 .data = .{
2888 .lhs = params.items[0],
2889 .rhs = return_type_expr,
2890 },
2891 });
2892 } else {
2893 break :blk try c.addNode(.{
2894 .tag = .fn_proto_multi,
2895 .main_token = fn_token,
2896 .data = .{
2897 .lhs = try c.addExtra(std.zig.Ast.Node.SubRange{
2898 .start = span.start,
2899 .end = span.end,
2900 }),
2901 .rhs = return_type_expr,
2902 },
2903 });
2904 }
2905 };
2906 return c.addNode(.{
2907 .tag = .fn_decl,
2908 .main_token = fn_token,
2909 .data = .{
2910 .lhs = fn_proto,
2911 .rhs = try renderNode(c, payload.body),
2912 },
2913 });
2914}
2915
2916fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) {
2917 _ = try c.addToken(.l_paren, "(");
2918 var rendered = try std.ArrayList(NodeIndex).initCapacity(c.gpa, @max(params.len, 1));
2919 errdefer rendered.deinit();
2920
2921 for (params, 0..) |param, i| {
2922 if (i != 0) _ = try c.addToken(.comma, ",");
2923 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
2924 if (param.name) |some| {
2925 _ = try c.addIdentifier(some);
2926 _ = try c.addToken(.colon, ":");
2927 }
2928 if (param.type.tag() == .@"anytype") {
2929 _ = try c.addToken(.keyword_anytype, "anytype");
2930 continue;
2931 }
2932 rendered.appendAssumeCapacity(try renderNode(c, param.type));
2933 }
2934 if (is_var_args) {
2935 if (params.len != 0) _ = try c.addToken(.comma, ",");
2936 _ = try c.addToken(.ellipsis3, "...");
2937 }
2938 _ = try c.addToken(.r_paren, ")");
2939
2940 if (rendered.items.len == 0) rendered.appendAssumeCapacity(0);
2941 return rendered;
2942}
src/translate_c/common.zig deleted-322
......@@ -1,322 +0,0 @@
1const std = @import("std");
2const ast = @import("ast.zig");
3const Node = ast.Node;
4const Tag = Node.Tag;
5
6const CallingConvention = std.builtin.CallingConvention;
7
8pub const Error = std.mem.Allocator.Error;
9pub const MacroProcessingError = Error || error{UnexpectedMacroToken};
10pub const TypeError = Error || error{UnsupportedType};
11pub const TransError = TypeError || error{UnsupportedTranslation};
12
13pub const SymbolTable = std.StringArrayHashMap(Node);
14pub const AliasList = std.ArrayList(struct {
15 alias: []const u8,
16 name: []const u8,
17});
18
19pub const ResultUsed = enum {
20 used,
21 unused,
22};
23
24pub fn ScopeExtra(comptime Context: type, comptime Type: type) type {
25 return struct {
26 id: Id,
27 parent: ?*Scope,
28
29 const Scope = @This();
30
31 pub const Id = enum {
32 block,
33 root,
34 condition,
35 loop,
36 do_loop,
37 };
38
39 /// Used for the scope of condition expressions, for example `if (cond)`.
40 /// The block is lazily initialised because it is only needed for rare
41 /// cases of comma operators being used.
42 pub const Condition = struct {
43 base: Scope,
44 block: ?Block = null,
45
46 pub fn getBlockScope(self: *Condition, c: *Context) !*Block {
47 if (self.block) |*b| return b;
48 self.block = try Block.init(c, &self.base, true);
49 return &self.block.?;
50 }
51
52 pub fn deinit(self: *Condition) void {
53 if (self.block) |*b| b.deinit();
54 }
55 };
56
57 /// Represents an in-progress Node.Block. This struct is stack-allocated.
58 /// When it is deinitialized, it produces an Node.Block which is allocated
59 /// into the main arena.
60 pub const Block = struct {
61 base: Scope,
62 statements: std.ArrayList(Node),
63 variables: AliasList,
64 mangle_count: u32 = 0,
65 label: ?[]const u8 = null,
66
67 /// By default all variables are discarded, since we do not know in advance if they
68 /// will be used. This maps the variable's name to the Discard payload, so that if
69 /// the variable is subsequently referenced we can indicate that the discard should
70 /// be skipped during the intermediate AST -> Zig AST render step.
71 variable_discards: std.StringArrayHashMap(*ast.Payload.Discard),
72
73 /// When the block corresponds to a function, keep track of the return type
74 /// so that the return expression can be cast, if necessary
75 return_type: ?Type = null,
76
77 /// C static local variables are wrapped in a block-local struct. The struct
78 /// is named after the (mangled) variable name, the Zig variable within the
79 /// struct itself is given this name.
80 pub const static_inner_name = "static";
81
82 pub fn init(c: *Context, parent: *Scope, labeled: bool) !Block {
83 var blk = Block{
84 .base = .{
85 .id = .block,
86 .parent = parent,
87 },
88 .statements = std.ArrayList(Node).init(c.gpa),
89 .variables = AliasList.init(c.gpa),
90 .variable_discards = std.StringArrayHashMap(*ast.Payload.Discard).init(c.gpa),
91 };
92 if (labeled) {
93 blk.label = try blk.makeMangledName(c, "blk");
94 }
95 return blk;
96 }
97
98 pub fn deinit(self: *Block) void {
99 self.statements.deinit();
100 self.variables.deinit();
101 self.variable_discards.deinit();
102 self.* = undefined;
103 }
104
105 pub fn complete(self: *Block, c: *Context) !Node {
106 if (self.base.parent.?.id == .do_loop) {
107 // We reserve 1 extra statement if the parent is a do_loop. This is in case of
108 // do while, we want to put `if (cond) break;` at the end.
109 const alloc_len = self.statements.items.len + @intFromBool(self.base.parent.?.id == .do_loop);
110 var stmts = try c.arena.alloc(Node, alloc_len);
111 stmts.len = self.statements.items.len;
112 @memcpy(stmts[0..self.statements.items.len], self.statements.items);
113 return Tag.block.create(c.arena, .{
114 .label = self.label,
115 .stmts = stmts,
116 });
117 }
118 if (self.statements.items.len == 0) return Tag.empty_block.init();
119 return Tag.block.create(c.arena, .{
120 .label = self.label,
121 .stmts = try c.arena.dupe(Node, self.statements.items),
122 });
123 }
124
125 /// Given the desired name, return a name that does not shadow anything from outer scopes.
126 /// Inserts the returned name into the scope.
127 /// The name will not be visible to callers of getAlias.
128 pub fn reserveMangledName(scope: *Block, c: *Context, name: []const u8) ![]const u8 {
129 return scope.createMangledName(c, name, true);
130 }
131
132 /// Same as reserveMangledName, but enables the alias immediately.
133 pub fn makeMangledName(scope: *Block, c: *Context, name: []const u8) ![]const u8 {
134 return scope.createMangledName(c, name, false);
135 }
136
137 pub fn createMangledName(scope: *Block, c: *Context, name: []const u8, reservation: bool) ![]const u8 {
138 const name_copy = try c.arena.dupe(u8, name);
139 var proposed_name = name_copy;
140 while (scope.contains(proposed_name)) {
141 scope.mangle_count += 1;
142 proposed_name = try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ name, scope.mangle_count });
143 }
144 const new_mangle = try scope.variables.addOne();
145 if (reservation) {
146 new_mangle.* = .{ .name = name_copy, .alias = name_copy };
147 } else {
148 new_mangle.* = .{ .name = name_copy, .alias = proposed_name };
149 }
150 return proposed_name;
151 }
152
153 pub fn getAlias(scope: *Block, name: []const u8) []const u8 {
154 for (scope.variables.items) |p| {
155 if (std.mem.eql(u8, p.name, name))
156 return p.alias;
157 }
158 return scope.base.parent.?.getAlias(name);
159 }
160
161 pub fn localContains(scope: *Block, name: []const u8) bool {
162 for (scope.variables.items) |p| {
163 if (std.mem.eql(u8, p.alias, name))
164 return true;
165 }
166 return false;
167 }
168
169 pub fn contains(scope: *Block, name: []const u8) bool {
170 if (scope.localContains(name))
171 return true;
172 return scope.base.parent.?.contains(name);
173 }
174
175 pub fn discardVariable(scope: *Block, c: *Context, name: []const u8) Error!void {
176 const name_node = try Tag.identifier.create(c.arena, name);
177 const discard = try Tag.discard.create(c.arena, .{ .should_skip = false, .value = name_node });
178 try scope.statements.append(discard);
179 try scope.variable_discards.putNoClobber(name, discard.castTag(.discard).?);
180 }
181 };
182
183 pub const Root = struct {
184 base: Scope,
185 sym_table: SymbolTable,
186 macro_table: SymbolTable,
187 blank_macros: std.StringArrayHashMap(void),
188 context: *Context,
189 nodes: std.ArrayList(Node),
190
191 pub fn init(c: *Context) Root {
192 return .{
193 .base = .{
194 .id = .root,
195 .parent = null,
196 },
197 .sym_table = SymbolTable.init(c.gpa),
198 .macro_table = SymbolTable.init(c.gpa),
199 .blank_macros = std.StringArrayHashMap(void).init(c.gpa),
200 .context = c,
201 .nodes = std.ArrayList(Node).init(c.gpa),
202 };
203 }
204
205 pub fn deinit(scope: *Root) void {
206 scope.sym_table.deinit();
207 scope.macro_table.deinit();
208 scope.blank_macros.deinit();
209 scope.nodes.deinit();
210 }
211
212 /// Check if the global scope contains this name, without looking into the "future", e.g.
213 /// ignore the preprocessed decl and macro names.
214 pub fn containsNow(scope: *Root, name: []const u8) bool {
215 return scope.sym_table.contains(name) or scope.macro_table.contains(name);
216 }
217
218 /// Check if the global scope contains the name, includes all decls that haven't been translated yet.
219 pub fn contains(scope: *Root, name: []const u8) bool {
220 return scope.containsNow(name) or scope.context.global_names.contains(name) or scope.context.weak_global_names.contains(name);
221 }
222 };
223
224 pub fn findBlockScope(inner: *Scope, c: *Context) !*Scope.Block {
225 var scope = inner;
226 while (true) {
227 switch (scope.id) {
228 .root => unreachable,
229 .block => return @fieldParentPtr(Block, "base", scope),
230 .condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c),
231 else => scope = scope.parent.?,
232 }
233 }
234 }
235
236 pub fn findBlockReturnType(inner: *Scope) Type {
237 var scope = inner;
238 while (true) {
239 switch (scope.id) {
240 .root => unreachable,
241 .block => {
242 const block = @fieldParentPtr(Block, "base", scope);
243 if (block.return_type) |ty| return ty;
244 scope = scope.parent.?;
245 },
246 else => scope = scope.parent.?,
247 }
248 }
249 }
250
251 pub fn getAlias(scope: *Scope, name: []const u8) []const u8 {
252 return switch (scope.id) {
253 .root => return name,
254 .block => @fieldParentPtr(Block, "base", scope).getAlias(name),
255 .loop, .do_loop, .condition => scope.parent.?.getAlias(name),
256 };
257 }
258
259 pub fn contains(scope: *Scope, name: []const u8) bool {
260 return switch (scope.id) {
261 .root => @fieldParentPtr(Root, "base", scope).contains(name),
262 .block => @fieldParentPtr(Block, "base", scope).contains(name),
263 .loop, .do_loop, .condition => scope.parent.?.contains(name),
264 };
265 }
266
267 pub fn getBreakableScope(inner: *Scope) *Scope {
268 var scope = inner;
269 while (true) {
270 switch (scope.id) {
271 .root => unreachable,
272 .loop, .do_loop => return scope,
273 else => scope = scope.parent.?,
274 }
275 }
276 }
277
278 /// Appends a node to the first block scope if inside a function, or to the root tree if not.
279 pub fn appendNode(inner: *Scope, node: Node) !void {
280 var scope = inner;
281 while (true) {
282 switch (scope.id) {
283 .root => {
284 const root = @fieldParentPtr(Root, "base", scope);
285 return root.nodes.append(node);
286 },
287 .block => {
288 const block = @fieldParentPtr(Block, "base", scope);
289 return block.statements.append(node);
290 },
291 else => scope = scope.parent.?,
292 }
293 }
294 }
295
296 pub fn skipVariableDiscard(inner: *Scope, name: []const u8) void {
297 if (true) {
298 // TODO: due to 'local variable is never mutated' errors, we can
299 // only skip discards if a variable is used as an lvalue, which
300 // we don't currently have detection for in translate-c.
301 // Once #17584 is completed, perhaps we can do away with this
302 // logic entirely, and instead rely on render to fixup code.
303 return;
304 }
305 var scope = inner;
306 while (true) {
307 switch (scope.id) {
308 .root => return,
309 .block => {
310 const block = @fieldParentPtr(Block, "base", scope);
311 if (block.variable_discards.get(name)) |discard| {
312 discard.data.should_skip = true;
313 return;
314 }
315 },
316 else => {},
317 }
318 scope = scope.parent.?;
319 }
320 }
321 };
322}