diff --git a/internal/worldgen/gen.go b/internal/worldgen/gen.go index 77f63168..dfbf1d17 100644 --- a/internal/worldgen/gen.go +++ b/internal/worldgen/gen.go @@ -46,6 +46,7 @@ type Generator struct { // 常用方块状态(启动时从注册表解析一次) stone, grass, dirt, bedrock, sand, water, snowB, log, leaves block.State coal, iron, gold, diamond, redstone block.State + planks, cobble, torch block.State // 村庄建筑用 } // New 创建生成器;必须的方块缺注册时报错。 @@ -105,6 +106,15 @@ func New(reg *block.Registry, seed int64, biomeScale, heightScale, caveDensity f if g.redstone, err = must(reg, "redstone_ore"); err != nil { return nil, err } + if g.planks, err = must(reg, "oak_planks"); err != nil { + return nil, err + } + if g.cobble, err = must(reg, "cobblestone"); err != nil { + return nil, err + } + if g.torch, err = must(reg, "torch"); err != nil { + return nil, err + } return g, nil } @@ -237,6 +247,8 @@ func (g *Generator) Generate(cx, cz int32) *chunk.Chunk { } // 树后处理 pass(世界生态.md §3.1:边缘留白避免跨区块,树冠不出界) g.placeTrees(c) + // 村庄结构 pass(村民系统.md §2:网格撒点 + 水井 + 房屋) + g.placeVillage(c, cx, cz) return c } diff --git a/internal/worldgen/gen_test.go b/internal/worldgen/gen_test.go index 89bb77a9..081db144 100644 --- a/internal/worldgen/gen_test.go +++ b/internal/worldgen/gen_test.go @@ -84,6 +84,48 @@ func TestTerrainStructure(t *testing.T) { } } +// TestVillage 村庄生成:存在村庄中心的区块应有木板/圆石建筑(村民系统.md §2)。 +func TestVillage(t *testing.T) { + reg := loadReg(t) + planks, _ := reg.ID("oak_planks") + cobble, _ := reg.ID("cobblestone") + g, err := New(reg, 424242, 0.005, 0.01, 0.1) + if err != nil { + t.Fatalf("创建生成器失败: %v", err) + } + // 扫描网格点找村庄 + found := 0 + for gx := int32(-2); gx <= 2; gx++ { + for gz := int32(-2); gz <= 2; gz++ { + vx, vz := g.villageCenter(gx, gz) + b := g.biomeAt(vx, vz) + if b != biomePlains && b != biomeForest { + continue + } + cx, cz := floorDiv32(vx, 16), floorDiv32(vz, 16) + ch := g.Generate(cx, cz) + plankCnt, cobbleCnt := 0, 0 + snap := ch.Snapshot() + for i := 0; i < 16*16*256; i++ { + switch snap[i].ID() { + case planks: + plankCnt++ + case cobble: + cobbleCnt++ + } + } + // 建筑跨区块:中心区块至少包含部分房屋/水井 + if plankCnt < 20 || cobbleCnt == 0 { + t.Fatalf("村庄区块 (%d,%d) 建筑过少: 木板 %d 圆石 %d", cx, cz, plankCnt, cobbleCnt) + } + found++ + } + } + if found == 0 { + t.Fatal("5×5 网格点内未发现村庄") + } +} + // TestOres 验证矿物只出现在规定深度区间(挖矿与矿物.md §2:y=100 只允许石头/煤矿)。 func TestOres(t *testing.T) { reg := loadReg(t) diff --git a/internal/worldgen/village.go b/internal/worldgen/village.go new file mode 100644 index 00000000..e43918b7 --- /dev/null +++ b/internal/worldgen/village.go @@ -0,0 +1,130 @@ +// 村庄生成:结构 pass(村民系统.md §2、世界生态.md §3)。 +// +// 规则:村庄按 384 格网格撒点(噪声抖动选位,仅平原/森林群系), +// 每个村庄水井 + 3 间房屋;建筑按绝对坐标定义,跨区块落位(世界生成.md §4)。 +package worldgen + +import ( + "mc/internal/block" + "mc/internal/chunk" +) + +// 村庄参数(村民系统.md §2)。 +const ( + villageSpacing = 384 // 村庄网格间距(格) + villageJitter = 96 // 中心抖动半径 + villageRadius = 32 // 村庄建筑最大半径(区块跨越判定) +) + +// villageCenter 返回网格点 (gx, gz) 派生出的村庄中心绝对坐标。 +func (g *Generator) villageCenter(gx, gz int32) (int32, int32) { + jx := int32(g.ore.Eval2(float64(gx)*7.7+91, float64(gz)*3.1+17) * villageJitter) + jz := int32(g.ore.Eval2(float64(gx)*5.3+57, float64(gz)*8.9+29) * villageJitter) + return gx*villageSpacing + villageSpacing/2 + jx, gz*villageSpacing + villageSpacing/2 + jz +} + +// placeVillage 生成跨越本区块的村庄建筑(世界生成.md §4 跨区块安全)。 +func (g *Generator) placeVillage(c *chunk.Chunk, cx, cz int32) { + minX, maxX := cx*16, cx*16+15 + minZ, maxZ := cz*16, cz*16+15 + // 附近的网格点(±1 个网格内即可覆盖) + for dgx := int32(-1); dgx <= 1; dgx++ { + for dgz := int32(-1); dgz <= 1; dgz++ { + gx := floorDiv32(cx*16, villageSpacing) + dgx + gz := floorDiv32(cz*16, villageSpacing) + dgz + vx, vz := g.villageCenter(gx, gz) + // 村庄建筑范围与本区块相交? + if vx < minX-villageRadius || vx > maxX+villageRadius || vz < minZ-villageRadius || vz > maxZ+villageRadius { + continue + } + // 群系白名单(沙漠/雪原不建村) + b := g.biomeAt(vx, vz) + if b != biomePlains && b != biomeForest { + continue + } + // 水井 + 房屋(绝对坐标,逐块过滤到当前区块) + h := int32(g.heightAt(vx, vz)) + g.placeWellAbs(c, cx, cz, vx, h, vz) + offsets := [][2]int32{{-12, -8}, {8, -10}, {-4, 12}} + for i, o := range offsets { + hx, hz := vx+o[0], vz+o[1] + hh := int32(g.heightAt(hx, hz)) + g.placeHouseAbs(c, cx, cz, hx, hh, hz, uint64(gx)*73856093^uint64(gz)*19349663^uint64(i)) + } + } + } +} + +// inChunk 判定绝对坐标是否属于区块 (cx, cz)。 +func inChunk(x, z, cx, cz int32) bool { + return floorDiv32(x, 16) == cx && floorDiv32(z, 16) == cz +} + +// setAbs 绝对坐标写入(跨区块过滤,世界生成.md §4)。 +func (g *Generator) setAbs(c *chunk.Chunk, cx, cz, x, y, z int32, s block.State) { + if y < 0 || y >= chunk.Height { + return + } + if !inChunk(x, z, cx, cz) { + return + } + c.Fill(int(x-cx*16), int(y), int(z-cz*16), s) +} + +// placeWellAbs 水井:圆石环 + 中心水(3×3,村民系统.md §2 布局)。 +func (g *Generator) placeWellAbs(c *chunk.Chunk, cx, cz, wx, h, wz int32) { + for dx := int32(-1); dx <= 1; dx++ { + for dz := int32(-1); dz <= 1; dz++ { + if dx == 0 && dz == 0 { + g.setAbs(c, cx, cz, wx+dx, h+1, wz+dz, g.water) // 井水 + } else { + g.setAbs(c, cx, cz, wx+dx, h+1, wz+dz, g.cobble) // 井沿 + } + } + } +} + +// placeHouseAbs 村民房屋:木板地基 + 墙高 3(门洞)+ 平顶外沿 + 四角火把。 +// 布局与 entity.Blueprint 一致(村民系统.md §6.2)。 +func (g *Generator) placeHouseAbs(c *chunk.Chunk, cx, cz, hx, h, hz int32, seed uint64) { + w, d := int32(5+seed%2), int32(5) // 5–6 × 5 + for x := int32(0); x < w; x++ { + for z := int32(0); z < d; z++ { + g.setAbs(c, cx, cz, hx+x, h+1, hz+z, g.planks) + } + } + // 墙(2 层,南侧门洞) + for y := int32(2); y <= 3; y++ { + for x := int32(0); x < w; x++ { + for z := int32(0); z < d; z++ { + edge := x == 0 || x == w-1 || z == 0 || z == d-1 + if !edge { + continue + } + if y == 2 && z == d-1 && x == w/2 { + continue // 门洞 + } + g.setAbs(c, cx, cz, hx+x, h+y, hz+z, g.planks) + } + } + } + // 屋顶外沿 + for x := int32(-1); x <= w; x++ { + for z := int32(-1); z <= d; z++ { + g.setAbs(c, cx, cz, hx+x, h+4, hz+z, g.planks) + } + } + // 四角火把 + for _, cc := range [4][2]int32{{0, 0}, {w - 1, 0}, {0, d - 1}, {w - 1, d - 1}} { + g.setAbs(c, cx, cz, hx+cc[0], h+3, hz+cc[1], g.torch) + } +} + +// floorDiv32 负安全除法(villageCenter 网格定位)。 +func floorDiv32(a, b int32) int32 { + q := a / b + if a%b < 0 { + q-- + } + return q +} diff --git a/tools/zig-x86_64-windows-0.14.1/LICENSE b/tools/zig-x86_64-windows-0.14.1/LICENSE new file mode 100644 index 00000000..9ce01373 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/LICENSE @@ -0,0 +1,21 @@ +The MIT License (Expat) + +Copyright (c) Zig contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tools/zig-x86_64-windows-0.14.1/README.md b/tools/zig-x86_64-windows-0.14.1/README.md new file mode 100644 index 00000000..818a7d67 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/README.md @@ -0,0 +1,147 @@ +![ZIG](https://ziglang.org/img/zig-logo-dynamic.svg) + +A general-purpose programming language and toolchain for maintaining +**robust**, **optimal**, and **reusable** software. + +https://ziglang.org/ + +## Documentation + +If you are looking at this README file in a source tree, please refer to the +**Release Notes**, **Language Reference**, or **Standard Library +Documentation** corresponding to the version of Zig that you are using by +following the appropriate link on the +[download page](https://ziglang.org/download). + +Otherwise, you're looking at a release of Zig, so you can find the language +reference at `doc/langref.html`, and the standard library documentation by +running `zig std`, which will open a browser tab. + +## Installation + + * [download a pre-built binary](https://ziglang.org/download/) + * [install from a package manager](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager) + * [bootstrap zig for any target](https://github.com/ziglang/zig-bootstrap) + +A Zig installation is composed of two things: + +1. The Zig executable +2. The lib/ directory + +At runtime, the executable searches up the file system for the lib/ directory, +relative to itself: + +* lib/ +* lib/zig/ +* ../lib/ +* ../lib/zig/ +* (and so on) + +In other words, you can **unpack a release of Zig anywhere**, and then begin +using it immediately. There is no need to install it globally, although this +mechanism supports that use case too (i.e. `/usr/bin/zig` and `/usr/lib/zig/`). + +## Building from Source + +Ensure you have the required dependencies: + + * CMake >= 3.15 + * System C/C++ Toolchain + * LLVM, Clang, LLD development libraries == 19.x + +Then it is the standard CMake build process: + +``` +mkdir build +cd build +cmake .. +make install +``` + +For more options, tips, and troubleshooting, please see the +[Building Zig From Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source) +page on the wiki. + +## Building from Source without LLVM + +In this case, the only system dependency is a C compiler. + +``` +cc -o bootstrap bootstrap.c +./bootstrap +``` + +This produces a `zig2` executable in the current working directory. This is a +"stage2" build of the compiler, +[without LLVM extensions](https://github.com/ziglang/zig/issues/16270), and is +therefore lacking these features: +- Release mode optimizations +- [aarch64 machine code backend](https://github.com/ziglang/zig/issues/21172) +- [@cImport](https://github.com/ziglang/zig/issues/20630) +- [zig translate-c](https://github.com/ziglang/zig/issues/20875) +- [Ability to compile assembly files](https://github.com/ziglang/zig/issues/21169) +- [Some ELF linking features](https://github.com/ziglang/zig/issues/17749) +- [Most COFF/PE linking features](https://github.com/ziglang/zig/issues/17751) +- [Some WebAssembly linking features](https://github.com/ziglang/zig/issues/17750) +- [Ability to create import libs from def files](https://github.com/ziglang/zig/issues/17807) +- [Ability to create static archives from object files](https://github.com/ziglang/zig/issues/9828) +- Ability to compile C, C++, Objective-C, and Objective-C++ files + +However, a compiler built this way does provide a C backend, which may be +useful for creating system packages of Zig projects using the system C +toolchain. **In this case, LLVM is not needed!** + +Furthermore, a compiler built this way provides an LLVM backend that produces +bitcode files, which may be compiled into object files via a system Clang +package. This can be used to produce system packages of Zig applications +without the Zig package dependency on LLVM. + +## Contributing + +[Donate monthly](https://ziglang.org/zsf/). + +Zig is Free and Open Source Software. We welcome bug reports and patches from +everyone. However, keep in mind that Zig governance is BDFN (Benevolent +Dictator For Now) which means that Andrew Kelley has final say on the design +and implementation of everything. + +One of the best ways you can contribute to Zig is to start using it for an +open-source personal project. + +This leads to discovering bugs and helps flesh out use cases, which lead to +further design iterations of Zig. Importantly, each issue found this way comes +with real world motivations, making it straightforward to explain the reasoning +behind proposals and feature requests. + +You will be taken much more seriously on the issue tracker if you have a +personal project that uses Zig. + +The issue label +[Contributor Friendly](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributor+friendly%22) +exists to help you find issues that are **limited in scope and/or knowledge of +Zig internals.** + +Please note that issues labeled +[Proposal](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal) +but do not also have the +[Accepted](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aaccepted) +label are still under consideration, and efforts to implement such a proposal +have a high risk of being wasted. If you are interested in a proposal which is +still under consideration, please express your interest in the issue tracker, +providing extra insights and considerations that others have not yet expressed. +The most highly regarded argument in such a discussion is a real world use case. + +For more tips, please see the +[Contributing](https://github.com/ziglang/zig/wiki/Contributing) page on the +wiki. + +## Community + +The Zig community is decentralized. Anyone is free to start and maintain their +own space for Zig users to gather. There is no concept of "official" or +"unofficial". Each gathering place has its own moderators and rules. Users are +encouraged to be aware of the social structures of the spaces they inhabit, and +work purposefully to facilitate spaces that align with their values. + +Please see the [Community](https://github.com/ziglang/zig/wiki/Community) wiki +page for a public listing of social spaces. diff --git a/tools/zig-x86_64-windows-0.14.1/doc/langref.html b/tools/zig-x86_64-windows-0.14.1/doc/langref.html new file mode 100644 index 00000000..87654e14 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/doc/langref.html @@ -0,0 +1,15939 @@ + + + + + + + Documentation - The Zig Programming Language + + + + + +

Zig Language Reference

+
+ +
+

Introduction §

+ +

+ Zig is a general-purpose programming language and toolchain for maintaining + robust, optimal, and reusable software. +

+
+
Robust
Behavior is correct even for edge cases such as out of memory.
+
Optimal
Write programs the best way they can behave and perform.
+
Reusable
The same code works in many environments which have different + constraints.
+
Maintainable
Precisely communicate intent to the compiler and + other programmers. The language imposes a low overhead to reading code and is + resilient to changing requirements and environments.
+
+

+ Often the most efficient way to learn something new is to see examples, so + this documentation shows how to use each of Zig's features. It is + all on one page so you can search with your browser's search tool. +

+

+ The code samples in this document are compiled and tested as part of the main test suite of Zig. +

+

+ This HTML document depends on no external files, so you can use it offline. +

+ + +

Zig Standard Library §

+ +

+ The Zig Standard Library has its own documentation. +

+

+ Zig's Standard Library contains commonly used algorithms, data structures, and definitions to help you build programs or libraries. + You will see many examples of Zig's Standard Library used in this documentation. To learn more about the Zig Standard Library, + visit the link above. +

+

+ Alternatively, the Zig Standard Library documentation is provided with each Zig distribution. It can be rendered via a local webserver with: +

+
Shell
zig std
+
+ + +

Hello World §

+ + +
hello.zig
const std = @import("std");
+
+pub fn main() !void {
+    const stdout = std.io.getStdOut().writer();
+    try stdout.print("Hello, {s}!\n", .{"world"});
+}
Shell
$ zig build-exe hello.zig
+$ ./hello
+Hello, world!
+
+ +

+ Most of the time, it is more appropriate to write to stderr rather than stdout, and + whether or not the message is successfully written to the stream is irrelevant. + For this common case, there is a simpler API: +

+
hello_again.zig
const std = @import("std");
+
+pub fn main() void {
+    std.debug.print("Hello, world!\n", .{});
+}
Shell
$ zig build-exe hello_again.zig
+$ ./hello_again
+Hello, world!
+
+ +

+ In this case, the ! may be omitted from the return + type of main because no errors are returned from the function. +

+

See also:

+ + +

Comments §

+ +

+ Zig supports 3 types of comments. Normal comments are ignored, but doc comments + and top-level doc comments are used by the compiler to generate the package documentation. +

+

+ The generated documentation is still experimental, and can be produced with: +

+
Shell
zig test -femit-docs main.zig
+
+
comments.zig
const print = @import("std").debug.print;
+
+pub fn main() void {
+    // Comments in Zig start with "//" and end at the next LF byte (end of line).
+    // The line below is a comment and won't be executed.
+
+    //print("Hello?", .{});
+
+    print("Hello, world!\n", .{}); // another comment
+}
Shell
$ zig build-exe comments.zig
+$ ./comments
+Hello, world!
+
+ +

+ There are no multiline comments in Zig (e.g. like /* */ + comments in C). This allows Zig to have the property that each line + of code can be tokenized out of context. +

+

Doc Comments §

+ +

+ A doc comment is one that begins with exactly three slashes (i.e. + /// but not ////); + multiple doc comments in a row are merged together to form a multiline + doc comment. The doc comment documents whatever immediately follows it. +

+
doc_comments.zig
/// A structure for storing a timestamp, with nanosecond precision (this is a
+/// multiline doc comment).
+const Timestamp = struct {
+    /// The number of seconds since the epoch (this is also a doc comment).
+    seconds: i64, // signed so we can represent pre-1970 (not a doc comment)
+    /// The number of nanoseconds past the second (doc comment again).
+    nanos: u32,
+
+    /// Returns a `Timestamp` struct representing the Unix epoch; that is, the
+    /// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).
+    pub fn unixEpoch() Timestamp {
+        return Timestamp{
+            .seconds = 0,
+            .nanos = 0,
+        };
+    }
+};
+ +

+ Doc comments are only allowed in certain places; it is a compile error to + have a doc comment in an unexpected place, such as in the middle of an expression, + or just before a non-doc comment. +

+
invalid_doc-comment.zig
/// doc-comment
+//! top-level doc-comment
+const std = @import("std");
Shell
$ zig build-obj invalid_doc-comment.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/invalid_doc-comment.zig:1:16: error: expected type expression, found 'a document comment'
+/// doc-comment
+               ^
+
+
+ +
unattached_doc-comment.zig
pub fn main() void {}
+
+/// End of file
Shell
$ zig build-obj unattached_doc-comment.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/unattached_doc-comment.zig:3:1: error: unattached documentation comment
+/// End of file
+^~~~~~~~~~~~~~~
+
+
+ +

+ Doc comments can be interleaved with normal comments. Currently, when producing + the package documentation, normal comments are merged with doc comments. +

+ +

Top-Level Doc Comments §

+ +

+ A top-level doc comment is one that begins with two slashes and an exclamation + point: //!; it documents the current module. +

+

+ It is a compile error if a top-level doc comment is not placed at the start + of a container, before any expressions. +

+
tldoc_comments.zig
//! This module provides functions for retrieving the current date and
+//! time with varying degrees of precision and accuracy. It does not
+//! depend on libc, but will use functions from it if available.
+
+const S = struct {
+    //! Top level comments are allowed inside a container other than a module,
+    //! but it is not very useful.  Currently, when producing the package
+    //! documentation, these comments are ignored.
+};
+ + + +

Values §

+ +
values.zig
// Top-level declarations are order-independent:
+const print = std.debug.print;
+const std = @import("std");
+const os = std.os;
+const assert = std.debug.assert;
+
+pub fn main() void {
+    // integers
+    const one_plus_one: i32 = 1 + 1;
+    print("1 + 1 = {}\n", .{one_plus_one});
+
+    // floats
+    const seven_div_three: f32 = 7.0 / 3.0;
+    print("7.0 / 3.0 = {}\n", .{seven_div_three});
+
+    // boolean
+    print("{}\n{}\n{}\n", .{
+        true and false,
+        true or false,
+        !true,
+    });
+
+    // optional
+    var optional_value: ?[]const u8 = null;
+    assert(optional_value == null);
+
+    print("\noptional 1\ntype: {}\nvalue: {?s}\n", .{
+        @TypeOf(optional_value), optional_value,
+    });
+
+    optional_value = "hi";
+    assert(optional_value != null);
+
+    print("\noptional 2\ntype: {}\nvalue: {?s}\n", .{
+        @TypeOf(optional_value), optional_value,
+    });
+
+    // error union
+    var number_or_error: anyerror!i32 = error.ArgNotFound;
+
+    print("\nerror union 1\ntype: {}\nvalue: {!}\n", .{
+        @TypeOf(number_or_error),
+        number_or_error,
+    });
+
+    number_or_error = 1234;
+
+    print("\nerror union 2\ntype: {}\nvalue: {!}\n", .{
+        @TypeOf(number_or_error), number_or_error,
+    });
+}
Shell
$ zig build-exe values.zig
+$ ./values
+1 + 1 = 2
+7.0 / 3.0 = 2.3333333e0
+false
+true
+false
+
+optional 1
+type: ?[]const u8
+value: null
+
+optional 2
+type: ?[]const u8
+value: hi
+
+error union 1
+type: anyerror!i32
+value: error.ArgNotFound
+
+error union 2
+type: anyerror!i32
+value: 1234
+
+ +

Primitive Types §

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Primitive Types
TypeC EquivalentDescription
i8int8_tsigned 8-bit integer
u8uint8_tunsigned 8-bit integer
i16int16_tsigned 16-bit integer
u16uint16_tunsigned 16-bit integer
i32int32_tsigned 32-bit integer
u32uint32_tunsigned 32-bit integer
i64int64_tsigned 64-bit integer
u64uint64_tunsigned 64-bit integer
i128__int128signed 128-bit integer
u128unsigned __int128unsigned 128-bit integer
isizeintptr_tsigned pointer sized integer
usizeuintptr_t, size_tunsigned pointer sized integer. Also see #5185
c_charcharfor ABI compatibility with C
c_shortshortfor ABI compatibility with C
c_ushortunsigned shortfor ABI compatibility with C
c_intintfor ABI compatibility with C
c_uintunsigned intfor ABI compatibility with C
c_longlongfor ABI compatibility with C
c_ulongunsigned longfor ABI compatibility with C
c_longlonglong longfor ABI compatibility with C
c_ulonglongunsigned long longfor ABI compatibility with C
c_longdoublelong doublefor ABI compatibility with C
f16_Float1616-bit floating point (10-bit mantissa) IEEE-754-2008 binary16
f32float32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32
f64double64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64
f80long double80-bit floating point (64-bit mantissa) IEEE-754-2008 80-bit extended precision
f128_Float128128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128
boolbooltrue or false
anyopaquevoidUsed for type-erased pointers.
void(none)Always the value void{}
noreturn(none)the type of break, continue, return, unreachable, and while (true) {}
type(none)the type of types
anyerror(none)an error code
comptime_int(none)Only allowed for comptime-known values. The type of integer literals.
comptime_float(none)Only allowed for comptime-known values. The type of float literals.
+
+

+ In addition to the integer types above, arbitrary bit-width integers can be referenced by using + an identifier of i or u followed by digits. For example, the identifier + i7 refers to a signed 7-bit integer. The maximum allowed bit-width of an + integer type is 65535. +

+

See also:

+ + +

Primitive Values §

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
Primitive Values
NameDescription
true and falsebool values
nullused to set an optional type to null
undefinedused to leave a value unspecified
+
+

See also:

+ + +

String Literals and Unicode Code Point Literals §

+ +

+ String literals are constant single-item Pointers to null-terminated byte arrays. + The type of string literals encodes both the length, and the fact that they are null-terminated, + and thus they can be coerced to both Slices and + Null-Terminated Pointers. + Dereferencing string literals converts them to Arrays. +

+

+ Because Zig source code is UTF-8 encoded, any + non-ASCII bytes appearing within a string literal in source code carry + their UTF-8 meaning into the content of the string in the Zig program; + the bytes are not modified by the compiler. It is possible to embed + non-UTF-8 bytes into a string literal using \xNN notation. +

+

Indexing into a string containing non-ASCII bytes returns individual + bytes, whether valid UTF-8 or not.

+

+ Unicode code point literals have type comptime_int, the same as + Integer Literals. All Escape Sequences are valid in both string literals + and Unicode code point literals. +

+
string_literals.zig
const print = @import("std").debug.print;
+const mem = @import("std").mem; // will be used to compare bytes
+
+pub fn main() void {
+    const bytes = "hello";
+    print("{}\n", .{@TypeOf(bytes)}); // *const [5:0]u8
+    print("{d}\n", .{bytes.len}); // 5
+    print("{c}\n", .{bytes[1]}); // 'e'
+    print("{d}\n", .{bytes[5]}); // 0
+    print("{}\n", .{'e' == '\x65'}); // true
+    print("{d}\n", .{'\u{1f4a9}'}); // 128169
+    print("{d}\n", .{'💯'}); // 128175
+    print("{u}\n", .{'⚡'});
+    print("{}\n", .{mem.eql(u8, "hello", "h\x65llo")}); // true
+    print("{}\n", .{mem.eql(u8, "💯", "\xf0\x9f\x92\xaf")}); // also true
+    const invalid_utf8 = "\xff\xfe"; // non-UTF-8 strings are possible with \xNN notation.
+    print("0x{x}\n", .{invalid_utf8[1]}); // indexing them returns individual bytes...
+    print("0x{x}\n", .{"💯"[1]}); // ...as does indexing part-way through non-ASCII characters
+}
Shell
$ zig build-exe string_literals.zig
+$ ./string_literals
+*const [5:0]u8
+5
+e
+0
+true
+128169
+128175
+⚡
+true
+true
+0xfe
+0x9f
+
+ +

See also:

+ +

Escape Sequences §

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Escape Sequences
Escape SequenceName
\nNewline
\rCarriage Return
\tTab
\\Backslash
\'Single Quote
\"Double Quote
\xNNhexadecimal 8-bit byte value (2 digits)
\u{NNNNNN}hexadecimal Unicode scalar value UTF-8 encoded (1 or more digits)
+
+

Note that the maximum valid Unicode scalar value is 0x10ffff.

+ +

Multiline String Literals §

+ +

+ Multiline string literals have no escapes and can span across multiple lines. + To start a multiline string literal, use the \\ token. Just like a comment, + the string literal goes until the end of the line. The end of the line is + not included in the string literal. + However, if the next line begins with \\ then a newline is appended and + the string literal continues. +

+
multiline_string_literals.zig
const hello_world_in_c =
+    \\#include <stdio.h>
+    \\
+    \\int main(int argc, char **argv) {
+    \\    printf("hello world\n");
+    \\    return 0;
+    \\}
+;
+ +

See also:

+ + + +

Assignment §

+ +

Use the const keyword to assign a value to an identifier:

+
constant_identifier_cannot_change.zig
const x = 1234;
+
+fn foo() void {
+    // It works at file scope as well as inside functions.
+    const y = 5678;
+
+    // Once assigned, an identifier cannot be changed.
+    y += 1;
+}
+
+pub fn main() void {
+    foo();
+}
Shell
$ zig build-exe constant_identifier_cannot_change.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/constant_identifier_cannot_change.zig:8:7: error: cannot assign to constant
+    y += 1;
+    ~~^~~~
+referenced by:
+    main: /home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/constant_identifier_cannot_change.zig:12:8
+    posixCallMainAndExit: /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22
+    4 reference(s) hidden; use '-freference-trace=6' to see all references
+
+
+ +

const applies to all of the bytes that the identifier immediately addresses. Pointers have their own const-ness.

+

If you need a variable that you can modify, use the var keyword:

+
mutable_var.zig
const print = @import("std").debug.print;
+
+pub fn main() void {
+    var y: i32 = 5678;
+
+    y += 1;
+
+    print("{d}", .{y});
+}
Shell
$ zig build-exe mutable_var.zig
+$ ./mutable_var
+5679
+
+ +

Variables must be initialized:

+
var_must_be_initialized.zig
pub fn main() void {
+    var x: i32;
+
+    x = 1;
+}
Shell
$ zig build-exe var_must_be_initialized.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/var_must_be_initialized.zig:2:15: error: expected '=', found ';'
+    var x: i32;
+              ^
+
+
+ +

undefined §

+ +

Use undefined to leave variables uninitialized:

+
assign_undefined.zig
const print = @import("std").debug.print;
+
+pub fn main() void {
+    var x: i32 = undefined;
+    x = 1;
+    print("{d}", .{x});
+}
Shell
$ zig build-exe assign_undefined.zig
+$ ./assign_undefined
+1
+
+ +

+ undefined can be coerced to any type. + Once this happens, it is no longer possible to detect that the value is undefined. + undefined means the value could be anything, even something that is nonsense + according to the type. Translated into English, undefined means "Not a meaningful + value. Using this value would be a bug. The value will be unused, or overwritten before being used." +

+

+ In Debug mode, Zig writes 0xaa bytes to undefined memory. This is to catch + bugs early, and to help detect use of undefined memory in a debugger. However, this behavior is only an + implementation feature, not a language semantic, so it is not guaranteed to be observable to code. +

+ + +

Destructuring §

+ +

+ A destructuring assignment can separate elements of indexable aggregate types + (Tuples, Arrays, Vectors): +

+
destructuring_to_existing.zig
const print = @import("std").debug.print;
+
+pub fn main() void {
+    var x: u32 = undefined;
+    var y: u32 = undefined;
+    var z: u32 = undefined;
+
+    const tuple = .{ 1, 2, 3 };
+
+    x, y, z = tuple;
+
+    print("tuple: x = {}, y = {}, z = {}\n", .{x, y, z});
+
+    const array = [_]u32{ 4, 5, 6 };
+
+    x, y, z = array;
+
+    print("array: x = {}, y = {}, z = {}\n", .{x, y, z});
+
+    const vector: @Vector(3, u32) = .{ 7, 8, 9 };
+
+    x, y, z = vector;
+
+    print("vector: x = {}, y = {}, z = {}\n", .{x, y, z});
+}
Shell
$ zig build-exe destructuring_to_existing.zig
+$ ./destructuring_to_existing
+tuple: x = 1, y = 2, z = 3
+array: x = 4, y = 5, z = 6
+vector: x = 7, y = 8, z = 9
+
+ +

+ A destructuring expression may only appear within a block (i.e. not at container scope). + The left hand side of the assignment must consist of a comma separated list, + each element of which may be either an lvalue (for instance, an existing `var`) or a variable declaration: +

+
destructuring_mixed.zig
const print = @import("std").debug.print;
+
+pub fn main() void {
+    var x: u32 = undefined;
+
+    const tuple = .{ 1, 2, 3 };
+
+    x, var y : u32, const z = tuple;
+
+    print("x = {}, y = {}, z = {}\n", .{x, y, z});
+
+    // y is mutable
+    y = 100;
+
+    // You can use _ to throw away unwanted values.
+    _, x, _ = tuple;
+
+    print("x = {}", .{x});
+}
Shell
$ zig build-exe destructuring_mixed.zig
+$ ./destructuring_mixed
+x = 1, y = 2, z = 3
+x = 2
+
+ +

+ A destructure may be prefixed with the comptime keyword, in which case the entire + destructure expression is evaluated at comptime. All vars declared would + be comptime vars and all expressions (both result locations and the assignee + expression) are evaluated at comptime. +

+ +

See also:

+ + + + +

Zig Test §

+ +

+ Code written within one or more test declarations can be used to ensure behavior meets expectations: +

+
testing_introduction.zig
const std = @import("std");
+
+test "expect addOne adds one to 41" {
+
+    // The Standard Library contains useful functions to help create tests.
+    // `expect` is a function that verifies its argument is true.
+    // It will return an error if its argument is false to indicate a failure.
+    // `try` is used to return an error to the test runner to notify it that the test failed.
+    try std.testing.expect(addOne(41) == 42);
+}
+
+test addOne {
+    // A test name can also be written using an identifier.
+    // This is a doctest, and serves as documentation for `addOne`.
+    try std.testing.expect(addOne(41) == 42);
+}
+
+/// The function `addOne` adds one to the number given as its argument.
+fn addOne(number: i32) i32 {
+    return number + 1;
+}
Shell
$ zig test testing_introduction.zig
+1/2 testing_introduction.test.expect addOne adds one to 41...OK
+2/2 testing_introduction.decltest.addOne...OK
+All 2 tests passed.
+
+ +

+ The testing_introduction.zig code sample tests the function + addOne to ensure that it returns 42 given the input + 41. From this test's perspective, the addOne function is + said to be code under test. +

+

+ zig test is a tool that creates and runs a test build. By default, it builds and runs an + executable program using the default test runner provided by the Zig Standard Library + as its main entry point. During the build, test declarations found while + resolving the given Zig source file are included for the default test runner + to run and report on. +

+ +

+ The shell output shown above displays two lines after the zig test command. These lines are + printed to standard error by the default test runner: +

+
+
1/2 testing_introduction.test.expect addOne adds one to 41...
+
Lines like this indicate which test, out of the total number of tests, is being run. + In this case, 1/2 indicates that the first test, out of a total of two tests, + is being run. Note that, when the test runner program's standard error is output + to the terminal, these lines are cleared when a test succeeds. +
+
2/2 testing_introduction.decltest.addOne...
+
When the test name is an identifier, the default test runner uses the text + decltest instead of test. +
+
All 2 tests passed.
+
This line indicates the total number of tests that have passed.
+
+

Test Declarations §

+ +

+ Test declarations contain the keyword test, followed by an + optional name written as a string literal or an + identifier, followed by a block containing any valid Zig code that + is allowed in a function. +

+

Non-named test blocks always run during test builds and are exempt from + Skip Tests.

+

+ Test declarations are similar to Functions: they have a return type and a block of code. The implicit + return type of test is the Error Union Type anyerror!void, + and it cannot be changed. When a Zig source file is not built using the zig test tool, the test + declarations are omitted from the build. +

+

+ Test declarations can be written in the same file, where code under test is written, or in a separate Zig source file. + Since test declarations are top-level declarations, they are order-independent and can + be written before or after the code under test. +

+

See also:

+ +

Doctests §

+ +

+ Test declarations named using an identifier are doctests. The identifier must refer to another declaration in + scope. A doctest, like a doc comment, serves as documentation for the associated declaration, and + will appear in the generated documentation for the declaration. +

+

+ An effective doctest should be self-contained and focused on the declaration being tested, answering questions a new + user might have about its interface or intended usage, while avoiding unnecessary or confusing details. A doctest is not + a substitute for a doc comment, but rather a supplement and companion providing a testable, code-driven example, verified + by zig test. +

+ + +

Test Failure §

+ +

+ The default test runner checks for an error returned from a test. + When a test returns an error, the test is considered a failure and its error return trace + is output to standard error. The total number of failures will be reported after all tests have run. +

+
testing_failure.zig
const std = @import("std");
+
+test "expect this to fail" {
+    try std.testing.expect(false);
+}
+
+test "expect this to succeed" {
+    try std.testing.expect(true);
+}
Shell
$ zig test testing_failure.zig
+1/2 testing_failure.test.expect this to fail...FAIL (TestUnexpectedResult)
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/testing.zig:580:14: 0x104865f in expect (test)
+    if (!ok) return error.TestUnexpectedResult;
+             ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/testing_failure.zig:4:5: 0x10486f5 in test.expect this to fail (test)
+    try std.testing.expect(false);
+    ^
+2/2 testing_failure.test.expect this to succeed...OK
+1 passed; 0 skipped; 1 failed.
+error: the following test command failed with exit code 1:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/4a2fad21710c87bc1399179ccb2726ce/test --seed=0xe0a3c2ed
+
+ + +

Skip Tests §

+ +

+ One way to skip tests is to filter them out by using the zig test command line parameter + --test-filter [text]. This makes the test build only include tests whose name contains the + supplied filter text. Note that non-named tests are run even when using the --test-filter [text] + command line parameter. +

+

+ To programmatically skip a test, make a test return the error + error.SkipZigTest and the default test runner will consider the test as being skipped. + The total number of skipped tests will be reported after all tests have run. +

+
testing_skip.zig
test "this will be skipped" {
+    return error.SkipZigTest;
+}
Shell
$ zig test testing_skip.zig
+1/1 testing_skip.test.this will be skipped...SKIP
+0 passed; 1 skipped; 0 failed.
+
+ + + +

Report Memory Leaks §

+ +

+ When code allocates Memory using the Zig Standard Library's testing allocator, + std.testing.allocator, the default test runner will report any leaks that are + found from using the testing allocator: +

+
testing_detect_leak.zig
const std = @import("std");
+
+test "detect leak" {
+    var list = std.ArrayList(u21).init(std.testing.allocator);
+    // missing `defer list.deinit();`
+    try list.append('☔');
+
+    try std.testing.expect(list.items.len == 1);
+}
Shell
$ zig test testing_detect_leak.zig
+1/1 testing_detect_leak.test.detect leak...OK
+[gpa] (err): memory address 0x7f6e07100000 leaked:
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/array_list.zig:474:67: 0x10693e2 in ensureTotalCapacityPrecise (test)
+                const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
+                                                                  ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/array_list.zig:450:51: 0x104e8c0 in ensureTotalCapacity (test)
+            return self.ensureTotalCapacityPrecise(better_capacity);
+                                                  ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/array_list.zig:500:41: 0x104cbef in addOne (test)
+            try self.ensureTotalCapacity(newlen);
+                                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/array_list.zig:261:49: 0x104a73d in append (test)
+            const new_item_ptr = try self.addOne();
+                                                ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/testing_detect_leak.zig:6:20: 0x10489d5 in test.detect leak (test)
+    try list.append('☔');
+                   ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10f77b9 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10f17bd in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10f0c32 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10f080d in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+
+All 1 tests passed.
+1 errors were logged.
+1 tests leaked memory.
+error: the following test command failed with exit code 1:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/fcfcd97a1656e2f497a263e3f045a84e/test --seed=0x9f0a3328
+
+ +

See also:

+ + +

Detecting Test Build §

+ +

+ Use the compile variable @import("builtin").is_test + to detect a test build: +

+
testing_detect_test.zig
const std = @import("std");
+const builtin = @import("builtin");
+const expect = std.testing.expect;
+
+test "builtin.is_test" {
+    try expect(isATest());
+}
+
+fn isATest() bool {
+    return builtin.is_test;
+}
Shell
$ zig test testing_detect_test.zig
+1/1 testing_detect_test.test.builtin.is_test...OK
+All 1 tests passed.
+
+ + +

Test Output and Logging §

+ +

+ The default test runner and the Zig Standard Library's testing namespace output messages to standard error. +

+ +

The Testing Namespace §

+ +

+ The Zig Standard Library's testing namespace contains useful functions to help + you create tests. In addition to the expect function, this document uses a couple of more functions + as exemplified here: +

+
testing_namespace.zig
const std = @import("std");
+
+test "expectEqual demo" {
+    const expected: i32 = 42;
+    const actual = 42;
+
+    // The first argument to `expectEqual` is the known, expected, result.
+    // The second argument is the result of some expression.
+    // The actual's type is casted to the type of expected.
+    try std.testing.expectEqual(expected, actual);
+}
+
+test "expectError demo" {
+    const expected_error = error.DemoError;
+    const actual_error_union: anyerror!void = error.DemoError;
+
+    // `expectError` will fail when the actual error is different than
+    // the expected error.
+    try std.testing.expectError(expected_error, actual_error_union);
+}
Shell
$ zig test testing_namespace.zig
+1/2 testing_namespace.test.expectEqual demo...OK
+2/2 testing_namespace.test.expectError demo...OK
+All 2 tests passed.
+
+ +

The Zig Standard Library also contains functions to compare Slices, strings, and more. See the rest of the + std.testing namespace in the Zig Standard Library for more available functions.

+ +

Test Tool Documentation §

+ +

+ zig test has a few command line parameters which affect the compilation. + See zig test --help for a full list. +

+ + + +

Variables §

+ +

+ A variable is a unit of Memory storage. +

+

+ It is generally preferable to use const rather than + var when declaring a variable. This causes less work for both + humans and computers to do when reading code, and creates more optimization opportunities. +

+

+ The extern keyword or @extern builtin function can be used to link against a variable that is exported + from another object. The export keyword or @export builtin function + can be used to make a variable available to other objects at link time. In both cases, + the type of the variable must be C ABI compatible. +

+

See also:

+ + +

Identifiers §

+ +

+ Variable identifiers are never allowed to shadow identifiers from an outer scope. +

+

+ Identifiers must start with an alphabetic character or underscore and may be followed + by any number of alphanumeric characters or underscores. + They must not overlap with any keywords. See Keyword Reference. +

+

+ If a name that does not fit these requirements is needed, such as for linking with external libraries, the @"" syntax may be used. +

+
identifiers.zig
const @"identifier with spaces in it" = 0xff;
+const @"1SmallStep4Man" = 112358;
+
+const c = @import("std").c;
+pub extern "c" fn @"error"() void;
+pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int;
+
+const Color = enum {
+    red,
+    @"really red",
+};
+const color: Color = .@"really red";
+ + + +

Container Level Variables §

+ +

+ Container level variables have static lifetime and are order-independent and lazily analyzed. + The initialization value of container level variables is implicitly + comptime. If a container level variable is const then its value is + comptime-known, otherwise it is runtime-known. +

+
test_container_level_variables.zig
var y: i32 = add(10, x);
+const x: i32 = add(12, 34);
+
+test "container level variables" {
+    try expect(x == 46);
+    try expect(y == 56);
+}
+
+fn add(a: i32, b: i32) i32 {
+    return a + b;
+}
+
+const std = @import("std");
+const expect = std.testing.expect;
Shell
$ zig test test_container_level_variables.zig
+1/1 test_container_level_variables.test.container level variables...OK
+All 1 tests passed.
+
+ +

+ Container level variables may be declared inside a struct, union, enum, or opaque: +

+
test_namespaced_container_level_variable.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "namespaced container level variable" {
+    try expect(foo() == 1235);
+    try expect(foo() == 1236);
+}
+
+const S = struct {
+    var x: i32 = 1234;
+};
+
+fn foo() i32 {
+    S.x += 1;
+    return S.x;
+}
Shell
$ zig test test_namespaced_container_level_variable.zig
+1/1 test_namespaced_container_level_variable.test.namespaced container level variable...OK
+All 1 tests passed.
+
+ + + +

Static Local Variables §

+ +

+ It is also possible to have local variables with static lifetime by using containers inside functions. +

+
test_static_local_variable.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "static local variable" {
+    try expect(foo() == 1235);
+    try expect(foo() == 1236);
+}
+
+fn foo() i32 {
+    const S = struct {
+        var x: i32 = 1234;
+    };
+    S.x += 1;
+    return S.x;
+}
Shell
$ zig test test_static_local_variable.zig
+1/1 test_static_local_variable.test.static local variable...OK
+All 1 tests passed.
+
+ + + +

Thread Local Variables §

+ +

A variable may be specified to be a thread-local variable using the + threadlocal keyword, + which makes each thread work with a separate instance of the variable:

+
test_thread_local_variables.zig
const std = @import("std");
+const assert = std.debug.assert;
+
+threadlocal var x: i32 = 1234;
+
+test "thread local storage" {
+    const thread1 = try std.Thread.spawn(.{}, testTls, .{});
+    const thread2 = try std.Thread.spawn(.{}, testTls, .{});
+    testTls();
+    thread1.join();
+    thread2.join();
+}
+
+fn testTls() void {
+    assert(x == 1234);
+    x += 1;
+    assert(x == 1235);
+}
Shell
$ zig test test_thread_local_variables.zig
+1/1 test_thread_local_variables.test.thread local storage...OK
+All 1 tests passed.
+
+ +

+ For Single Threaded Builds, all thread local variables are treated as regular Container Level Variables. +

+

+ Thread local variables may not be const. +

+ + +

Local Variables §

+ +

+ Local variables occur inside Functions, comptime blocks, and @cImport blocks. +

+

+ When a local variable is const, it means that after initialization, the variable's + value will not change. If the initialization value of a const variable is + comptime-known, then the variable is also comptime-known. +

+

+ A local variable may be qualified with the comptime keyword. This causes + the variable's value to be comptime-known, and all loads and stores of the + variable to happen during semantic analysis of the program, rather than at runtime. + All variables declared in a comptime expression are implicitly + comptime variables. +

+
test_comptime_variables.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "comptime vars" {
+    var x: i32 = 1;
+    comptime var y: i32 = 1;
+
+    x += 1;
+    y += 1;
+
+    try expect(x == 2);
+    try expect(y == 2);
+
+    if (y != 2) {
+        // This compile error never triggers because y is a comptime variable,
+        // and so `y != 2` is a comptime value, and this if is statically evaluated.
+        @compileError("wrong y value");
+    }
+}
Shell
$ zig test test_comptime_variables.zig
+1/1 test_comptime_variables.test.comptime vars...OK
+All 1 tests passed.
+
+ + + + +

Integers §

+ +

Integer Literals §

+ +
integer_literals.zig
const decimal_int = 98222;
+const hex_int = 0xff;
+const another_hex_int = 0xFF;
+const octal_int = 0o755;
+const binary_int = 0b11110000;
+
+// underscores may be placed between two digits as a visual separator
+const one_billion = 1_000_000_000;
+const binary_mask = 0b1_1111_1111;
+const permissions = 0o7_5_5;
+const big_address = 0xFF80_0000_0000_0000;
+ + +

Runtime Integer Values §

+ +

+ Integer literals have no size limitation, and if any Illegal Behavior occurs, + the compiler catches it. +

+

+ However, once an integer value is no longer known at compile-time, it must have a + known size, and is vulnerable to safety-checked Illegal Behavior. +

+
runtime_vs_comptime.zig
fn divide(a: i32, b: i32) i32 {
+    return a / b;
+}
+ +

+ In this function, values a and b are known only at runtime, + and thus this division operation is vulnerable to both Integer Overflow and + Division by Zero. +

+

+ Operators such as + and - cause Illegal Behavior on + integer overflow. Alternative operators are provided for wrapping and saturating arithmetic on all targets. + +% and -% perform wrapping arithmetic + while +| and -| perform saturating arithmetic. +

+

+ Zig supports arbitrary bit-width integers, referenced by using + an identifier of i or u followed by digits. For example, the identifier + i7 refers to a signed 7-bit integer. The maximum allowed bit-width of an + integer type is 65535. For signed integer types, Zig uses a + two's complement representation. +

+

See also:

+ + + +

Floats §

+ +

Zig has the following floating point types:

+
    +
  • f16 - IEEE-754-2008 binary16
  • +
  • f32 - IEEE-754-2008 binary32
  • +
  • f64 - IEEE-754-2008 binary64
  • +
  • f80 - IEEE-754-2008 80-bit extended precision
  • +
  • f128 - IEEE-754-2008 binary128
  • +
  • c_longdouble - matches long double for the target C ABI
  • +
+

Float Literals §

+ +

+ Float literals have type comptime_float which is guaranteed to have + the same precision and operations of the largest other floating point type, which is + f128. +

+

+ Float literals coerce to any floating point type, + and to any integer type when there is no fractional component. +

+
float_literals.zig
const floating_point = 123.0E+77;
+const another_float = 123.0;
+const yet_another = 123.0e+77;
+
+const hex_floating_point = 0x103.70p-5;
+const another_hex_float = 0x103.70;
+const yet_another_hex_float = 0x103.70P-5;
+
+// underscores may be placed between two digits as a visual separator
+const lightspeed = 299_792_458.000_000;
+const nanosecond = 0.000_000_001;
+const more_hex = 0x1234_5678.9ABC_CDEFp-10;
+ +

+ There is no syntax for NaN, infinity, or negative infinity. For these special values, + one must use the standard library: +

+
float_special_values.zig
const std = @import("std");
+
+const inf = std.math.inf(f32);
+const negative_inf = -std.math.inf(f64);
+const nan = std.math.nan(f128);
+ + +

Floating Point Operations §

+ +

By default floating point operations use Strict mode, + but you can switch to Optimized mode on a per-block basis:

+
float_mode_obj.zig
const std = @import("std");
+const big = @as(f64, 1 << 40);
+
+export fn foo_strict(x: f64) f64 {
+    return x + big - big;
+}
+
+export fn foo_optimized(x: f64) f64 {
+    @setFloatMode(.optimized);
+    return x + big - big;
+}
Shell
$ zig build-obj float_mode_obj.zig -O ReleaseFast
+
+ +

For this test we have to separate code into two object files - + otherwise the optimizer figures out all the values at compile-time, + which operates in strict mode.

+
float_mode_exe.zig
const print = @import("std").debug.print;
+
+extern fn foo_strict(x: f64) f64;
+extern fn foo_optimized(x: f64) f64;
+
+pub fn main() void {
+    const x = 0.001;
+    print("optimized = {}\n", .{foo_optimized(x)});
+    print("strict = {}\n", .{foo_strict(x)});
+}
+ +

See also:

+ + + +

Operators §

+ +

+ There is no operator overloading. When you see an operator in Zig, you know that + it is doing something from this table, and nothing else. +

+

Table of Operators §

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameSyntaxTypesRemarksExample
Addition
a + b
+a += b
+ + + + +
2 + 5 == 7
+
Wrapping Addition
a +% b
+a +%= b
+ + + + +
@as(u32, 0xffffffff) +% 1 == 0
+
Saturating Addition
a +| b
+a +|= b
+ + + + +
@as(u8, 255) +| 1 == @as(u8, 255)
+
Subtraction
a - b
+a -= b
+ + + + +
2 - 5 == -3
+
Wrapping Subtraction
a -% b
+a -%= b
+ + + + +
@as(u8, 0) -% 1 == 255
+
Saturating Subtraction
a -| b
+a -|= b
+ + + + +
@as(u32, 0) -| 1 == 0
+
Negation
-a
+ + + + +
-1 == 0 - 1
+
Wrapping Negation
-%a
+ + +
    +
  • Twos-complement wrapping behavior.
  • +
+
+
-%@as(i8, -128) == -128
+
Multiplication
a * b
+a *= b
+ + + + +
2 * 5 == 10
+
Wrapping Multiplication
a *% b
+a *%= b
+ + + + +
@as(u8, 200) *% 2 == 144
+
Saturating Multiplication
a *| b
+a *|= b
+ + + + +
@as(u8, 200) *| 2 == 255
+
Division
a / b
+a /= b
+ + + + +
10 / 5 == 2
+
Remainder Division
a % b
+a %= b
+ + + + +
10 % 3 == 1
+
Bit Shift Left
a << b
+a <<= b
+ + +
    +
  • Moves all bits to the left, inserting new zeroes at the + least-significant bit.
  • +
  • b must be + comptime-known or have a type with log2 number + of bits as a.
  • +
  • See also @shlExact.
  • +
  • See also @shlWithOverflow.
  • +
+
+
0b1 << 8 == 0b100000000
+
Saturating Bit Shift Left
a <<| b
+a <<|= b
+ + + + +
@as(u8, 1) <<| 8 == 255
+
Bit Shift Right
a >> b
+a >>= b
+ + +
    +
  • Moves all bits to the right, inserting zeroes at the most-significant bit.
  • +
  • b must be + comptime-known or have a type with log2 number + of bits as a.
  • +
  • See also @shrExact.
  • +
+
+
0b1010 >> 1 == 0b101
+
Bitwise And
a & b
+a &= b
+ + + + +
0b011 & 0b101 == 0b001
+
Bitwise Or
a | b
+a |= b
+ + + + +
0b010 | 0b100 == 0b110
+
Bitwise Xor
a ^ b
+a ^= b
+ + + + +
0b011 ^ 0b101 == 0b110
+
Bitwise Not
~a
+ + +
~@as(u8, 0b10101111) == 0b01010000
+
Defaulting Optional Unwrap
a orelse b
+ + If a is null, + returns b ("default value"), + otherwise returns the unwrapped value of a. + Note that b may be a value of type noreturn. + +
const value: ?u32 = null;
+const unwrapped = value orelse 1234;
+unwrapped == 1234
+
Optional Unwrap
a.?
+ + + Equivalent to: +
a orelse unreachable
+
+
const value: ?u32 = 5678;
+value.? == 5678
+
Defaulting Error Unwrap
a catch b
+a catch |err| b
+ + If a is an error, + returns b ("default value"), + otherwise returns the unwrapped value of a. + Note that b may be a value of type noreturn. +err is the error and is in scope of the expression b. + +
const value: anyerror!u32 = error.Broken;
+const unwrapped = value catch 1234;
+unwrapped == 1234
+
Logical And
a and b
+ + + If a is false, returns false + without evaluating b. Otherwise, returns b. + +
(false and true) == false
+
Logical Or
a or b
+ + + If a is true, + returns true without evaluating + b. Otherwise, returns + b. + +
(false or true) == true
+
Boolean Not
!a
+ + +
!false == true
+
Equality
a == b
+ + + Returns true if a and b are equal, otherwise returns false. + Invokes Peer Type Resolution for the operands. + +
(1 == 1) == true
+
Null Check
a == null
+ + + Returns true if a is null, otherwise returns false. + +
const value: ?u32 = null;
+(value == null) == true
+
Inequality
a != b
+ + + Returns false if a and b are equal, otherwise returns true. + Invokes Peer Type Resolution for the operands. + +
(1 != 1) == false
+
Non-Null Check
a != null
+ + + Returns false if a is null, otherwise returns true. + +
const value: ?u32 = null;
+(value != null) == false
+
Greater Than
a > b
+ + + Returns true if a is greater than b, otherwise returns false. + Invokes Peer Type Resolution for the operands. + +
(2 > 1) == true
+
Greater or Equal
a >= b
+ + + Returns true if a is greater than or equal to b, otherwise returns false. + Invokes Peer Type Resolution for the operands. + +
(2 >= 1) == true
+
Less Than
a < b
+ + + Returns true if a is less than b, otherwise returns false. + Invokes Peer Type Resolution for the operands. + +
(1 < 2) == true
+
Lesser or Equal
a <= b
+ + + Returns true if a is less than or equal to b, otherwise returns false. + Invokes Peer Type Resolution for the operands. + +
(1 <= 2) == true
+
Array Concatenation
a ++ b
+ + + + +
const mem = @import("std").mem;
+const array1 = [_]u32{1,2};
+const array2 = [_]u32{3,4};
+const together = array1 ++ array2;
+mem.eql(u32, &together, &[_]u32{1,2,3,4})
+
Array Multiplication
a ** b
+ + + + +
const mem = @import("std").mem;
+const pattern = "ab" ** 3;
+mem.eql(u8, pattern, "ababab")
+
Pointer Dereference
a.*
+ + + Pointer dereference. + +
const x: u32 = 1234;
+const ptr = &x;
+ptr.* == 1234
+
Address Of
&a
+ All types + + +
const x: u32 = 1234;
+const ptr = &x;
+ptr.* == 1234
+
Error Set Merge
a || b
+ + + Merging Error Sets + +
const A = error{One};
+const B = error{Two};
+(A || B) == error{One, Two}
+
+
+ +

Precedence §

+ +
x() x[] x.y x.* x.?
+a!b
+x{}
+!x -x -%x ~x &x ?x
+* / % ** *% *| ||
++ - ++ +% -% +| -|
+<< >> <<|
+& ^ | orelse catch
+== != < > <= >=
+and
+or
+= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |=
+ + +

Arrays §

+ +
test_arrays.zig
const expect = @import("std").testing.expect;
+const assert = @import("std").debug.assert;
+const mem = @import("std").mem;
+
+// array literal
+const message = [_]u8{ 'h', 'e', 'l', 'l', 'o' };
+
+// alternative initialization using result location
+const alt_message: [5]u8 = .{ 'h', 'e', 'l', 'l', 'o' };
+
+comptime {
+    assert(mem.eql(u8, &message, &alt_message));
+}
+
+// get the size of an array
+comptime {
+    assert(message.len == 5);
+}
+
+// A string literal is a single-item pointer to an array.
+const same_message = "hello";
+
+comptime {
+    assert(mem.eql(u8, &message, same_message));
+}
+
+test "iterate over an array" {
+    var sum: usize = 0;
+    for (message) |byte| {
+        sum += byte;
+    }
+    try expect(sum == 'h' + 'e' + 'l' * 2 + 'o');
+}
+
+// modifiable array
+var some_integers: [100]i32 = undefined;
+
+test "modify an array" {
+    for (&some_integers, 0..) |*item, i| {
+        item.* = @intCast(i);
+    }
+    try expect(some_integers[10] == 10);
+    try expect(some_integers[99] == 99);
+}
+
+// array concatenation works if the values are known
+// at compile time
+const part_one = [_]i32{ 1, 2, 3, 4 };
+const part_two = [_]i32{ 5, 6, 7, 8 };
+const all_of_it = part_one ++ part_two;
+comptime {
+    assert(mem.eql(i32, &all_of_it, &[_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }));
+}
+
+// remember that string literals are arrays
+const hello = "hello";
+const world = "world";
+const hello_world = hello ++ " " ++ world;
+comptime {
+    assert(mem.eql(u8, hello_world, "hello world"));
+}
+
+// ** does repeating patterns
+const pattern = "ab" ** 3;
+comptime {
+    assert(mem.eql(u8, pattern, "ababab"));
+}
+
+// initialize an array to zero
+const all_zero = [_]u16{0} ** 10;
+
+comptime {
+    assert(all_zero.len == 10);
+    assert(all_zero[5] == 0);
+}
+
+// use compile-time code to initialize an array
+var fancy_array = init: {
+    var initial_value: [10]Point = undefined;
+    for (&initial_value, 0..) |*pt, i| {
+        pt.* = Point{
+            .x = @intCast(i),
+            .y = @intCast(i * 2),
+        };
+    }
+    break :init initial_value;
+};
+const Point = struct {
+    x: i32,
+    y: i32,
+};
+
+test "compile-time array initialization" {
+    try expect(fancy_array[4].x == 4);
+    try expect(fancy_array[4].y == 8);
+}
+
+// call a function to initialize an array
+var more_points = [_]Point{makePoint(3)} ** 10;
+fn makePoint(x: i32) Point {
+    return Point{
+        .x = x,
+        .y = x * 2,
+    };
+}
+test "array initialization with function calls" {
+    try expect(more_points[4].x == 3);
+    try expect(more_points[4].y == 6);
+    try expect(more_points.len == 10);
+}
Shell
$ zig test test_arrays.zig
+1/4 test_arrays.test.iterate over an array...OK
+2/4 test_arrays.test.modify an array...OK
+3/4 test_arrays.test.compile-time array initialization...OK
+4/4 test_arrays.test.array initialization with function calls...OK
+All 4 tests passed.
+
+ +

See also:

+ + +

Multidimensional Arrays §

+ +

+ Multidimensional arrays can be created by nesting arrays: +

+
test_multidimensional_arrays.zig
const std = @import("std");
+const expect = std.testing.expect;
+const expectEqual = std.testing.expectEqual;
+
+const mat4x5 = [4][5]f32{
+    [_]f32{ 1.0, 0.0, 0.0, 0.0, 0.0 },
+    [_]f32{ 0.0, 1.0, 0.0, 1.0, 0.0 },
+    [_]f32{ 0.0, 0.0, 1.0, 0.0, 0.0 },
+    [_]f32{ 0.0, 0.0, 0.0, 1.0, 9.9 },
+};
+test "multidimensional arrays" {
+    // mat4x5 itself is a one-dimensional array of arrays.
+    try expectEqual(mat4x5[1], [_]f32{ 0.0, 1.0, 0.0, 1.0, 0.0 });
+
+    // Access the 2D array by indexing the outer array, and then the inner array.
+    try expect(mat4x5[3][4] == 9.9);
+
+    // Here we iterate with for loops.
+    for (mat4x5, 0..) |row, row_index| {
+        for (row, 0..) |cell, column_index| {
+            if (row_index == column_index) {
+                try expect(cell == 1.0);
+            }
+        }
+    }
+
+    // Initialize a multidimensional array to zeros.
+    const all_zero: [4][5]f32 = .{.{0} ** 5} ** 4;
+    try expect(all_zero[0][0] == 0);
+}
Shell
$ zig test test_multidimensional_arrays.zig
+1/1 test_multidimensional_arrays.test.multidimensional arrays...OK
+All 1 tests passed.
+
+ + + +

Sentinel-Terminated Arrays §

+ +

+ The syntax [N:x]T describes an array which has a sentinel element of value x at the + index corresponding to the length N. +

+
test_null_terminated_array.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "0-terminated sentinel array" {
+    const array = [_:0]u8{ 1, 2, 3, 4 };
+
+    try expect(@TypeOf(array) == [4:0]u8);
+    try expect(array.len == 4);
+    try expect(array[4] == 0);
+}
+
+test "extra 0s in 0-terminated sentinel array" {
+    // The sentinel value may appear earlier, but does not influence the compile-time 'len'.
+    const array = [_:0]u8{ 1, 0, 0, 4 };
+
+    try expect(@TypeOf(array) == [4:0]u8);
+    try expect(array.len == 4);
+    try expect(array[4] == 0);
+}
Shell
$ zig test test_null_terminated_array.zig
+1/2 test_null_terminated_array.test.0-terminated sentinel array...OK
+2/2 test_null_terminated_array.test.extra 0s in 0-terminated sentinel array...OK
+All 2 tests passed.
+
+ +

See also:

+ + + +

Destructuring Arrays §

+ +

+ Arrays can be destructured: +

+
destructuring_arrays.zig
const print = @import("std").debug.print;
+
+fn swizzleRgbaToBgra(rgba: [4]u8) [4]u8 {
+    // readable swizzling by destructuring
+    const r, const g, const b, const a = rgba;
+    return .{ b, g, r, a };
+}
+
+pub fn main() void {
+    const pos = [_]i32{ 1, 2 };
+    const x, const y = pos;
+    print("x = {}, y = {}\n", .{x, y});
+
+    const orange: [4]u8 = .{ 255, 165, 0, 255 };
+    print("{any}\n", .{swizzleRgbaToBgra(orange)});
+}
Shell
$ zig build-exe destructuring_arrays.zig
+$ ./destructuring_arrays
+x = 1, y = 2
+{ 0, 165, 255, 255 }
+
+ +

See also:

+ + + + +

Vectors §

+ +

+ A vector is a group of booleans, Integers, Floats, or + Pointers which are operated on in parallel, using SIMD instructions if possible. + Vector types are created with the builtin function @Vector. +

+

+ Vectors support the same builtin operators as their underlying base types. + These operations are performed element-wise, and return a vector of the same length + as the input vectors. This includes: +

+
    +
  • Arithmetic (+, -, /, *, + @divFloor, @sqrt, @ceil, + @log, etc.)
  • +
  • Bitwise operators (>>, <<, &, + |, ~, etc.)
  • +
  • Comparison operators (<, >, ==, etc.)
  • +
+

+ It is prohibited to use a math operator on a mixture of scalars (individual numbers) + and vectors. Zig provides the @splat builtin to easily convert from scalars + to vectors, and it supports @reduce and array indexing syntax to convert + from vectors to scalars. Vectors also support assignment to and from fixed-length + arrays with comptime-known length. +

+

+ For rearranging elements within and between vectors, Zig provides the @shuffle and @select functions. +

+

+ Operations on vectors shorter than the target machine's native SIMD size will typically compile to single SIMD + instructions, while vectors longer than the target machine's native SIMD size will compile to multiple SIMD + instructions. If a given operation doesn't have SIMD support on the target architecture, the compiler will default + to operating on each vector element one at a time. Zig supports any comptime-known vector length up to 2^32-1, + although small powers of two (2-64) are most typical. Note that excessively long vector lengths (e.g. 2^20) may + result in compiler crashes on current versions of Zig. +

+
test_vector.zig
const std = @import("std");
+const expectEqual = std.testing.expectEqual;
+
+test "Basic vector usage" {
+    // Vectors have a compile-time known length and base type.
+    const a = @Vector(4, i32){ 1, 2, 3, 4 };
+    const b = @Vector(4, i32){ 5, 6, 7, 8 };
+
+    // Math operations take place element-wise.
+    const c = a + b;
+
+    // Individual vector elements can be accessed using array indexing syntax.
+    try expectEqual(6, c[0]);
+    try expectEqual(8, c[1]);
+    try expectEqual(10, c[2]);
+    try expectEqual(12, c[3]);
+}
+
+test "Conversion between vectors, arrays, and slices" {
+    // Vectors and fixed-length arrays can be automatically assigned back and forth
+    const arr1: [4]f32 = [_]f32{ 1.1, 3.2, 4.5, 5.6 };
+    const vec: @Vector(4, f32) = arr1;
+    const arr2: [4]f32 = vec;
+    try expectEqual(arr1, arr2);
+
+    // You can also assign from a slice with comptime-known length to a vector using .*
+    const vec2: @Vector(2, f32) = arr1[1..3].*;
+
+    const slice: []const f32 = &arr1;
+    var offset: u32 = 1; // var to make it runtime-known
+    _ = &offset; // suppress 'var is never mutated' error
+    // To extract a comptime-known length from a runtime-known offset,
+    // first extract a new slice from the starting offset, then an array of
+    // comptime-known length
+    const vec3: @Vector(2, f32) = slice[offset..][0..2].*;
+    try expectEqual(slice[offset], vec2[0]);
+    try expectEqual(slice[offset + 1], vec2[1]);
+    try expectEqual(vec2, vec3);
+}
Shell
$ zig test test_vector.zig
+1/2 test_vector.test.Basic vector usage...OK
+2/2 test_vector.test.Conversion between vectors, arrays, and slices...OK
+All 2 tests passed.
+
+ +

+ TODO talk about C ABI interop
+ TODO consider suggesting std.MultiArrayList +

+

See also:

+ + +

Destructuring Vectors §

+ +

+ Vectors can be destructured: +

+
destructuring_vectors.zig
const print = @import("std").debug.print;
+
+// emulate punpckldq
+pub fn unpack(x: @Vector(4, f32), y: @Vector(4, f32)) @Vector(4, f32) {
+    const a, const c, _, _ = x;
+    const b, const d, _, _ = y;
+    return .{ a, b, c, d };
+}
+
+pub fn main() void {
+    const x: @Vector(4, f32) = .{ 1.0, 2.0, 3.0, 4.0 };
+    const y: @Vector(4, f32) = .{ 5.0, 6.0, 7.0, 8.0 };
+    print("{}", .{unpack(x, y)});
+}
Shell
$ zig build-exe destructuring_vectors.zig
+$ ./destructuring_vectors
+{ 1e0, 5e0, 2e0, 6e0 }
+
+

See also:

+ + + + + +

Pointers §

+ +

+ Zig has two kinds of pointers: single-item and many-item. +

+
    +
  • *T - single-item pointer to exactly one item. +
      +
    • Supports deref syntax: ptr.*
    • +
    • Supports slice syntax: ptr[0..1]
    • +
    • Supports pointer subtraction: ptr - ptr
    • +
    +
  • +
  • [*]T - many-item pointer to unknown number of items. +
      +
    • Supports index syntax: ptr[i]
    • +
    • Supports slice syntax: ptr[start..end] and ptr[start..]
    • +
    • Supports pointer-integer arithmetic: ptr + int, ptr - int
    • +
    • Supports pointer subtraction: ptr - ptr
    • +
    + T must have a known size, which means that it cannot be + anyopaque or any other opaque type. +
  • +
+

These types are closely related to Arrays and Slices:

+
    +
  • *[N]T - pointer to N items, same as single-item pointer to an array. +
      +
    • Supports index syntax: array_ptr[i]
    • +
    • Supports slice syntax: array_ptr[start..end]
    • +
    • Supports len property: array_ptr.len
    • +
    • Supports pointer subtraction: array_ptr - array_ptr
    • +
    +
  • +
+
    +
  • []T - is a slice (a fat pointer, which contains a pointer of type [*]T and a length). +
      +
    • Supports index syntax: slice[i]
    • +
    • Supports slice syntax: slice[start..end]
    • +
    • Supports len property: slice.len
    • +
    +
  • +
+

Use &x to obtain a single-item pointer:

+
test_single_item_pointer.zig
const expect = @import("std").testing.expect;
+
+test "address of syntax" {
+    // Get the address of a variable:
+    const x: i32 = 1234;
+    const x_ptr = &x;
+
+    // Dereference a pointer:
+    try expect(x_ptr.* == 1234);
+
+    // When you get the address of a const variable, you get a const single-item pointer.
+    try expect(@TypeOf(x_ptr) == *const i32);
+
+    // If you want to mutate the value, you'd need an address of a mutable variable:
+    var y: i32 = 5678;
+    const y_ptr = &y;
+    try expect(@TypeOf(y_ptr) == *i32);
+    y_ptr.* += 1;
+    try expect(y_ptr.* == 5679);
+}
+
+test "pointer array access" {
+    // Taking an address of an individual element gives a
+    // single-item pointer. This kind of pointer
+    // does not support pointer arithmetic.
+    var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+    const ptr = &array[2];
+    try expect(@TypeOf(ptr) == *u8);
+
+    try expect(array[2] == 3);
+    ptr.* += 1;
+    try expect(array[2] == 4);
+}
+
+test "slice syntax" {
+    // Get a pointer to a variable:
+    var x: i32 = 1234;
+    const x_ptr = &x;
+
+    // Convert to array pointer using slice syntax:
+    const x_array_ptr = x_ptr[0..1];
+    try expect(@TypeOf(x_array_ptr) == *[1]i32);
+
+    // Coerce to many-item pointer:
+    const x_many_ptr: [*]i32 = x_array_ptr;
+    try expect(x_many_ptr[0] == 1234);
+}
Shell
$ zig test test_single_item_pointer.zig
+1/3 test_single_item_pointer.test.address of syntax...OK
+2/3 test_single_item_pointer.test.pointer array access...OK
+3/3 test_single_item_pointer.test.slice syntax...OK
+All 3 tests passed.
+
+ +

+ Zig supports pointer arithmetic. It's better to assign the pointer to [*]T and increment that variable. For example, directly incrementing the pointer from a slice will corrupt it. +

+
test_pointer_arithmetic.zig
const expect = @import("std").testing.expect;
+
+test "pointer arithmetic with many-item pointer" {
+    const array = [_]i32{ 1, 2, 3, 4 };
+    var ptr: [*]const i32 = &array;
+
+    try expect(ptr[0] == 1);
+    ptr += 1;
+    try expect(ptr[0] == 2);
+
+    // slicing a many-item pointer without an end is equivalent to
+    // pointer arithmetic: `ptr[start..] == ptr + start`
+    try expect(ptr[1..] == ptr + 1);
+
+    // subtraction between any two pointers except slices based on element size is supported
+    try expect(&ptr[1] - &ptr[0] == 1);
+}
+
+test "pointer arithmetic with slices" {
+    var array = [_]i32{ 1, 2, 3, 4 };
+    var length: usize = 0; // var to make it runtime-known
+    _ = &length; // suppress 'var is never mutated' error
+    var slice = array[length..array.len];
+
+    try expect(slice[0] == 1);
+    try expect(slice.len == 4);
+
+    slice.ptr += 1;
+    // now the slice is in an bad state since len has not been updated
+
+    try expect(slice[0] == 2);
+    try expect(slice.len == 4);
+}
Shell
$ zig test test_pointer_arithmetic.zig
+1/2 test_pointer_arithmetic.test.pointer arithmetic with many-item pointer...OK
+2/2 test_pointer_arithmetic.test.pointer arithmetic with slices...OK
+All 2 tests passed.
+
+ +

+ In Zig, we generally prefer Slices rather than Sentinel-Terminated Pointers. + You can turn an array or pointer into a slice using slice syntax. +

+

+ Slices have bounds checking and are therefore protected + against this kind of Illegal Behavior. This is one reason + we prefer slices to pointers. +

+
test_slice_bounds.zig
const expect = @import("std").testing.expect;
+
+test "pointer slicing" {
+    var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+    var start: usize = 2; // var to make it runtime-known
+    _ = &start; // suppress 'var is never mutated' error
+    const slice = array[start..4];
+    try expect(slice.len == 2);
+
+    try expect(array[3] == 4);
+    slice[1] += 1;
+    try expect(array[3] == 5);
+}
Shell
$ zig test test_slice_bounds.zig
+1/1 test_slice_bounds.test.pointer slicing...OK
+All 1 tests passed.
+
+ +

Pointers work at compile-time too, as long as the code does not depend on + an undefined memory layout:

+
test_comptime_pointers.zig
const expect = @import("std").testing.expect;
+
+test "comptime pointers" {
+    comptime {
+        var x: i32 = 1;
+        const ptr = &x;
+        ptr.* += 1;
+        x += 1;
+        try expect(ptr.* == 3);
+    }
+}
Shell
$ zig test test_comptime_pointers.zig
+1/1 test_comptime_pointers.test.comptime pointers...OK
+All 1 tests passed.
+
+ +

To convert an integer address into a pointer, use @ptrFromInt. + To convert a pointer to an integer, use @intFromPtr:

+
test_integer_pointer_conversion.zig
const expect = @import("std").testing.expect;
+
+test "@intFromPtr and @ptrFromInt" {
+    const ptr: *i32 = @ptrFromInt(0xdeadbee0);
+    const addr = @intFromPtr(ptr);
+    try expect(@TypeOf(addr) == usize);
+    try expect(addr == 0xdeadbee0);
+}
Shell
$ zig test test_integer_pointer_conversion.zig
+1/1 test_integer_pointer_conversion.test.@intFromPtr and @ptrFromInt...OK
+All 1 tests passed.
+
+ +

Zig is able to preserve memory addresses in comptime code, as long as + the pointer is never dereferenced:

+
test_comptime_pointer_conversion.zig
const expect = @import("std").testing.expect;
+
+test "comptime @ptrFromInt" {
+    comptime {
+        // Zig is able to do this at compile-time, as long as
+        // ptr is never dereferenced.
+        const ptr: *i32 = @ptrFromInt(0xdeadbee0);
+        const addr = @intFromPtr(ptr);
+        try expect(@TypeOf(addr) == usize);
+        try expect(addr == 0xdeadbee0);
+    }
+}
Shell
$ zig test test_comptime_pointer_conversion.zig
+1/1 test_comptime_pointer_conversion.test.comptime @ptrFromInt...OK
+All 1 tests passed.
+
+ +

+ @ptrCast converts a pointer's element type to another. This + creates a new pointer that can cause undetectable Illegal Behavior + depending on the loads and stores that pass through it. Generally, other + kinds of type conversions are preferable to + @ptrCast if possible. +

+
test_pointer_casting.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "pointer casting" {
+    const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 };
+    const u32_ptr: *const u32 = @ptrCast(&bytes);
+    try expect(u32_ptr.* == 0x12121212);
+
+    // Even this example is contrived - there are better ways to do the above than
+    // pointer casting. For example, using a slice narrowing cast:
+    const u32_value = std.mem.bytesAsSlice(u32, bytes[0..])[0];
+    try expect(u32_value == 0x12121212);
+
+    // And even another way, the most straightforward way to do it:
+    try expect(@as(u32, @bitCast(bytes)) == 0x12121212);
+}
+
+test "pointer child type" {
+    // pointer types have a `child` field which tells you the type they point to.
+    try expect(@typeInfo(*u32).pointer.child == u32);
+}
Shell
$ zig test test_pointer_casting.zig
+1/2 test_pointer_casting.test.pointer casting...OK
+2/2 test_pointer_casting.test.pointer child type...OK
+All 2 tests passed.
+
+ +

See also:

+ +

volatile §

+ +

Loads and stores are assumed to not have side effects. If a given load or store + should have side effects, such as Memory Mapped Input/Output (MMIO), use volatile. + In the following code, loads and stores with mmio_ptr are guaranteed to all happen + and in the same order as in source code:

+
test_volatile.zig
const expect = @import("std").testing.expect;
+
+test "volatile" {
+    const mmio_ptr: *volatile u8 = @ptrFromInt(0x12345678);
+    try expect(@TypeOf(mmio_ptr) == *volatile u8);
+}
Shell
$ zig test test_volatile.zig
+1/1 test_volatile.test.volatile...OK
+All 1 tests passed.
+
+ +

+ Note that volatile is unrelated to concurrency and Atomics. + If you see code that is using volatile for something other than Memory Mapped + Input/Output, it is probably a bug. +

+ + +

Alignment §

+ +

+ Each type has an alignment - a number of bytes such that, + when a value of the type is loaded from or stored to memory, + the memory address must be evenly divisible by this number. You can use + @alignOf to find out this value for any type. +

+

+ Alignment depends on the CPU architecture, but is always a power of two, and + less than 1 << 29. +

+

+ In Zig, a pointer type has an alignment value. If the value is equal to the + alignment of the underlying type, it can be omitted from the type: +

+
test_variable_alignment.zig
const std = @import("std");
+const builtin = @import("builtin");
+const expect = std.testing.expect;
+
+test "variable alignment" {
+    var x: i32 = 1234;
+    const align_of_i32 = @alignOf(@TypeOf(x));
+    try expect(@TypeOf(&x) == *i32);
+    try expect(*i32 == *align(align_of_i32) i32);
+    if (builtin.target.cpu.arch == .x86_64) {
+        try expect(@typeInfo(*i32).pointer.alignment == 4);
+    }
+}
Shell
$ zig test test_variable_alignment.zig
+1/1 test_variable_alignment.test.variable alignment...OK
+All 1 tests passed.
+
+ +

In the same way that a *i32 can be coerced to a + *const i32, a pointer with a larger alignment can be implicitly + cast to a pointer with a smaller alignment, but not vice versa. +

+

+ You can specify alignment on variables and functions. If you do this, then + pointers to them get the specified alignment: +

+
test_variable_func_alignment.zig
const expect = @import("std").testing.expect;
+
+var foo: u8 align(4) = 100;
+
+test "global variable alignment" {
+    try expect(@typeInfo(@TypeOf(&foo)).pointer.alignment == 4);
+    try expect(@TypeOf(&foo) == *align(4) u8);
+    const as_pointer_to_array: *align(4) [1]u8 = &foo;
+    const as_slice: []align(4) u8 = as_pointer_to_array;
+    const as_unaligned_slice: []u8 = as_slice;
+    try expect(as_unaligned_slice[0] == 100);
+}
+
+fn derp() align(@sizeOf(usize) * 2) i32 {
+    return 1234;
+}
+fn noop1() align(1) void {}
+fn noop4() align(4) void {}
+
+test "function alignment" {
+    try expect(derp() == 1234);
+    try expect(@TypeOf(derp) == fn () i32);
+    try expect(@TypeOf(&derp) == *align(@sizeOf(usize) * 2) const fn () i32);
+
+    noop1();
+    try expect(@TypeOf(noop1) == fn () void);
+    try expect(@TypeOf(&noop1) == *align(1) const fn () void);
+
+    noop4();
+    try expect(@TypeOf(noop4) == fn () void);
+    try expect(@TypeOf(&noop4) == *align(4) const fn () void);
+}
Shell
$ zig test test_variable_func_alignment.zig
+1/2 test_variable_func_alignment.test.global variable alignment...OK
+2/2 test_variable_func_alignment.test.function alignment...OK
+All 2 tests passed.
+
+ +

+ If you have a pointer or a slice that has a small alignment, but you know that it actually + has a bigger alignment, use @alignCast to change the + pointer into a more aligned pointer. This is a no-op at runtime, but inserts a + safety check: +

+
test_incorrect_pointer_alignment.zig
const std = @import("std");
+
+test "pointer alignment safety" {
+    var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
+    const bytes = std.mem.sliceAsBytes(array[0..]);
+    try std.testing.expect(foo(bytes) == 0x11111111);
+}
+fn foo(bytes: []u8) u32 {
+    const slice4 = bytes[1..5];
+    const int_slice = std.mem.bytesAsSlice(u32, @as([]align(4) u8, @alignCast(slice4)));
+    return int_slice[0];
+}
Shell
$ zig test test_incorrect_pointer_alignment.zig
+1/1 test_incorrect_pointer_alignment.test.pointer alignment safety...thread 1081785 panic: incorrect alignment
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_incorrect_pointer_alignment.zig:10:68: 0x10488a2 in foo (test)
+    const int_slice = std.mem.bytesAsSlice(u32, @as([]align(4) u8, @alignCast(slice4)));
+                                                                   ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_incorrect_pointer_alignment.zig:6:31: 0x104874f in test.pointer alignment safety (test)
+    try std.testing.expect(foo(bytes) == 0x11111111);
+                              ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10eecf9 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10e709d in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e6512 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e60ed in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/60041bbef0fbc0cb6f825ff8b942404c/test --seed=0x60598034
+
+ + + +

allowzero §

+ +

+ This pointer attribute allows a pointer to have address zero. This is only ever needed on the + freestanding OS target, where the address zero is mappable. If you want to represent null pointers, use + Optional Pointers instead. Optional Pointers with allowzero + are not the same size as pointers. In this code example, if the pointer + did not have the allowzero attribute, this would be a + Pointer Cast Invalid Null panic: +

+
test_allowzero.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "allowzero" {
+    var zero: usize = 0; // var to make to runtime-known
+    _ = &zero; // suppress 'var is never mutated' error
+    const ptr: *allowzero i32 = @ptrFromInt(zero);
+    try expect(@intFromPtr(ptr) == 0);
+}
Shell
$ zig test test_allowzero.zig
+1/1 test_allowzero.test.allowzero...OK
+All 1 tests passed.
+
+ + + +

Sentinel-Terminated Pointers §

+ +

+ The syntax [*:x]T describes a pointer that + has a length determined by a sentinel value. This provides protection + against buffer overflow and overreads. +

+
sentinel-terminated_pointer.zig
const std = @import("std");
+
+// This is also available as `std.c.printf`.
+pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
+
+pub fn main() anyerror!void {
+    _ = printf("Hello, world!\n"); // OK
+
+    const msg = "Hello, world!\n";
+    const non_null_terminated_msg: [msg.len]u8 = msg.*;
+    _ = printf(&non_null_terminated_msg);
+}
Shell
$ zig build-exe sentinel-terminated_pointer.zig -lc
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/sentinel-terminated_pointer.zig:11:16: error: expected type '[*:0]const u8', found '*const [14]u8'
+    _ = printf(&non_null_terminated_msg);
+               ^~~~~~~~~~~~~~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/sentinel-terminated_pointer.zig:11:16: note: destination pointer requires '0' sentinel
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/sentinel-terminated_pointer.zig:4:34: note: parameter type declared here
+pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
+                                 ^~~~~~~~~~~~~
+referenced by:
+    main: /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:660:37
+    comptime: /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:58:30
+    2 reference(s) hidden; use '-freference-trace=4' to see all references
+
+
+ +

See also:

+ + + + +

Slices §

+ +

+ A slice is a pointer and a length. The difference between an array and + a slice is that the array's length is part of the type and known at + compile-time, whereas the slice's length is known at runtime. + Both can be accessed with the len field. +

+
test_basic_slices.zig
const expect = @import("std").testing.expect;
+const expectEqualSlices = @import("std").testing.expectEqualSlices;
+
+test "basic slices" {
+    var array = [_]i32{ 1, 2, 3, 4 };
+    var known_at_runtime_zero: usize = 0;
+    _ = &known_at_runtime_zero;
+    const slice = array[known_at_runtime_zero..array.len];
+
+    // alternative initialization using result location
+    const alt_slice: []const i32 = &.{ 1, 2, 3, 4 };
+
+    try expectEqualSlices(i32, slice, alt_slice);
+
+    try expect(@TypeOf(slice) == []i32);
+    try expect(&slice[0] == &array[0]);
+    try expect(slice.len == array.len);
+
+    // If you slice with comptime-known start and end positions, the result is
+    // a pointer to an array, rather than a slice.
+    const array_ptr = array[0..array.len];
+    try expect(@TypeOf(array_ptr) == *[array.len]i32);
+
+    // You can perform a slice-by-length by slicing twice. This allows the compiler
+    // to perform some optimisations like recognising a comptime-known length when
+    // the start position is only known at runtime.
+    var runtime_start: usize = 1;
+    _ = &runtime_start;
+    const length = 2;
+    const array_ptr_len = array[runtime_start..][0..length];
+    try expect(@TypeOf(array_ptr_len) == *[length]i32);
+
+    // Using the address-of operator on a slice gives a single-item pointer.
+    try expect(@TypeOf(&slice[0]) == *i32);
+    // Using the `ptr` field gives a many-item pointer.
+    try expect(@TypeOf(slice.ptr) == [*]i32);
+    try expect(@intFromPtr(slice.ptr) == @intFromPtr(&slice[0]));
+
+    // Slices have array bounds checking. If you try to access something out
+    // of bounds, you'll get a safety check failure:
+    slice[10] += 1;
+
+    // Note that `slice.ptr` does not invoke safety checking, while `&slice[0]`
+    // asserts that the slice has len > 0.
+
+    // Empty slices can be created like this:
+    const empty1 = &[0]u8{};
+    // If the type is known you can use this short hand:
+    const empty2: []u8 = &.{};
+    try expect(empty1.len == 0);
+    try expect(empty2.len == 0);
+
+    // A zero-length initialization can always be used to create an empty slice, even if the slice is mutable.
+    // This is because the pointed-to data is zero bits long, so its immutability is irrelevant.
+}
Shell
$ zig test test_basic_slices.zig
+1/1 test_basic_slices.test.basic slices...thread 1082565 panic: index out of bounds: index 10, len 4
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_basic_slices.zig:41:10: 0x104b241 in test.basic slices (test)
+    slice[10] += 1;
+         ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10f21b9 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10ea55d in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e99d2 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e95ad in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/f9263bb559fc5a754baaa433017d4d71/test --seed=0x314392aa
+
+ +

This is one reason we prefer slices to pointers.

+
test_slices.zig
const std = @import("std");
+const expect = std.testing.expect;
+const mem = std.mem;
+const fmt = std.fmt;
+
+test "using slices for strings" {
+    // Zig has no concept of strings. String literals are const pointers
+    // to null-terminated arrays of u8, and by convention parameters
+    // that are "strings" are expected to be UTF-8 encoded slices of u8.
+    // Here we coerce *const [5:0]u8 and *const [6:0]u8 to []const u8
+    const hello: []const u8 = "hello";
+    const world: []const u8 = "世界";
+
+    var all_together: [100]u8 = undefined;
+    // You can use slice syntax with at least one runtime-known index on an
+    // array to convert an array into a slice.
+    var start: usize = 0;
+    _ = &start;
+    const all_together_slice = all_together[start..];
+    // String concatenation example.
+    const hello_world = try fmt.bufPrint(all_together_slice, "{s} {s}", .{ hello, world });
+
+    // Generally, you can use UTF-8 and not worry about whether something is a
+    // string. If you don't need to deal with individual characters, no need
+    // to decode.
+    try expect(mem.eql(u8, hello_world, "hello 世界"));
+}
+
+test "slice pointer" {
+    var array: [10]u8 = undefined;
+    const ptr = &array;
+    try expect(@TypeOf(ptr) == *[10]u8);
+
+    // A pointer to an array can be sliced just like an array:
+    var start: usize = 0;
+    var end: usize = 5;
+    _ = .{ &start, &end };
+    const slice = ptr[start..end];
+    // The slice is mutable because we sliced a mutable pointer.
+    try expect(@TypeOf(slice) == []u8);
+    slice[2] = 3;
+    try expect(array[2] == 3);
+
+    // Again, slicing with comptime-known indexes will produce another pointer
+    // to an array:
+    const ptr2 = slice[2..3];
+    try expect(ptr2.len == 1);
+    try expect(ptr2[0] == 3);
+    try expect(@TypeOf(ptr2) == *[1]u8);
+}
Shell
$ zig test test_slices.zig
+1/2 test_slices.test.using slices for strings...OK
+2/2 test_slices.test.slice pointer...OK
+All 2 tests passed.
+
+ +

See also:

+ + +

Sentinel-Terminated Slices §

+ +

+ The syntax [:x]T is a slice which has a runtime-known length + and also guarantees a sentinel value at the element indexed by the length. The type does not + guarantee that there are no sentinel elements before that. Sentinel-terminated slices allow element + access to the len index. +

+
test_null_terminated_slice.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "0-terminated slice" {
+    const slice: [:0]const u8 = "hello";
+
+    try expect(slice.len == 5);
+    try expect(slice[5] == 0);
+}
Shell
$ zig test test_null_terminated_slice.zig
+1/1 test_null_terminated_slice.test.0-terminated slice...OK
+All 1 tests passed.
+
+ +

+ Sentinel-terminated slices can also be created using a variation of the slice syntax + data[start..end :x], where data is a many-item pointer, + array or slice and x is the sentinel value. +

+
test_null_terminated_slicing.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "0-terminated slicing" {
+    var array = [_]u8{ 3, 2, 1, 0, 3, 2, 1, 0 };
+    var runtime_length: usize = 3;
+    _ = &runtime_length;
+    const slice = array[0..runtime_length :0];
+
+    try expect(@TypeOf(slice) == [:0]u8);
+    try expect(slice.len == 3);
+}
Shell
$ zig test test_null_terminated_slicing.zig
+1/1 test_null_terminated_slicing.test.0-terminated slicing...OK
+All 1 tests passed.
+
+ +

+ Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is + actually the sentinel value. If this is not the case, safety-checked Illegal Behavior results. +

+
test_sentinel_mismatch.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "sentinel mismatch" {
+    var array = [_]u8{ 3, 2, 1, 0 };
+
+    // Creating a sentinel-terminated slice from the array with a length of 2
+    // will result in the value `1` occupying the sentinel element position.
+    // This does not match the indicated sentinel value of `0` and will lead
+    // to a runtime panic.
+    var runtime_length: usize = 2;
+    _ = &runtime_length;
+    const slice = array[0..runtime_length :0];
+
+    _ = slice;
+}
Shell
$ zig test test_sentinel_mismatch.zig
+1/1 test_sentinel_mismatch.test.sentinel mismatch...thread 1083169 panic: sentinel mismatch: expected 0, found 1
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_sentinel_mismatch.zig:13:24: 0x10487a1 in test.sentinel mismatch (test)
+    const slice = array[0..runtime_length :0];
+                       ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10eea69 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10e6e0d in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e6282 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e5e5d in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/5999cad80b529a1b559a5322826e4b05/test --seed=0x30c9f67
+
+ +

See also:

+ + + + +

struct §

+ +
test_structs.zig
// Declare a struct.
+// Zig gives no guarantees about the order of fields and the size of
+// the struct but the fields are guaranteed to be ABI-aligned.
+const Point = struct {
+    x: f32,
+    y: f32,
+};
+
+// Declare an instance of a struct.
+const p: Point = .{
+    .x = 0.12,
+    .y = 0.34,
+};
+
+// Functions in the struct's namespace can be called with dot syntax.
+const Vec3 = struct {
+    x: f32,
+    y: f32,
+    z: f32,
+
+    pub fn init(x: f32, y: f32, z: f32) Vec3 {
+        return Vec3{
+            .x = x,
+            .y = y,
+            .z = z,
+        };
+    }
+
+    pub fn dot(self: Vec3, other: Vec3) f32 {
+        return self.x * other.x + self.y * other.y + self.z * other.z;
+    }
+};
+
+test "dot product" {
+    const v1 = Vec3.init(1.0, 0.0, 0.0);
+    const v2 = Vec3.init(0.0, 1.0, 0.0);
+    try expect(v1.dot(v2) == 0.0);
+
+    // Other than being available to call with dot syntax, struct methods are
+    // not special. You can reference them as any other declaration inside
+    // the struct:
+    try expect(Vec3.dot(v1, v2) == 0.0);
+}
+
+// Structs can have declarations.
+// Structs can have 0 fields.
+const Empty = struct {
+    pub const PI = 3.14;
+};
+test "struct namespaced variable" {
+    try expect(Empty.PI == 3.14);
+    try expect(@sizeOf(Empty) == 0);
+
+    // Empty structs can be instantiated the same as usual.
+    const does_nothing: Empty = .{};
+
+    _ = does_nothing;
+}
+
+// Struct field order is determined by the compiler, however, a base pointer
+// can be computed from a field pointer:
+fn setYBasedOnX(x: *f32, y: f32) void {
+    const point: *Point = @fieldParentPtr("x", x);
+    point.y = y;
+}
+test "field parent pointer" {
+    var point = Point{
+        .x = 0.1234,
+        .y = 0.5678,
+    };
+    setYBasedOnX(&point.x, 0.9);
+    try expect(point.y == 0.9);
+}
+
+// Structs can be returned from functions.
+fn LinkedList(comptime T: type) type {
+    return struct {
+        pub const Node = struct {
+            prev: ?*Node,
+            next: ?*Node,
+            data: T,
+        };
+
+        first: ?*Node,
+        last: ?*Node,
+        len: usize,
+    };
+}
+
+test "linked list" {
+    // Functions called at compile-time are memoized.
+    try expect(LinkedList(i32) == LinkedList(i32));
+
+    const list = LinkedList(i32){
+        .first = null,
+        .last = null,
+        .len = 0,
+    };
+    try expect(list.len == 0);
+
+    // Since types are first class values you can instantiate the type
+    // by assigning it to a variable:
+    const ListOfInts = LinkedList(i32);
+    try expect(ListOfInts == LinkedList(i32));
+
+    var node = ListOfInts.Node{
+        .prev = null,
+        .next = null,
+        .data = 1234,
+    };
+    const list2 = LinkedList(i32){
+        .first = &node,
+        .last = &node,
+        .len = 1,
+    };
+
+    // When using a pointer to a struct, fields can be accessed directly,
+    // without explicitly dereferencing the pointer.
+    // So you can do
+    try expect(list2.first.?.data == 1234);
+    // instead of try expect(list2.first.?.*.data == 1234);
+}
+
+const expect = @import("std").testing.expect;
Shell
$ zig test test_structs.zig
+1/4 test_structs.test.dot product...OK
+2/4 test_structs.test.struct namespaced variable...OK
+3/4 test_structs.test.field parent pointer...OK
+4/4 test_structs.test.linked list...OK
+All 4 tests passed.
+
+ + +

Default Field Values §

+ +

+ Each struct field may have an expression indicating the default field + value. Such expressions are executed at comptime, and allow the + field to be omitted in a struct literal expression: +

+
struct_default_field_values.zig
const Foo = struct {
+    a: i32 = 1234,
+    b: i32,
+};
+
+test "default struct initialization fields" {
+    const x: Foo = .{
+        .b = 5,
+    };
+    if (x.a + x.b != 1239) {
+        comptime unreachable;
+    }
+}
Shell
$ zig test struct_default_field_values.zig
+1/1 struct_default_field_values.test.default struct initialization fields...OK
+All 1 tests passed.
+
+ +

Faulty Default Field Values §

+ +

+ Default field values are only appropriate when the data invariants of a struct + cannot be violated by omitting that field from an initialization. +

+

+ For example, here is an inappropriate use of default struct field initialization: +

+
bad_default_value.zig
const Threshold = struct {
+    minimum: f32 = 0.25,
+    maximum: f32 = 0.75,
+
+    const Category = enum { low, medium, high };
+
+    fn categorize(t: Threshold, value: f32) Category {
+        assert(t.maximum >= t.minimum);
+        if (value < t.minimum) return .low;
+        if (value > t.maximum) return .high;
+        return .medium;
+    }
+};
+
+pub fn main() !void {
+    var threshold: Threshold = .{
+        .maximum = 0.20,
+    };
+    const category = threshold.categorize(0.90);
+    try std.io.getStdOut().writeAll(@tagName(category));
+}
+
+const std = @import("std");
+const assert = std.debug.assert;
Shell
$ zig build-exe bad_default_value.zig
+$ ./bad_default_value
+thread 1084966 panic: reached unreachable code
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/debug.zig:550:14: 0x1048b9d in assert (bad_default_value)
+    if (!ok) unreachable; // assertion failure
+             ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/bad_default_value.zig:8:15: 0x10de0d9 in categorize (bad_default_value)
+        assert(t.maximum >= t.minimum);
+              ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/bad_default_value.zig:19:42: 0x10de01a in main (bad_default_value)
+    const category = threshold.categorize(0.90);
+                                         ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:660:37: 0x10ddf2a in posixCallMainAndExit (bad_default_value)
+            const result = root.main() catch |err| {
+                                    ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10ddadd in _start (bad_default_value)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ +

+ Above you can see the danger of ignoring this principle. The default + field values caused the data invariant to be violated, causing illegal + behavior. +

+

+ To fix this, remove the default values from all the struct fields, and provide + a named default value: +

+
struct_default_value.zig
const Threshold = struct {
+    minimum: f32,
+    maximum: f32,
+
+    const default: Threshold = .{
+        .minimum = 0.25,
+        .maximum = 0.75,
+    };
+};
+ +

If a struct value requires a runtime-known value in order to be initialized + without violating data invariants, then use an initialization method that accepts + those runtime values, and populates the remaining fields.

+ + + +

extern struct §

+ +

An extern struct has in-memory layout matching + the C ABI for the target.

+

If well-defined in-memory layout is not required, struct is a better choice + because it places fewer restrictions on the compiler.

+

See packed struct for a struct that has the ABI of its backing integer, + which can be useful for modeling flags.

+

See also:

+ + + +

packed struct §

+ +

+ Unlike normal structs, packed structs have guaranteed in-memory layout: +

+
    +
  • Fields remain in the order declared, least to most significant.
  • +
  • There is no padding between fields.
  • +
  • Zig supports arbitrary width Integers and although normally, integers with fewer + than 8 bits will still use 1 byte of memory, in packed structs, they use + exactly their bit width. +
  • +
  • bool fields use exactly 1 bit.
  • +
  • An enum field uses exactly the bit width of its integer tag type.
  • +
  • A packed union field uses exactly the bit width of the union field with + the largest bit width.
  • +
  • Packed structs support equality operators.
  • +
+

+ This means that a packed struct can participate + in a @bitCast or a @ptrCast to reinterpret memory. + This even works at comptime: +

+
test_packed_structs.zig
const std = @import("std");
+const native_endian = @import("builtin").target.cpu.arch.endian();
+const expect = std.testing.expect;
+
+const Full = packed struct {
+    number: u16,
+};
+const Divided = packed struct {
+    half1: u8,
+    quarter3: u4,
+    quarter4: u4,
+};
+
+test "@bitCast between packed structs" {
+    try doTheTest();
+    try comptime doTheTest();
+}
+
+fn doTheTest() !void {
+    try expect(@sizeOf(Full) == 2);
+    try expect(@sizeOf(Divided) == 2);
+    const full = Full{ .number = 0x1234 };
+    const divided: Divided = @bitCast(full);
+    try expect(divided.half1 == 0x34);
+    try expect(divided.quarter3 == 0x2);
+    try expect(divided.quarter4 == 0x1);
+
+    const ordered: [2]u8 = @bitCast(full);
+    switch (native_endian) {
+        .big => {
+            try expect(ordered[0] == 0x12);
+            try expect(ordered[1] == 0x34);
+        },
+        .little => {
+            try expect(ordered[0] == 0x34);
+            try expect(ordered[1] == 0x12);
+        },
+    }
+}
Shell
$ zig test test_packed_structs.zig
+1/1 test_packed_structs.test.@bitCast between packed structs...OK
+All 1 tests passed.
+
+ +

+ The backing integer is inferred from the fields' total bit width. + Optionally, it can be explicitly provided and enforced at compile time: +

+
test_missized_packed_struct.zig
test "missized packed struct" {
+    const S = packed struct(u32) { a: u16, b: u8 };
+    _ = S{ .a = 4, .b = 2 };
+}
Shell
$ zig test test_missized_packed_struct.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_missized_packed_struct.zig:2:29: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 24
+    const S = packed struct(u32) { a: u16, b: u8 };
+                            ^~~
+referenced by:
+    test.missized packed struct: /home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_missized_packed_struct.zig:2:22
+
+
+ +

+ Zig allows the address to be taken of a non-byte-aligned field: +

+
test_pointer_to_non-byte_aligned_field.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const BitField = packed struct {
+    a: u3,
+    b: u3,
+    c: u2,
+};
+
+var foo = BitField{
+    .a = 1,
+    .b = 2,
+    .c = 3,
+};
+
+test "pointer to non-byte-aligned field" {
+    const ptr = &foo.b;
+    try expect(ptr.* == 2);
+}
Shell
$ zig test test_pointer_to_non-byte_aligned_field.zig
+1/1 test_pointer_to_non-byte_aligned_field.test.pointer to non-byte-aligned field...OK
+All 1 tests passed.
+
+ +

+ However, the pointer to a non-byte-aligned field has special properties and cannot + be passed when a normal pointer is expected: +

+
test_misaligned_pointer.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const BitField = packed struct {
+    a: u3,
+    b: u3,
+    c: u2,
+};
+
+var bit_field = BitField{
+    .a = 1,
+    .b = 2,
+    .c = 3,
+};
+
+test "pointer to non-byte-aligned field" {
+    try expect(bar(&bit_field.b) == 2);
+}
+
+fn bar(x: *const u3) u3 {
+    return x.*;
+}
Shell
$ zig test test_misaligned_pointer.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_misaligned_pointer.zig:17:20: error: expected type '*const u3', found '*align(1:3:1) u3'
+    try expect(bar(&bit_field.b) == 2);
+                   ^~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_misaligned_pointer.zig:17:20: note: pointer host size '1' cannot cast into pointer host size '0'
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_misaligned_pointer.zig:17:20: note: pointer bit offset '3' cannot cast into pointer bit offset '0'
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_misaligned_pointer.zig:20:11: note: parameter type declared here
+fn bar(x: *const u3) u3 {
+          ^~~~~~~~~
+
+
+ +

+ In this case, the function bar cannot be called because the pointer + to the non-ABI-aligned field mentions the bit offset, but the function expects an ABI-aligned pointer. +

+

+ Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer: +

+
test_packed_struct_field_address.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const BitField = packed struct {
+    a: u3,
+    b: u3,
+    c: u2,
+};
+
+var bit_field = BitField{
+    .a = 1,
+    .b = 2,
+    .c = 3,
+};
+
+test "pointers of sub-byte-aligned fields share addresses" {
+    try expect(@intFromPtr(&bit_field.a) == @intFromPtr(&bit_field.b));
+    try expect(@intFromPtr(&bit_field.a) == @intFromPtr(&bit_field.c));
+}
Shell
$ zig test test_packed_struct_field_address.zig
+1/1 test_packed_struct_field_address.test.pointers of sub-byte-aligned fields share addresses...OK
+All 1 tests passed.
+
+ +

+ This can be observed with @bitOffsetOf and offsetOf: +

+
test_bitOffsetOf_offsetOf.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const BitField = packed struct {
+    a: u3,
+    b: u3,
+    c: u2,
+};
+
+test "offsets of non-byte-aligned fields" {
+    comptime {
+        try expect(@bitOffsetOf(BitField, "a") == 0);
+        try expect(@bitOffsetOf(BitField, "b") == 3);
+        try expect(@bitOffsetOf(BitField, "c") == 6);
+
+        try expect(@offsetOf(BitField, "a") == 0);
+        try expect(@offsetOf(BitField, "b") == 0);
+        try expect(@offsetOf(BitField, "c") == 0);
+    }
+}
Shell
$ zig test test_bitOffsetOf_offsetOf.zig
+1/1 test_bitOffsetOf_offsetOf.test.offsets of non-byte-aligned fields...OK
+All 1 tests passed.
+
+ +

+ Packed structs have the same alignment as their backing integer, however, overaligned + pointers to packed structs can override this: +

+
test_overaligned_packed_struct.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const S = packed struct {
+    a: u32,
+    b: u32,
+};
+test "overaligned pointer to packed struct" {
+    var foo: S align(4) = .{ .a = 1, .b = 2 };
+    const ptr: *align(4) S = &foo;
+    const ptr_to_b: *u32 = &ptr.b;
+    try expect(ptr_to_b.* == 2);
+}
Shell
$ zig test test_overaligned_packed_struct.zig
+1/1 test_overaligned_packed_struct.test.overaligned pointer to packed struct...OK
+All 1 tests passed.
+
+ +

+ It's also possible to set alignment of struct fields: +

+
test_aligned_struct_fields.zig
const std = @import("std");
+const expectEqual = std.testing.expectEqual;
+
+test "aligned struct fields" {
+    const S = struct {
+        a: u32 align(2),
+        b: u32 align(64),
+    };
+    var foo = S{ .a = 1, .b = 2 };
+
+    try expectEqual(64, @alignOf(S));
+    try expectEqual(*align(2) u32, @TypeOf(&foo.a));
+    try expectEqual(*align(64) u32, @TypeOf(&foo.b));
+}
Shell
$ zig test test_aligned_struct_fields.zig
+1/1 test_aligned_struct_fields.test.aligned struct fields...OK
+All 1 tests passed.
+
+ +

+ Equating packed structs results in a comparison of the backing integer, + and only works for the `==` and `!=` operators. +

+
test_packed_struct_equality.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "packed struct equality" {
+    const S = packed struct {
+        a: u4,
+        b: u4,
+    };
+    const x: S = .{ .a = 1, .b = 2 };
+    const y: S = .{ .b = 2, .a = 1 };
+    try expect(x == y);
+}
Shell
$ zig test test_packed_struct_equality.zig
+1/1 test_packed_struct_equality.test.packed struct equality...OK
+All 1 tests passed.
+
+ +

+ Using packed structs with volatile is problematic, and may be a compile error in the future. + For details on this subscribe to + this issue. + TODO update these docs with a recommendation on how to use packed structs with MMIO + (the use case for volatile packed structs) once this issue is resolved. + Don't worry, there will be a good solution for this use case in zig. +

+ + +

Struct Naming §

+ +

Since all structs are anonymous, Zig infers the type name based on a few rules.

+
    +
  • If the struct is in the initialization expression of a variable, it gets named after + that variable.
  • +
  • If the struct is in the return expression, it gets named after + the function it is returning from, with the parameter values serialized.
  • +
  • Otherwise, the struct gets a name such as (filename.funcname__struct_ID).
  • +
  • If the struct is declared inside another struct, it gets named after both the parent + struct and the name inferred by the previous rules, separated by a dot.
  • +
+
struct_name.zig
const std = @import("std");
+
+pub fn main() void {
+    const Foo = struct {};
+    std.debug.print("variable: {s}\n", .{@typeName(Foo)});
+    std.debug.print("anonymous: {s}\n", .{@typeName(struct {})});
+    std.debug.print("function: {s}\n", .{@typeName(List(i32))});
+}
+
+fn List(comptime T: type) type {
+    return struct {
+        x: T,
+    };
+}
Shell
$ zig build-exe struct_name.zig
+$ ./struct_name
+variable: struct_name.main.Foo
+anonymous: struct_name.main__struct_24002
+function: struct_name.List(i32)
+
+ + + +

Anonymous Struct Literals §

+ +

+ Zig allows omitting the struct type of a literal. When the result is coerced, + the struct literal will directly instantiate the result location, + with no copy: +

+
test_struct_result.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Point = struct { x: i32, y: i32 };
+
+test "anonymous struct literal" {
+    const pt: Point = .{
+        .x = 13,
+        .y = 67,
+    };
+    try expect(pt.x == 13);
+    try expect(pt.y == 67);
+}
Shell
$ zig test test_struct_result.zig
+1/1 test_struct_result.test.anonymous struct literal...OK
+All 1 tests passed.
+
+ +

+ The struct type can be inferred. Here the result location + does not include a type, and so Zig infers the type: +

+
test_anonymous_struct.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "fully anonymous struct" {
+    try check(.{
+        .int = @as(u32, 1234),
+        .float = @as(f64, 12.34),
+        .b = true,
+        .s = "hi",
+    });
+}
+
+fn check(args: anytype) !void {
+    try expect(args.int == 1234);
+    try expect(args.float == 12.34);
+    try expect(args.b);
+    try expect(args.s[0] == 'h');
+    try expect(args.s[1] == 'i');
+}
Shell
$ zig test test_anonymous_struct.zig
+1/1 test_anonymous_struct.test.fully anonymous struct...OK
+All 1 tests passed.
+
+ + + +

Tuples §

+ +

+ Anonymous structs can be created without specifying field names, and are referred to as "tuples". An empty tuple looks like .{} and can be seen in one of the Hello World examples. +

+

+ The fields are implicitly named using numbers starting from 0. Because their names are integers, + they cannot be accessed with . syntax without also wrapping them in + @"". Names inside @"" are always recognised as + identifiers. +

+

+ Like arrays, tuples have a .len field, can be indexed (provided the index is comptime-known) + and work with the ++ and ** operators. They can also be iterated over with inline for. +

+
test_tuples.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "tuple" {
+    const values = .{
+        @as(u32, 1234),
+        @as(f64, 12.34),
+        true,
+        "hi",
+    } ++ .{false} ** 2;
+    try expect(values[0] == 1234);
+    try expect(values[4] == false);
+    inline for (values, 0..) |v, i| {
+        if (i != 2) continue;
+        try expect(v);
+    }
+    try expect(values.len == 6);
+    try expect(values.@"3"[0] == 'h');
+}
Shell
$ zig test test_tuples.zig
+1/1 test_tuples.test.tuple...OK
+All 1 tests passed.
+
+ +

Destructuring Tuples §

+ +

+ Tuples can be destructured. +

+

+ Tuple destructuring is helpful for returning multiple values from a block: +

+
destructuring_block.zig
const print = @import("std").debug.print;
+
+pub fn main() void {
+    const digits = [_]i8 { 3, 8, 9, 0, 7, 4, 1 };
+
+    const min, const max = blk: {
+        var min: i8 = 127;
+        var max: i8 = -128;
+
+        for (digits) |digit| {
+            if (digit < min) min = digit;
+            if (digit > max) max = digit;
+        }
+
+        break :blk .{ min, max };
+    };
+
+    print("min = {}", .{ min });
+    print("max = {}", .{ max });
+}
Shell
$ zig build-exe destructuring_block.zig
+$ ./destructuring_block
+min = 0max = 9
+
+ +

+ Tuple destructuring is helpful for dealing with functions and built-ins that return multiple values + as a tuple: +

+
destructuring_return_value.zig
const print = @import("std").debug.print;
+
+fn divmod(numerator: u32, denominator: u32) struct { u32, u32 } {
+    return .{ numerator / denominator, numerator % denominator };
+}
+
+pub fn main() void {
+    const div, const mod = divmod(10, 3);
+
+    print("10 / 3 = {}\n", .{div});
+    print("10 % 3 = {}\n", .{mod});
+}
Shell
$ zig build-exe destructuring_return_value.zig
+$ ./destructuring_return_value
+10 / 3 = 3
+10 % 3 = 1
+
+ +

See also:

+ + + +

See also:

+ + +

enum §

+ +
test_enums.zig
const expect = @import("std").testing.expect;
+const mem = @import("std").mem;
+
+// Declare an enum.
+const Type = enum {
+    ok,
+    not_ok,
+};
+
+// Declare a specific enum field.
+const c = Type.ok;
+
+// If you want access to the ordinal value of an enum, you
+// can specify the tag type.
+const Value = enum(u2) {
+    zero,
+    one,
+    two,
+};
+// Now you can cast between u2 and Value.
+// The ordinal value starts from 0, counting up by 1 from the previous member.
+test "enum ordinal value" {
+    try expect(@intFromEnum(Value.zero) == 0);
+    try expect(@intFromEnum(Value.one) == 1);
+    try expect(@intFromEnum(Value.two) == 2);
+}
+
+// You can override the ordinal value for an enum.
+const Value2 = enum(u32) {
+    hundred = 100,
+    thousand = 1000,
+    million = 1000000,
+};
+test "set enum ordinal value" {
+    try expect(@intFromEnum(Value2.hundred) == 100);
+    try expect(@intFromEnum(Value2.thousand) == 1000);
+    try expect(@intFromEnum(Value2.million) == 1000000);
+}
+
+// You can also override only some values.
+const Value3 = enum(u4) {
+    a,
+    b = 8,
+    c,
+    d = 4,
+    e,
+};
+test "enum implicit ordinal values and overridden values" {
+    try expect(@intFromEnum(Value3.a) == 0);
+    try expect(@intFromEnum(Value3.b) == 8);
+    try expect(@intFromEnum(Value3.c) == 9);
+    try expect(@intFromEnum(Value3.d) == 4);
+    try expect(@intFromEnum(Value3.e) == 5);
+}
+
+// Enums can have methods, the same as structs and unions.
+// Enum methods are not special, they are only namespaced
+// functions that you can call with dot syntax.
+const Suit = enum {
+    clubs,
+    spades,
+    diamonds,
+    hearts,
+
+    pub fn isClubs(self: Suit) bool {
+        return self == Suit.clubs;
+    }
+};
+test "enum method" {
+    const p = Suit.spades;
+    try expect(!p.isClubs());
+}
+
+// An enum can be switched upon.
+const Foo = enum {
+    string,
+    number,
+    none,
+};
+test "enum switch" {
+    const p = Foo.number;
+    const what_is_it = switch (p) {
+        Foo.string => "this is a string",
+        Foo.number => "this is a number",
+        Foo.none => "this is a none",
+    };
+    try expect(mem.eql(u8, what_is_it, "this is a number"));
+}
+
+// @typeInfo can be used to access the integer tag type of an enum.
+const Small = enum {
+    one,
+    two,
+    three,
+    four,
+};
+test "std.meta.Tag" {
+    try expect(@typeInfo(Small).@"enum".tag_type == u2);
+}
+
+// @typeInfo tells us the field count and the fields names:
+test "@typeInfo" {
+    try expect(@typeInfo(Small).@"enum".fields.len == 4);
+    try expect(mem.eql(u8, @typeInfo(Small).@"enum".fields[1].name, "two"));
+}
+
+// @tagName gives a [:0]const u8 representation of an enum value:
+test "@tagName" {
+    try expect(mem.eql(u8, @tagName(Small.three), "three"));
+}
Shell
$ zig test test_enums.zig
+1/8 test_enums.test.enum ordinal value...OK
+2/8 test_enums.test.set enum ordinal value...OK
+3/8 test_enums.test.enum implicit ordinal values and overridden values...OK
+4/8 test_enums.test.enum method...OK
+5/8 test_enums.test.enum switch...OK
+6/8 test_enums.test.std.meta.Tag...OK
+7/8 test_enums.test.@typeInfo...OK
+8/8 test_enums.test.@tagName...OK
+All 8 tests passed.
+
+ +

See also:

+ + +

extern enum §

+ +

+ By default, enums are not guaranteed to be compatible with the C ABI: +

+
enum_export_error.zig
const Foo = enum { a, b, c };
+export fn entry(foo: Foo) void {
+    _ = foo;
+}
Shell
$ zig build-obj enum_export_error.zig -target x86_64-linux
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/enum_export_error.zig:2:17: error: parameter of type 'enum_export_error.Foo' not allowed in function with calling convention 'x86_64_sysv'
+export fn entry(foo: Foo) void {
+                ^~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/enum_export_error.zig:2:17: note: enum tag type 'u2' is not extern compatible
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/enum_export_error.zig:2:17: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/enum_export_error.zig:1:13: note: enum declared here
+const Foo = enum { a, b, c };
+            ^~~~~~~~~~~~~~~~
+referenced by:
+    root: /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:3:22
+    comptime: /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:27:9
+    2 reference(s) hidden; use '-freference-trace=4' to see all references
+
+
+ +

+ For a C-ABI-compatible enum, provide an explicit tag type to + the enum: +

+
enum_export.zig
const Foo = enum(c_int) { a, b, c };
+export fn entry(foo: Foo) void {
+    _ = foo;
+}
Shell
$ zig build-obj enum_export.zig
+
+ + + +

Enum Literals §

+ +

+ Enum literals allow specifying the name of an enum field without specifying the enum type: +

+
test_enum_literals.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Color = enum {
+    auto,
+    off,
+    on,
+};
+
+test "enum literals" {
+    const color1: Color = .auto;
+    const color2 = Color.auto;
+    try expect(color1 == color2);
+}
+
+test "switch using enum literals" {
+    const color = Color.on;
+    const result = switch (color) {
+        .auto => false,
+        .on => true,
+        .off => false,
+    };
+    try expect(result);
+}
Shell
$ zig test test_enum_literals.zig
+1/2 test_enum_literals.test.enum literals...OK
+2/2 test_enum_literals.test.switch using enum literals...OK
+All 2 tests passed.
+
+ + + +

Non-exhaustive enum §

+ +

+ A non-exhaustive enum can be created by adding a trailing _ field. + The enum must specify a tag type and cannot consume every enumeration value. +

+

+ @enumFromInt on a non-exhaustive enum involves the safety semantics + of @intCast to the integer tag type, but beyond that always results in + a well-defined enum value. +

+

+ A switch on a non-exhaustive enum can include a _ prong as an alternative to an else prong. + With a _ prong the compiler errors if all the known tag names are not handled by the switch. +

+
test_switch_non-exhaustive.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Number = enum(u8) {
+    one,
+    two,
+    three,
+    _,
+};
+
+test "switch on non-exhaustive enum" {
+    const number = Number.one;
+    const result = switch (number) {
+        .one => true,
+        .two, .three => false,
+        _ => false,
+    };
+    try expect(result);
+    const is_one = switch (number) {
+        .one => true,
+        else => false,
+    };
+    try expect(is_one);
+}
Shell
$ zig test test_switch_non-exhaustive.zig
+1/1 test_switch_non-exhaustive.test.switch on non-exhaustive enum...OK
+All 1 tests passed.
+
+ + + + +

union §

+ +

+ A bare union defines a set of possible types that a value + can be as a list of fields. Only one field can be active at a time. + The in-memory representation of bare unions is not guaranteed. + Bare unions cannot be used to reinterpret memory. For that, use @ptrCast, + or use an extern union or a packed union which have + guaranteed in-memory layout. + Accessing the non-active field is + safety-checked Illegal Behavior: +

+
test_wrong_union_access.zig
const Payload = union {
+    int: i64,
+    float: f64,
+    boolean: bool,
+};
+test "simple union" {
+    var payload = Payload{ .int = 1234 };
+    payload.float = 12.34;
+}
Shell
$ zig test test_wrong_union_access.zig
+1/1 test_wrong_union_access.test.simple union...thread 1081145 panic: access of union field 'float' while field 'int' is active
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_wrong_union_access.zig:8:12: 0x10487af in test.simple union (test)
+    payload.float = 12.34;
+           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10eeb99 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10e6f3d in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e63b2 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e5f8d in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/8f6c2970fa4ed12c76dd41bda2086b47/test --seed=0x32e9061f
+
+ +

You can activate another field by assigning the entire union:

+
test_simple_union.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Payload = union {
+    int: i64,
+    float: f64,
+    boolean: bool,
+};
+test "simple union" {
+    var payload = Payload{ .int = 1234 };
+    try expect(payload.int == 1234);
+    payload = Payload{ .float = 12.34 };
+    try expect(payload.float == 12.34);
+}
Shell
$ zig test test_simple_union.zig
+1/1 test_simple_union.test.simple union...OK
+All 1 tests passed.
+
+ +

+ In order to use switch with a union, it must be a Tagged union. +

+

+ To initialize a union when the tag is a comptime-known name, see @unionInit. +

+ +

Tagged union §

+ +

Unions can be declared with an enum tag type. + This turns the union into a tagged union, which makes it eligible + to use with switch expressions. + Tagged unions coerce to their tag type: Type Coercion: Unions and Enums. +

+
test_tagged_union.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const ComplexTypeTag = enum {
+    ok,
+    not_ok,
+};
+const ComplexType = union(ComplexTypeTag) {
+    ok: u8,
+    not_ok: void,
+};
+
+test "switch on tagged union" {
+    const c = ComplexType{ .ok = 42 };
+    try expect(@as(ComplexTypeTag, c) == ComplexTypeTag.ok);
+
+    switch (c) {
+        .ok => |value| try expect(value == 42),
+        .not_ok => unreachable,
+    }
+}
+
+test "get tag type" {
+    try expect(std.meta.Tag(ComplexType) == ComplexTypeTag);
+}
Shell
$ zig test test_tagged_union.zig
+1/2 test_tagged_union.test.switch on tagged union...OK
+2/2 test_tagged_union.test.get tag type...OK
+All 2 tests passed.
+
+ +

In order to modify the payload of a tagged union in a switch expression, + place a * before the variable name to make it a pointer: +

+
test_switch_modify_tagged_union.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const ComplexTypeTag = enum {
+    ok,
+    not_ok,
+};
+const ComplexType = union(ComplexTypeTag) {
+    ok: u8,
+    not_ok: void,
+};
+
+test "modify tagged union in switch" {
+    var c = ComplexType{ .ok = 42 };
+
+    switch (c) {
+        ComplexTypeTag.ok => |*value| value.* += 1,
+        ComplexTypeTag.not_ok => unreachable,
+    }
+
+    try expect(c.ok == 43);
+}
Shell
$ zig test test_switch_modify_tagged_union.zig
+1/1 test_switch_modify_tagged_union.test.modify tagged union in switch...OK
+All 1 tests passed.
+
+ +

+ Unions can be made to infer the enum tag type. + Further, unions can have methods just like structs and enums. +

+
test_union_method.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Variant = union(enum) {
+    int: i32,
+    boolean: bool,
+
+    // void can be omitted when inferring enum tag type.
+    none,
+
+    fn truthy(self: Variant) bool {
+        return switch (self) {
+            Variant.int => |x_int| x_int != 0,
+            Variant.boolean => |x_bool| x_bool,
+            Variant.none => false,
+        };
+    }
+};
+
+test "union method" {
+    var v1: Variant = .{ .int = 1 };
+    var v2: Variant = .{ .boolean = false };
+    var v3: Variant = .none;
+
+    try expect(v1.truthy());
+    try expect(!v2.truthy());
+    try expect(!v3.truthy());
+}
Shell
$ zig test test_union_method.zig
+1/1 test_union_method.test.union method...OK
+All 1 tests passed.
+
+ +

+ @tagName can be used to return a comptime + [:0]const u8 value representing the field name: +

+
test_tagName.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Small2 = union(enum) {
+    a: i32,
+    b: bool,
+    c: u8,
+};
+test "@tagName" {
+    try expect(std.mem.eql(u8, @tagName(Small2.a), "a"));
+}
Shell
$ zig test test_tagName.zig
+1/1 test_tagName.test.@tagName...OK
+All 1 tests passed.
+
+ + + +

extern union §

+ +

+ An extern union has memory layout guaranteed to be compatible with + the target C ABI. +

+

See also:

+ + + +

packed union §

+ +

A packed union has well-defined in-memory layout and is eligible + to be in a packed struct.

+ + +

Anonymous Union Literals §

+ +

Anonymous Struct Literals syntax can be used to initialize unions without specifying + the type:

+
test_anonymous_union.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Number = union {
+    int: i32,
+    float: f64,
+};
+
+test "anonymous union literal syntax" {
+    const i: Number = .{ .int = 42 };
+    const f = makeNumber();
+    try expect(i.int == 42);
+    try expect(f.float == 12.34);
+}
+
+fn makeNumber() Number {
+    return .{ .float = 12.34 };
+}
Shell
$ zig test test_anonymous_union.zig
+1/1 test_anonymous_union.test.anonymous union literal syntax...OK
+All 1 tests passed.
+
+ + + + + +

opaque §

+ +

+ opaque {} declares a new type with an unknown (but non-zero) size and alignment. + It can contain declarations the same as structs, unions, + and enums. +

+

+ This is typically used for type safety when interacting with C code that does not expose struct details. + Example: +

+
test_opaque.zig
const Derp = opaque {};
+const Wat = opaque {};
+
+extern fn bar(d: *Derp) void;
+fn foo(w: *Wat) callconv(.C) void {
+    bar(w);
+}
+
+test "call foo" {
+    foo(undefined);
+}
Shell
$ zig test test_opaque.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_opaque.zig:6:9: error: expected type '*test_opaque.Derp', found '*test_opaque.Wat'
+    bar(w);
+        ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_opaque.zig:6:9: note: pointer type child 'test_opaque.Wat' cannot cast into pointer type child 'test_opaque.Derp'
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_opaque.zig:2:13: note: opaque declared here
+const Wat = opaque {};
+            ^~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_opaque.zig:1:14: note: opaque declared here
+const Derp = opaque {};
+             ^~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_opaque.zig:4:18: note: parameter type declared here
+extern fn bar(d: *Derp) void;
+                 ^~~~~
+referenced by:
+    test.call foo: /home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_opaque.zig:10:8
+
+
+ + + +

Blocks §

+ +

+ Blocks are used to limit the scope of variable declarations: +

+
test_blocks.zig
test "access variable after block scope" {
+    {
+        var x: i32 = 1;
+        _ = &x;
+    }
+    x += 1;
+}
Shell
$ zig test test_blocks.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_blocks.zig:6:5: error: use of undeclared identifier 'x'
+    x += 1;
+    ^
+
+
+ +

Blocks are expressions. When labeled, break can be used + to return a value from the block: +

+
test_labeled_break.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "labeled break from labeled block expression" {
+    var y: i32 = 123;
+
+    const x = blk: {
+        y += 1;
+        break :blk y;
+    };
+    try expect(x == 124);
+    try expect(y == 124);
+}
Shell
$ zig test test_labeled_break.zig
+1/1 test_labeled_break.test.labeled break from labeled block expression...OK
+All 1 tests passed.
+
+ +

Here, blk can be any name.

+

See also:

+ + +

Shadowing §

+ +

Identifiers are never allowed to "hide" other identifiers by using the same name:

+
test_shadowing.zig
const pi = 3.14;
+
+test "inside test block" {
+    // Let's even go inside another block
+    {
+        var pi: i32 = 1234;
+    }
+}
Shell
$ zig test test_shadowing.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_shadowing.zig:6:13: error: local variable shadows declaration of 'pi'
+        var pi: i32 = 1234;
+            ^~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_shadowing.zig:1:1: note: declared here
+const pi = 3.14;
+^~~~~~~~~~~~~~~
+
+
+ +

+ Because of this, when you read Zig code you can always rely on an identifier to consistently mean + the same thing within the scope it is defined. Note that you can, however, use the same name if + the scopes are separate: +

+
test_scopes.zig
test "separate scopes" {
+    {
+        const pi = 3.14;
+        _ = pi;
+    }
+    {
+        var pi: bool = true;
+        _ = &pi;
+    }
+}
Shell
$ zig test test_scopes.zig
+1/1 test_scopes.test.separate scopes...OK
+All 1 tests passed.
+
+ + + +

Empty Blocks §

+ +

An empty block is equivalent to void{}:

+
test_empty_block.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test {
+    const a = {};
+    const b = void{};
+    try expect(@TypeOf(a) == void);
+    try expect(@TypeOf(b) == void);
+    try expect(a == b);
+}
Shell
$ zig test test_empty_block.zig
+1/1 test_empty_block.test_0...OK
+All 1 tests passed.
+
+ + + + +

switch §

+ +
test_switch.zig
const std = @import("std");
+const builtin = @import("builtin");
+const expect = std.testing.expect;
+
+test "switch simple" {
+    const a: u64 = 10;
+    const zz: u64 = 103;
+
+    // All branches of a switch expression must be able to be coerced to a
+    // common type.
+    //
+    // Branches cannot fallthrough. If fallthrough behavior is desired, combine
+    // the cases and use an if.
+    const b = switch (a) {
+        // Multiple cases can be combined via a ','
+        1, 2, 3 => 0,
+
+        // Ranges can be specified using the ... syntax. These are inclusive
+        // of both ends.
+        5...100 => 1,
+
+        // Branches can be arbitrarily complex.
+        101 => blk: {
+            const c: u64 = 5;
+            break :blk c * 2 + 1;
+        },
+
+        // Switching on arbitrary expressions is allowed as long as the
+        // expression is known at compile-time.
+        zz => zz,
+        blk: {
+            const d: u32 = 5;
+            const e: u32 = 100;
+            break :blk d + e;
+        } => 107,
+
+        // The else branch catches everything not already captured.
+        // Else branches are mandatory unless the entire range of values
+        // is handled.
+        else => 9,
+    };
+
+    try expect(b == 1);
+}
+
+// Switch expressions can be used outside a function:
+const os_msg = switch (builtin.target.os.tag) {
+    .linux => "we found a linux user",
+    else => "not a linux user",
+};
+
+// Inside a function, switch statements implicitly are compile-time
+// evaluated if the target expression is compile-time known.
+test "switch inside function" {
+    switch (builtin.target.os.tag) {
+        .fuchsia => {
+            // On an OS other than fuchsia, block is not even analyzed,
+            // so this compile error is not triggered.
+            // On fuchsia this compile error would be triggered.
+            @compileError("fuchsia not supported");
+        },
+        else => {},
+    }
+}
Shell
$ zig test test_switch.zig
+1/2 test_switch.test.switch simple...OK
+2/2 test_switch.test.switch inside function...OK
+All 2 tests passed.
+
+ +

+ switch can be used to capture the field values + of a Tagged union. Modifications to the field values can be + done by placing a * before the capture variable name, + turning it into a pointer. +

+
test_switch_tagged_union.zig
const expect = @import("std").testing.expect;
+
+test "switch on tagged union" {
+    const Point = struct {
+        x: u8,
+        y: u8,
+    };
+    const Item = union(enum) {
+        a: u32,
+        c: Point,
+        d,
+        e: u32,
+    };
+
+    var a = Item{ .c = Point{ .x = 1, .y = 2 } };
+
+    // Switching on more complex enums is allowed.
+    const b = switch (a) {
+        // A capture group is allowed on a match, and will return the enum
+        // value matched. If the payload types of both cases are the same
+        // they can be put into the same switch prong.
+        Item.a, Item.e => |item| item,
+
+        // A reference to the matched value can be obtained using `*` syntax.
+        Item.c => |*item| blk: {
+            item.*.x += 1;
+            break :blk 6;
+        },
+
+        // No else is required if the types cases was exhaustively handled
+        Item.d => 8,
+    };
+
+    try expect(b == 6);
+    try expect(a.c.x == 2);
+}
Shell
$ zig test test_switch_tagged_union.zig
+1/1 test_switch_tagged_union.test.switch on tagged union...OK
+All 1 tests passed.
+
+ +

See also:

+ + +

Exhaustive Switching §

+ +

+ When a switch expression does not have an else clause, + it must exhaustively list all the possible values. Failure to do so is a compile error: +

+
test_unhandled_enumeration_value.zig
const Color = enum {
+    auto,
+    off,
+    on,
+};
+
+test "exhaustive switching" {
+    const color = Color.off;
+    switch (color) {
+        Color.auto => {},
+        Color.on => {},
+    }
+}
Shell
$ zig test test_unhandled_enumeration_value.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_unhandled_enumeration_value.zig:9:5: error: switch must handle all possibilities
+    switch (color) {
+    ^~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_unhandled_enumeration_value.zig:3:5: note: unhandled enumeration value: 'off'
+    off,
+    ^~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_unhandled_enumeration_value.zig:1:15: note: enum 'test_unhandled_enumeration_value.Color' declared here
+const Color = enum {
+              ^~~~
+
+
+ + + +

Switching with Enum Literals §

+ +

+ Enum Literals can be useful to use with switch to avoid + repetitively specifying enum or union types: +

+
test_exhaustive_switch.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Color = enum {
+    auto,
+    off,
+    on,
+};
+
+test "enum literals with switch" {
+    const color = Color.off;
+    const result = switch (color) {
+        .auto => false,
+        .on => false,
+        .off => true,
+    };
+    try expect(result);
+}
Shell
$ zig test test_exhaustive_switch.zig
+1/1 test_exhaustive_switch.test.enum literals with switch...OK
+All 1 tests passed.
+
+ + + +

Labeled switch §

+ +

+ When a switch statement is labeled, it can be referenced from a + break or continue. + break will return a value from the switch. +

+

+ A continue targeting a switch must have an + operand. When executed, it will jump to the matching prong, as if the + switch were executed again with the continue's operand replacing the initial switch value. +

+ +
test_switch_continue.zig
const std = @import("std");
+
+test "switch continue" {
+    sw: switch (@as(i32, 5)) {
+        5 => continue :sw 4,
+
+        // `continue` can occur multiple times within a single switch prong.
+        2...4 => |v| {
+            if (v > 3) {
+                continue :sw 2;
+            } else if (v == 3) {
+
+                // `break` can target labeled loops.
+                break :sw;
+            }
+
+            continue :sw 1;
+        },
+
+        1 => return,
+
+        else => unreachable,
+    }
+}
Shell
$ zig test test_switch_continue.zig
+1/1 test_switch_continue.test.switch continue...OK
+All 1 tests passed.
+
+ +

+ Semantically, this is equivalent to the following loop: +

+
test_switch_continue_equivalent.zig
const std = @import("std");
+
+test "switch continue, equivalent loop" {
+    var sw: i32 = 5;
+    while (true) {
+        switch (sw) {
+            5 => {
+                sw = 4;
+                continue;
+            },
+            2...4 => |v| {
+                if (v > 3) {
+                    sw = 2;
+                    continue;
+                } else if (v == 3) {
+                    break;
+                }
+
+                sw = 1;
+                continue;
+            },
+            1 => return,
+            else => unreachable,
+        }
+    }
+}
Shell
$ zig test test_switch_continue_equivalent.zig
+1/1 test_switch_continue_equivalent.test.switch continue, equivalent loop...OK
+All 1 tests passed.
+
+ +

+ This can improve clarity of (for example) state machines, where the syntax continue :sw .next_state is unambiguous, explicit, and immediately understandable. +

+

+ However, the motivating example is a switch on each element of an array, where using a single switch can improve clarity and performance: +

+
test_switch_dispatch_loop.zig
const std = @import("std");
+const expectEqual = std.testing.expectEqual;
+
+const Instruction = enum {
+    add,
+    mul,
+    end,
+};
+
+fn evaluate(initial_stack: []const i32, code: []const Instruction) !i32 {
+    var stack = try std.BoundedArray(i32, 8).fromSlice(initial_stack);
+    var ip: usize = 0;
+
+    return vm: switch (code[ip]) {
+        // Because all code after `continue` is unreachable, this branch does
+        // not provide a result.
+        .add => {
+            try stack.append(stack.pop().? + stack.pop().?);
+
+            ip += 1;
+            continue :vm code[ip];
+        },
+        .mul => {
+            try stack.append(stack.pop().? * stack.pop().?);
+
+            ip += 1;
+            continue :vm code[ip];
+        },
+        .end => stack.pop().?,
+    };
+}
+
+test "evaluate" {
+    const result = try evaluate(&.{ 7, 2, -3 }, &.{ .mul, .add, .end });
+    try expectEqual(1, result);
+}
Shell
$ zig test test_switch_dispatch_loop.zig
+1/1 test_switch_dispatch_loop.test.evaluate...OK
+All 1 tests passed.
+
+ +

+ If the operand to continue is + comptime-known, then it can be lowered to an unconditional branch + to the relevant case. Such a branch is perfectly predicted, and hence + typically very fast to execute. +

+ +

+ If the operand is runtime-known, each continue can + embed a conditional branch inline (ideally through a jump table), which + allows a CPU to predict its target independently of any other prong. A + loop-based lowering would force every branch through the same dispatch + point, hindering branch prediction. +

+ + + + +

Inline Switch Prongs §

+ +

+ Switch prongs can be marked as inline to generate + the prong's body for each possible value it could have, making the + captured value comptime. +

+
test_inline_switch.zig
const std = @import("std");
+const expect = std.testing.expect;
+const expectError = std.testing.expectError;
+
+fn isFieldOptional(comptime T: type, field_index: usize) !bool {
+    const fields = @typeInfo(T).@"struct".fields;
+    return switch (field_index) {
+        // This prong is analyzed twice with `idx` being a
+        // comptime-known value each time.
+        inline 0, 1 => |idx| @typeInfo(fields[idx].type) == .optional,
+        else => return error.IndexOutOfBounds,
+    };
+}
+
+const Struct1 = struct { a: u32, b: ?u32 };
+
+test "using @typeInfo with runtime values" {
+    var index: usize = 0;
+    try expect(!try isFieldOptional(Struct1, index));
+    index += 1;
+    try expect(try isFieldOptional(Struct1, index));
+    index += 1;
+    try expectError(error.IndexOutOfBounds, isFieldOptional(Struct1, index));
+}
+
+// Calls to `isFieldOptional` on `Struct1` get unrolled to an equivalent
+// of this function:
+fn isFieldOptionalUnrolled(field_index: usize) !bool {
+    return switch (field_index) {
+        0 => false,
+        1 => true,
+        else => return error.IndexOutOfBounds,
+    };
+}
Shell
$ zig test test_inline_switch.zig
+1/1 test_inline_switch.test.using @typeInfo with runtime values...OK
+All 1 tests passed.
+
+ +

The inline keyword may also be combined with ranges:

+
inline_prong_range.zig
fn isFieldOptional(comptime T: type, field_index: usize) !bool {
+    const fields = @typeInfo(T).@"struct".fields;
+    return switch (field_index) {
+        inline 0...fields.len - 1 => |idx| @typeInfo(fields[idx].type) == .optional,
+        else => return error.IndexOutOfBounds,
+    };
+}
+ +

+ inline else prongs can be used as a type safe + alternative to inline for loops: +

+
test_inline_else.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const SliceTypeA = extern struct {
+    len: usize,
+    ptr: [*]u32,
+};
+const SliceTypeB = extern struct {
+    ptr: [*]SliceTypeA,
+    len: usize,
+};
+const AnySlice = union(enum) {
+    a: SliceTypeA,
+    b: SliceTypeB,
+    c: []const u8,
+    d: []AnySlice,
+};
+
+fn withFor(any: AnySlice) usize {
+    const Tag = @typeInfo(AnySlice).@"union".tag_type.?;
+    inline for (@typeInfo(Tag).@"enum".fields) |field| {
+        // With `inline for` the function gets generated as
+        // a series of `if` statements relying on the optimizer
+        // to convert it to a switch.
+        if (field.value == @intFromEnum(any)) {
+            return @field(any, field.name).len;
+        }
+    }
+    // When using `inline for` the compiler doesn't know that every
+    // possible case has been handled requiring an explicit `unreachable`.
+    unreachable;
+}
+
+fn withSwitch(any: AnySlice) usize {
+    return switch (any) {
+        // With `inline else` the function is explicitly generated
+        // as the desired switch and the compiler can check that
+        // every possible case is handled.
+        inline else => |slice| slice.len,
+    };
+}
+
+test "inline for and inline else similarity" {
+    const any = AnySlice{ .c = "hello" };
+    try expect(withFor(any) == 5);
+    try expect(withSwitch(any) == 5);
+}
Shell
$ zig test test_inline_else.zig
+1/1 test_inline_else.test.inline for and inline else similarity...OK
+All 1 tests passed.
+
+ +

+ When using an inline prong switching on an union an additional + capture can be used to obtain the union's enum tag value. +

+
test_inline_switch_union_tag.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const U = union(enum) {
+    a: u32,
+    b: f32,
+};
+
+fn getNum(u: U) u32 {
+    switch (u) {
+        // Here `num` is a runtime-known value that is either
+        // `u.a` or `u.b` and `tag` is `u`'s comptime-known tag value.
+        inline else => |num, tag| {
+            if (tag == .b) {
+                return @intFromFloat(num);
+            }
+            return num;
+        },
+    }
+}
+
+test "test" {
+    const u = U{ .b = 42 };
+    try expect(getNum(u) == 42);
+}
Shell
$ zig test test_inline_switch_union_tag.zig
+1/1 test_inline_switch_union_tag.test.test...OK
+All 1 tests passed.
+
+ +

See also:

+ + + + +

while §

+ +

+ A while loop is used to repeatedly execute an expression until + some condition is no longer true. +

+
test_while.zig
const expect = @import("std").testing.expect;
+
+test "while basic" {
+    var i: usize = 0;
+    while (i < 10) {
+        i += 1;
+    }
+    try expect(i == 10);
+}
Shell
$ zig test test_while.zig
+1/1 test_while.test.while basic...OK
+All 1 tests passed.
+
+ +

+ Use break to exit a while loop early. +

+
test_while_break.zig
const expect = @import("std").testing.expect;
+
+test "while break" {
+    var i: usize = 0;
+    while (true) {
+        if (i == 10)
+            break;
+        i += 1;
+    }
+    try expect(i == 10);
+}
Shell
$ zig test test_while_break.zig
+1/1 test_while_break.test.while break...OK
+All 1 tests passed.
+
+ +

+ Use continue to jump back to the beginning of the loop. +

+
test_while_continue.zig
const expect = @import("std").testing.expect;
+
+test "while continue" {
+    var i: usize = 0;
+    while (true) {
+        i += 1;
+        if (i < 10)
+            continue;
+        break;
+    }
+    try expect(i == 10);
+}
Shell
$ zig test test_while_continue.zig
+1/1 test_while_continue.test.while continue...OK
+All 1 tests passed.
+
+ +

+ While loops support a continue expression which is executed when the loop + is continued. The continue keyword respects this expression. +

+
test_while_continue_expression.zig
const expect = @import("std").testing.expect;
+
+test "while loop continue expression" {
+    var i: usize = 0;
+    while (i < 10) : (i += 1) {}
+    try expect(i == 10);
+}
+
+test "while loop continue expression, more complicated" {
+    var i: usize = 1;
+    var j: usize = 1;
+    while (i * j < 2000) : ({
+        i *= 2;
+        j *= 3;
+    }) {
+        const my_ij = i * j;
+        try expect(my_ij < 2000);
+    }
+}
Shell
$ zig test test_while_continue_expression.zig
+1/2 test_while_continue_expression.test.while loop continue expression...OK
+2/2 test_while_continue_expression.test.while loop continue expression, more complicated...OK
+All 2 tests passed.
+
+ +

+ While loops are expressions. The result of the expression is the + result of the else clause of a while loop, which is executed when + the condition of the while loop is tested as false. +

+

+ break, like return, accepts a value + parameter. This is the result of the while expression. + When you break from a while loop, the else branch is not + evaluated. +

+
test_while_else.zig
const expect = @import("std").testing.expect;
+
+test "while else" {
+    try expect(rangeHasNumber(0, 10, 5));
+    try expect(!rangeHasNumber(0, 10, 15));
+}
+
+fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
+    var i = begin;
+    return while (i < end) : (i += 1) {
+        if (i == number) {
+            break true;
+        }
+    } else false;
+}
Shell
$ zig test test_while_else.zig
+1/1 test_while_else.test.while else...OK
+All 1 tests passed.
+
+ +

Labeled while §

+ +

When a while loop is labeled, it can be referenced from a break + or continue from within a nested loop:

+
test_while_nested_break.zig
test "nested break" {
+    outer: while (true) {
+        while (true) {
+            break :outer;
+        }
+    }
+}
+
+test "nested continue" {
+    var i: usize = 0;
+    outer: while (i < 10) : (i += 1) {
+        while (true) {
+            continue :outer;
+        }
+    }
+}
Shell
$ zig test test_while_nested_break.zig
+1/2 test_while_nested_break.test.nested break...OK
+2/2 test_while_nested_break.test.nested continue...OK
+All 2 tests passed.
+
+ + +

while with Optionals §

+ +

+ Just like if expressions, while loops can take an optional as the + condition and capture the payload. When null is encountered the loop + exits. +

+

+ When the |x| syntax is present on a while expression, + the while condition must have an Optional Type. +

+

+ The else branch is allowed on optional iteration. In this case, it will + be executed on the first null value encountered. +

+
test_while_null_capture.zig
const expect = @import("std").testing.expect;
+
+test "while null capture" {
+    var sum1: u32 = 0;
+    numbers_left = 3;
+    while (eventuallyNullSequence()) |value| {
+        sum1 += value;
+    }
+    try expect(sum1 == 3);
+
+    // null capture with an else block
+    var sum2: u32 = 0;
+    numbers_left = 3;
+    while (eventuallyNullSequence()) |value| {
+        sum2 += value;
+    } else {
+        try expect(sum2 == 3);
+    }
+
+    // null capture with a continue expression
+    var i: u32 = 0;
+    var sum3: u32 = 0;
+    numbers_left = 3;
+    while (eventuallyNullSequence()) |value| : (i += 1) {
+        sum3 += value;
+    }
+    try expect(i == 3);
+}
+
+var numbers_left: u32 = undefined;
+fn eventuallyNullSequence() ?u32 {
+    return if (numbers_left == 0) null else blk: {
+        numbers_left -= 1;
+        break :blk numbers_left;
+    };
+}
Shell
$ zig test test_while_null_capture.zig
+1/1 test_while_null_capture.test.while null capture...OK
+All 1 tests passed.
+
+ + + +

while with Error Unions §

+ +

+ Just like if expressions, while loops can take an error union as + the condition and capture the payload or the error code. When the + condition results in an error code the else branch is evaluated and + the loop is finished. +

+

+ When the else |x| syntax is present on a while expression, + the while condition must have an Error Union Type. +

+
test_while_error_capture.zig
const expect = @import("std").testing.expect;
+
+test "while error union capture" {
+    var sum1: u32 = 0;
+    numbers_left = 3;
+    while (eventuallyErrorSequence()) |value| {
+        sum1 += value;
+    } else |err| {
+        try expect(err == error.ReachedZero);
+    }
+}
+
+var numbers_left: u32 = undefined;
+
+fn eventuallyErrorSequence() anyerror!u32 {
+    return if (numbers_left == 0) error.ReachedZero else blk: {
+        numbers_left -= 1;
+        break :blk numbers_left;
+    };
+}
Shell
$ zig test test_while_error_capture.zig
+1/1 test_while_error_capture.test.while error union capture...OK
+All 1 tests passed.
+
+ + + +

inline while §

+ +

+ While loops can be inlined. This causes the loop to be unrolled, which + allows the code to do some things which only work at compile time, + such as use types as first class values. +

+
test_inline_while.zig
const expect = @import("std").testing.expect;
+
+test "inline while loop" {
+    comptime var i = 0;
+    var sum: usize = 0;
+    inline while (i < 3) : (i += 1) {
+        const T = switch (i) {
+            0 => f32,
+            1 => i8,
+            2 => bool,
+            else => unreachable,
+        };
+        sum += typeNameLength(T);
+    }
+    try expect(sum == 9);
+}
+
+fn typeNameLength(comptime T: type) usize {
+    return @typeName(T).len;
+}
Shell
$ zig test test_inline_while.zig
+1/1 test_inline_while.test.inline while loop...OK
+All 1 tests passed.
+
+ +

+ It is recommended to use inline loops only for one of these reasons: +

+
    +
  • You need the loop to execute at comptime for the semantics to work.
  • +
  • + You have a benchmark to prove that forcibly unrolling the loop in this way is measurably faster. +
  • +
+ +

See also:

+ + +

for §

+ +
test_for.zig
const expect = @import("std").testing.expect;
+
+test "for basics" {
+    const items = [_]i32{ 4, 5, 3, 4, 0 };
+    var sum: i32 = 0;
+
+    // For loops iterate over slices and arrays.
+    for (items) |value| {
+        // Break and continue are supported.
+        if (value == 0) {
+            continue;
+        }
+        sum += value;
+    }
+    try expect(sum == 16);
+
+    // To iterate over a portion of a slice, reslice.
+    for (items[0..1]) |value| {
+        sum += value;
+    }
+    try expect(sum == 20);
+
+    // To access the index of iteration, specify a second condition as well
+    // as a second capture value.
+    var sum2: i32 = 0;
+    for (items, 0..) |_, i| {
+        try expect(@TypeOf(i) == usize);
+        sum2 += @as(i32, @intCast(i));
+    }
+    try expect(sum2 == 10);
+
+    // To iterate over consecutive integers, use the range syntax.
+    // Unbounded range is always a compile error.
+    var sum3: usize = 0;
+    for (0..5) |i| {
+        sum3 += i;
+    }
+    try expect(sum3 == 10);
+}
+
+test "multi object for" {
+    const items = [_]usize{ 1, 2, 3 };
+    const items2 = [_]usize{ 4, 5, 6 };
+    var count: usize = 0;
+
+    // Iterate over multiple objects.
+    // All lengths must be equal at the start of the loop, otherwise detectable
+    // illegal behavior occurs.
+    for (items, items2) |i, j| {
+        count += i + j;
+    }
+
+    try expect(count == 21);
+}
+
+test "for reference" {
+    var items = [_]i32{ 3, 4, 2 };
+
+    // Iterate over the slice by reference by
+    // specifying that the capture value is a pointer.
+    for (&items) |*value| {
+        value.* += 1;
+    }
+
+    try expect(items[0] == 4);
+    try expect(items[1] == 5);
+    try expect(items[2] == 3);
+}
+
+test "for else" {
+    // For allows an else attached to it, the same as a while loop.
+    const items = [_]?i32{ 3, 4, null, 5 };
+
+    // For loops can also be used as expressions.
+    // Similar to while loops, when you break from a for loop, the else branch is not evaluated.
+    var sum: i32 = 0;
+    const result = for (items) |value| {
+        if (value != null) {
+            sum += value.?;
+        }
+    } else blk: {
+        try expect(sum == 12);
+        break :blk sum;
+    };
+    try expect(result == 12);
+}
Shell
$ zig test test_for.zig
+1/4 test_for.test.for basics...OK
+2/4 test_for.test.multi object for...OK
+3/4 test_for.test.for reference...OK
+4/4 test_for.test.for else...OK
+All 4 tests passed.
+
+ +

Labeled for §

+ +

When a for loop is labeled, it can be referenced from a break + or continue from within a nested loop:

+
test_for_nested_break.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "nested break" {
+    var count: usize = 0;
+    outer: for (1..6) |_| {
+        for (1..6) |_| {
+            count += 1;
+            break :outer;
+        }
+    }
+    try expect(count == 1);
+}
+
+test "nested continue" {
+    var count: usize = 0;
+    outer: for (1..9) |_| {
+        for (1..6) |_| {
+            count += 1;
+            continue :outer;
+        }
+    }
+
+    try expect(count == 8);
+}
Shell
$ zig test test_for_nested_break.zig
+1/2 test_for_nested_break.test.nested break...OK
+2/2 test_for_nested_break.test.nested continue...OK
+All 2 tests passed.
+
+ + +

inline for §

+ +

+ For loops can be inlined. This causes the loop to be unrolled, which + allows the code to do some things which only work at compile time, + such as use types as first class values. + The capture value and iterator value of inlined for loops are + compile-time known. +

+
test_inline_for.zig
const expect = @import("std").testing.expect;
+
+test "inline for loop" {
+    const nums = [_]i32{ 2, 4, 6 };
+    var sum: usize = 0;
+    inline for (nums) |i| {
+        const T = switch (i) {
+            2 => f32,
+            4 => i8,
+            6 => bool,
+            else => unreachable,
+        };
+        sum += typeNameLength(T);
+    }
+    try expect(sum == 9);
+}
+
+fn typeNameLength(comptime T: type) usize {
+    return @typeName(T).len;
+}
Shell
$ zig test test_inline_for.zig
+1/1 test_inline_for.test.inline for loop...OK
+All 1 tests passed.
+
+ +

+ It is recommended to use inline loops only for one of these reasons: +

+
    +
  • You need the loop to execute at comptime for the semantics to work.
  • +
  • + You have a benchmark to prove that forcibly unrolling the loop in this way is measurably faster. +
  • +
+ +

See also:

+ + +

if §

+ +
test_if.zig
// If expressions have three uses, corresponding to the three types:
+// * bool
+// * ?T
+// * anyerror!T
+
+const expect = @import("std").testing.expect;
+
+test "if expression" {
+    // If expressions are used instead of a ternary expression.
+    const a: u32 = 5;
+    const b: u32 = 4;
+    const result = if (a != b) 47 else 3089;
+    try expect(result == 47);
+}
+
+test "if boolean" {
+    // If expressions test boolean conditions.
+    const a: u32 = 5;
+    const b: u32 = 4;
+    if (a != b) {
+        try expect(true);
+    } else if (a == 9) {
+        unreachable;
+    } else {
+        unreachable;
+    }
+}
+
+test "if error union" {
+    // If expressions test for errors.
+    // Note the |err| capture on the else.
+
+    const a: anyerror!u32 = 0;
+    if (a) |value| {
+        try expect(value == 0);
+    } else |err| {
+        _ = err;
+        unreachable;
+    }
+
+    const b: anyerror!u32 = error.BadValue;
+    if (b) |value| {
+        _ = value;
+        unreachable;
+    } else |err| {
+        try expect(err == error.BadValue);
+    }
+
+    // The else and |err| capture is strictly required.
+    if (a) |value| {
+        try expect(value == 0);
+    } else |_| {}
+
+    // To check only the error value, use an empty block expression.
+    if (b) |_| {} else |err| {
+        try expect(err == error.BadValue);
+    }
+
+    // Access the value by reference using a pointer capture.
+    var c: anyerror!u32 = 3;
+    if (c) |*value| {
+        value.* = 9;
+    } else |_| {
+        unreachable;
+    }
+
+    if (c) |value| {
+        try expect(value == 9);
+    } else |_| {
+        unreachable;
+    }
+}
Shell
$ zig test test_if.zig
+1/3 test_if.test.if expression...OK
+2/3 test_if.test.if boolean...OK
+3/3 test_if.test.if error union...OK
+All 3 tests passed.
+
+ +

if with Optionals §

+ + +
test_if_optionals.zig
const expect = @import("std").testing.expect;
+
+test "if optional" {
+    // If expressions test for null.
+
+    const a: ?u32 = 0;
+    if (a) |value| {
+        try expect(value == 0);
+    } else {
+        unreachable;
+    }
+
+    const b: ?u32 = null;
+    if (b) |_| {
+        unreachable;
+    } else {
+        try expect(true);
+    }
+
+    // The else is not required.
+    if (a) |value| {
+        try expect(value == 0);
+    }
+
+    // To test against null only, use the binary equality operator.
+    if (b == null) {
+        try expect(true);
+    }
+
+    // Access the value by reference using a pointer capture.
+    var c: ?u32 = 3;
+    if (c) |*value| {
+        value.* = 2;
+    }
+
+    if (c) |value| {
+        try expect(value == 2);
+    } else {
+        unreachable;
+    }
+}
+
+test "if error union with optional" {
+    // If expressions test for errors before unwrapping optionals.
+    // The |optional_value| capture's type is ?u32.
+
+    const a: anyerror!?u32 = 0;
+    if (a) |optional_value| {
+        try expect(optional_value.? == 0);
+    } else |err| {
+        _ = err;
+        unreachable;
+    }
+
+    const b: anyerror!?u32 = null;
+    if (b) |optional_value| {
+        try expect(optional_value == null);
+    } else |_| {
+        unreachable;
+    }
+
+    const c: anyerror!?u32 = error.BadValue;
+    if (c) |optional_value| {
+        _ = optional_value;
+        unreachable;
+    } else |err| {
+        try expect(err == error.BadValue);
+    }
+
+    // Access the value by reference by using a pointer capture each time.
+    var d: anyerror!?u32 = 3;
+    if (d) |*optional_value| {
+        if (optional_value.*) |*value| {
+            value.* = 9;
+        }
+    } else |_| {
+        unreachable;
+    }
+
+    if (d) |optional_value| {
+        try expect(optional_value.? == 9);
+    } else |_| {
+        unreachable;
+    }
+}
Shell
$ zig test test_if_optionals.zig
+1/2 test_if_optionals.test.if optional...OK
+2/2 test_if_optionals.test.if error union with optional...OK
+All 2 tests passed.
+
+ + +

See also:

+ + +

defer §

+ +

Executes an expression unconditionally at scope exit.

+
test_defer.zig
const std = @import("std");
+const expect = std.testing.expect;
+const print = std.debug.print;
+
+fn deferExample() !usize {
+    var a: usize = 1;
+
+    {
+        defer a = 2;
+        a = 1;
+    }
+    try expect(a == 2);
+
+    a = 5;
+    return a;
+}
+
+test "defer basics" {
+    try expect((try deferExample()) == 5);
+}
Shell
$ zig test test_defer.zig
+1/1 test_defer.test.defer basics...OK
+All 1 tests passed.
+
+ +

Defer expressions are evaluated in reverse order.

+
defer_unwind.zig
const std = @import("std");
+const expect = std.testing.expect;
+const print = std.debug.print;
+
+test "defer unwinding" {
+    print("\n", .{});
+
+    defer {
+        print("1 ", .{});
+    }
+    defer {
+        print("2 ", .{});
+    }
+    if (false) {
+        // defers are not run if they are never executed.
+        defer {
+            print("3 ", .{});
+        }
+    }
+}
Shell
$ zig test defer_unwind.zig
+1/1 defer_unwind.test.defer unwinding...
+2 1 OK
+All 1 tests passed.
+
+ +

Inside a defer expression the return statement is not allowed.

+
test_invalid_defer.zig
fn deferInvalidExample() !void {
+    defer {
+        return error.DeferError;
+    }
+
+    return error.DeferError;
+}
Shell
$ zig test test_invalid_defer.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_invalid_defer.zig:3:9: error: cannot return from defer expression
+        return error.DeferError;
+        ^~~~~~~~~~~~~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_invalid_defer.zig:2:5: note: defer expression here
+    defer {
+    ^~~~~
+
+
+ +

See also:

+ + +

unreachable §

+ +

+ In Debug and ReleaseSafe mode + unreachable emits a call to panic with the message reached unreachable code. +

+

+ In ReleaseFast and ReleaseSmall mode, the optimizer uses the assumption that unreachable code + will never be hit to perform optimizations. +

+

Basics §

+ +
test_unreachable.zig
// unreachable is used to assert that control flow will never reach a
+// particular location:
+test "basic math" {
+    const x = 1;
+    const y = 2;
+    if (x + y != 3) {
+        unreachable;
+    }
+}
Shell
$ zig test test_unreachable.zig
+1/1 test_unreachable.test.basic math...OK
+All 1 tests passed.
+
+ +

In fact, this is how std.debug.assert is implemented:

+
test_assertion_failure.zig
// This is how std.debug.assert is implemented
+fn assert(ok: bool) void {
+    if (!ok) unreachable; // assertion failure
+}
+
+// This test will fail because we hit unreachable.
+test "this will fail" {
+    assert(false);
+}
Shell
$ zig test test_assertion_failure.zig
+1/1 test_assertion_failure.test.this will fail...thread 1079538 panic: reached unreachable code
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_assertion_failure.zig:3:14: 0x104866d in assert (test)
+    if (!ok) unreachable; // assertion failure
+             ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_assertion_failure.zig:8:11: 0x104863a in test.this will fail (test)
+    assert(false);
+          ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10ee969 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10e6d0d in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e6182 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e5d5d in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/d70b4afba1753abfc36c3e045b83ca5b/test --seed=0xb28f0ea5
+
+ + +

At Compile-Time §

+ +
test_comptime_unreachable.zig
const assert = @import("std").debug.assert;
+
+test "type of unreachable" {
+    comptime {
+        // The type of unreachable is noreturn.
+
+        // However this assertion will still fail to compile because
+        // unreachable expressions are compile errors.
+
+        assert(@TypeOf(unreachable) == noreturn);
+    }
+}
Shell
$ zig test test_comptime_unreachable.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_unreachable.zig:10:16: error: unreachable code
+        assert(@TypeOf(unreachable) == noreturn);
+               ^~~~~~~~~~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_unreachable.zig:10:24: note: control flow is diverted here
+        assert(@TypeOf(unreachable) == noreturn);
+                       ^~~~~~~~~~~
+
+
+ +

See also:

+ + + +

noreturn §

+ +

+ noreturn is the type of: +

+
    +
  • break
  • +
  • continue
  • +
  • return
  • +
  • unreachable
  • +
  • while (true) {}
  • +
+

When resolving types together, such as if clauses or switch prongs, + the noreturn type is compatible with every other type. Consider: +

+
test_noreturn.zig
fn foo(condition: bool, b: u32) void {
+    const a = if (condition) b else return;
+    _ = a;
+    @panic("do something with a");
+}
+test "noreturn" {
+    foo(false, 1);
+}
Shell
$ zig test test_noreturn.zig
+1/1 test_noreturn.test.noreturn...OK
+All 1 tests passed.
+
+ +

Another use case for noreturn is the exit function:

+
test_noreturn_from_exit.zig
const std = @import("std");
+const builtin = @import("builtin");
+const native_arch = builtin.cpu.arch;
+const expect = std.testing.expect;
+
+const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) .Stdcall else .C;
+extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(WINAPI) noreturn;
+
+test "foo" {
+    const value = bar() catch ExitProcess(1);
+    try expect(value == 1234);
+}
+
+fn bar() anyerror!u32 {
+    return 1234;
+}
Shell
$ zig test test_noreturn_from_exit.zig -target x86_64-windows --test-no-exec
+
+ + + +

Functions §

+ +
test_functions.zig
const std = @import("std");
+const builtin = @import("builtin");
+const native_arch = builtin.cpu.arch;
+const expect = std.testing.expect;
+
+// Functions are declared like this
+fn add(a: i8, b: i8) i8 {
+    if (a == 0) {
+        return b;
+    }
+
+    return a + b;
+}
+
+// The export specifier makes a function externally visible in the generated
+// object file, and makes it use the C ABI.
+export fn sub(a: i8, b: i8) i8 {
+    return a - b;
+}
+
+// The extern specifier is used to declare a function that will be resolved
+// at link time, when linking statically, or at runtime, when linking
+// dynamically. The quoted identifier after the extern keyword specifies
+// the library that has the function. (e.g. "c" -> libc.so)
+// The callconv specifier changes the calling convention of the function.
+const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) .Stdcall else .C;
+extern "kernel32" fn ExitProcess(exit_code: u32) callconv(WINAPI) noreturn;
+extern "c" fn atan2(a: f64, b: f64) f64;
+
+// The @branchHint builtin can be used to tell the optimizer that a function is rarely called ("cold").
+fn abort() noreturn {
+    @branchHint(.cold);
+    while (true) {}
+}
+
+// The naked calling convention makes a function not have any function prologue or epilogue.
+// This can be useful when integrating with assembly.
+fn _start() callconv(.Naked) noreturn {
+    abort();
+}
+
+// The inline calling convention forces a function to be inlined at all call sites.
+// If the function cannot be inlined, it is a compile-time error.
+inline fn shiftLeftOne(a: u32) u32 {
+    return a << 1;
+}
+
+// The pub specifier allows the function to be visible when importing.
+// Another file can use @import and call sub2
+pub fn sub2(a: i8, b: i8) i8 {
+    return a - b;
+}
+
+// Function pointers are prefixed with `*const `.
+const Call2Op = *const fn (a: i8, b: i8) i8;
+fn doOp(fnCall: Call2Op, op1: i8, op2: i8) i8 {
+    return fnCall(op1, op2);
+}
+
+test "function" {
+    try expect(doOp(add, 5, 6) == 11);
+    try expect(doOp(sub2, 5, 6) == -1);
+}
Shell
$ zig test test_functions.zig
+1/1 test_functions.test.function...OK
+All 1 tests passed.
+
+ +

There is a difference between a function body and a function pointer. + Function bodies are comptime-only types while function Pointers may be + runtime-known.

+

Pass-by-value Parameters §

+ +

+ Primitive types such as Integers and Floats passed as parameters + are copied, and then the copy is available in the function body. This is called "passing by value". + Copying a primitive type is essentially free and typically involves nothing more than + setting a register. +

+

+ Structs, unions, and arrays can sometimes be more efficiently passed as a reference, since a copy + could be arbitrarily expensive depending on the size. When these types are passed + as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way + Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable. +

+
test_pass_by_reference_or_value.zig
const Point = struct {
+    x: i32,
+    y: i32,
+};
+
+fn foo(point: Point) i32 {
+    // Here, `point` could be a reference, or a copy. The function body
+    // can ignore the difference and treat it as a value. Be very careful
+    // taking the address of the parameter - it should be treated as if
+    // the address will become invalid when the function returns.
+    return point.x + point.y;
+}
+
+const expect = @import("std").testing.expect;
+
+test "pass struct to function" {
+    try expect(foo(Point{ .x = 1, .y = 2 }) == 3);
+}
Shell
$ zig test test_pass_by_reference_or_value.zig
+1/1 test_pass_by_reference_or_value.test.pass struct to function...OK
+All 1 tests passed.
+
+ +

+ For extern functions, Zig follows the C ABI for passing structs and unions by value. +

+ +

Function Parameter Type Inference §

+ +

+ Function parameters can be declared with anytype in place of the type. + In this case the parameter types will be inferred when the function is called. + Use @TypeOf and @typeInfo to get information about the inferred type. +

+
test_fn_type_inference.zig
const expect = @import("std").testing.expect;
+
+fn addFortyTwo(x: anytype) @TypeOf(x) {
+    return x + 42;
+}
+
+test "fn type inference" {
+    try expect(addFortyTwo(1) == 43);
+    try expect(@TypeOf(addFortyTwo(1)) == comptime_int);
+    const y: i64 = 2;
+    try expect(addFortyTwo(y) == 44);
+    try expect(@TypeOf(addFortyTwo(y)) == i64);
+}
Shell
$ zig test test_fn_type_inference.zig
+1/1 test_fn_type_inference.test.fn type inference...OK
+All 1 tests passed.
+
+ + + + +

inline fn §

+ +

+ Adding the inline keyword to a function definition makes that + function become semantically inlined at the callsite. This is + not a hint to be possibly observed by optimization passes, but has + implications on the types and values involved in the function call. +

+

+ Unlike normal function calls, arguments at an inline function callsite which are + compile-time known are treated as Compile Time Parameters. This can potentially + propagate all the way to the return value: +

+
inline_call.zig
test "inline function call" {
+    if (foo(1200, 34) != 1234) {
+        @compileError("bad");
+    }
+}
+
+inline fn foo(a: i32, b: i32) i32 {
+    return a + b;
+}
Shell
$ zig test inline_call.zig
+1/1 inline_call.test.inline function call...OK
+All 1 tests passed.
+
+ +

If inline is removed, the test fails with the compile error + instead of passing.

+

It is generally better to let the compiler decide when to inline a + function, except for these scenarios:

+
    +
  • To change how many stack frames are in the call stack, for debugging purposes.
  • +
  • To force comptime-ness of the arguments to propagate to the return value of the function, as in the above example.
  • +
  • Real world performance measurements demand it.
  • +
+

Note that inline actually restricts + what the compiler is allowed to do. This can harm binary size, + compilation speed, and even runtime performance.

+ + +

Function Reflection §

+ +
test_fn_reflection.zig
const std = @import("std");
+const math = std.math;
+const testing = std.testing;
+
+test "fn reflection" {
+    try testing.expect(@typeInfo(@TypeOf(testing.expect)).@"fn".params[0].type.? == bool);
+    try testing.expect(@typeInfo(@TypeOf(testing.tmpDir)).@"fn".return_type.? == testing.TmpDir);
+
+    try testing.expect(@typeInfo(@TypeOf(math.Log2Int)).@"fn".is_generic);
+}
Shell
$ zig test test_fn_reflection.zig
+1/1 test_fn_reflection.test.fn reflection...OK
+All 1 tests passed.
+
+ + + +

Errors §

+ +

Error Set Type §

+ +

+ An error set is like an enum. + However, each error name across the entire compilation gets assigned an unsigned integer + greater than 0. You are allowed to declare the same error name more than once, and if you do, it + gets assigned the same integer value. +

+

+ The error set type defaults to a u16, though if the maximum number of distinct + error values is provided via the --error-limit [num] command line parameter an integer type + with the minimum number of bits required to represent all of the error values will be used. +

+

+ You can coerce an error from a subset to a superset: +

+
test_coerce_error_subset_to_superset.zig
const std = @import("std");
+
+const FileOpenError = error{
+    AccessDenied,
+    OutOfMemory,
+    FileNotFound,
+};
+
+const AllocationError = error{
+    OutOfMemory,
+};
+
+test "coerce subset to superset" {
+    const err = foo(AllocationError.OutOfMemory);
+    try std.testing.expect(err == FileOpenError.OutOfMemory);
+}
+
+fn foo(err: AllocationError) FileOpenError {
+    return err;
+}
Shell
$ zig test test_coerce_error_subset_to_superset.zig
+1/1 test_coerce_error_subset_to_superset.test.coerce subset to superset...OK
+All 1 tests passed.
+
+ +

+ But you cannot coerce an error from a superset to a subset: +

+
test_coerce_error_superset_to_subset.zig
const FileOpenError = error{
+    AccessDenied,
+    OutOfMemory,
+    FileNotFound,
+};
+
+const AllocationError = error{
+    OutOfMemory,
+};
+
+test "coerce superset to subset" {
+    foo(FileOpenError.OutOfMemory) catch {};
+}
+
+fn foo(err: FileOpenError) AllocationError {
+    return err;
+}
Shell
$ zig test test_coerce_error_superset_to_subset.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_coerce_error_superset_to_subset.zig:16:12: error: expected type 'error{OutOfMemory}', found 'error{AccessDenied,OutOfMemory,FileNotFound}'
+    return err;
+           ^~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_coerce_error_superset_to_subset.zig:16:12: note: 'error.AccessDenied' not a member of destination error set
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_coerce_error_superset_to_subset.zig:16:12: note: 'error.FileNotFound' not a member of destination error set
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_coerce_error_superset_to_subset.zig:15:28: note: function return type declared here
+fn foo(err: FileOpenError) AllocationError {
+                           ^~~~~~~~~~~~~~~
+referenced by:
+    test.coerce superset to subset: /home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_coerce_error_superset_to_subset.zig:12:8
+
+
+ +

+ There is a shortcut for declaring an error set with only 1 value, and then getting that value: +

+
single_value_error_set_shortcut.zig
const err = error.FileNotFound;
+ +

This is equivalent to:

+
single_value_error_set.zig
const err = (error{FileNotFound}).FileNotFound;
+ +

+ This becomes useful when using Inferred Error Sets. +

+

The Global Error Set §

+ +

anyerror refers to the global error set. + This is the error set that contains all errors in the entire compilation unit, i.e. it is the union of all other error sets. +

+

+ You can coerce any error set to the global one, and you can explicitly + cast an error of the global error set to a non-global one. This inserts a language-level + assert to make sure the error value is in fact in the destination error set. +

+

+ The global error set should generally be avoided because it prevents the + compiler from knowing what errors are possible at compile-time. Knowing + the error set at compile-time is better for generated documentation and + helpful error messages, such as forgetting a possible error value in a switch. +

+ + +

Error Union Type §

+ +

+ An error set type and normal type can be combined with the ! + binary operator to form an error union type. You are likely to use an + error union type more often than an error set type by itself. +

+

+ Here is a function to parse a string into a 64-bit integer: +

+
error_union_parsing_u64.zig
const std = @import("std");
+const maxInt = std.math.maxInt;
+
+pub fn parseU64(buf: []const u8, radix: u8) !u64 {
+    var x: u64 = 0;
+
+    for (buf) |c| {
+        const digit = charToDigit(c);
+
+        if (digit >= radix) {
+            return error.InvalidChar;
+        }
+
+        // x *= radix
+        var ov = @mulWithOverflow(x, radix);
+        if (ov[1] != 0) return error.OverFlow;
+
+        // x += digit
+        ov = @addWithOverflow(ov[0], digit);
+        if (ov[1] != 0) return error.OverFlow;
+        x = ov[0];
+    }
+
+    return x;
+}
+
+fn charToDigit(c: u8) u8 {
+    return switch (c) {
+        '0'...'9' => c - '0',
+        'A'...'Z' => c - 'A' + 10,
+        'a'...'z' => c - 'a' + 10,
+        else => maxInt(u8),
+    };
+}
+
+test "parse u64" {
+    const result = try parseU64("1234", 10);
+    try std.testing.expect(result == 1234);
+}
Shell
$ zig test error_union_parsing_u64.zig
+1/1 error_union_parsing_u64.test.parse u64...OK
+All 1 tests passed.
+
+ +

+ Notice the return type is !u64. This means that the function + either returns an unsigned 64 bit integer, or an error. We left off the error set + to the left of the !, so the error set is inferred. +

+

+ Within the function definition, you can see some return statements that return + an error, and at the bottom a return statement that returns a u64. + Both types coerce to anyerror!u64. +

+

+ What it looks like to use this function varies depending on what you're + trying to do. One of the following: +

+
    +
  • You want to provide a default value if it returned an error.
  • +
  • If it returned an error then you want to return the same error.
  • +
  • You know with complete certainty it will not return an error, so want to unconditionally unwrap it.
  • +
  • You want to take a different action for each possible error.
  • +
+

catch §

+ +

If you want to provide a default value, you can use the catch binary operator:

+
catch.zig
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
+
+fn doAThing(str: []u8) void {
+    const number = parseU64(str, 10) catch 13;
+    _ = number; // ...
+}
+ +

+ In this code, number will be equal to the successfully parsed string, or + a default value of 13. The type of the right hand side of the binary catch operator must + match the unwrapped error union type, or be of type noreturn. +

+

+ If you want to provide a default value with + catch after performing some logic, you + can combine catch with named Blocks: +

+
handle_error_with_catch_block.zig.zig
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
+
+fn doAThing(str: []u8) void {
+    const number = parseU64(str, 10) catch blk: {
+        // do things
+        break :blk 13;
+    };
+    _ = number; // number is now initialized
+}
+ + +

try §

+ +

Let's say you wanted to return the error if you got one, otherwise continue with the + function logic:

+
catch_err_return.zig
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
+
+fn doAThing(str: []u8) !void {
+    const number = parseU64(str, 10) catch |err| return err;
+    _ = number; // ...
+}
+ +

+ There is a shortcut for this. The try expression: +

+
try.zig
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
+
+fn doAThing(str: []u8) !void {
+    const number = try parseU64(str, 10);
+    _ = number; // ...
+}
+ +

+ try evaluates an error union expression. If it is an error, it returns + from the current function with the same error. Otherwise, the expression results in + the unwrapped value. +

+ +

+ Maybe you know with complete certainty that an expression will never be an error. + In this case you can do this: +

+ const number = parseU64("1234", 10) catch unreachable; +

+ Here we know for sure that "1234" will parse successfully. So we put the + unreachable value on the right hand side. + unreachable invokes safety-checked Illegal Behavior, so + in Debug and ReleaseSafe, triggers a safety panic by default. So, while + we're debugging the application, if there was a surprise error here, the application + would crash appropriately. +

+

+ You may want to take a different action for every situation. For that, we combine + the if and switch expression: +

+
handle_all_error_scenarios.zig
fn doAThing(str: []u8) void {
+    if (parseU64(str, 10)) |number| {
+        doSomethingWithNumber(number);
+    } else |err| switch (err) {
+        error.Overflow => {
+            // handle overflow...
+        },
+        // we promise that InvalidChar won't happen (or crash in debug mode if it does)
+        error.InvalidChar => unreachable,
+    }
+}
+

+ Finally, you may want to handle only some errors. For that, you can capture the unhandled + errors in the else case, which now contains a narrower error set: +

+
handle_some_error_scenarios.zig
fn doAnotherThing(str: []u8) error{InvalidChar}!void {
+    if (parseU64(str, 10)) |number| {
+        doSomethingWithNumber(number);
+    } else |err| switch (err) {
+        error.Overflow => {
+            // handle overflow...
+        },
+        else => |leftover_err| return leftover_err,
+    }
+}
+

+ You must use the variable capture syntax. If you don't need the + variable, you can capture with _ and avoid the + switch. +

+
handle_no_error_scenarios.zig
fn doADifferentThing(str: []u8) void {
+    if (parseU64(str, 10)) |number| {
+        doSomethingWithNumber(number);
+    } else |_| {
+        // do as you'd like
+    }
+}
+

errdefer §

+ +

+ The other component to error handling is defer statements. + In addition to an unconditional defer, Zig has errdefer, + which evaluates the deferred expression on block exit path if and only if + the function returned with an error from the block. +

+

+ Example: +

+
errdefer_example.zig
fn createFoo(param: i32) !Foo {
+    const foo = try tryToAllocateFoo();
+    // now we have allocated foo. we need to free it if the function fails.
+    // but we want to return it if the function succeeds.
+    errdefer deallocateFoo(foo);
+
+    const tmp_buf = allocateTmpBuffer() orelse return error.OutOfMemory;
+    // tmp_buf is truly a temporary resource, and we for sure want to clean it up
+    // before this block leaves scope
+    defer deallocateTmpBuffer(tmp_buf);
+
+    if (param > 1337) return error.InvalidParam;
+
+    // here the errdefer will not run since we're returning success from the function.
+    // but the defer will run!
+    return foo;
+}
+

+ The neat thing about this is that you get robust error handling without + the verbosity and cognitive overhead of trying to make sure every exit path + is covered. The deallocation code is always directly following the allocation code. +

+

+ The errdefer statement can optionally capture the error: +

+
test_errdefer_capture.zig
const std = @import("std");
+
+fn captureError(captured: *?anyerror) !void {
+    errdefer |err| {
+        captured.* = err;
+    }
+    return error.GeneralFailure;
+}
+
+test "errdefer capture" {
+    var captured: ?anyerror = null;
+
+    if (captureError(&captured)) unreachable else |err| {
+        try std.testing.expectEqual(error.GeneralFailure, captured.?);
+        try std.testing.expectEqual(error.GeneralFailure, err);
+    }
+}
Shell
$ zig test test_errdefer_capture.zig
+1/1 test_errdefer_capture.test.errdefer capture...OK
+All 1 tests passed.
+
+ +

+ A couple of other tidbits about error handling: +

+
    +
  • These primitives give enough expressiveness that it's completely practical + to have failing to check for an error be a compile error. If you really want + to ignore the error, you can add catch unreachable and + get the added benefit of crashing in Debug and ReleaseSafe modes if your assumption was wrong. +
  • +
  • + Since Zig understands error types, it can pre-weight branches in favor of + errors not occurring. Just a small optimization benefit that is not available + in other languages. +
  • +
+

See also:

+ + +

An error union is created with the ! binary operator. + You can use compile-time reflection to access the child type of an error union:

+
test_error_union.zig
const expect = @import("std").testing.expect;
+
+test "error union" {
+    var foo: anyerror!i32 = undefined;
+
+    // Coerce from child type of an error union:
+    foo = 1234;
+
+    // Coerce from an error set:
+    foo = error.SomeError;
+
+    // Use compile-time reflection to access the payload type of an error union:
+    try comptime expect(@typeInfo(@TypeOf(foo)).error_union.payload == i32);
+
+    // Use compile-time reflection to access the error set type of an error union:
+    try comptime expect(@typeInfo(@TypeOf(foo)).error_union.error_set == anyerror);
+}
Shell
$ zig test test_error_union.zig
+1/1 test_error_union.test.error union...OK
+All 1 tests passed.
+
+ +

Merging Error Sets §

+ +

+ Use the || operator to merge two error sets together. The resulting + error set contains the errors of both error sets. Doc comments from the left-hand + side override doc comments from the right-hand side. In this example, the doc + comments for C.PathNotFound is A doc comment. +

+

+ This is especially useful for functions which return different error sets depending + on comptime branches. For example, the Zig standard library uses + LinuxFileOpenError || WindowsFileOpenError for the error set of opening + files. +

+
test_merging_error_sets.zig
const A = error{
+    NotDir,
+
+    /// A doc comment
+    PathNotFound,
+};
+const B = error{
+    OutOfMemory,
+
+    /// B doc comment
+    PathNotFound,
+};
+
+const C = A || B;
+
+fn foo() C!void {
+    return error.NotDir;
+}
+
+test "merge error sets" {
+    if (foo()) {
+        @panic("unexpected");
+    } else |err| switch (err) {
+        error.OutOfMemory => @panic("unexpected"),
+        error.PathNotFound => @panic("unexpected"),
+        error.NotDir => {},
+    }
+}
Shell
$ zig test test_merging_error_sets.zig
+1/1 test_merging_error_sets.test.merge error sets...OK
+All 1 tests passed.
+
+ + +

Inferred Error Sets §

+ +

+ Because many functions in Zig return a possible error, Zig supports inferring the error set. + To infer the error set for a function, prepend the ! operator to the function’s return type, like !T: +

+
test_inferred_error_sets.zig
// With an inferred error set
+pub fn add_inferred(comptime T: type, a: T, b: T) !T {
+    const ov = @addWithOverflow(a, b);
+    if (ov[1] != 0) return error.Overflow;
+    return ov[0];
+}
+
+// With an explicit error set
+pub fn add_explicit(comptime T: type, a: T, b: T) Error!T {
+    const ov = @addWithOverflow(a, b);
+    if (ov[1] != 0) return error.Overflow;
+    return ov[0];
+}
+
+const Error = error{
+    Overflow,
+};
+
+const std = @import("std");
+
+test "inferred error set" {
+    if (add_inferred(u8, 255, 1)) |_| unreachable else |err| switch (err) {
+        error.Overflow => {}, // ok
+    }
+}
Shell
$ zig test test_inferred_error_sets.zig
+1/1 test_inferred_error_sets.test.inferred error set...OK
+All 1 tests passed.
+
+ +

+ When a function has an inferred error set, that function becomes generic and thus it becomes + trickier to do certain things with it, such as obtain a function pointer, or have an error + set that is consistent across different build targets. Additionally, inferred error sets + are incompatible with recursion. +

+

+ In these situations, it is recommended to use an explicit error set. You can generally start + with an empty error set and let compile errors guide you toward completing the set. +

+

+ These limitations may be overcome in a future version of Zig. +

+ + +

Error Return Traces §

+ +

+ Error Return Traces show all the points in the code that an error was returned to the calling function. This makes it practical to use try everywhere and then still be able to know what happened if an error ends up bubbling all the way out of your application. +

+
error_return_trace.zig
pub fn main() !void {
+    try foo(12);
+}
+
+fn foo(x: i32) !void {
+    if (x >= 5) {
+        try bar();
+    } else {
+        try bang2();
+    }
+}
+
+fn bar() !void {
+    if (baz()) {
+        try quux();
+    } else |err| switch (err) {
+        error.FileNotFound => try hello(),
+    }
+}
+
+fn baz() !void {
+    try bang1();
+}
+
+fn quux() !void {
+    try bang2();
+}
+
+fn hello() !void {
+    try bang2();
+}
+
+fn bang1() !void {
+    return error.FileNotFound;
+}
+
+fn bang2() !void {
+    return error.PermissionDenied;
+}
Shell
$ zig build-exe error_return_trace.zig
+$ ./error_return_trace
+error: PermissionDenied
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/error_return_trace.zig:34:5: 0x10de038 in bang1 (error_return_trace)
+    return error.FileNotFound;
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/error_return_trace.zig:22:5: 0x10de063 in baz (error_return_trace)
+    try bang1();
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/error_return_trace.zig:38:5: 0x10de088 in bang2 (error_return_trace)
+    return error.PermissionDenied;
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/error_return_trace.zig:30:5: 0x10de0f3 in hello (error_return_trace)
+    try bang2();
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/error_return_trace.zig:17:31: 0x10de198 in bar (error_return_trace)
+        error.FileNotFound => try hello(),
+                              ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/error_return_trace.zig:7:9: 0x10de200 in foo (error_return_trace)
+        try bar();
+        ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/error_return_trace.zig:2:5: 0x10de258 in main (error_return_trace)
+    try foo(12);
+    ^
+
+ +

+ Look closely at this example. This is no stack trace. +

+

+ You can see that the final error bubbled up was PermissionDenied, + but the original error that started this whole thing was FileNotFound. In the bar function, the code handles the original error code, + and then returns another one, from the switch statement. Error Return Traces make this clear, whereas a stack trace would look like this: +

+
stack_trace.zig
pub fn main() void {
+    foo(12);
+}
+
+fn foo(x: i32) void {
+    if (x >= 5) {
+        bar();
+    } else {
+        bang2();
+    }
+}
+
+fn bar() void {
+    if (baz()) {
+        quux();
+    } else {
+        hello();
+    }
+}
+
+fn baz() bool {
+    return bang1();
+}
+
+fn quux() void {
+    bang2();
+}
+
+fn hello() void {
+    bang2();
+}
+
+fn bang1() bool {
+    return false;
+}
+
+fn bang2() void {
+    @panic("PermissionDenied");
+}
Shell
$ zig build-exe stack_trace.zig
+$ ./stack_trace
+thread 1081770 panic: PermissionDenied
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/stack_trace.zig:38:5: 0x10decfc in bang2 (stack_trace)
+    @panic("PermissionDenied");
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/stack_trace.zig:30:10: 0x10df5c8 in hello (stack_trace)
+    bang2();
+         ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/stack_trace.zig:17:14: 0x10decd0 in bar (stack_trace)
+        hello();
+             ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/stack_trace.zig:7:12: 0x10deaf4 in foo (stack_trace)
+        bar();
+           ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/stack_trace.zig:2:8: 0x10de28d in main (stack_trace)
+    foo(12);
+       ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddc82 in posixCallMainAndExit (stack_trace)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd85d in _start (stack_trace)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ +

+ Here, the stack trace does not explain how the control + flow in bar got to the hello() call. + One would have to open a debugger or further instrument the application + in order to find out. The error return trace, on the other hand, + shows exactly how the error bubbled up. +

+

+ This debugging feature makes it easier to iterate quickly on code that + robustly handles all error conditions. This means that Zig developers + will naturally find themselves writing correct, robust code in order + to increase their development pace. +

+

+ Error Return Traces are enabled by default in Debug and ReleaseSafe builds and disabled by default in ReleaseFast and ReleaseSmall builds. +

+

+ There are a few ways to activate this error return tracing feature: +

+
    +
  • Return an error from main
  • +
  • An error makes its way to catch unreachable and you have not overridden the default panic handler
  • +
  • Use errorReturnTrace to access the current return trace. You can use std.debug.dumpStackTrace to print it. This function returns comptime-known null when building without error return tracing support.
  • +
+

Implementation Details §

+ +

+ To analyze performance cost, there are two cases: +

+
    +
  • when no errors are returned
  • +
  • when returning errors
  • +
+

+ For the case when no errors are returned, the cost is a single memory write operation, only in the first non-failable function in the call graph that calls a failable function, i.e. when a function returning void calls a function returning error. + This is to initialize this struct in the stack memory: +

+
stack_trace_struct.zig
pub const StackTrace = struct {
+    index: usize,
+    instruction_addresses: [N]usize,
+};
+

+ Here, N is the maximum function call depth as determined by call graph analysis. Recursion is ignored and counts for 2. +

+

+ A pointer to StackTrace is passed as a secret parameter to every function that can return an error, but it's always the first parameter, so it can likely sit in a register and stay there. +

+

+ That's it for the path when no errors occur. It's practically free in terms of performance. +

+

+ When generating the code for a function that returns an error, just before the return statement (only for the return statements that return errors), Zig generates a call to this function: +

+
zig_return_error_fn.zig
// marked as "no-inline" in LLVM IR
+fn __zig_return_error(stack_trace: *StackTrace) void {
+    stack_trace.instruction_addresses[stack_trace.index] = @returnAddress();
+    stack_trace.index = (stack_trace.index + 1) % N;
+}
+

+ The cost is 2 math operations plus some memory reads and writes. The memory accessed is constrained and should remain cached for the duration of the error return bubbling. +

+

+ As for code size cost, 1 function call before a return statement is no big deal. Even so, + I have a plan to make the call to + __zig_return_error a tail call, which brings the code size cost down to actually zero. What is a return statement in code without error return tracing can become a jump instruction in code with error return tracing. +

+ + + +

Optionals §

+ +

+ One area that Zig provides safety without compromising efficiency or + readability is with the optional type. +

+

+ The question mark symbolizes the optional type. You can convert a type to an optional + type by putting a question mark in front of it, like this: +

+
optional_integer.zig
// normal integer
+const normal_int: i32 = 1234;
+
+// optional integer
+const optional_int: ?i32 = 5678;
+ +

+ Now the variable optional_int could be an i32, or null. +

+

+ Instead of integers, let's talk about pointers. Null references are the source of many runtime + exceptions, and even stand accused of being + the worst mistake of computer science. +

+

Zig does not have them.

+

+ Instead, you can use an optional pointer. This secretly compiles down to a normal pointer, + since we know we can use 0 as the null value for the optional type. But the compiler + can check your work and make sure you don't assign null to something that can't be null. +

+

+ Typically the downside of not having null is that it makes the code more verbose to + write. But, let's compare some equivalent C code and Zig code. +

+

+ Task: call malloc, if the result is null, return null. +

+

C code

+
call_malloc_in_c.c
// malloc prototype included for reference
+void *malloc(size_t size);
+
+struct Foo *do_a_thing(void) {
+    char *ptr = malloc(1234);
+    if (!ptr) return NULL;
+    // ...
+}
+

Zig code

+
call_malloc_from_zig.zig
// malloc prototype included for reference
+extern fn malloc(size: usize) ?[*]u8;
+
+fn doAThing() ?*Foo {
+    const ptr = malloc(1234) orelse return null;
+    _ = ptr; // ...
+}
+

+ Here, Zig is at least as convenient, if not more, than C. And, the type of "ptr" + is [*]u8 not ?[*]u8. The orelse keyword + unwrapped the optional type and therefore ptr is guaranteed to be non-null everywhere + it is used in the function. +

+

+ The other form of checking against NULL you might see looks like this: +

+
checking_null_in_c.c
void do_a_thing(struct Foo *foo) {
+    // do some stuff
+
+    if (foo) {
+        do_something_with_foo(foo);
+    }
+
+    // do some stuff
+}
+

+ In Zig you can accomplish the same thing: +

+
checking_null_in_zig.zig
const Foo = struct {};
+fn doSomethingWithFoo(foo: *Foo) void {
+    _ = foo;
+}
+
+fn doAThing(optional_foo: ?*Foo) void {
+    // do some stuff
+
+    if (optional_foo) |foo| {
+        doSomethingWithFoo(foo);
+    }
+
+    // do some stuff
+}
+ +

+ Once again, the notable thing here is that inside the if block, + foo is no longer an optional pointer, it is a pointer, which + cannot be null. +

+

+ One benefit to this is that functions which take pointers as arguments can + be annotated with the "nonnull" attribute - __attribute__((nonnull)) in + GCC. + The optimizer can sometimes make better decisions knowing that pointer arguments + cannot be null. +

+

Optional Type §

+ +

An optional is created by putting ? in front of a type. You can use compile-time + reflection to access the child type of an optional:

+
test_optional_type.zig
const expect = @import("std").testing.expect;
+
+test "optional type" {
+    // Declare an optional and coerce from null:
+    var foo: ?i32 = null;
+
+    // Coerce from child type of an optional
+    foo = 1234;
+
+    // Use compile-time reflection to access the child type of the optional:
+    try comptime expect(@typeInfo(@TypeOf(foo)).optional.child == i32);
+}
Shell
$ zig test test_optional_type.zig
+1/1 test_optional_type.test.optional type...OK
+All 1 tests passed.
+
+ + +

null §

+ +

+ Just like undefined, null has its own type, and the only way to use it is to + cast it to a different type: +

+
null.zig
const optional_value: ?i32 = null;
+ + +

Optional Pointers §

+ +

An optional pointer is guaranteed to be the same size as a pointer. The null of + the optional is guaranteed to be address 0.

+
test_optional_pointer.zig
const expect = @import("std").testing.expect;
+
+test "optional pointers" {
+    // Pointers cannot be null. If you want a null pointer, use the optional
+    // prefix `?` to make the pointer type optional.
+    var ptr: ?*i32 = null;
+
+    var x: i32 = 1;
+    ptr = &x;
+
+    try expect(ptr.?.* == 1);
+
+    // Optional pointers are the same size as normal pointers, because pointer
+    // value 0 is used as the null value.
+    try expect(@sizeOf(?*i32) == @sizeOf(*i32));
+}
Shell
$ zig test test_optional_pointer.zig
+1/1 test_optional_pointer.test.optional pointers...OK
+All 1 tests passed.
+
+ + + +

See also:

+ + +

Casting §

+ +

+ A type cast converts a value of one type to another. + Zig has Type Coercion for conversions that are known to be completely safe and unambiguous, + and Explicit Casts for conversions that one would not want to happen on accident. + There is also a third kind of type conversion called Peer Type Resolution for + the case when a result type must be decided given multiple operand types. +

+

Type Coercion §

+ +

+ Type coercion occurs when one type is expected, but different type is provided: +

+
test_type_coercion.zig
test "type coercion - variable declaration" {
+    const a: u8 = 1;
+    const b: u16 = a;
+    _ = b;
+}
+
+test "type coercion - function call" {
+    const a: u8 = 1;
+    foo(a);
+}
+
+fn foo(b: u16) void {
+    _ = b;
+}
+
+test "type coercion - @as builtin" {
+    const a: u8 = 1;
+    const b = @as(u16, a);
+    _ = b;
+}
Shell
$ zig test test_type_coercion.zig
+1/3 test_type_coercion.test.type coercion - variable declaration...OK
+2/3 test_type_coercion.test.type coercion - function call...OK
+3/3 test_type_coercion.test.type coercion - @as builtin...OK
+All 3 tests passed.
+
+ +

+ Type coercions are only allowed when it is completely unambiguous how to get from one type to another, + and the transformation is guaranteed to be safe. There is one exception, which is C Pointers. +

+

Type Coercion: Stricter Qualification §

+ +

+ Values which have the same representation at runtime can be cast to increase the strictness + of the qualifiers, no matter how nested the qualifiers are: +

+
    +
  • const - non-const to const is allowed
  • +
  • volatile - non-volatile to volatile is allowed
  • +
  • align - bigger to smaller alignment is allowed
  • +
  • error sets to supersets is allowed
  • +
+

+ These casts are no-ops at runtime since the value representation does not change. +

+
test_no_op_casts.zig
test "type coercion - const qualification" {
+    var a: i32 = 1;
+    const b: *i32 = &a;
+    foo(b);
+}
+
+fn foo(_: *const i32) void {}
Shell
$ zig test test_no_op_casts.zig
+1/1 test_no_op_casts.test.type coercion - const qualification...OK
+All 1 tests passed.
+
+ +

+ In addition, pointers coerce to const optional pointers: +

+
test_pointer_coerce_const_optional.zig
const std = @import("std");
+const expect = std.testing.expect;
+const mem = std.mem;
+
+test "cast *[1][*:0]const u8 to []const ?[*:0]const u8" {
+    const window_name = [1][*:0]const u8{"window name"};
+    const x: []const ?[*:0]const u8 = &window_name;
+    try expect(mem.eql(u8, mem.span(x[0].?), "window name"));
+}
Shell
$ zig test test_pointer_coerce_const_optional.zig
+1/1 test_pointer_coerce_const_optional.test.cast *[1][*:0]const u8 to []const ?[*:0]const u8...OK
+All 1 tests passed.
+
+ + +

Type Coercion: Integer and Float Widening §

+ +

+ Integers coerce to integer types which can represent every value of the old type, and likewise + Floats coerce to float types which can represent every value of the old type. +

+
test_integer_widening.zig
const std = @import("std");
+const builtin = @import("builtin");
+const expect = std.testing.expect;
+const mem = std.mem;
+
+test "integer widening" {
+    const a: u8 = 250;
+    const b: u16 = a;
+    const c: u32 = b;
+    const d: u64 = c;
+    const e: u64 = d;
+    const f: u128 = e;
+    try expect(f == a);
+}
+
+test "implicit unsigned integer to signed integer" {
+    const a: u8 = 250;
+    const b: i16 = a;
+    try expect(b == 250);
+}
+
+test "float widening" {
+    const a: f16 = 12.34;
+    const b: f32 = a;
+    const c: f64 = b;
+    const d: f128 = c;
+    try expect(d == a);
+}
Shell
$ zig test test_integer_widening.zig
+1/3 test_integer_widening.test.integer widening...OK
+2/3 test_integer_widening.test.implicit unsigned integer to signed integer...OK
+3/3 test_integer_widening.test.float widening...OK
+All 3 tests passed.
+
+ + +

Type Coercion: Float to Int §

+ +

+ A compiler error is appropriate because this ambiguous expression leaves the compiler + two choices about the coercion. +

+
    +
  • Cast 54.0 to comptime_int resulting in @as(comptime_int, 10), which is casted to @as(f32, 10)
  • +
  • Cast 5 to comptime_float resulting in @as(comptime_float, 10.8), which is casted to @as(f32, 10.8)
  • +
+
test_ambiguous_coercion.zig
// Compile time coercion of float to int
+test "implicit cast to comptime_int" {
+    const f: f32 = 54.0 / 5;
+    _ = f;
+}
Shell
$ zig test test_ambiguous_coercion.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_ambiguous_coercion.zig:3:25: error: ambiguous coercion of division operands 'comptime_float' and 'comptime_int'; non-zero remainder '4'
+    const f: f32 = 54.0 / 5;
+                   ~~~~~^~~
+
+
+ + +

Type Coercion: Slices, Arrays and Pointers §

+ +
test_coerce_slices_arrays_and_pointers.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+// You can assign constant pointers to arrays to a slice with
+// const modifier on the element type. Useful in particular for
+// String literals.
+test "*const [N]T to []const T" {
+    const x1: []const u8 = "hello";
+    const x2: []const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
+    try expect(std.mem.eql(u8, x1, x2));
+
+    const y: []const f32 = &[2]f32{ 1.2, 3.4 };
+    try expect(y[0] == 1.2);
+}
+
+// Likewise, it works when the destination type is an error union.
+test "*const [N]T to E![]const T" {
+    const x1: anyerror![]const u8 = "hello";
+    const x2: anyerror![]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
+    try expect(std.mem.eql(u8, try x1, try x2));
+
+    const y: anyerror![]const f32 = &[2]f32{ 1.2, 3.4 };
+    try expect((try y)[0] == 1.2);
+}
+
+// Likewise, it works when the destination type is an optional.
+test "*const [N]T to ?[]const T" {
+    const x1: ?[]const u8 = "hello";
+    const x2: ?[]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
+    try expect(std.mem.eql(u8, x1.?, x2.?));
+
+    const y: ?[]const f32 = &[2]f32{ 1.2, 3.4 };
+    try expect(y.?[0] == 1.2);
+}
+
+// In this cast, the array length becomes the slice length.
+test "*[N]T to []T" {
+    var buf: [5]u8 = "hello".*;
+    const x: []u8 = &buf;
+    try expect(std.mem.eql(u8, x, "hello"));
+
+    const buf2 = [2]f32{ 1.2, 3.4 };
+    const x2: []const f32 = &buf2;
+    try expect(std.mem.eql(f32, x2, &[2]f32{ 1.2, 3.4 }));
+}
+
+// Single-item pointers to arrays can be coerced to many-item pointers.
+test "*[N]T to [*]T" {
+    var buf: [5]u8 = "hello".*;
+    const x: [*]u8 = &buf;
+    try expect(x[4] == 'o');
+    // x[5] would be an uncaught out of bounds pointer dereference!
+}
+
+// Likewise, it works when the destination type is an optional.
+test "*[N]T to ?[*]T" {
+    var buf: [5]u8 = "hello".*;
+    const x: ?[*]u8 = &buf;
+    try expect(x.?[4] == 'o');
+}
+
+// Single-item pointers can be cast to len-1 single-item arrays.
+test "*T to *[1]T" {
+    var x: i32 = 1234;
+    const y: *[1]i32 = &x;
+    const z: [*]i32 = y;
+    try expect(z[0] == 1234);
+}
Shell
$ zig test test_coerce_slices_arrays_and_pointers.zig
+1/7 test_coerce_slices_arrays_and_pointers.test.*const [N]T to []const T...OK
+2/7 test_coerce_slices_arrays_and_pointers.test.*const [N]T to E![]const T...OK
+3/7 test_coerce_slices_arrays_and_pointers.test.*const [N]T to ?[]const T...OK
+4/7 test_coerce_slices_arrays_and_pointers.test.*[N]T to []T...OK
+5/7 test_coerce_slices_arrays_and_pointers.test.*[N]T to [*]T...OK
+6/7 test_coerce_slices_arrays_and_pointers.test.*[N]T to ?[*]T...OK
+7/7 test_coerce_slices_arrays_and_pointers.test.*T to *[1]T...OK
+All 7 tests passed.
+
+ +

See also:

+ + +

Type Coercion: Optionals §

+ +

+ The payload type of Optionals, as well as null, coerce to the optional type. +

+
test_coerce_optionals.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "coerce to optionals" {
+    const x: ?i32 = 1234;
+    const y: ?i32 = null;
+
+    try expect(x.? == 1234);
+    try expect(y == null);
+}
Shell
$ zig test test_coerce_optionals.zig
+1/1 test_coerce_optionals.test.coerce to optionals...OK
+All 1 tests passed.
+
+ +

Optionals work nested inside the Error Union Type, too:

+
test_coerce_optional_wrapped_error_union.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "coerce to optionals wrapped in error union" {
+    const x: anyerror!?i32 = 1234;
+    const y: anyerror!?i32 = null;
+
+    try expect((try x).? == 1234);
+    try expect((try y) == null);
+}
Shell
$ zig test test_coerce_optional_wrapped_error_union.zig
+1/1 test_coerce_optional_wrapped_error_union.test.coerce to optionals wrapped in error union...OK
+All 1 tests passed.
+
+ + +

Type Coercion: Error Unions §

+ +

The payload type of an Error Union Type as well as the Error Set Type + coerce to the error union type: +

+
test_coerce_to_error_union.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "coercion to error unions" {
+    const x: anyerror!i32 = 1234;
+    const y: anyerror!i32 = error.Failure;
+
+    try expect((try x) == 1234);
+    try std.testing.expectError(error.Failure, y);
+}
Shell
$ zig test test_coerce_to_error_union.zig
+1/1 test_coerce_to_error_union.test.coercion to error unions...OK
+All 1 tests passed.
+
+ + +

Type Coercion: Compile-Time Known Numbers §

+ +

When a number is comptime-known to be representable in the destination type, + it may be coerced: +

+
test_coerce_large_to_small.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "coercing large integer type to smaller one when value is comptime-known to fit" {
+    const x: u64 = 255;
+    const y: u8 = x;
+    try expect(y == 255);
+}
Shell
$ zig test test_coerce_large_to_small.zig
+1/1 test_coerce_large_to_small.test.coercing large integer type to smaller one when value is comptime-known to fit...OK
+All 1 tests passed.
+
+ + +

Type Coercion: Unions and Enums §

+ +

Tagged unions can be coerced to enums, and enums can be coerced to tagged unions + when they are comptime-known to be a field of the union that has only one possible value, such as + void: +

+
test_coerce_unions_enums.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const E = enum {
+    one,
+    two,
+    three,
+};
+
+const U = union(E) {
+    one: i32,
+    two: f32,
+    three,
+};
+
+const U2 = union(enum) {
+    a: void,
+    b: f32,
+
+    fn tag(self: U2) usize {
+        switch (self) {
+            .a => return 1,
+            .b => return 2,
+        }
+    }
+};
+
+test "coercion between unions and enums" {
+    const u = U{ .two = 12.34 };
+    const e: E = u; // coerce union to enum
+    try expect(e == E.two);
+
+    const three = E.three;
+    const u_2: U = three; // coerce enum to union
+    try expect(u_2 == E.three);
+
+    const u_3: U = .three; // coerce enum literal to union
+    try expect(u_3 == E.three);
+
+    const u_4: U2 = .a; // coerce enum literal to union with inferred enum tag type.
+    try expect(u_4.tag() == 1);
+
+    // The following example is invalid.
+    // error: coercion from enum '@TypeOf(.enum_literal)' to union 'test_coerce_unions_enum.U2' must initialize 'f32' field 'b'
+    //var u_5: U2 = .b;
+    //try expect(u_5.tag() == 2);
+}
Shell
$ zig test test_coerce_unions_enums.zig
+1/1 test_coerce_unions_enums.test.coercion between unions and enums...OK
+All 1 tests passed.
+
+ +

See also:

+ + +

Type Coercion: undefined §

+ +

undefined can be coerced to any type.

+ + +

Type Coercion: Tuples to Arrays §

+ +

Tuples can be coerced to arrays, if all of the fields have the same type.

+
test_coerce_tuples_arrays.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Tuple = struct { u8, u8 };
+test "coercion from homogeneous tuple to array" {
+    const tuple: Tuple = .{ 5, 6 };
+    const array: [2]u8 = tuple;
+    _ = array;
+}
Shell
$ zig test test_coerce_tuples_arrays.zig
+1/1 test_coerce_tuples_arrays.test.coercion from homogeneous tuple to array...OK
+All 1 tests passed.
+
+ + + + +

Explicit Casts §

+ +

+ Explicit casts are performed via Builtin Functions. + Some explicit casts are safe; some are not. + Some explicit casts perform language-level assertions; some do not. + Some explicit casts are no-ops at runtime; some are not. +

+
    +
  • @bitCast - change type but maintain bit representation
  • +
  • @alignCast - make a pointer have more alignment
  • +
  • @enumFromInt - obtain an enum value based on its integer tag value
  • +
  • @errorFromInt - obtain an error code based on its integer value
  • +
  • @errorCast - convert to a smaller error set
  • +
  • @floatCast - convert a larger float to a smaller float
  • +
  • @floatFromInt - convert an integer to a float value
  • +
  • @intCast - convert between integer types
  • +
  • @intFromBool - convert true to 1 and false to 0
  • +
  • @intFromEnum - obtain the integer tag value of an enum or tagged union
  • +
  • @intFromError - obtain the integer value of an error code
  • +
  • @intFromFloat - obtain the integer part of a float value
  • +
  • @intFromPtr - obtain the address of a pointer
  • +
  • @ptrFromInt - convert an address to a pointer
  • +
  • @ptrCast - convert between pointer types
  • +
  • @truncate - convert between integer types, chopping off bits
  • +
+ + +

Peer Type Resolution §

+ +

Peer Type Resolution occurs in these places:

+ +

+ This kind of type resolution chooses a type that all peer types can coerce into. Here are + some examples: +

+
test_peer_type_resolution.zig
const std = @import("std");
+const expect = std.testing.expect;
+const mem = std.mem;
+
+test "peer resolve int widening" {
+    const a: i8 = 12;
+    const b: i16 = 34;
+    const c = a + b;
+    try expect(c == 46);
+    try expect(@TypeOf(c) == i16);
+}
+
+test "peer resolve arrays of different size to const slice" {
+    try expect(mem.eql(u8, boolToStr(true), "true"));
+    try expect(mem.eql(u8, boolToStr(false), "false"));
+    try comptime expect(mem.eql(u8, boolToStr(true), "true"));
+    try comptime expect(mem.eql(u8, boolToStr(false), "false"));
+}
+fn boolToStr(b: bool) []const u8 {
+    return if (b) "true" else "false";
+}
+
+test "peer resolve array and const slice" {
+    try testPeerResolveArrayConstSlice(true);
+    try comptime testPeerResolveArrayConstSlice(true);
+}
+fn testPeerResolveArrayConstSlice(b: bool) !void {
+    const value1 = if (b) "aoeu" else @as([]const u8, "zz");
+    const value2 = if (b) @as([]const u8, "zz") else "aoeu";
+    try expect(mem.eql(u8, value1, "aoeu"));
+    try expect(mem.eql(u8, value2, "zz"));
+}
+
+test "peer type resolution: ?T and T" {
+    try expect(peerTypeTAndOptionalT(true, false).? == 0);
+    try expect(peerTypeTAndOptionalT(false, false).? == 3);
+    comptime {
+        try expect(peerTypeTAndOptionalT(true, false).? == 0);
+        try expect(peerTypeTAndOptionalT(false, false).? == 3);
+    }
+}
+fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
+    if (c) {
+        return if (b) null else @as(usize, 0);
+    }
+
+    return @as(usize, 3);
+}
+
+test "peer type resolution: *[0]u8 and []const u8" {
+    try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+    try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+    comptime {
+        try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+        try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+    }
+}
+fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
+    if (a) {
+        return &[_]u8{};
+    }
+
+    return slice[0..1];
+}
+test "peer type resolution: *[0]u8, []const u8, and anyerror![]u8" {
+    {
+        var data = "hi".*;
+        const slice = data[0..];
+        try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
+        try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
+    }
+    comptime {
+        var data = "hi".*;
+        const slice = data[0..];
+        try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
+        try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
+    }
+}
+fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
+    if (a) {
+        return &[_]u8{};
+    }
+
+    return slice[0..1];
+}
+
+test "peer type resolution: *const T and ?*T" {
+    const a: *const usize = @ptrFromInt(0x123456780);
+    const b: ?*usize = @ptrFromInt(0x123456780);
+    try expect(a == b);
+    try expect(b == a);
+}
+
+test "peer type resolution: error union switch" {
+    // The non-error and error cases are only peers if the error case is just a switch expression;
+    // the pattern `if (x) {...} else |err| blk: { switch (err) {...} }` does not consider the
+    // non-error and error case to be peers.
+    var a: error{ A, B, C }!u32 = 0;
+    _ = &a;
+    const b = if (a) |x|
+        x + 3
+    else |err| switch (err) {
+        error.A => 0,
+        error.B => 1,
+        error.C => null,
+    };
+    try expect(@TypeOf(b) == ?u32);
+
+    // The non-error and error cases are only peers if the error case is just a switch expression;
+    // the pattern `x catch |err| blk: { switch (err) {...} }` does not consider the unwrapped `x`
+    // and error case to be peers.
+    const c = a catch |err| switch (err) {
+        error.A => 0,
+        error.B => 1,
+        error.C => null,
+    };
+    try expect(@TypeOf(c) == ?u32);
+}
Shell
$ zig test test_peer_type_resolution.zig
+1/8 test_peer_type_resolution.test.peer resolve int widening...OK
+2/8 test_peer_type_resolution.test.peer resolve arrays of different size to const slice...OK
+3/8 test_peer_type_resolution.test.peer resolve array and const slice...OK
+4/8 test_peer_type_resolution.test.peer type resolution: ?T and T...OK
+5/8 test_peer_type_resolution.test.peer type resolution: *[0]u8 and []const u8...OK
+6/8 test_peer_type_resolution.test.peer type resolution: *[0]u8, []const u8, and anyerror![]u8...OK
+7/8 test_peer_type_resolution.test.peer type resolution: *const T and ?*T...OK
+8/8 test_peer_type_resolution.test.peer type resolution: error union switch...OK
+All 8 tests passed.
+
+ + + + +

Zero Bit Types §

+ +

For some types, @sizeOf is 0:

+
    +
  • void
  • +
  • The Integers u0 and i0.
  • +
  • Arrays and Vectors with len 0, or with an element type that is a zero bit type.
  • +
  • An enum with only 1 tag.
  • +
  • A struct with all fields being zero bit types.
  • +
  • A union with only 1 field which is a zero bit type.
  • +
+

+ These types can only ever have one possible value, and thus + require 0 bits to represent. Code that makes use of these types is + not included in the final generated code: +

+
zero_bit_types.zig
export fn entry() void {
+    var x: void = {};
+    var y: void = {};
+    x = y;
+    y = x;
+}
+ +

When this turns into machine code, there is no code generated in the + body of entry, even in Debug mode. For example, on x86_64:

+
0000000000000010 <entry>:
+  10:	55                   	push   %rbp
+  11:	48 89 e5             	mov    %rsp,%rbp
+  14:	5d                   	pop    %rbp
+  15:	c3                   	retq   
+

These assembly instructions do not have any code associated with the void values - + they only perform the function call prologue and epilogue.

+ +

void §

+ +

+ void can be useful for instantiating generic types. For example, given a + Map(Key, Value), one can pass void for the Value + type to make it into a Set: +

+
test_void_in_hashmap.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "turn HashMap into a set with void" {
+    var map = std.AutoHashMap(i32, void).init(std.testing.allocator);
+    defer map.deinit();
+
+    try map.put(1, {});
+    try map.put(2, {});
+
+    try expect(map.contains(2));
+    try expect(!map.contains(3));
+
+    _ = map.remove(2);
+    try expect(!map.contains(2));
+}
Shell
$ zig test test_void_in_hashmap.zig
+1/1 test_void_in_hashmap.test.turn HashMap into a set with void...OK
+All 1 tests passed.
+
+ +

Note that this is different from using a dummy value for the hash map value. + By using void as the type of the value, the hash map entry type has no value field, and + thus the hash map takes up less space. Further, all the code that deals with storing and loading the + value is deleted, as seen above. +

+

+ void is distinct from anyopaque. + void has a known size of 0 bytes, and anyopaque has an unknown, but non-zero, size. +

+

+ Expressions of type void are the only ones whose value can be ignored. For example, ignoring + a non-void expression is a compile error: +

+
test_expression_ignored.zig
test "ignoring expression value" {
+    foo();
+}
+
+fn foo() i32 {
+    return 1234;
+}
Shell
$ zig test test_expression_ignored.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_expression_ignored.zig:2:8: error: value of type 'i32' ignored
+    foo();
+    ~~~^~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_expression_ignored.zig:2:8: note: all non-void values must be used
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_expression_ignored.zig:2:8: note: to discard the value, assign it to '_'
+
+
+ +

However, if the expression has type void, there will be no error. Expression results can be explicitly ignored by assigning them to _.

+
test_void_ignored.zig
test "void is ignored" {
+    returnsVoid();
+}
+
+test "explicitly ignoring expression value" {
+    _ = foo();
+}
+
+fn returnsVoid() void {}
+
+fn foo() i32 {
+    return 1234;
+}
Shell
$ zig test test_void_ignored.zig
+1/2 test_void_ignored.test.void is ignored...OK
+2/2 test_void_ignored.test.explicitly ignoring expression value...OK
+All 2 tests passed.
+
+ + + + +

Result Location Semantics §

+ +

+ During compilation, every Zig expression and sub-expression is assigned optional result location + information. This information dictates what type the expression should have (its result type), and + where the resulting value should be placed in memory (its result location). The information is + optional in the sense that not every expression has this information: assignment to + _, for instance, does not provide any information about the type of an + expression, nor does it provide a concrete memory location to place it in. +

+

+ As a motivating example, consider the statement const x: u32 = 42;. The type + annotation here provides a result type of u32 to the initialization expression + 42, instructing the compiler to coerce this integer (initially of type + comptime_int) to this type. We will see more examples shortly. +

+

+ This is not an implementation detail: the logic outlined above is codified into the Zig language + specification, and is the primary mechanism of type inference in the language. This system is + collectively referred to as "Result Location Semantics". +

+

Result Types §

+ +

+ Result types are propagated recursively through expressions where possible. For instance, if the + expression &e has result type *u32, then + e is given a result type of u32, allowing the + language to perform this coercion before taking a reference. +

+

+ The result type mechanism is utilized by casting builtins such as @intCast. + Rather than taking as an argument the type to cast to, these builtins use their result type to + determine this information. The result type is often known from context; where it is not, the + @as builtin can be used to explicitly provide a result type. +

+

+ We can break down the result types for each component of a simple expression as follows: +

+
result_type_propagation.zig
const expectEqual = @import("std").testing.expectEqual;
+test "result type propagates through struct initializer" {
+    const S = struct { x: u32 };
+    const val: u64 = 123;
+    const s: S = .{ .x = @intCast(val) };
+    // .{ .x = @intCast(val) }   has result type `S` due to the type annotation
+    //         @intCast(val)     has result type `u32` due to the type of the field `S.x`
+    //                  val      has no result type, as it is permitted to be any integer type
+    try expectEqual(@as(u32, 123), s.x);
+}
Shell
$ zig test result_type_propagation.zig
+1/1 result_type_propagation.test.result type propagates through struct initializer...OK
+All 1 tests passed.
+
+ +

+ This result type information is useful for the aforementioned cast builtins, as well as to avoid + the construction of pre-coercion values, and to avoid the need for explicit type coercions in some + cases. The following table details how some common expressions propagate result types, where + x and y are arbitrary sub-expressions. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExpressionParent Result TypeSub-expression Result Type
const val: T = x-x is a T
var val: T = x-x is a T
val = x-x is a @TypeOf(val)
@as(T, x)-x is a T
&x*Tx is a T
&x[]Tx is some array of T
f(x)-x has the type of the first parameter of f
.{x}Tx is a @FieldType(T, "0")
.{ .a = x }Tx is a @FieldType(T, "a")
T{x}-x is a @FieldType(T, "0")
T{ .a = x }-x is a @FieldType(T, "a")
@Type(x)-x is a std.builtin.Type
@typeInfo(x)-x is a type
x << y-y is a std.math.Log2IntCeil(@TypeOf(x))
+
+ +

Result Locations §

+ +

+ In addition to result type information, every expression may be optionally assigned a result + location: a pointer to which the value must be directly written. This system can be used to prevent + intermediate copies when initializing data structures, which can be important for types which must + have a fixed memory address ("pinned" types). +

+

+ When compiling the simple assignment expression x = e, many languages would + create the temporary value e on the stack, and then assign it to + x, potentially performing a type coercion in the process. Zig approaches this + differently. The expression e is given a result type matching the type of + x, and a result location of &x. For many syntactic + forms of e, this has no practical impact. However, it can have important + semantic effects when working with more complex syntax forms. +

+

+ For instance, if the expression .{ .a = x, .b = y } has a result location of + ptr, then x is given a result location of + &ptr.a, and y a result location of &ptr.b. + Without this system, this expression would construct a temporary struct value entirely on the stack, and + only then copy it to the destination address. In essence, Zig desugars the assignment + foo = .{ .a = x, .b = y } to the two statements foo.a = x; foo.b = y;. +

+

+ This can sometimes be important when assigning an aggregate value where the initialization + expression depends on the previous value of the aggregate. The easiest way to demonstrate this is by + attempting to swap fields of a struct or array - the following logic looks sound, but in fact is not: +

+
result_location_interfering_with_swap.zig
const expect = @import("std").testing.expect;
+test "attempt to swap array elements with array initializer" {
+    var arr: [2]u32 = .{ 1, 2 };
+    arr = .{ arr[1], arr[0] };
+    // The previous line is equivalent to the following two lines:
+    //   arr[0] = arr[1];
+    //   arr[1] = arr[0];
+    // So this fails!
+    try expect(arr[0] == 2); // succeeds
+    try expect(arr[1] == 1); // fails
+}
Shell
$ zig test result_location_interfering_with_swap.zig
+1/1 result_location_interfering_with_swap.test.attempt to swap array elements with array initializer...FAIL (TestUnexpectedResult)
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/testing.zig:580:14: 0x104861f in expect (test)
+    if (!ok) return error.TestUnexpectedResult;
+             ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/result_location_interfering_with_swap.zig:10:5: 0x1048705 in test.attempt to swap array elements with array initializer (test)
+    try expect(arr[1] == 1); // fails
+    ^
+0 passed; 0 skipped; 1 failed.
+error: the following test command failed with exit code 1:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/5cf73dcca47fe5ad7ad8e07722996213/test --seed=0x914c57cf
+
+ +

+ The following table details how some common expressions propagate result locations, where + x and y are arbitrary sub-expressions. Note that + some expressions cannot provide meaningful result locations to sub-expressions, even if they + themselves have a result location. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExpressionResult LocationSub-expression Result Locations
const val: T = x-x has result location &val
var val: T = x-x has result location &val
val = x-x has result location &val
@as(T, x)ptrx has no result location
&xptrx has no result location
f(x)ptrx has no result location
.{x}ptrx has result location &ptr[0]
.{ .a = x }ptrx has result location &ptr.a
T{x}ptrx has no result location (typed initializers do not propagate result locations)
T{ .a = x }ptrx has no result location (typed initializers do not propagate result locations)
@Type(x)ptrx has no result location
@typeInfo(x)ptrx has no result location
x << yptrx and y do not have result locations
+
+ + + +

usingnamespace §

+ +

+ usingnamespace is a declaration that mixes all the public + declarations of the operand, which must be a struct, union, enum, + or opaque, into the namespace: +

+
test_usingnamespace.zig
test "using std namespace" {
+    const S = struct {
+        usingnamespace @import("std");
+    };
+    try S.testing.expect(true);
+}
Shell
$ zig test test_usingnamespace.zig
+1/1 test_usingnamespace.test.using std namespace...OK
+All 1 tests passed.
+
+ +

+ usingnamespace has an important use case when organizing the public + API of a file or package. For example, one might have c.zig with all of the + C imports: +

+
c.zig
pub usingnamespace @cImport({
+    @cInclude("epoxy/gl.h");
+    @cInclude("GLFW/glfw3.h");
+    @cDefine("STBI_ONLY_PNG", "");
+    @cDefine("STBI_NO_STDIO", "");
+    @cInclude("stb_image.h");
+});
+

+ The above example demonstrates using pub to qualify the + usingnamespace additionally makes the imported declarations + pub. This can be used to forward declarations, giving precise control + over what declarations a given file exposes. +

+ + + +

comptime §

+ +

+ Zig places importance on the concept of whether an expression is known at compile-time. + There are a few different places this concept is used, and these building blocks are used + to keep the language small, readable, and powerful. +

+

Introducing the Compile-Time Concept §

+ +

Compile-Time Parameters §

+ +

+ Compile-time parameters is how Zig implements generics. It is compile-time duck typing. +

+
compile-time_duck_typing.zig
fn max(comptime T: type, a: T, b: T) T {
+    return if (a > b) a else b;
+}
+fn gimmeTheBiggerFloat(a: f32, b: f32) f32 {
+    return max(f32, a, b);
+}
+fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
+    return max(u64, a, b);
+}
+ +

+ In Zig, types are first-class citizens. They can be assigned to variables, passed as parameters to functions, + and returned from functions. However, they can only be used in expressions which are known at compile-time, + which is why the parameter T in the above snippet must be marked with comptime. +

+

+ A comptime parameter means that: +

+
    +
  • At the callsite, the value must be known at compile-time, or it is a compile error.
  • +
  • In the function definition, the value is known at compile-time.
  • +
+

+ For example, if we were to introduce another function to the above snippet: +

+
test_unresolved_comptime_value.zig
fn max(comptime T: type, a: T, b: T) T {
+    return if (a > b) a else b;
+}
+test "try to pass a runtime type" {
+    foo(false);
+}
+fn foo(condition: bool) void {
+    const result = max(if (condition) f32 else u64, 1234, 5678);
+    _ = result;
+}
Shell
$ zig test test_unresolved_comptime_value.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_unresolved_comptime_value.zig:8:28: error: unable to resolve comptime value
+    const result = max(if (condition) f32 else u64, 1234, 5678);
+                           ^~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_unresolved_comptime_value.zig:8:24: note: argument to comptime parameter must be comptime-known
+    const result = max(if (condition) f32 else u64, 1234, 5678);
+                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_unresolved_comptime_value.zig:1:8: note: parameter declared comptime here
+fn max(comptime T: type, a: T, b: T) T {
+       ^~~~~~~~
+referenced by:
+    test.try to pass a runtime type: /home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_unresolved_comptime_value.zig:5:8
+
+
+ +

+ This is an error because the programmer attempted to pass a value only known at run-time + to a function which expects a value known at compile-time. +

+

+ Another way to get an error is if we pass a type that violates the type checker when the + function is analyzed. This is what it means to have compile-time duck typing. +

+

+ For example: +

+
test_comptime_mismatched_type.zig
fn max(comptime T: type, a: T, b: T) T {
+    return if (a > b) a else b;
+}
+test "try to compare bools" {
+    _ = max(bool, true, false);
+}
Shell
$ zig test test_comptime_mismatched_type.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_mismatched_type.zig:2:18: error: operator > not allowed for type 'bool'
+    return if (a > b) a else b;
+               ~~^~~
+referenced by:
+    test.try to compare bools: /home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_mismatched_type.zig:5:12
+
+
+ +

+ On the flip side, inside the function definition with the comptime parameter, the + value is known at compile-time. This means that we actually could make this work for the bool type + if we wanted to: +

+
test_comptime_max_with_bool.zig
fn max(comptime T: type, a: T, b: T) T {
+    if (T == bool) {
+        return a or b;
+    } else if (a > b) {
+        return a;
+    } else {
+        return b;
+    }
+}
+test "try to compare bools" {
+    try @import("std").testing.expect(max(bool, false, true) == true);
+}
Shell
$ zig test test_comptime_max_with_bool.zig
+1/1 test_comptime_max_with_bool.test.try to compare bools...OK
+All 1 tests passed.
+
+ +

+ This works because Zig implicitly inlines if expressions when the condition + is known at compile-time, and the compiler guarantees that it will skip analysis of + the branch not taken. +

+

+ This means that the actual function generated for max in this situation looks like + this: +

+
compiler_generated_function.zig
fn max(a: bool, b: bool) bool {
+    {
+        return a or b;
+    }
+}
+ +

+ All the code that dealt with compile-time known values is eliminated and we are left with only + the necessary run-time code to accomplish the task. +

+

+ This works the same way for switch expressions - they are implicitly inlined + when the target expression is compile-time known. +

+ +

Compile-Time Variables §

+ +

+ In Zig, the programmer can label variables as comptime. This guarantees to the compiler + that every load and store of the variable is performed at compile-time. Any violation of this results in a + compile error. +

+

+ This combined with the fact that we can inline loops allows us to write + a function which is partially evaluated at compile-time and partially at run-time. +

+

+ For example: +

+
test_comptime_evaluation.zig
const expect = @import("std").testing.expect;
+
+const CmdFn = struct {
+    name: []const u8,
+    func: fn (i32) i32,
+};
+
+const cmd_fns = [_]CmdFn{
+    CmdFn{ .name = "one", .func = one },
+    CmdFn{ .name = "two", .func = two },
+    CmdFn{ .name = "three", .func = three },
+};
+fn one(value: i32) i32 {
+    return value + 1;
+}
+fn two(value: i32) i32 {
+    return value + 2;
+}
+fn three(value: i32) i32 {
+    return value + 3;
+}
+
+fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
+    var result: i32 = start_value;
+    comptime var i = 0;
+    inline while (i < cmd_fns.len) : (i += 1) {
+        if (cmd_fns[i].name[0] == prefix_char) {
+            result = cmd_fns[i].func(result);
+        }
+    }
+    return result;
+}
+
+test "perform fn" {
+    try expect(performFn('t', 1) == 6);
+    try expect(performFn('o', 0) == 1);
+    try expect(performFn('w', 99) == 99);
+}
Shell
$ zig test test_comptime_evaluation.zig
+1/1 test_comptime_evaluation.test.perform fn...OK
+All 1 tests passed.
+
+ +

+ This example is a bit contrived, because the compile-time evaluation component is unnecessary; + this code would work fine if it was all done at run-time. But it does end up generating + different code. In this example, the function performFn is generated three different times, + for the different values of prefix_char provided: +

+
performFn_1
// From the line:
+// expect(performFn('t', 1) == 6);
+fn performFn(start_value: i32) i32 {
+    var result: i32 = start_value;
+    result = two(result);
+    result = three(result);
+    return result;
+}
+
performFn_2
// From the line:
+// expect(performFn('o', 0) == 1);
+fn performFn(start_value: i32) i32 {
+    var result: i32 = start_value;
+    result = one(result);
+    return result;
+}
+
performFn_3
// From the line:
+// expect(performFn('w', 99) == 99);
+fn performFn(start_value: i32) i32 {
+    var result: i32 = start_value;
+    _ = &result;
+    return result;
+}
+

+ Note that this happens even in a debug build. + This is not a way to write more optimized code, but it is a way to make sure that what should happen + at compile-time, does happen at compile-time. This catches more errors and allows expressiveness + that in other languages requires using macros, generated code, or a preprocessor to accomplish. +

+ +

Compile-Time Expressions §

+ +

+ In Zig, it matters whether a given expression is known at compile-time or run-time. A programmer can + use a comptime expression to guarantee that the expression will be evaluated at compile-time. + If this cannot be accomplished, the compiler will emit an error. For example: +

+
test_comptime_call_extern_function.zig
extern fn exit() noreturn;
+
+test "foo" {
+    comptime {
+        exit();
+    }
+}
Shell
$ zig test test_comptime_call_extern_function.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_call_extern_function.zig:5:13: error: comptime call of extern function
+        exit();
+        ~~~~^~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_call_extern_function.zig:4:5: note: 'comptime' keyword forces comptime evaluation
+    comptime {
+    ^~~~~~~~
+
+
+ +

+ It doesn't make sense that a program could call exit() (or any other external function) + at compile-time, so this is a compile error. However, a comptime expression does much + more than sometimes cause a compile error. +

+

+ Within a comptime expression: +

+
    +
  • All variables are comptime variables.
  • +
  • All if, while, for, and switch + expressions are evaluated at compile-time, or emit a compile error if this is not possible.
  • +
  • All return and try expressions are invalid (unless the function itself is called at compile-time).
  • +
  • All code with runtime side effects or depending on runtime values emits a compile error.
  • +
  • All function calls cause the compiler to interpret the function at compile-time, emitting a + compile error if the function tries to do something that has global runtime side effects.
  • +
+

+ This means that a programmer can create a function which is called both at compile-time and run-time, with + no modification to the function required. +

+

+ Let's look at an example: +

+
test_fibonacci_recursion.zig
const expect = @import("std").testing.expect;
+
+fn fibonacci(index: u32) u32 {
+    if (index < 2) return index;
+    return fibonacci(index - 1) + fibonacci(index - 2);
+}
+
+test "fibonacci" {
+    // test fibonacci at run-time
+    try expect(fibonacci(7) == 13);
+
+    // test fibonacci at compile-time
+    try comptime expect(fibonacci(7) == 13);
+}
Shell
$ zig test test_fibonacci_recursion.zig
+1/1 test_fibonacci_recursion.test.fibonacci...OK
+All 1 tests passed.
+
+ +

+ Imagine if we had forgotten the base case of the recursive function and tried to run the tests: +

+
test_fibonacci_comptime_overflow.zig
const expect = @import("std").testing.expect;
+
+fn fibonacci(index: u32) u32 {
+    //if (index < 2) return index;
+    return fibonacci(index - 1) + fibonacci(index - 2);
+}
+
+test "fibonacci" {
+    try comptime expect(fibonacci(7) == 13);
+}
Shell
$ zig test test_fibonacci_comptime_overflow.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_fibonacci_comptime_overflow.zig:5:28: error: overflow of integer type 'u32' with value '-1'
+    return fibonacci(index - 1) + fibonacci(index - 2);
+                     ~~~~~~^~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_fibonacci_comptime_overflow.zig:5:21: note: called from here (7 times)
+    return fibonacci(index - 1) + fibonacci(index - 2);
+           ~~~~~~~~~^~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_fibonacci_comptime_overflow.zig:9:34: note: called from here
+    try comptime expect(fibonacci(7) == 13);
+                        ~~~~~~~~~^~~
+
+
+ +

+ The compiler produces an error which is a stack trace from trying to evaluate the + function at compile-time. +

+

+ Luckily, we used an unsigned integer, and so when we tried to subtract 1 from 0, it triggered + Illegal Behavior, which is always a compile error if the compiler knows it happened. + But what would have happened if we used a signed integer? +

+
fibonacci_comptime_infinite_recursion.zig
const assert = @import("std").debug.assert;
+
+fn fibonacci(index: i32) i32 {
+    //if (index < 2) return index;
+    return fibonacci(index - 1) + fibonacci(index - 2);
+}
+
+test "fibonacci" {
+    try comptime assert(fibonacci(7) == 13);
+}
+ +

+ The compiler is supposed to notice that evaluating this function at + compile-time took more than 1000 branches, and thus emits an error and + gives up. If the programmer wants to increase the budget for compile-time + computation, they can use a built-in function called + @setEvalBranchQuota to change the default number 1000 to + something else. +

+

+ However, there is a design + flaw in the compiler causing it to stack overflow instead of having the proper + behavior here. I'm terribly sorry about that. I hope to get this resolved + before the next release. +

+

+ What if we fix the base case, but put the wrong value in the + expect line? +

+
test_fibonacci_comptime_unreachable.zig
const assert = @import("std").debug.assert;
+
+fn fibonacci(index: i32) i32 {
+    if (index < 2) return index;
+    return fibonacci(index - 1) + fibonacci(index - 2);
+}
+
+test "fibonacci" {
+    try comptime assert(fibonacci(7) == 99999);
+}
Shell
$ zig test test_fibonacci_comptime_unreachable.zig
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/debug.zig:550:14: error: reached unreachable code
+    if (!ok) unreachable; // assertion failure
+             ^~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_fibonacci_comptime_unreachable.zig:9:24: note: called from here
+    try comptime assert(fibonacci(7) == 99999);
+                 ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
+
+
+ + +

+ At container level (outside of any function), all expressions are implicitly + comptime expressions. This means that we can use functions to + initialize complex static data. For example: +

+
test_container-level_comptime_expressions.zig
const first_25_primes = firstNPrimes(25);
+const sum_of_first_25_primes = sum(&first_25_primes);
+
+fn firstNPrimes(comptime n: usize) [n]i32 {
+    var prime_list: [n]i32 = undefined;
+    var next_index: usize = 0;
+    var test_number: i32 = 2;
+    while (next_index < prime_list.len) : (test_number += 1) {
+        var test_prime_index: usize = 0;
+        var is_prime = true;
+        while (test_prime_index < next_index) : (test_prime_index += 1) {
+            if (test_number % prime_list[test_prime_index] == 0) {
+                is_prime = false;
+                break;
+            }
+        }
+        if (is_prime) {
+            prime_list[next_index] = test_number;
+            next_index += 1;
+        }
+    }
+    return prime_list;
+}
+
+fn sum(numbers: []const i32) i32 {
+    var result: i32 = 0;
+    for (numbers) |x| {
+        result += x;
+    }
+    return result;
+}
+
+test "variable values" {
+    try @import("std").testing.expect(sum_of_first_25_primes == 1060);
+}
Shell
$ zig test test_container-level_comptime_expressions.zig
+1/1 test_container-level_comptime_expressions.test.variable values...OK
+All 1 tests passed.
+
+ +

+ When we compile this program, Zig generates the constants + with the answer pre-computed. Here are the lines from the generated LLVM IR: +

+
@0 = internal unnamed_addr constant [25 x i32] [i32 2, i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53, i32 59, i32 61, i32 67, i32 71, i32 73, i32 79, i32 83, i32 89, i32 97]
+@1 = internal unnamed_addr constant i32 1060
+

+ Note that we did not have to do anything special with the syntax of these functions. For example, + we could call the sum function as is with a slice of numbers whose length and values were + only known at run-time. +

+ + +

Generic Data Structures §

+ +

+ Zig uses comptime capabilities to implement generic data structures without introducing any + special-case syntax. +

+

+ Here is an example of a generic List data structure. +

+
generic_data_structure.zig
fn List(comptime T: type) type {
+    return struct {
+        items: []T,
+        len: usize,
+    };
+}
+
+// The generic List data structure can be instantiated by passing in a type:
+var buffer: [10]i32 = undefined;
+var list = List(i32){
+    .items = &buffer,
+    .len = 0,
+};
+ +

+ That's it. It's a function that returns an anonymous struct. + For the purposes of error messages and debugging, Zig infers the name + "List(i32)" from the function name and parameters invoked when creating + the anonymous struct. +

+

+ To explicitly give a type a name, we assign it to a constant. +

+
anonymous_struct_name.zig
const Node = struct {
+    next: ?*Node,
+    name: []const u8,
+};
+
+var node_a = Node{
+    .next = null,
+    .name = "Node A",
+};
+
+var node_b = Node{
+    .next = &node_a,
+    .name = "Node B",
+};
+ +

+ In this example, the Node struct refers to itself. + This works because all top level declarations are order-independent. + As long as the compiler can determine the size of the struct, it is free to refer to itself. + In this case, Node refers to itself as a pointer, which has a + well-defined size at compile time, so it works fine. +

+ +

Case Study: print in Zig §

+ +

+ Putting all of this together, let's see how print works in Zig. +

+
print.zig
const print = @import("std").debug.print;
+
+const a_number: i32 = 1234;
+const a_string = "foobar";
+
+pub fn main() void {
+    print("here is a string: '{s}' here is a number: {}\n", .{ a_string, a_number });
+}
Shell
$ zig build-exe print.zig
+$ ./print
+here is a string: 'foobar' here is a number: 1234
+
+ + +

+ Let's crack open the implementation of this and see how it works: +

+ +
poc_print_fn.zig
const Writer = struct {
+    /// Calls print and then flushes the buffer.
+    pub fn print(self: *Writer, comptime format: []const u8, args: anytype) anyerror!void {
+        const State = enum {
+            start,
+            open_brace,
+            close_brace,
+        };
+
+        comptime var start_index: usize = 0;
+        comptime var state = State.start;
+        comptime var next_arg: usize = 0;
+
+        inline for (format, 0..) |c, i| {
+            switch (state) {
+                State.start => switch (c) {
+                    '{' => {
+                        if (start_index < i) try self.write(format[start_index..i]);
+                        state = State.open_brace;
+                    },
+                    '}' => {
+                        if (start_index < i) try self.write(format[start_index..i]);
+                        state = State.close_brace;
+                    },
+                    else => {},
+                },
+                State.open_brace => switch (c) {
+                    '{' => {
+                        state = State.start;
+                        start_index = i;
+                    },
+                    '}' => {
+                        try self.printValue(args[next_arg]);
+                        next_arg += 1;
+                        state = State.start;
+                        start_index = i + 1;
+                    },
+                    's' => {
+                        continue;
+                    },
+                    else => @compileError("Unknown format character: " ++ [1]u8{c}),
+                },
+                State.close_brace => switch (c) {
+                    '}' => {
+                        state = State.start;
+                        start_index = i;
+                    },
+                    else => @compileError("Single '}' encountered in format string"),
+                },
+            }
+        }
+        comptime {
+            if (args.len != next_arg) {
+                @compileError("Unused arguments");
+            }
+            if (state != State.start) {
+                @compileError("Incomplete format string: " ++ format);
+            }
+        }
+        if (start_index < format.len) {
+            try self.write(format[start_index..format.len]);
+        }
+        try self.flush();
+    }
+
+    fn write(self: *Writer, value: []const u8) !void {
+        _ = self;
+        _ = value;
+    }
+    pub fn printValue(self: *Writer, value: anytype) !void {
+        _ = self;
+        _ = value;
+    }
+    fn flush(self: *Writer) !void {
+        _ = self;
+    }
+};
+ +

+ This is a proof of concept implementation; the actual function in the standard library has more + formatting capabilities. +

+

+ Note that this is not hard-coded into the Zig compiler; this is userland code in the standard library. +

+

+ When this function is analyzed from our example code above, Zig partially evaluates the function + and emits a function that actually looks like this: +

+
Emitted print Function
pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {
+    try self.write("here is a string: '");
+    try self.printValue(arg0);
+    try self.write("' here is a number: ");
+    try self.printValue(arg1);
+    try self.write("\n");
+    try self.flush();
+}
+

+ printValue is a function that takes a parameter of any type, and does different things depending + on the type: +

+
poc_printValue_fn.zig
const Writer = struct {
+    pub fn printValue(self: *Writer, value: anytype) !void {
+        switch (@typeInfo(@TypeOf(value))) {
+            .int => {
+                return self.writeInt(value);
+            },
+            .float => {
+                return self.writeFloat(value);
+            },
+            .pointer => {
+                return self.write(value);
+            },
+            else => {
+                @compileError("Unable to print type '" ++ @typeName(@TypeOf(value)) ++ "'");
+            },
+        }
+    }
+
+    fn write(self: *Writer, value: []const u8) !void {
+        _ = self;
+        _ = value;
+    }
+    fn writeInt(self: *Writer, value: anytype) !void {
+        _ = self;
+        _ = value;
+    }
+    fn writeFloat(self: *Writer, value: anytype) !void {
+        _ = self;
+        _ = value;
+    }
+};
+ +

+ And now, what happens if we give too many arguments to print? +

+
test_print_too_many_args.zig
const print = @import("std").debug.print;
+
+const a_number: i32 = 1234;
+const a_string = "foobar";
+
+test "print too many arguments" {
+    print("here is a string: '{s}' here is a number: {}\n", .{
+        a_string,
+        a_number,
+        a_number,
+    });
+}
Shell
$ zig test test_print_too_many_args.zig
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/fmt.zig:211:18: error: unused argument in 'here is a string: '{s}' here is a number: {}
+                                                                                        '
+            1 => @compileError("unused argument in '" ++ fmt ++ "'"),
+                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+referenced by:
+    print__anon_679: /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/io/Writer.zig:24:26
+    print__anon_420: /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/io.zig:312:47
+    1 reference(s) hidden; use '-freference-trace=3' to see all references
+
+
+ +

+ Zig gives programmers the tools needed to protect themselves against their own mistakes. +

+

+ Zig doesn't care whether the format argument is a string literal, + only that it is a compile-time known value that can be coerced to a []const u8: +

+
print_comptime-known_format.zig
const print = @import("std").debug.print;
+
+const a_number: i32 = 1234;
+const a_string = "foobar";
+const fmt = "here is a string: '{s}' here is a number: {}\n";
+
+pub fn main() void {
+    print(fmt, .{ a_string, a_number });
+}
Shell
$ zig build-exe print_comptime-known_format.zig
+$ ./print_comptime-known_format
+here is a string: 'foobar' here is a number: 1234
+
+ +

+ This works fine. +

+

+ Zig does not special case string formatting in the compiler and instead exposes enough power to accomplish this + task in userland. It does so without introducing another language on top of Zig, such as + a macro language or a preprocessor language. It's Zig all the way down. +

+ +

See also:

+ + +

Assembly §

+ +

+ For some use cases, it may be necessary to directly control the machine code generated + by Zig programs, rather than relying on Zig's code generation. For these cases, one + can use inline assembly. Here is an example of implementing Hello, World on x86_64 Linux + using inline assembly: +

+
inline_assembly.zig
pub fn main() noreturn {
+    const msg = "hello world\n";
+    _ = syscall3(SYS_write, STDOUT_FILENO, @intFromPtr(msg), msg.len);
+    _ = syscall1(SYS_exit, 0);
+    unreachable;
+}
+
+pub const SYS_write = 1;
+pub const SYS_exit = 60;
+
+pub const STDOUT_FILENO = 1;
+
+pub fn syscall1(number: usize, arg1: usize) usize {
+    return asm volatile ("syscall"
+        : [ret] "={rax}" (-> usize),
+        : [number] "{rax}" (number),
+          [arg1] "{rdi}" (arg1),
+        : "rcx", "r11"
+    );
+}
+
+pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
+    return asm volatile ("syscall"
+        : [ret] "={rax}" (-> usize),
+        : [number] "{rax}" (number),
+          [arg1] "{rdi}" (arg1),
+          [arg2] "{rsi}" (arg2),
+          [arg3] "{rdx}" (arg3),
+        : "rcx", "r11"
+    );
+}
Shell
$ zig build-exe inline_assembly.zig -target x86_64-linux
+$ ./inline_assembly
+hello world
+
+ +

+ Dissecting the syntax: +

+
Assembly Syntax Explained.zig
pub fn syscall1(number: usize, arg1: usize) usize {
+    // Inline assembly is an expression which returns a value.
+    // the `asm` keyword begins the expression.
+    return asm
+    // `volatile` is an optional modifier that tells Zig this
+    // inline assembly expression has side-effects. Without
+    // `volatile`, Zig is allowed to delete the inline assembly
+    // code if the result is unused.
+    volatile (
+    // Next is a comptime string which is the assembly code.
+    // Inside this string one may use `%[ret]`, `%[number]`,
+    // or `%[arg1]` where a register is expected, to specify
+    // the register that Zig uses for the argument or return value,
+    // if the register constraint strings are used. However in
+    // the below code, this is not used. A literal `%` can be
+    // obtained by escaping it with a double percent: `%%`.
+    // Often multiline string syntax comes in handy here.
+        \\syscall
+        // Next is the output. It is possible in the future Zig will
+        // support multiple outputs, depending on how
+        // https://github.com/ziglang/zig/issues/215 is resolved.
+        // It is allowed for there to be no outputs, in which case
+        // this colon would be directly followed by the colon for the inputs.
+        :
+        // This specifies the name to be used in `%[ret]` syntax in
+        // the above assembly string. This example does not use it,
+        // but the syntax is mandatory.
+          [ret]
+          // Next is the output constraint string. This feature is still
+          // considered unstable in Zig, and so LLVM/GCC documentation
+          // must be used to understand the semantics.
+          // http://releases.llvm.org/10.0.0/docs/LangRef.html#inline-asm-constraint-string
+          // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
+          // In this example, the constraint string means "the result value of
+          // this inline assembly instruction is whatever is in $rax".
+          "={rax}"
+          // Next is either a value binding, or `->` and then a type. The
+          // type is the result type of the inline assembly expression.
+          // If it is a value binding, then `%[ret]` syntax would be used
+          // to refer to the register bound to the value.
+          (-> usize),
+          // Next is the list of inputs.
+          // The constraint for these inputs means, "when the assembly code is
+          // executed, $rax shall have the value of `number` and $rdi shall have
+          // the value of `arg1`". Any number of input parameters is allowed,
+          // including none.
+        : [number] "{rax}" (number),
+          [arg1] "{rdi}" (arg1),
+          // Next is the list of clobbers. These declare a set of registers whose
+          // values will not be preserved by the execution of this assembly code.
+          // These do not include output or input registers. The special clobber
+          // value of "memory" means that the assembly writes to arbitrary undeclared
+          // memory locations - not only the memory pointed to by a declared indirect
+          // output. In this example we list $rcx and $r11 because it is known the
+          // kernel syscall does not preserve these registers.
+        : "rcx", "r11"
+    );
+}
+ +

+ For x86 and x86_64 targets, the syntax is AT&T syntax, rather than the more + popular Intel syntax. This is due to technical constraints; assembly parsing is + provided by LLVM and its support for Intel syntax is buggy and not well tested. +

+

+ Some day Zig may have its own assembler. This would allow it to integrate more seamlessly + into the language, as well as be compatible with the popular NASM syntax. This documentation + section will be updated before 1.0.0 is released, with a conclusive statement about the status + of AT&T vs Intel/NASM syntax. +

+

Output Constraints §

+ +

+ Output constraints are still considered to be unstable in Zig, and + so + LLVM documentation + and + GCC documentation + must be used to understand the semantics. +

+

+ Note that some breaking changes to output constraints are planned with + issue #215. +

+ + +

Input Constraints §

+ +

+ Input constraints are still considered to be unstable in Zig, and + so + LLVM documentation + and + GCC documentation + must be used to understand the semantics. +

+

+ Note that some breaking changes to input constraints are planned with + issue #215. +

+ + +

Clobbers §

+ +

+ Clobbers are the set of registers whose values will not be preserved by the execution of + the assembly code. These do not include output or input registers. The special clobber + value of "memory" means that the assembly causes writes to + arbitrary undeclared memory locations - not only the memory pointed to by a declared + indirect output. +

+

+ Failure to declare the full set of clobbers for a given inline assembly + expression is unchecked Illegal Behavior. +

+ + +

Global Assembly §

+ +

+ When an assembly expression occurs in a container level comptime block, this is + global assembly. +

+

+ This kind of assembly has different rules than inline assembly. First, volatile + is not valid because all global assembly is unconditionally included. + Second, there are no inputs, outputs, or clobbers. All global assembly is concatenated + verbatim into one long string and assembled together. There are no template substitution rules regarding + % as there are in inline assembly expressions. +

+
test_global_assembly.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+comptime {
+    asm (
+        \\.global my_func;
+        \\.type my_func, @function;
+        \\my_func:
+        \\  lea (%rdi,%rsi,1),%eax
+        \\  retq
+    );
+}
+
+extern fn my_func(a: i32, b: i32) i32;
+
+test "global assembly" {
+    try expect(my_func(12, 34) == 46);
+}
Shell
$ zig test test_global_assembly.zig -target x86_64-linux
+1/1 test_global_assembly.test.global assembly...OK
+All 1 tests passed.
+
+ + + + +

Atomics §

+ +

TODO: @atomic rmw

+

TODO: builtin atomic memory ordering enum

+ +

See also:

+ + + + +

Async Functions §

+ +

Async functions regressed with the release of 0.11.0. Their future in + the Zig language is unclear due to multiple unsolved problems:

+
    +
  • LLVM's lack of ability to optimize them.
  • +
  • Third-party debuggers' lack of ability to debug them.
  • +
  • The cancellation problem.
  • +
  • Async function pointers preventing the stack size from being known.
  • +
+

These problems are surmountable, but it will take time. The Zig team + is currently focused on other priorities.

+ + +

Builtin Functions §

+ +

+ Builtin functions are provided by the compiler and are prefixed with @. + The comptime keyword on a parameter means that the parameter must be known + at compile time. +

+

@addrSpaceCast §

+ +
@addrSpaceCast(ptr: anytype) anytype
+

+ Converts a pointer from one address space to another. The new address space is inferred + based on the result type. Depending on the current target and address spaces, this cast + may be a no-op, a complex operation, or illegal. If the cast is legal, then the resulting + pointer points to the same memory location as the pointer operand. It is always valid to + cast a pointer between the same address spaces. +

+ +

@addWithOverflow §

+ +
@addWithOverflow(a: anytype, b: anytype) struct { @TypeOf(a, b), u1 }
+

+ Performs a + b and returns a tuple with the result and a possible overflow bit. +

+ +

@alignCast §

+ +
@alignCast(ptr: anytype) anytype
+

+ ptr can be *T, ?*T, or []T. + Changes the alignment of a pointer. The alignment to use is inferred based on the result type. +

+

A pointer alignment safety check is added + to the generated code to make sure the pointer is aligned as promised.

+ + +

@alignOf §

+ +
@alignOf(comptime T: type) comptime_int
+

+ This function returns the number of bytes that this type should be aligned to + for the current target to match the C ABI. When the child type of a pointer has + this alignment, the alignment can be omitted from the type. +

+
const assert = @import("std").debug.assert;
+comptime {
+    assert(*u32 == *align(@alignOf(u32)) u32);
+}
+

+ The result is a target-specific compile time constant. It is guaranteed to be + less than or equal to @sizeOf(T). +

+

See also:

+ + + +

@as §

+ +
@as(comptime T: type, expression) T
+

+ Performs Type Coercion. This cast is allowed when the conversion is unambiguous and safe, + and is the preferred way to convert between types, whenever possible. +

+ + +

@atomicLoad §

+ +
@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: AtomicOrder) T
+

+ This builtin function atomically dereferences a pointer to a T and returns the value. +

+

+ T must be a pointer, a bool, a float, + an integer or an enum. +

+

AtomicOrder can be found with @import("std").builtin.AtomicOrder.

+

See also:

+ + + +

@atomicRmw §

+ +
@atomicRmw(comptime T: type, ptr: *T, comptime op: AtomicRmwOp, operand: T, comptime ordering: AtomicOrder) T
+

+ This builtin function dereferences a pointer to a T and atomically + modifies the value and returns the previous value. +

+

+ T must be a pointer, a bool, a float, + an integer or an enum. +

+

AtomicOrder can be found with @import("std").builtin.AtomicOrder.

+

AtomicRmwOp can be found with @import("std").builtin.AtomicRmwOp.

+

See also:

+ + + +

@atomicStore §

+ +
@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: AtomicOrder) void
+

+ This builtin function dereferences a pointer to a T and atomically stores the given value. +

+

+ T must be a pointer, a bool, a float, + an integer or an enum. +

+

AtomicOrder can be found with @import("std").builtin.AtomicOrder.

+

See also:

+ + + +

@bitCast §

+ +
@bitCast(value: anytype) anytype
+

+ Converts a value of one type to another type. The return type is the + inferred result type. +

+

+ Asserts that @sizeOf(@TypeOf(value)) == @sizeOf(DestType). +

+

+ Asserts that @typeInfo(DestType) != .pointer. Use @ptrCast or @ptrFromInt if you need this. +

+

+ Can be used for these things for example: +

+
    +
  • Convert f32 to u32 bits
  • +
  • Convert i32 to u32 preserving twos complement
  • +
+

+ Works at compile-time if value is known at compile time. It's a compile error to bitcast a value of undefined layout; this means that, besides the restriction from types which possess dedicated casting builtins (enums, pointers, error sets), bare structs, error unions, slices, optionals, and any other type without a well-defined memory layout, also cannot be used in this operation. +

+ + +

@bitOffsetOf §

+ +
@bitOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int
+

+ Returns the bit offset of a field relative to its containing struct. +

+

+ For non packed structs, this will always be divisible by 8. + For packed structs, non-byte-aligned fields will share a byte offset, but they will have different + bit offsets. +

+

See also:

+ + + +

@bitSizeOf §

+ +
@bitSizeOf(comptime T: type) comptime_int
+

+ This function returns the number of bits it takes to store T in memory if the type + were a field in a packed struct/union. + The result is a target-specific compile time constant. +

+

+ This function measures the size at runtime. For types that are disallowed at runtime, such as + comptime_int and type, the result is 0. +

+

See also:

+ + + +

@branchHint §

+ +
@branchHint(hint: BranchHint) void
+

Hints to the optimizer how likely a given branch of control flow is to be reached.

+

BranchHint can be found with @import("std").builtin.BranchHint.

+

This function is only valid as the first statement in a control flow branch, or the first statement in a function.

+ + +

@breakpoint §

+ +
@breakpoint() void
+

+ This function inserts a platform-specific debug trap instruction which causes + debuggers to break there. + Unlike for @trap(), execution may continue after this point if the program is resumed. +

+

+ This function is only valid within function scope. +

+

See also:

+ + + +

@mulAdd §

+ +
@mulAdd(comptime T: type, a: T, b: T, c: T) T
+

+ Fused multiply-add, similar to (a * b) + c, except + only rounds once, and is thus more accurate. +

+

+ Supports Floats and Vectors of floats. +

+ + +

@byteSwap §

+ +
@byteSwap(operand: anytype) T
+

@TypeOf(operand) must be an integer type or an integer vector type with bit count evenly divisible by 8.

+

operand may be an integer or vector.

+

+ Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, + and converts a little endian integer to a big endian integer. +

+

+ Note that for the purposes of memory layout with respect to endianness, the integer type should be + related to the number of bytes reported by @sizeOf bytes. This is demonstrated with + u24. @sizeOf(u24) == 4, which means that a + u24 stored in memory takes 4 bytes, and those 4 bytes are what are swapped on + a little vs big endian system. On the other hand, if T is specified to + be u24, then only 3 bytes are reversed. +

+ + +

@bitReverse §

+ +
@bitReverse(integer: anytype) T
+

@TypeOf(anytype) accepts any integer type or integer vector type.

+

+ Reverses the bitpattern of an integer value, including the sign bit if applicable. +

+

+ For example 0b10110110 (u8 = 182, i8 = -74) + becomes 0b01101101 (u8 = 109, i8 = 109). +

+ + +

@offsetOf §

+ +
@offsetOf(comptime T: type, comptime field_name: []const u8) comptime_int
+

+ Returns the byte offset of a field relative to its containing struct. +

+

See also:

+ + + +

@call §

+ +
@call(modifier: std.builtin.CallModifier, function: anytype, args: anytype) anytype
+

+ Calls a function, in the same way that invoking an expression with parentheses does: +

+
test_call_builtin.zig
const expect = @import("std").testing.expect;
+
+test "noinline function call" {
+    try expect(@call(.auto, add, .{ 3, 9 }) == 12);
+}
+
+fn add(a: i32, b: i32) i32 {
+    return a + b;
+}
Shell
$ zig test test_call_builtin.zig
+1/1 test_call_builtin.test.noinline function call...OK
+All 1 tests passed.
+
+ +

+ @call allows more flexibility than normal function call syntax does. The + CallModifier enum is reproduced here: +

+
builtin.CallModifier struct.zig
pub const CallModifier = enum {
+    /// Equivalent to function call syntax.
+    auto,
+
+    /// Equivalent to async keyword used with function call syntax.
+    async_kw,
+
+    /// Prevents tail call optimization. This guarantees that the return
+    /// address will point to the callsite, as opposed to the callsite's
+    /// callsite. If the call is otherwise required to be tail-called
+    /// or inlined, a compile error is emitted instead.
+    never_tail,
+
+    /// Guarantees that the call will not be inlined. If the call is
+    /// otherwise required to be inlined, a compile error is emitted instead.
+    never_inline,
+
+    /// Asserts that the function call will not suspend. This allows a
+    /// non-async function to call an async function.
+    no_async,
+
+    /// Guarantees that the call will be generated with tail call optimization.
+    /// If this is not possible, a compile error is emitted instead.
+    always_tail,
+
+    /// Guarantees that the call will be inlined at the callsite.
+    /// If this is not possible, a compile error is emitted instead.
+    always_inline,
+
+    /// Evaluates the call at compile-time. If the call cannot be completed at
+    /// compile-time, a compile error is emitted instead.
+    compile_time,
+};
+ + + +

@cDefine §

+ +
@cDefine(comptime name: []const u8, value) void
+

+ This function can only occur inside @cImport. +

+

+ This appends #define $name $value to the @cImport + temporary buffer. +

+

+ To define without a value, like this: +

+
#define _GNU_SOURCE
+

+ Use the void value, like this: +

+
@cDefine("_GNU_SOURCE", {})
+

See also:

+ + +

@cImport §

+ +
@cImport(expression) type
+

+ This function parses C code and imports the functions, types, variables, + and compatible macro definitions into a new empty struct type, and then + returns that type. +

+

+ expression is interpreted at compile time. The builtin functions + @cInclude, @cDefine, and @cUndef work + within this expression, appending to a temporary buffer which is then parsed as C code. +

+

+ Usually you should only have one @cImport in your entire application, because it saves the compiler + from invoking clang multiple times, and prevents inline functions from being duplicated. +

+

+ Reasons for having multiple @cImport expressions would be: +

+
    +
  • To avoid a symbol collision, for example if foo.h and bar.h both #define CONNECTION_COUNT
  • +
  • To analyze the C code with different preprocessor defines
  • +
+

See also:

+ + +

@cInclude §

+ +
@cInclude(comptime path: []const u8) void
+

+ This function can only occur inside @cImport. +

+

+ This appends #include <$path>\n to the c_import + temporary buffer. +

+

See also:

+ + + +

@clz §

+ +
@clz(operand: anytype) anytype
+

@TypeOf(operand) must be an integer type or an integer vector type.

+

operand may be an integer or vector.

+

+ Counts the number of most-significant (leading in a big-endian sense) zeroes in an integer - "count leading zeroes". +

+

+ The return type is an unsigned integer or vector of unsigned integers with the minimum number + of bits that can represent the bit count of the integer type. +

+

+ If operand is zero, @clz returns the bit width + of integer type T. +

+

See also:

+ + + +

@cmpxchgStrong §

+ +
@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T
+

+ This function performs a strong atomic compare-and-exchange operation, returning null + if the current value is the given expected value. It's the equivalent of this code, + except atomic: +

+
not_atomic_cmpxchgStrong.zig
fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T {
+    const old_value = ptr.*;
+    if (old_value == expected_value) {
+        ptr.* = new_value;
+        return null;
+    } else {
+        return old_value;
+    }
+}
+ +

+ If you are using cmpxchg in a retry loop, @cmpxchgWeak is the better choice, because it can be implemented + more efficiently in machine instructions. +

+

+ T must be a pointer, a bool, a float, + an integer or an enum. +

+

@typeInfo(@TypeOf(ptr)).pointer.alignment must be >= @sizeOf(T).

+

AtomicOrder can be found with @import("std").builtin.AtomicOrder.

+

See also:

+ + + +

@cmpxchgWeak §

+ +
@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T
+

+ This function performs a weak atomic compare-and-exchange operation, returning null + if the current value is the given expected value. It's the equivalent of this code, + except atomic: +

+
cmpxchgWeakButNotAtomic
fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T {
+    const old_value = ptr.*;
+    if (old_value == expected_value and usuallyTrueButSometimesFalse()) {
+        ptr.* = new_value;
+        return null;
+    } else {
+        return old_value;
+    }
+}
+

+ If you are using cmpxchg in a retry loop, the sporadic failure will be no problem, and cmpxchgWeak + is the better choice, because it can be implemented more efficiently in machine instructions. + However if you need a stronger guarantee, use @cmpxchgStrong. +

+

+ T must be a pointer, a bool, a float, + an integer or an enum. +

+

@typeInfo(@TypeOf(ptr)).pointer.alignment must be >= @sizeOf(T).

+

AtomicOrder can be found with @import("std").builtin.AtomicOrder.

+

See also:

+ + + +

@compileError §

+ +
@compileError(comptime msg: []const u8) noreturn
+

+ This function, when semantically analyzed, causes a compile error with the + message msg. +

+

+ There are several ways that code avoids being semantically checked, such as + using if or switch with compile time constants, + and comptime functions. +

+ + +

@compileLog §

+ +
@compileLog(...) void
+

+ This function prints the arguments passed to it at compile-time. +

+

+ To prevent accidentally leaving compile log statements in a codebase, + a compilation error is added to the build, pointing to the compile + log statement. This error prevents code from being generated, but + does not otherwise interfere with analysis. +

+

+ This function can be used to do "printf debugging" on + compile-time executing code. +

+
test_compileLog_builtin.zig
const print = @import("std").debug.print;
+
+const num1 = blk: {
+    var val1: i32 = 99;
+    @compileLog("comptime val1 = ", val1);
+    val1 = val1 + 1;
+    break :blk val1;
+};
+
+test "main" {
+    @compileLog("comptime in main");
+
+    print("Runtime in main, num1 = {}.\n", .{num1});
+}
Shell
$ zig test test_compileLog_builtin.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_compileLog_builtin.zig:11:5: error: found compile log statement
+    @compileLog("comptime in main");
+    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_compileLog_builtin.zig:5:5: note: also here
+    @compileLog("comptime val1 = ", val1);
+    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Compile Log Output:
+@as(*const [16:0]u8, "comptime in main")
+@as(*const [16:0]u8, "comptime val1 = "), @as(i32, 99)
+
+ + + +

@constCast §

+ +
@constCast(value: anytype) DestType
+

+ Remove const qualifier from a pointer. +

+ + +

@ctz §

+ +
@ctz(operand: anytype) anytype
+

@TypeOf(operand) must be an integer type or an integer vector type.

+

operand may be an integer or vector.

+

+ Counts the number of least-significant (trailing in a big-endian sense) zeroes in an integer - "count trailing zeroes". +

+

+ The return type is an unsigned integer or vector of unsigned integers with the minimum number + of bits that can represent the bit count of the integer type. +

+

+ If operand is zero, @ctz returns + the bit width of integer type T. +

+

See also:

+ + + +

@cUndef §

+ +
@cUndef(comptime name: []const u8) void
+

+ This function can only occur inside @cImport. +

+

+ This appends #undef $name to the @cImport + temporary buffer. +

+

See also:

+ + + +

@cVaArg §

+ +
@cVaArg(operand: *std.builtin.VaList, comptime T: type) T
+

+ Implements the C macro va_arg. +

+

See also:

+ + +

@cVaCopy §

+ +
@cVaCopy(src: *std.builtin.VaList) std.builtin.VaList
+

+ Implements the C macro va_copy. +

+

See also:

+ + +

@cVaEnd §

+ +
@cVaEnd(src: *std.builtin.VaList) void
+

+ Implements the C macro va_end. +

+

See also:

+ + +

@cVaStart §

+ +
@cVaStart() std.builtin.VaList
+

+ Implements the C macro va_start. Only valid inside a variadic function. +

+

See also:

+ + + +

@divExact §

+ +
@divExact(numerator: T, denominator: T) T
+

+ Exact division. Caller guarantees denominator != 0 and + @divTrunc(numerator, denominator) * denominator == numerator. +

+
    +
  • @divExact(6, 3) == 2
  • +
  • @divExact(a, b) * b == a
  • +
+

For a function that returns a possible error code, use @import("std").math.divExact.

+

See also:

+ + +

@divFloor §

+ +
@divFloor(numerator: T, denominator: T) T
+

+ Floored division. Rounds toward negative infinity. For unsigned integers it is + the same as numerator / denominator. Caller guarantees denominator != 0 and + !(@typeInfo(T) == .int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1). +

+
    +
  • @divFloor(-5, 3) == -2
  • +
  • (@divFloor(a, b) * b) + @mod(a, b) == a
  • +
+

For a function that returns a possible error code, use @import("std").math.divFloor.

+

See also:

+ + +

@divTrunc §

+ +
@divTrunc(numerator: T, denominator: T) T
+

+ Truncated division. Rounds toward zero. For unsigned integers it is + the same as numerator / denominator. Caller guarantees denominator != 0 and + !(@typeInfo(T) == .int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1). +

+
    +
  • @divTrunc(-5, 3) == -1
  • +
  • (@divTrunc(a, b) * b) + @rem(a, b) == a
  • +
+

For a function that returns a possible error code, use @import("std").math.divTrunc.

+

See also:

+ + + +

@embedFile §

+ +
@embedFile(comptime path: []const u8) *const [N:0]u8
+

+ This function returns a compile time constant pointer to null-terminated, + fixed-size array with length equal to the byte count of the file given by + path. The contents of the array are the contents of the file. + This is equivalent to a string literal + with the file contents. +

+

+ path is absolute or relative to the current file, just like @import. +

+

See also:

+ + + +

@enumFromInt §

+ +
@enumFromInt(integer: anytype) anytype
+

+ Converts an integer into an enum value. The return type is the inferred result type. +

+

+ Attempting to convert an integer with no corresponding value in the enum invokes + safety-checked Illegal Behavior. + Note that a non-exhaustive enum has corresponding values for all + integers in the enum's integer tag type: the _ value represents all + the remaining unnamed integers in the enum's tag type. +

+

See also:

+ + + +

@errorFromInt §

+ +
@errorFromInt(value: std.meta.Int(.unsigned, @bitSizeOf(anyerror))) anyerror
+

+ Converts from the integer representation of an error into The Global Error Set type. +

+

+ It is generally recommended to avoid this + cast, as the integer representation of an error is not stable across source code changes. +

+

+ Attempting to convert an integer that does not correspond to any error results in + safety-checked Illegal Behavior. +

+

See also:

+ + + +

@errorName §

+ +
@errorName(err: anyerror) [:0]const u8
+

+ This function returns the string representation of an error. The string representation + of error.OutOfMem is "OutOfMem". +

+

+ If there are no calls to @errorName in an entire application, + or all calls have a compile-time known value for err, then no + error name table will be generated. +

+ + +

@errorReturnTrace §

+ +
@errorReturnTrace() ?*builtin.StackTrace
+

+ If the binary is built with error return tracing, and this function is invoked in a + function that calls a function with an error or error union return type, returns a + stack trace object. Otherwise returns null. +

+ + +

@errorCast §

+ +
@errorCast(value: anytype) anytype
+

+ Converts an error set or error union value from one error set to another error set. The return type is the + inferred result type. Attempting to convert an error which is not in the destination error + set results in safety-checked Illegal Behavior. +

+ + +

@export §

+ +
@export(comptime ptr: *const anyopaque, comptime options: std.builtin.ExportOptions) void
+

Creates a symbol in the output object file which refers to the target of ptr.

+

ptr must point to a global variable or a comptime-known constant.

+

+ This builtin can be called from a comptime block to conditionally export symbols. + When ptr points to a function with the C calling convention and + options.linkage is .Strong, this is equivalent to + the export keyword used on a function: +

+
export_builtin.zig
comptime {
+    @export(&internalName, .{ .name = "foo", .linkage = .strong });
+}
+
+fn internalName() callconv(.C) void {}
Shell
$ zig build-obj export_builtin.zig
+
+ +

This is equivalent to:

+
export_builtin_equivalent_code.zig
export fn foo() void {}
Shell
$ zig build-obj export_builtin_equivalent_code.zig
+
+ +

Note that even when using export, the @"foo" syntax for + identifiers can be used to choose any string for the symbol name:

+
export_any_symbol_name.zig
export fn @"A function name that is a complete sentence."() void {}
Shell
$ zig build-obj export_any_symbol_name.zig
+
+ +

+ When looking at the resulting object, you can see the symbol is used verbatim: +

+
00000000000001f0 T A function name that is a complete sentence.
+

See also:

+ + + +

@extern §

+ +
@extern(T: type, comptime options: std.builtin.ExternOptions) T
+

+ Creates a reference to an external symbol in the output object file. + T must be a pointer type. +

+

See also:

+ + + +

@field §

+ +
@field(lhs: anytype, comptime field_name: []const u8) (field)
+

Performs field access by a compile-time string. Works on both fields and declarations. +

+
test_field_builtin.zig
const std = @import("std");
+
+const Point = struct {
+    x: u32,
+    y: u32,
+
+    pub var z: u32 = 1;
+};
+
+test "field access by string" {
+    const expect = std.testing.expect;
+    var p = Point{ .x = 0, .y = 0 };
+
+    @field(p, "x") = 4;
+    @field(p, "y") = @field(p, "x") + 1;
+
+    try expect(@field(p, "x") == 4);
+    try expect(@field(p, "y") == 5);
+}
+
+test "decl access by string" {
+    const expect = std.testing.expect;
+
+    try expect(@field(Point, "z") == 1);
+
+    @field(Point, "z") = 2;
+    try expect(@field(Point, "z") == 2);
+}
Shell
$ zig test test_field_builtin.zig
+1/2 test_field_builtin.test.field access by string...OK
+2/2 test_field_builtin.test.decl access by string...OK
+All 2 tests passed.
+
+ + + + +

@fieldParentPtr §

+ +
@fieldParentPtr(comptime field_name: []const u8, field_ptr: *T) anytype
+

+ Given a pointer to a struct field, returns a pointer to the struct containing that field. + The return type (and struct in question) is the inferred result type. +

+

+ If field_ptr does not point to the field_name field of an instance of + the result type, and the result type has ill-defined layout, invokes unchecked Illegal Behavior. +

+ + +

@FieldType §

+ +
@FieldType(comptime Type: type, comptime field_name: []const u8) type
+

+ Given a type and the name of one of its fields, returns the type of that field. +

+ + +

@floatCast §

+ +
@floatCast(value: anytype) anytype
+

+ Convert from one float type to another. This cast is safe, but may cause the + numeric value to lose precision. The return type is the inferred result type. +

+ + +

@floatFromInt §

+ +
@floatFromInt(int: anytype) anytype
+

+ Converts an integer to the closest floating point representation. The return type is the inferred result type. + To convert the other way, use @intFromFloat. This operation is legal + for all values of all integer types. +

+ + +

@frameAddress §

+ +
@frameAddress() usize
+

+ This function returns the base pointer of the current stack frame. +

+

+ The implications of this are target-specific and not consistent across all + platforms. The frame address may not be available in release mode due to + aggressive optimizations. +

+

+ This function is only valid within function scope. +

+ + +

@hasDecl §

+ +
@hasDecl(comptime Container: type, comptime name: []const u8) bool
+

+ Returns whether or not a container has a declaration + matching name. +

+
test_hasDecl_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+const Foo = struct {
+    nope: i32,
+
+    pub var blah = "xxx";
+    const hi = 1;
+};
+
+test "@hasDecl" {
+    try expect(@hasDecl(Foo, "blah"));
+
+    // Even though `hi` is private, @hasDecl returns true because this test is
+    // in the same file scope as Foo. It would return false if Foo was declared
+    // in a different file.
+    try expect(@hasDecl(Foo, "hi"));
+
+    // @hasDecl is for declarations; not fields.
+    try expect(!@hasDecl(Foo, "nope"));
+    try expect(!@hasDecl(Foo, "nope1234"));
+}
Shell
$ zig test test_hasDecl_builtin.zig
+1/1 test_hasDecl_builtin.test.@hasDecl...OK
+All 1 tests passed.
+
+ +

See also:

+ + + +

@hasField §

+ +
@hasField(comptime Container: type, comptime name: []const u8) bool
+

Returns whether the field name of a struct, union, or enum exists.

+

+ The result is a compile time constant. +

+

+ It does not include functions, variables, or constants. +

+

See also:

+ + + +

@import §

+ +
@import(comptime path: []const u8) type
+

+ This function finds a zig file corresponding to path and adds it to the build, + if it is not already added. +

+

+ Zig source files are implicitly structs, with a name equal to the file's basename with the extension + truncated. @import returns the struct type corresponding to the file. +

+

+ Declarations which have the pub keyword may be referenced from a different + source file than the one they are declared in. +

+

+ path can be a relative path or it can be the name of a package. + If it is a relative path, it is relative to the file that contains the @import + function call. +

+

+ The following packages are always available: +

+
    +
  • @import("std") - Zig Standard Library
  • +
  • @import("builtin") - Target-specific information + The command zig build-exe --show-builtin outputs the source to stdout for reference. +
  • +
  • @import("root") - Root source file + This is usually src/main.zig but depends on what file is built. +
  • +
+

See also:

+ + + +

@inComptime §

+ +
@inComptime() bool
+

+ Returns whether the builtin was run in a comptime context. The result is a compile-time constant. +

+

+ This can be used to provide alternative, comptime-friendly implementations of functions. It should not be used, for instance, to exclude certain functions from being evaluated at comptime. +

+

See also:

+ + + +

@intCast §

+ +
@intCast(int: anytype) anytype
+

+ Converts an integer to another integer while keeping the same numerical value. + The return type is the inferred result type. + Attempting to convert a number which is out of range of the destination type results in + safety-checked Illegal Behavior. +

+
test_intCast_builtin.zig
test "integer cast panic" {
+    var a: u16 = 0xabcd; // runtime-known
+    _ = &a;
+    const b: u8 = @intCast(a);
+    _ = b;
+}
Shell
$ zig test test_intCast_builtin.zig
+1/1 test_intCast_builtin.test.integer cast panic...thread 1079293 panic: integer cast truncated bits
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_intCast_builtin.zig:4:19: 0x1048628 in test.integer cast panic (test)
+    const b: u8 = @intCast(a);
+                  ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10ee939 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10e6cdd in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e6152 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e5d2d in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/2c71aa993d97ec069b8d8d63e8a61ada/test --seed=0x3e858e4e
+
+ +

+ To truncate the significant bits of a number out of range of the destination type, use @truncate. +

+

+ If T is comptime_int, + then this is semantically equivalent to Type Coercion. +

+ + +

@intFromBool §

+ +
@intFromBool(value: bool) u1
+

+ Converts true to @as(u1, 1) and false to + @as(u1, 0). +

+ + +

@intFromEnum §

+ +
@intFromEnum(enum_or_tagged_union: anytype) anytype
+

+ Converts an enumeration value into its integer tag type. When a tagged union is passed, + the tag value is used as the enumeration value. +

+

+ If there is only one possible enum value, the result is a comptime_int + known at comptime. +

+

See also:

+ + + +

@intFromError §

+ +
@intFromError(err: anytype) std.meta.Int(.unsigned, @bitSizeOf(anyerror))
+

+ Supports the following types: +

+ +

+ Converts an error to the integer representation of an error. +

+

+ It is generally recommended to avoid this + cast, as the integer representation of an error is not stable across source code changes. +

+

See also:

+ + + +

@intFromFloat §

+ +
@intFromFloat(float: anytype) anytype
+

+ Converts the integer part of a floating point number to the inferred result type. +

+

+ If the integer part of the floating point number cannot fit in the destination type, + it invokes safety-checked Illegal Behavior. +

+

See also:

+ + + +

@intFromPtr §

+ +
@intFromPtr(value: anytype) usize
+

+ Converts value to a usize which is the address of the pointer. + value can be *T or ?*T. +

+

To convert the other way, use @ptrFromInt

+ + +

@max §

+ +
@max(...) T
+

+ Takes two or more arguments and returns the biggest value included (the maximum). This builtin accepts integers, floats, and vectors of either. In the latter case, the operation is performed element wise. +

+

+ NaNs are handled as follows: return the biggest non-NaN value included. If all operands are NaN, return NaN. +

+

See also:

+ + + +

@memcpy §

+ +
@memcpy(noalias dest, noalias source) void
+

This function copies bytes from one region of memory to another.

+

dest must be a mutable slice, a mutable pointer to an array, or + a mutable many-item pointer. It may have any + alignment, and it may have any element type.

+

source must be a slice, a pointer to + an array, or a many-item pointer. It may + have any alignment, and it may have any element type.

+

The source element type must have the same in-memory + representation as the dest element type.

+

Similar to for loops, at least one of source and + dest must provide a length, and if two lengths are provided, + they must be equal.

+

Finally, the two memory regions must not overlap.

+ + +

@memset §

+ +
@memset(dest, elem) void
+

This function sets all the elements of a memory region to elem.

+

dest must be a mutable slice or a mutable pointer to an array. + It may have any alignment, and it may have any element type.

+

elem is coerced to the element type of dest.

+

For securely zeroing out sensitive contents from memory, you should use + std.crypto.secureZero

+ + +

@min §

+ +
@min(...) T
+

+ Takes two or more arguments and returns the smallest value included (the minimum). This builtin accepts integers, floats, and vectors of either. In the latter case, the operation is performed element wise. +

+

+ NaNs are handled as follows: return the smallest non-NaN value included. If all operands are NaN, return NaN. +

+

See also:

+ + + +

@wasmMemorySize §

+ +
@wasmMemorySize(index: u32) usize
+

+ This function returns the size of the Wasm memory identified by index as + an unsigned value in units of Wasm pages. Note that each Wasm page is 64KB in size. +

+

+ This function is a low level intrinsic with no safety mechanisms usually useful for allocator + designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use + something like @import("std").heap.WasmPageAllocator. +

+

See also:

+ + + +

@wasmMemoryGrow §

+ +
@wasmMemoryGrow(index: u32, delta: usize) isize
+

+ This function increases the size of the Wasm memory identified by index by + delta in units of unsigned number of Wasm pages. Note that each Wasm page + is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, + returns -1. +

+

+ This function is a low level intrinsic with no safety mechanisms usually useful for allocator + designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use + something like @import("std").heap.WasmPageAllocator. +

+
test_wasmMemoryGrow_builtin.zig
const std = @import("std");
+const native_arch = @import("builtin").target.cpu.arch;
+const expect = std.testing.expect;
+
+test "@wasmMemoryGrow" {
+    if (native_arch != .wasm32) return error.SkipZigTest;
+
+    const prev = @wasmMemorySize(0);
+    try expect(prev == @wasmMemoryGrow(0, 1));
+    try expect(prev + 1 == @wasmMemorySize(0));
+}
Shell
$ zig test test_wasmMemoryGrow_builtin.zig
+1/1 test_wasmMemoryGrow_builtin.test.@wasmMemoryGrow...SKIP
+0 passed; 1 skipped; 0 failed.
+
+ +

See also:

+ + + +

@mod §

+ +
@mod(numerator: T, denominator: T) T
+

+ Modulus division. For unsigned integers this is the same as + numerator % denominator. Caller guarantees denominator > 0, otherwise the + operation will result in a Remainder Division by Zero when runtime safety checks are enabled. +

+
    +
  • @mod(-5, 3) == 1
  • +
  • (@divFloor(a, b) * b) + @mod(a, b) == a
  • +
+

For a function that returns an error code, see @import("std").math.mod.

+

See also:

+ + + +

@mulWithOverflow §

+ +
@mulWithOverflow(a: anytype, b: anytype) struct { @TypeOf(a, b), u1 }
+

+ Performs a * b and returns a tuple with the result and a possible overflow bit. +

+ + +

@panic §

+ +
@panic(message: []const u8) noreturn
+

+ Invokes the panic handler function. By default the panic handler function + calls the public panic function exposed in the root source file, or + if there is not one specified, the std.builtin.default_panic + function from std/builtin.zig. +

+

Generally it is better to use @import("std").debug.panic. + However, @panic can be useful for 2 scenarios: +

+
    +
  • From library code, calling the programmer's panic function if they exposed one in the root source file.
  • +
  • When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.
  • +
+

See also:

+ + + +

@popCount §

+ +
@popCount(operand: anytype) anytype
+

@TypeOf(operand) must be an integer type.

+

operand may be an integer or vector.

+

+ Counts the number of bits set in an integer - "population count". +

+

+ The return type is an unsigned integer or vector of unsigned integers with the minimum number + of bits that can represent the bit count of the integer type. +

+

See also:

+ + + +

@prefetch §

+ +
@prefetch(ptr: anytype, comptime options: PrefetchOptions) void
+

+ This builtin tells the compiler to emit a prefetch instruction if supported by the + target CPU. If the target CPU does not support the requested prefetch instruction, + this builtin is a no-op. This function has no effect on the behavior of the program, + only on the performance characteristics. +

+

+ The ptr argument may be any pointer type and determines the memory + address to prefetch. This function does not dereference the pointer, it is perfectly legal + to pass a pointer to invalid memory to this function and no Illegal Behavior will result. +

+

PrefetchOptions can be found with @import("std").builtin.PrefetchOptions.

+ + +

@ptrCast §

+ +
@ptrCast(value: anytype) anytype
+

+ Converts a pointer of one type to a pointer of another type. The return type is the inferred result type. +

+

+ Optional Pointers are allowed. Casting an optional pointer which is null + to a non-optional pointer invokes safety-checked Illegal Behavior. +

+

+ @ptrCast cannot be used for: +

+
    +
  • Removing const qualifier, use @constCast.
  • +
  • Removing volatile qualifier, use @volatileCast.
  • +
  • Changing pointer address space, use @addrSpaceCast.
  • +
  • Increasing pointer alignment, use @alignCast.
  • +
  • Casting a non-slice pointer to a slice, use slicing syntax ptr[start..end].
  • +
+ + +

@ptrFromInt §

+ +
@ptrFromInt(address: usize) anytype
+

+ Converts an integer to a pointer. The return type is the inferred result type. + To convert the other way, use @intFromPtr. Casting an address of 0 to a destination type + which in not optional and does not have the allowzero attribute will result in a + Pointer Cast Invalid Null panic when runtime safety checks are enabled. +

+

+ If the destination pointer type does not allow address zero and address + is zero, this invokes safety-checked Illegal Behavior. +

+ + +

@rem §

+ +
@rem(numerator: T, denominator: T) T
+

+ Remainder division. For unsigned integers this is the same as + numerator % denominator. Caller guarantees denominator > 0, otherwise the + operation will result in a Remainder Division by Zero when runtime safety checks are enabled. +

+
    +
  • @rem(-5, 3) == -2
  • +
  • (@divTrunc(a, b) * b) + @rem(a, b) == a
  • +
+

For a function that returns an error code, see @import("std").math.rem.

+

See also:

+ + + +

@returnAddress §

+ +
@returnAddress() usize
+

+ This function returns the address of the next machine code instruction that will be executed + when the current function returns. +

+

+ The implications of this are target-specific and not consistent across + all platforms. +

+

+ This function is only valid within function scope. If the function gets inlined into + a calling function, the returned address will apply to the calling function. +

+ + +

@select §

+ +
@select(comptime T: type, pred: @Vector(len, bool), a: @Vector(len, T), b: @Vector(len, T)) @Vector(len, T)
+

+ Selects values element-wise from a or b based on pred. If pred[i] is true, the corresponding element in the result will be a[i] and otherwise b[i]. +

+

See also:

+ + + +

@setEvalBranchQuota §

+ +
@setEvalBranchQuota(comptime new_quota: u32) void
+

+ Increase the maximum number of backwards branches that compile-time code + execution can use before giving up and making a compile error. +

+

+ If the new_quota is smaller than the default quota (1000) or + a previously explicitly set quota, it is ignored. +

+

+ Example: +

+
test_without_setEvalBranchQuota_builtin.zig
test "foo" {
+    comptime {
+        var i = 0;
+        while (i < 1001) : (i += 1) {}
+    }
+}
Shell
$ zig test test_without_setEvalBranchQuota_builtin.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_without_setEvalBranchQuota_builtin.zig:4:9: error: evaluation exceeded 1000 backwards branches
+        while (i < 1001) : (i += 1) {}
+        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_without_setEvalBranchQuota_builtin.zig:4:9: note: use @setEvalBranchQuota() to raise the branch limit from 1000
+
+
+ +

Now we use @setEvalBranchQuota:

+
test_setEvalBranchQuota_builtin.zig
test "foo" {
+    comptime {
+        @setEvalBranchQuota(1001);
+        var i = 0;
+        while (i < 1001) : (i += 1) {}
+    }
+}
Shell
$ zig test test_setEvalBranchQuota_builtin.zig
+1/1 test_setEvalBranchQuota_builtin.test.foo...OK
+All 1 tests passed.
+
+ + +

See also:

+ + + +

@setFloatMode §

+ +
@setFloatMode(comptime mode: FloatMode) void
+

Changes the current scope's rules about how floating point operations are defined.

+
    +
  • + Strict (default) - Floating point operations follow strict IEEE compliance. +
  • +
  • + Optimized - Floating point operations may do all of the following: +
      +
    • Assume the arguments and result are not NaN. Optimizations are required to retain legal behavior over NaNs, but the value of the result is undefined.
    • +
    • Assume the arguments and result are not +/-Inf. Optimizations are required to retain legal behavior over +/-Inf, but the value of the result is undefined.
    • +
    • Treat the sign of a zero argument or result as insignificant.
    • +
    • Use the reciprocal of an argument rather than perform division.
    • +
    • Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-add).
    • +
    • Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate).
    • +
    + This is equivalent to -ffast-math in GCC. +
  • +
+

+ The floating point mode is inherited by child scopes, and can be overridden in any scope. + You can set the floating point mode in a struct or module scope by using a comptime block. +

+

FloatMode can be found with @import("std").builtin.FloatMode.

+

See also:

+ + + +

@setRuntimeSafety §

+ +
@setRuntimeSafety(comptime safety_on: bool) void
+

+ Sets whether runtime safety checks are enabled for the scope that contains the function call. +

+
test_setRuntimeSafety_builtin.zig
test "@setRuntimeSafety" {
+    // The builtin applies to the scope that it is called in. So here, integer overflow
+    // will not be caught in ReleaseFast and ReleaseSmall modes:
+    // var x: u8 = 255;
+    // x += 1; // Unchecked Illegal Behavior in ReleaseFast/ReleaseSmall modes.
+    {
+        // However this block has safety enabled, so safety checks happen here,
+        // even in ReleaseFast and ReleaseSmall modes.
+        @setRuntimeSafety(true);
+        var x: u8 = 255;
+        x += 1;
+
+        {
+            // The value can be overridden at any scope. So here integer overflow
+            // would not be caught in any build mode.
+            @setRuntimeSafety(false);
+            // var x: u8 = 255;
+            // x += 1; // Unchecked Illegal Behavior in all build modes.
+        }
+    }
+}
Shell
$ zig test test_setRuntimeSafety_builtin.zig -OReleaseFast
+1/1 test_setRuntimeSafety_builtin.test.@setRuntimeSafety...thread 1083480 panic: integer overflow
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_setRuntimeSafety_builtin.zig:11:11: 0x100a6a8 in test.@setRuntimeSafety (test)
+        x += 1;
+          ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x1031ad8 in main (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x103028d in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x102ff7d in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/785fdecfc68325a878131d6159c06409/test --seed=0x882a3448
+
+ +

Note: it is planned to replace + @setRuntimeSafety with @optimizeFor

+ + + +

@shlExact §

+ +
@shlExact(value: T, shift_amt: Log2T) T
+

+ Performs the left shift operation (<<). + For unsigned integers, the result is undefined if any 1 bits + are shifted out. For signed integers, the result is undefined if + any bits that disagree with the resultant sign bit are shifted out. +

+

+ The type of shift_amt is an unsigned integer with log2(@typeInfo(T).int.bits) bits. + This is because shift_amt >= @typeInfo(T).int.bits triggers safety-checked Illegal Behavior. +

+

+ comptime_int is modeled as an integer with an infinite number of bits, + meaning that in such case, @shlExact always produces a result and + cannot produce a compile error. +

+

See also:

+ + + +

@shlWithOverflow §

+ +
@shlWithOverflow(a: anytype, shift_amt: Log2T) struct { @TypeOf(a), u1 }
+

+ Performs a << b and returns a tuple with the result and a possible overflow bit. +

+

+ The type of shift_amt is an unsigned integer with log2(@typeInfo(@TypeOf(a)).int.bits) bits. + This is because shift_amt >= @typeInfo(@TypeOf(a)).int.bits triggers safety-checked Illegal Behavior. +

+

See also:

+ + + +

@shrExact §

+ +
@shrExact(value: T, shift_amt: Log2T) T
+

+ Performs the right shift operation (>>). Caller guarantees + that the shift will not shift any 1 bits out. +

+

+ The type of shift_amt is an unsigned integer with log2(@typeInfo(T).int.bits) bits. + This is because shift_amt >= @typeInfo(T).int.bits triggers safety-checked Illegal Behavior. +

+

See also:

+ + + +

@shuffle §

+ +
@shuffle(comptime E: type, a: @Vector(a_len, E), b: @Vector(b_len, E), comptime mask: @Vector(mask_len, i32)) @Vector(mask_len, E)
+

+ Constructs a new vector by selecting elements from a and + b based on mask. +

+

+ Each element in mask selects an element from either a or + b. Positive numbers select from a starting at 0. + Negative values select from b, starting at -1 and going down. + It is recommended to use the ~ operator for indexes from b + so that both indexes can start from 0 (i.e. ~@as(i32, 0) is + -1). +

+

+ For each element of mask, if it or the selected value from + a or b is undefined, + then the resulting element is undefined. +

+

+ a_len and b_len may differ in length. Out-of-bounds element + indexes in mask result in compile errors. +

+

+ If a or b is undefined, it + is equivalent to a vector of all undefined with the same length as the other vector. + If both vectors are undefined, @shuffle returns + a vector with all elements undefined. +

+

+ E must be an integer, float, + pointer, or bool. The mask may be any vector length, and its + length determines the result length. +

+
test_shuffle_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "vector @shuffle" {
+    const a = @Vector(7, u8){ 'o', 'l', 'h', 'e', 'r', 'z', 'w' };
+    const b = @Vector(4, u8){ 'w', 'd', '!', 'x' };
+
+    // To shuffle within a single vector, pass undefined as the second argument.
+    // Notice that we can re-order, duplicate, or omit elements of the input vector
+    const mask1 = @Vector(5, i32){ 2, 3, 1, 1, 0 };
+    const res1: @Vector(5, u8) = @shuffle(u8, a, undefined, mask1);
+    try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello"));
+
+    // Combining two vectors
+    const mask2 = @Vector(6, i32){ -1, 0, 4, 1, -2, -3 };
+    const res2: @Vector(6, u8) = @shuffle(u8, a, b, mask2);
+    try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!"));
+}
Shell
$ zig test test_shuffle_builtin.zig
+1/1 test_shuffle_builtin.test.vector @shuffle...OK
+All 1 tests passed.
+
+ +

See also:

+ + + +

@sizeOf §

+ +
@sizeOf(comptime T: type) comptime_int
+

+ This function returns the number of bytes it takes to store T in memory. + The result is a target-specific compile time constant. +

+

+ This size may contain padding bytes. If there were two consecutive T in memory, the padding would be the offset + in bytes between element at index 0 and the element at index 1. For integer, + consider whether you want to use @sizeOf(T) or + @typeInfo(T).int.bits. +

+

+ This function measures the size at runtime. For types that are disallowed at runtime, such as + comptime_int and type, the result is 0. +

+

See also:

+ + + +

@splat §

+ +
@splat(scalar: anytype) anytype
+

+ Produces a vector where each element is the value scalar. + The return type and thus the length of the vector is inferred. +

+
test_splat_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "vector @splat" {
+    const scalar: u32 = 5;
+    const result: @Vector(4, u32) = @splat(scalar);
+    try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 }));
+}
Shell
$ zig test test_splat_builtin.zig
+1/1 test_splat_builtin.test.vector @splat...OK
+All 1 tests passed.
+
+ +

+ scalar must be an integer, bool, + float, or pointer. +

+

See also:

+ + + +

@reduce §

+ +
@reduce(comptime op: std.builtin.ReduceOp, value: anytype) E
+

+ Transforms a vector into a scalar value (of type E) + by performing a sequential horizontal reduction of its elements using the + specified operator op. +

+

+ Not every operator is available for every vector element type: +

+
    +
  • Every operator is available for integer vectors.
  • +
  • .And, .Or, + .Xor are additionally available for + bool vectors,
  • +
  • .Min, .Max, + .Add, .Mul are + additionally available for floating point vectors,
  • +
+

+ Note that .Add and .Mul + reductions on integral types are wrapping; when applied on floating point + types the operation associativity is preserved, unless the float mode is + set to Optimized. +

+
test_reduce_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "vector @reduce" {
+    const V = @Vector(4, i32);
+    const value = V{ 1, -1, 1, -1 };
+    const result = value > @as(V, @splat(0));
+    // result is { true, false, true, false };
+    try comptime expect(@TypeOf(result) == @Vector(4, bool));
+    const is_all_true = @reduce(.And, result);
+    try comptime expect(@TypeOf(is_all_true) == bool);
+    try expect(is_all_true == false);
+}
Shell
$ zig test test_reduce_builtin.zig
+1/1 test_reduce_builtin.test.vector @reduce...OK
+All 1 tests passed.
+
+ +

See also:

+ + + +

@src §

+ +
@src() std.builtin.SourceLocation
+

+ Returns a SourceLocation struct representing the function's name and location in the source code. This must be called in a function. +

+
test_src_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "@src" {
+    try doTheTest();
+}
+
+fn doTheTest() !void {
+    const src = @src();
+
+    try expect(src.line == 9);
+    try expect(src.column == 17);
+    try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
+    try expect(std.mem.endsWith(u8, src.file, "test_src_builtin.zig"));
+}
Shell
$ zig test test_src_builtin.zig
+1/1 test_src_builtin.test.@src...OK
+All 1 tests passed.
+
+ + +

@sqrt §

+ +
@sqrt(value: anytype) @TypeOf(value)
+

+ Performs the square root of a floating point number. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@sin §

+ +
@sin(value: anytype) @TypeOf(value)
+

+ Sine trigonometric function on a floating point number in radians. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ + +

@cos §

+ +
@cos(value: anytype) @TypeOf(value)
+

+ Cosine trigonometric function on a floating point number in radians. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ + +

@tan §

+ +
@tan(value: anytype) @TypeOf(value)
+

+ Tangent trigonometric function on a floating point number in radians. + Uses a dedicated hardware instruction when available. +

+

+ Supports Floats and Vectors of floats. +

+ + +

@exp §

+ +
@exp(value: anytype) @TypeOf(value)
+

+ Base-e exponential function on a floating point number. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@exp2 §

+ +
@exp2(value: anytype) @TypeOf(value)
+

+ Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@log §

+ +
@log(value: anytype) @TypeOf(value)
+

+ Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@log2 §

+ +
@log2(value: anytype) @TypeOf(value)
+

+ Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@log10 §

+ +
@log10(value: anytype) @TypeOf(value)
+

+ Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction + when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@abs §

+ +
@abs(value: anytype) anytype
+

+ Returns the absolute value of an integer or a floating point number. Uses a dedicated hardware instruction + when available. + + The return type is always an unsigned integer of the same bit width as the operand if the operand is an integer. + Unsigned integer operands are supported. The builtin cannot overflow for signed integer operands. +

+

+ Supports Floats, Integers and Vectors of floats or integers. +

+ +

@floor §

+ +
@floor(value: anytype) @TypeOf(value)
+

+ Returns the largest integral value not greater than the given floating point number. + Uses a dedicated hardware instruction when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@ceil §

+ +
@ceil(value: anytype) @TypeOf(value)
+

+ Returns the smallest integral value not less than the given floating point number. + Uses a dedicated hardware instruction when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@trunc §

+ +
@trunc(value: anytype) @TypeOf(value)
+

+ Rounds the given floating point number to an integer, towards zero. + Uses a dedicated hardware instruction when available. +

+

+ Supports Floats and Vectors of floats. +

+ +

@round §

+ +
@round(value: anytype) @TypeOf(value)
+

+ Rounds the given floating point number to the nearest integer. If two integers are equally close, rounds away from zero. + Uses a dedicated hardware instruction when available. +

+
test_round_builtin.zig
const expect = @import("std").testing.expect;
+
+test "@round" {
+    try expect(@round(1.4) == 1);
+    try expect(@round(1.5) == 2);
+    try expect(@round(-1.4) == -1);
+    try expect(@round(-2.5) == -3);
+}
Shell
$ zig test test_round_builtin.zig
+1/1 test_round_builtin.test.@round...OK
+All 1 tests passed.
+
+ +

+ Supports Floats and Vectors of floats. +

+ + +

@subWithOverflow §

+ +
@subWithOverflow(a: anytype, b: anytype) struct { @TypeOf(a, b), u1 }
+

+ Performs a - b and returns a tuple with the result and a possible overflow bit. +

+ + +

@tagName §

+ +
@tagName(value: anytype) [:0]const u8
+

+ Converts an enum value or union value to a string literal representing the name.

If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked Illegal Behavior. +

+ + +

@This §

+ +
@This() type
+

+ Returns the innermost struct, enum, or union that this function call is inside. + This can be useful for an anonymous struct that needs to refer to itself: +

+
test_this_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "@This()" {
+    var items = [_]i32{ 1, 2, 3, 4 };
+    const list = List(i32){ .items = items[0..] };
+    try expect(list.length() == 4);
+}
+
+fn List(comptime T: type) type {
+    return struct {
+        const Self = @This();
+
+        items: []T,
+
+        fn length(self: Self) usize {
+            return self.items.len;
+        }
+    };
+}
Shell
$ zig test test_this_builtin.zig
+1/1 test_this_builtin.test.@This()...OK
+All 1 tests passed.
+
+ +

+ When @This() is used at file scope, it returns a reference to the + struct that corresponds to the current file. +

+ + +

@trap §

+ +
@trap() noreturn
+

+ This function inserts a platform-specific trap/jam instruction which can be used to exit the program abnormally. + This may be implemented by explicitly emitting an invalid instruction which may cause an illegal instruction exception of some sort. + Unlike for @breakpoint(), execution does not continue after this point. +

+

+ Outside function scope, this builtin causes a compile error. +

+

See also:

+ + + +

@truncate §

+ +
@truncate(integer: anytype) anytype
+

+ This function truncates bits from an integer type, resulting in a smaller + or same-sized integer type. The return type is the inferred result type. +

+

+ This function always truncates the significant bits of the integer, regardless + of endianness on the target platform. +

+

+ Calling @truncate on a number out of range of the destination type is well defined and working code: +

+
test_truncate_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "integer truncation" {
+    const a: u16 = 0xabcd;
+    const b: u8 = @truncate(a);
+    try expect(b == 0xcd);
+}
Shell
$ zig test test_truncate_builtin.zig
+1/1 test_truncate_builtin.test.integer truncation...OK
+All 1 tests passed.
+
+ +

+ Use @intCast to convert numbers guaranteed to fit the destination type. +

+ + +

@Type §

+ +
@Type(comptime info: std.builtin.Type) type
+

+ This function is the inverse of @typeInfo. It reifies type information + into a type. +

+

+ It is available for the following types: +

+ + +

@typeInfo §

+ +
@typeInfo(comptime T: type) std.builtin.Type
+

+ Provides type reflection. +

+

+ Type information of structs, unions, enums, and + error sets has fields which are guaranteed to be in the same + order as appearance in the source file. +

+

+ Type information of structs, unions, enums, and + opaques has declarations, which are also guaranteed to be in the same + order as appearance in the source file. +

+ + +

@typeName §

+ +
@typeName(T: type) *const [N:0]u8
+

+ This function returns the string representation of a type, as + an array. It is equivalent to a string literal of the type name. + The returned type name is fully qualified with the parent namespace included + as part of the type name with a series of dots. +

+ + +

@TypeOf §

+ +
@TypeOf(...) type
+

+ @TypeOf is a special builtin function that takes any (non-zero) number of expressions + as parameters and returns the type of the result, using Peer Type Resolution. +

+

+ The expressions are evaluated, however they are guaranteed to have no runtime side-effects: +

+
test_TypeOf_builtin.zig
const std = @import("std");
+const expect = std.testing.expect;
+
+test "no runtime side effects" {
+    var data: i32 = 0;
+    const T = @TypeOf(foo(i32, &data));
+    try comptime expect(T == i32);
+    try expect(data == 0);
+}
+
+fn foo(comptime T: type, ptr: *T) T {
+    ptr.* += 1;
+    return ptr.*;
+}
Shell
$ zig test test_TypeOf_builtin.zig
+1/1 test_TypeOf_builtin.test.no runtime side effects...OK
+All 1 tests passed.
+
+ + + +

@unionInit §

+ +
@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union
+

+ This is the same thing as union initialization syntax, except that the field name is a + comptime-known value rather than an identifier token. +

+

+ @unionInit forwards its result location to init_expr. +

+ + + +

@Vector §

+ +
@Vector(len: comptime_int, Element: type) type
+

Creates Vectors.

+ + +

@volatileCast §

+ +
@volatileCast(value: anytype) DestType
+

+ Remove volatile qualifier from a pointer. +

+ + +

@workGroupId §

+ +
@workGroupId(comptime dimension: u32) u32
+

+ Returns the index of the work group in the current kernel invocation in dimension dimension. +

+ + +

@workGroupSize §

+ +
@workGroupSize(comptime dimension: u32) u32
+

+ Returns the number of work items that a work group has in dimension dimension. +

+ + +

@workItemId §

+ +
@workItemId(comptime dimension: u32) u32
+

+ Returns the index of the work item in the work group in dimension dimension. This function returns values between 0 (inclusive) and @workGroupSize(dimension) (exclusive). +

+ + + + +

Build Mode §

+ +

+ Zig has four build modes: +

+ +

+ To add standard build options to a build.zig file: +

+
build.zig
const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+    const optimize = b.standardOptimizeOption(.{});
+    const exe = b.addExecutable(.{
+        .name = "example",
+        .root_source_file = b.path("example.zig"),
+        .optimize = optimize,
+    });
+    b.default_step.dependOn(&exe.step);
+}
+ +

+ This causes these options to be available: +

+
+
-Doptimize=Debug
Optimizations off and safety on (default)
+
-Doptimize=ReleaseSafe
Optimizations on and safety on
+
-Doptimize=ReleaseFast
Optimizations on and safety off
+
-Doptimize=ReleaseSmall
Size optimizations on and safety off
+
+

Debug §

+ +
Shell
$ zig build-exe example.zig
+
+
    +
  • Fast compilation speed
  • +
  • Safety checks enabled
  • +
  • Slow runtime performance
  • +
  • Large binary size
  • +
  • No reproducible build requirement
  • +
+ +

ReleaseFast §

+ +
Shell
$ zig build-exe example.zig -O ReleaseFast
+
+
    +
  • Fast runtime performance
  • +
  • Safety checks disabled
  • +
  • Slow compilation speed
  • +
  • Large binary size
  • +
  • Reproducible build
  • +
+ +

ReleaseSafe §

+ +
Shell
$ zig build-exe example.zig -O ReleaseSafe
+
+
    +
  • Medium runtime performance
  • +
  • Safety checks enabled
  • +
  • Slow compilation speed
  • +
  • Large binary size
  • +
  • Reproducible build
  • +
+ +

ReleaseSmall §

+ +
Shell
$ zig build-exe example.zig -O ReleaseSmall
+
+
    +
  • Medium runtime performance
  • +
  • Safety checks disabled
  • +
  • Slow compilation speed
  • +
  • Small binary size
  • +
  • Reproducible build
  • +
+ +

See also:

+ + + +

Single Threaded Builds §

+ +

Zig has a compile option -fsingle-threaded which has the following effects:

+
    +
  • All Thread Local Variables are treated as regular Container Level Variables.
  • +
  • The overhead of Async Functions becomes equivalent to function call overhead.
  • +
  • The @import("builtin").single_threaded becomes true + and therefore various userland APIs which read this variable become more efficient. + For example std.Mutex becomes + an empty data structure and all of its functions become no-ops.
  • +
+ + +

Illegal Behavior §

+ +

+ Many operations in Zig trigger what is known as "Illegal Behavior" (IB). If Illegal Behavior is detected at + compile-time, Zig emits a compile error and refuses to continue. Otherwise, when Illegal Behavior is not caught + at compile-time, it falls into one of two categories. +

+

+ Some Illegal Behavior is safety-checked: this means that the compiler will insert "safety checks" + anywhere that the Illegal Behavior may occur at runtime, to determine whether it is about to happen. If it + is, the safety check "fails", which triggers a panic. +

+

+ All other Illegal Behavior is unchecked, meaning the compiler is unable to insert safety checks for + it. If Unchecked Illegal Behavior is invoked at runtime, anything can happen: usually that will be some kind of + crash, but the optimizer is free to make Unchecked Illegal Behavior do anything, such as calling arbitrary functions + or clobbering arbitrary data. This is similar to the concept of "undefined behavior" in some other languages. Note that + Unchecked Illegal Behavior still always results in a compile error if evaluated at comptime, because the Zig + compiler is able to perform more sophisticated checks at compile-time than at runtime. +

+

+ Most Illegal Behavior is safety-checked. However, to facilitate optimizations, safety checks are disabled by default + in the ReleaseFast and ReleaseSmall optimization modes. Safety checks can also be enabled or disabled + on a per-block basis, overriding the default for the current optimization mode, using @setRuntimeSafety. When + safety checks are disabled, Safety-Checked Illegal Behavior behaves like Unchecked Illegal Behavior; that is, any behavior + may result from invoking it. +

+

+ When a safety check fails, Zig's default panic handler crashes with a stack trace, like this: +

+
test_illegal_behavior.zig
test "safety check" {
+    unreachable;
+}
Shell
$ zig test test_illegal_behavior.zig
+1/1 test_illegal_behavior.test.safety check...thread 1083790 panic: reached unreachable code
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_illegal_behavior.zig:2:5: 0x10485f8 in test.safety check (test)
+    unreachable;
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:214:25: 0x10ee8f9 in mainTerminal (test)
+        if (test_fn.func()) |_| {
+                        ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:62:28: 0x10e6c9d in main (test)
+        return mainTerminal();
+                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e6112 in posixCallMainAndExit (test)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e5ced in _start (test)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+error: the following test command crashed:
+/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/2b8c5b0a72f5884998aeae5b01332698/test --seed=0x6ebca125
+
+ +

Reaching Unreachable Code §

+ +

At compile-time:

+
test_comptime_reaching_unreachable.zig
comptime {
+    assert(false);
+}
+fn assert(ok: bool) void {
+    if (!ok) unreachable; // assertion failure
+}
Shell
$ zig test test_comptime_reaching_unreachable.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_reaching_unreachable.zig:5:14: error: reached unreachable code
+    if (!ok) unreachable; // assertion failure
+             ^~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_reaching_unreachable.zig:2:11: note: called from here
+    assert(false);
+    ~~~~~~^~~~~~~
+
+
+ +

At runtime:

+
runtime_reaching_unreachable.zig
const std = @import("std");
+
+pub fn main() void {
+    std.debug.assert(false);
+}
Shell
$ zig build-exe runtime_reaching_unreachable.zig
+$ ./runtime_reaching_unreachable
+thread 1080425 panic: reached unreachable code
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/debug.zig:550:14: 0x10487fd in assert (runtime_reaching_unreachable)
+    if (!ok) unreachable; // assertion failure
+             ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_reaching_unreachable.zig:4:21: 0x10de16a in main (runtime_reaching_unreachable)
+    std.debug.assert(false);
+                    ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddb62 in posixCallMainAndExit (runtime_reaching_unreachable)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd73d in _start (runtime_reaching_unreachable)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Index out of Bounds §

+ +

At compile-time:

+
test_comptime_index_out_of_bounds.zig
comptime {
+    const array: [5]u8 = "hello".*;
+    const garbage = array[5];
+    _ = garbage;
+}
Shell
$ zig test test_comptime_index_out_of_bounds.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_index_out_of_bounds.zig:3:27: error: index 5 outside array of length 5
+    const garbage = array[5];
+                          ^
+
+
+ +

At runtime:

+
runtime_index_out_of_bounds.zig
pub fn main() void {
+    const x = foo("hello");
+    _ = x;
+}
+
+fn foo(x: []const u8) u8 {
+    return x[5];
+}
Shell
$ zig build-exe runtime_index_out_of_bounds.zig
+$ ./runtime_index_out_of_bounds
+thread 1080298 panic: index out of bounds: index 5, len 5
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_index_out_of_bounds.zig:7:13: 0x10dea41 in foo (runtime_index_out_of_bounds)
+    return x[5];
+            ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_index_out_of_bounds.zig:2:18: 0x10de1a6 in main (runtime_index_out_of_bounds)
+    const x = foo("hello");
+                 ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddb92 in posixCallMainAndExit (runtime_index_out_of_bounds)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd76d in _start (runtime_index_out_of_bounds)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Cast Negative Number to Unsigned Integer §

+ +

At compile-time:

+
test_comptime_invalid_cast.zig
comptime {
+    const value: i32 = -1;
+    const unsigned: u32 = @intCast(value);
+    _ = unsigned;
+}
Shell
$ zig test test_comptime_invalid_cast.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_cast.zig:3:36: error: type 'u32' cannot represent integer value '-1'
+    const unsigned: u32 = @intCast(value);
+                                   ^~~~~
+
+
+ +

At runtime:

+
runtime_invalid_cast.zig
const std = @import("std");
+
+pub fn main() void {
+    var value: i32 = -1; // runtime-known
+    _ = &value;
+    const unsigned: u32 = @intCast(value);
+    std.debug.print("value: {}\n", .{unsigned});
+}
Shell
$ zig build-exe runtime_invalid_cast.zig
+$ ./runtime_invalid_cast
+thread 1083123 panic: attempt to cast negative value to unsigned integer
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_invalid_cast.zig:6:27: 0x10de2b6 in main (runtime_invalid_cast)
+    const unsigned: u32 = @intCast(value);
+                          ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddc92 in posixCallMainAndExit (runtime_invalid_cast)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd86d in _start (runtime_invalid_cast)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ +

+ To obtain the maximum value of an unsigned integer, use std.math.maxInt. +

+ +

Cast Truncates Data §

+ +

At compile-time:

+
test_comptime_invalid_cast_truncate.zig
comptime {
+    const spartan_count: u16 = 300;
+    const byte: u8 = @intCast(spartan_count);
+    _ = byte;
+}
Shell
$ zig test test_comptime_invalid_cast_truncate.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_cast_truncate.zig:3:31: error: type 'u8' cannot represent integer value '300'
+    const byte: u8 = @intCast(spartan_count);
+                              ^~~~~~~~~~~~~
+
+
+ +

At runtime:

+
runtime_invalid_cast_truncate.zig
const std = @import("std");
+
+pub fn main() void {
+    var spartan_count: u16 = 300; // runtime-known
+    _ = &spartan_count;
+    const byte: u8 = @intCast(spartan_count);
+    std.debug.print("value: {}\n", .{byte});
+}
Shell
$ zig build-exe runtime_invalid_cast_truncate.zig
+$ ./runtime_invalid_cast_truncate
+thread 1083524 panic: integer cast truncated bits
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_invalid_cast_truncate.zig:6:22: 0x10de348 in main (runtime_invalid_cast_truncate)
+    const byte: u8 = @intCast(spartan_count);
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddd22 in posixCallMainAndExit (runtime_invalid_cast_truncate)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd8fd in _start (runtime_invalid_cast_truncate)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ +

+ To truncate bits, use @truncate. +

+ +

Integer Overflow §

+ +

Default Operations §

+ +

The following operators can cause integer overflow:

+
    +
  • + (addition)
  • +
  • - (subtraction)
  • +
  • - (negation)
  • +
  • * (multiplication)
  • +
  • / (division)
  • +
  • @divTrunc (division)
  • +
  • @divFloor (division)
  • +
  • @divExact (division)
  • +
+

Example with addition at compile-time:

+
test_comptime_overflow.zig
comptime {
+    var byte: u8 = 255;
+    byte += 1;
+}
Shell
$ zig test test_comptime_overflow.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_overflow.zig:3:10: error: overflow of integer type 'u8' with value '256'
+    byte += 1;
+    ~~~~~^~~~
+
+
+ +

At runtime:

+
runtime_overflow.zig
const std = @import("std");
+
+pub fn main() void {
+    var byte: u8 = 255;
+    byte += 1;
+    std.debug.print("value: {}\n", .{byte});
+}
Shell
$ zig build-exe runtime_overflow.zig
+$ ./runtime_overflow
+thread 1084363 panic: integer overflow
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_overflow.zig:5:10: 0x10de349 in main (runtime_overflow)
+    byte += 1;
+         ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddd22 in posixCallMainAndExit (runtime_overflow)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd8fd in _start (runtime_overflow)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Standard Library Math Functions §

+ +

These functions provided by the standard library return possible errors.

+
    +
  • @import("std").math.add
  • +
  • @import("std").math.sub
  • +
  • @import("std").math.mul
  • +
  • @import("std").math.divTrunc
  • +
  • @import("std").math.divFloor
  • +
  • @import("std").math.divExact
  • +
  • @import("std").math.shl
  • +
+

Example of catching an overflow for addition:

+
math_add.zig
const math = @import("std").math;
+const print = @import("std").debug.print;
+pub fn main() !void {
+    var byte: u8 = 255;
+
+    byte = if (math.add(u8, byte, 1)) |result| result else |err| {
+        print("unable to add one: {s}\n", .{@errorName(err)});
+        return err;
+    };
+
+    print("result: {}\n", .{byte});
+}
Shell
$ zig build-exe math_add.zig
+$ ./math_add
+unable to add one: Overflow
+error: Overflow
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/math.zig:565:21: 0x10de335 in add__anon_23882 (math_add)
+    if (ov[1] != 0) return error.Overflow;
+                    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/math_add.zig:8:9: 0x10de2cb in main (math_add)
+        return err;
+        ^
+
+ + +

Builtin Overflow Functions §

+ +

+ These builtins return a tuple containing whether there was an overflow + (as a u1) and the possibly overflowed bits of the operation: +

+ +

+ Example of @addWithOverflow: +

+
addWithOverflow_builtin.zig
const print = @import("std").debug.print;
+pub fn main() void {
+    const byte: u8 = 255;
+
+    const ov = @addWithOverflow(byte, 10);
+    if (ov[1] != 0) {
+        print("overflowed result: {}\n", .{ov[0]});
+    } else {
+        print("result: {}\n", .{ov[0]});
+    }
+}
Shell
$ zig build-exe addWithOverflow_builtin.zig
+$ ./addWithOverflow_builtin
+overflowed result: 9
+
+ + +

Wrapping Operations §

+ +

+ These operations have guaranteed wraparound semantics. +

+
    +
  • +% (wraparound addition)
  • +
  • -% (wraparound subtraction)
  • +
  • -% (wraparound negation)
  • +
  • *% (wraparound multiplication)
  • +
+
test_wraparound_semantics.zig
const std = @import("std");
+const expect = std.testing.expect;
+const minInt = std.math.minInt;
+const maxInt = std.math.maxInt;
+
+test "wraparound addition and subtraction" {
+    const x: i32 = maxInt(i32);
+    const min_val = x +% 1;
+    try expect(min_val == minInt(i32));
+    const max_val = min_val -% 1;
+    try expect(max_val == maxInt(i32));
+}
Shell
$ zig test test_wraparound_semantics.zig
+1/1 test_wraparound_semantics.test.wraparound addition and subtraction...OK
+All 1 tests passed.
+
+ + + +

Exact Left Shift Overflow §

+ +

At compile-time:

+
test_comptime_shlExact_overwlow.zig
comptime {
+    const x = @shlExact(@as(u8, 0b01010101), 2);
+    _ = x;
+}
Shell
$ zig test test_comptime_shlExact_overwlow.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_shlExact_overwlow.zig:2:15: error: operation caused overflow
+    const x = @shlExact(@as(u8, 0b01010101), 2);
+              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+ +

At runtime:

+
runtime_shlExact_overflow.zig
const std = @import("std");
+
+pub fn main() void {
+    var x: u8 = 0b01010101; // runtime-known
+    _ = &x;
+    const y = @shlExact(x, 2);
+    std.debug.print("value: {}\n", .{y});
+}
Shell
$ zig build-exe runtime_shlExact_overflow.zig
+$ ./runtime_shlExact_overflow
+thread 1084615 panic: left shift overflowed bits
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_shlExact_overflow.zig:6:5: 0x10de3b1 in main (runtime_shlExact_overflow)
+    const y = @shlExact(x, 2);
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddd62 in posixCallMainAndExit (runtime_shlExact_overflow)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd93d in _start (runtime_shlExact_overflow)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Exact Right Shift Overflow §

+ +

At compile-time:

+
test_comptime_shrExact_overflow.zig
comptime {
+    const x = @shrExact(@as(u8, 0b10101010), 2);
+    _ = x;
+}
Shell
$ zig test test_comptime_shrExact_overflow.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_shrExact_overflow.zig:2:15: error: exact shift shifted out 1 bits
+    const x = @shrExact(@as(u8, 0b10101010), 2);
+              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+ +

At runtime:

+
runtime_shrExact_overflow.zig
const std = @import("std");
+
+pub fn main() void {
+    var x: u8 = 0b10101010; // runtime-known
+    _ = &x;
+    const y = @shrExact(x, 2);
+    std.debug.print("value: {}\n", .{y});
+}
Shell
$ zig build-exe runtime_shrExact_overflow.zig
+$ ./runtime_shrExact_overflow
+thread 1085645 panic: right shift overflowed bits
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_shrExact_overflow.zig:6:5: 0x10de3ad in main (runtime_shrExact_overflow)
+    const y = @shrExact(x, 2);
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddd62 in posixCallMainAndExit (runtime_shrExact_overflow)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd93d in _start (runtime_shrExact_overflow)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Division by Zero §

+ +

At compile-time:

+
test_comptime_division_by_zero.zig
comptime {
+    const a: i32 = 1;
+    const b: i32 = 0;
+    const c = a / b;
+    _ = c;
+}
Shell
$ zig test test_comptime_division_by_zero.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_division_by_zero.zig:4:19: error: division by zero here causes undefined behavior
+    const c = a / b;
+                  ^
+
+
+ +

At runtime:

+
runtime_division_by_zero.zig
const std = @import("std");
+
+pub fn main() void {
+    var a: u32 = 1;
+    var b: u32 = 0;
+    _ = .{ &a, &b };
+    const c = a / b;
+    std.debug.print("value: {}\n", .{c});
+}
Shell
$ zig build-exe runtime_division_by_zero.zig
+$ ./runtime_division_by_zero
+thread 1080185 panic: division by zero
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_division_by_zero.zig:7:17: 0x10de2ea in main (runtime_division_by_zero)
+    const c = a / b;
+                ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddc92 in posixCallMainAndExit (runtime_division_by_zero)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd86d in _start (runtime_division_by_zero)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Remainder Division by Zero §

+ +

At compile-time:

+
test_comptime_remainder_division_by_zero.zig
comptime {
+    const a: i32 = 10;
+    const b: i32 = 0;
+    const c = a % b;
+    _ = c;
+}
Shell
$ zig test test_comptime_remainder_division_by_zero.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_remainder_division_by_zero.zig:4:19: error: division by zero here causes undefined behavior
+    const c = a % b;
+                  ^
+
+
+ +

At runtime:

+
runtime_remainder_division_by_zero.zig
const std = @import("std");
+
+pub fn main() void {
+    var a: u32 = 10;
+    var b: u32 = 0;
+    _ = .{ &a, &b };
+    const c = a % b;
+    std.debug.print("value: {}\n", .{c});
+}
Shell
$ zig build-exe runtime_remainder_division_by_zero.zig
+$ ./runtime_remainder_division_by_zero
+thread 1086160 panic: division by zero
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_remainder_division_by_zero.zig:7:17: 0x10de2ea in main (runtime_remainder_division_by_zero)
+    const c = a % b;
+                ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddc92 in posixCallMainAndExit (runtime_remainder_division_by_zero)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd86d in _start (runtime_remainder_division_by_zero)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Exact Division Remainder §

+ +

At compile-time:

+
test_comptime_divExact_remainder.zig
comptime {
+    const a: u32 = 10;
+    const b: u32 = 3;
+    const c = @divExact(a, b);
+    _ = c;
+}
Shell
$ zig test test_comptime_divExact_remainder.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_divExact_remainder.zig:4:15: error: exact division produced remainder
+    const c = @divExact(a, b);
+              ^~~~~~~~~~~~~~~
+
+
+ +

At runtime:

+
runtime_divExact_remainder.zig
const std = @import("std");
+
+pub fn main() void {
+    var a: u32 = 10;
+    var b: u32 = 3;
+    _ = .{ &a, &b };
+    const c = @divExact(a, b);
+    std.debug.print("value: {}\n", .{c});
+}
Shell
$ zig build-exe runtime_divExact_remainder.zig
+$ ./runtime_divExact_remainder
+thread 1079082 panic: exact division produced remainder
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_divExact_remainder.zig:7:15: 0x10de30b in main (runtime_divExact_remainder)
+    const c = @divExact(a, b);
+              ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddc92 in posixCallMainAndExit (runtime_divExact_remainder)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd86d in _start (runtime_divExact_remainder)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Attempt to Unwrap Null §

+ +

At compile-time:

+
test_comptime_unwrap_null.zig
comptime {
+    const optional_number: ?i32 = null;
+    const number = optional_number.?;
+    _ = number;
+}
Shell
$ zig test test_comptime_unwrap_null.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_unwrap_null.zig:3:35: error: unable to unwrap null
+    const number = optional_number.?;
+                   ~~~~~~~~~~~~~~~^~
+
+
+ +

At runtime:

+
runtime_unwrap_null.zig
const std = @import("std");
+
+pub fn main() void {
+    var optional_number: ?i32 = null;
+    _ = &optional_number;
+    const number = optional_number.?;
+    std.debug.print("value: {}\n", .{number});
+}
Shell
$ zig build-exe runtime_unwrap_null.zig
+$ ./runtime_unwrap_null
+thread 1081607 panic: attempt to use null value
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_unwrap_null.zig:6:35: 0x10de2d6 in main (runtime_unwrap_null)
+    const number = optional_number.?;
+                                  ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddc92 in posixCallMainAndExit (runtime_unwrap_null)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd86d in _start (runtime_unwrap_null)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ +

One way to avoid this crash is to test for null instead of assuming non-null, with + the if expression:

+
testing_null_with_if.zig
const print = @import("std").debug.print;
+pub fn main() void {
+    const optional_number: ?i32 = null;
+
+    if (optional_number) |number| {
+        print("got number: {}\n", .{number});
+    } else {
+        print("it's null\n", .{});
+    }
+}
Shell
$ zig build-exe testing_null_with_if.zig
+$ ./testing_null_with_if
+it's null
+
+ +

See also:

+ + +

Attempt to Unwrap Error §

+ +

At compile-time:

+
test_comptime_unwrap_error.zig
comptime {
+    const number = getNumberOrFail() catch unreachable;
+    _ = number;
+}
+
+fn getNumberOrFail() !i32 {
+    return error.UnableToReturnNumber;
+}
Shell
$ zig test test_comptime_unwrap_error.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_unwrap_error.zig:2:44: error: caught unexpected error 'UnableToReturnNumber'
+    const number = getNumberOrFail() catch unreachable;
+                                           ^~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_unwrap_error.zig:7:18: note: error returned here
+    return error.UnableToReturnNumber;
+                 ^~~~~~~~~~~~~~~~~~~~
+
+
+ +

At runtime:

+
runtime_unwrap_error.zig
const std = @import("std");
+
+pub fn main() void {
+    const number = getNumberOrFail() catch unreachable;
+    std.debug.print("value: {}\n", .{number});
+}
+
+fn getNumberOrFail() !i32 {
+    return error.UnableToReturnNumber;
+}
Shell
$ zig build-exe runtime_unwrap_error.zig
+$ ./runtime_unwrap_error
+thread 1082107 panic: attempt to unwrap error: UnableToReturnNumber
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_unwrap_error.zig:9:5: 0x10debaf in getNumberOrFail (runtime_unwrap_error)
+    return error.UnableToReturnNumber;
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_unwrap_error.zig:4:44: 0x10de341 in main (runtime_unwrap_error)
+    const number = getNumberOrFail() catch unreachable;
+                                           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddcf2 in posixCallMainAndExit (runtime_unwrap_error)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd8cd in _start (runtime_unwrap_error)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ +

One way to avoid this crash is to test for an error instead of assuming a successful result, with + the if expression:

+
testing_error_with_if.zig
const print = @import("std").debug.print;
+
+pub fn main() void {
+    const result = getNumberOrFail();
+
+    if (result) |number| {
+        print("got number: {}\n", .{number});
+    } else |err| {
+        print("got error: {s}\n", .{@errorName(err)});
+    }
+}
+
+fn getNumberOrFail() !i32 {
+    return error.UnableToReturnNumber;
+}
Shell
$ zig build-exe testing_error_with_if.zig
+$ ./testing_error_with_if
+got error: UnableToReturnNumber
+
+ +

See also:

+ + +

Invalid Error Code §

+ +

At compile-time:

+
test_comptime_invalid_error_code.zig
comptime {
+    const err = error.AnError;
+    const number = @intFromError(err) + 10;
+    const invalid_err = @errorFromInt(number);
+    _ = invalid_err;
+}
Shell
$ zig test test_comptime_invalid_error_code.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_error_code.zig:4:39: error: integer value '11' represents no error
+    const invalid_err = @errorFromInt(number);
+                                      ^~~~~~
+
+
+ +

At runtime:

+
runtime_invalid_error_code.zig
const std = @import("std");
+
+pub fn main() void {
+    const err = error.AnError;
+    var number = @intFromError(err) + 500;
+    _ = &number;
+    const invalid_err = @errorFromInt(number);
+    std.debug.print("value: {}\n", .{invalid_err});
+}
Shell
$ zig build-exe runtime_invalid_error_code.zig
+$ ./runtime_invalid_error_code
+thread 1086294 panic: invalid error code
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_invalid_error_code.zig:7:5: 0x10de396 in main (runtime_invalid_error_code)
+    const invalid_err = @errorFromInt(number);
+    ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddd22 in posixCallMainAndExit (runtime_invalid_error_code)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd8fd in _start (runtime_invalid_error_code)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Invalid Enum Cast §

+ +

At compile-time:

+
test_comptime_invalid_enum_cast.zig
const Foo = enum {
+    a,
+    b,
+    c,
+};
+comptime {
+    const a: u2 = 3;
+    const b: Foo = @enumFromInt(a);
+    _ = b;
+}
Shell
$ zig test test_comptime_invalid_enum_cast.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_enum_cast.zig:8:20: error: enum 'test_comptime_invalid_enum_cast.Foo' has no tag with value '3'
+    const b: Foo = @enumFromInt(a);
+                   ^~~~~~~~~~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_enum_cast.zig:1:13: note: enum declared here
+const Foo = enum {
+            ^~~~
+
+
+ +

At runtime:

+
runtime_invalid_enum_cast.zig
const std = @import("std");
+
+const Foo = enum {
+    a,
+    b,
+    c,
+};
+
+pub fn main() void {
+    var a: u2 = 3;
+    _ = &a;
+    const b: Foo = @enumFromInt(a);
+    std.debug.print("value: {s}\n", .{@tagName(b)});
+}
Shell
$ zig build-exe runtime_invalid_enum_cast.zig
+$ ./runtime_invalid_enum_cast
+thread 1081070 panic: invalid enum value
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_invalid_enum_cast.zig:12:20: 0x10de33a in main (runtime_invalid_enum_cast)
+    const b: Foo = @enumFromInt(a);
+                   ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddd12 in posixCallMainAndExit (runtime_invalid_enum_cast)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd8ed in _start (runtime_invalid_enum_cast)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + + +

Invalid Error Set Cast §

+ +

At compile-time:

+
test_comptime_invalid_error_set_cast.zig
const Set1 = error{
+    A,
+    B,
+};
+const Set2 = error{
+    A,
+    C,
+};
+comptime {
+    _ = @as(Set2, @errorCast(Set1.B));
+}
Shell
$ zig test test_comptime_invalid_error_set_cast.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_error_set_cast.zig:10:19: error: 'error.B' not a member of error set 'error{A,C}'
+    _ = @as(Set2, @errorCast(Set1.B));
+                  ^~~~~~~~~~~~~~~~~~
+
+
+ +

At runtime:

+
runtime_invalid_error_set_cast.zig
const std = @import("std");
+
+const Set1 = error{
+    A,
+    B,
+};
+const Set2 = error{
+    A,
+    C,
+};
+pub fn main() void {
+    foo(Set1.B);
+}
+fn foo(set1: Set1) void {
+    const x: Set2 = @errorCast(set1);
+    std.debug.print("value: {}\n", .{x});
+}
Shell
$ zig build-exe runtime_invalid_error_set_cast.zig
+$ ./runtime_invalid_error_set_cast
+thread 1085024 panic: invalid error code
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_invalid_error_set_cast.zig:15:21: 0x10dec2d in foo (runtime_invalid_error_set_cast)
+    const x: Set2 = @errorCast(set1);
+                    ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_invalid_error_set_cast.zig:12:8: 0x10de35c in main (runtime_invalid_error_set_cast)
+    foo(Set1.B);
+       ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddd42 in posixCallMainAndExit (runtime_invalid_error_set_cast)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd91d in _start (runtime_invalid_error_set_cast)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + + +

Incorrect Pointer Alignment §

+ +

At compile-time:

+
test_comptime_incorrect_pointer_alignment.zig
comptime {
+    const ptr: *align(1) i32 = @ptrFromInt(0x1);
+    const aligned: *align(4) i32 = @alignCast(ptr);
+    _ = aligned;
+}
Shell
$ zig test test_comptime_incorrect_pointer_alignment.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_incorrect_pointer_alignment.zig:3:47: error: pointer address 0x1 is not aligned to 4 bytes
+    const aligned: *align(4) i32 = @alignCast(ptr);
+                                              ^~~
+
+
+ +

At runtime:

+
runtime_incorrect_pointer_alignment.zig
const mem = @import("std").mem;
+pub fn main() !void {
+    var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
+    const bytes = mem.sliceAsBytes(array[0..]);
+    if (foo(bytes) != 0x11111111) return error.Wrong;
+}
+fn foo(bytes: []u8) u32 {
+    const slice4 = bytes[1..5];
+    const int_slice = mem.bytesAsSlice(u32, @as([]align(4) u8, @alignCast(slice4)));
+    return int_slice[0];
+}
Shell
$ zig build-exe runtime_incorrect_pointer_alignment.zig
+$ ./runtime_incorrect_pointer_alignment
+thread 1085556 panic: incorrect alignment
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_incorrect_pointer_alignment.zig:9:64: 0x10de0f2 in foo (runtime_incorrect_pointer_alignment)
+    const int_slice = mem.bytesAsSlice(u32, @as([]align(4) u8, @alignCast(slice4)));
+                                                               ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_incorrect_pointer_alignment.zig:5:12: 0x10ddfef in main (runtime_incorrect_pointer_alignment)
+    if (foo(bytes) != 0x11111111) return error.Wrong;
+           ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:660:37: 0x10ddeda in posixCallMainAndExit (runtime_incorrect_pointer_alignment)
+            const result = root.main() catch |err| {
+                                    ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dda8d in _start (runtime_incorrect_pointer_alignment)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + +

Wrong Union Field Access §

+ +

At compile-time:

+
test_comptime_wrong_union_field_access.zig
comptime {
+    var f = Foo{ .int = 42 };
+    f.float = 12.34;
+}
+
+const Foo = union {
+    float: f32,
+    int: u32,
+};
Shell
$ zig test test_comptime_wrong_union_field_access.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_wrong_union_field_access.zig:3:6: error: access of union field 'float' while field 'int' is active
+    f.float = 12.34;
+    ~^~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_wrong_union_field_access.zig:6:13: note: union declared here
+const Foo = union {
+            ^~~~~
+
+
+ +

At runtime:

+
runtime_wrong_union_field_access.zig
const std = @import("std");
+
+const Foo = union {
+    float: f32,
+    int: u32,
+};
+
+pub fn main() void {
+    var f = Foo{ .int = 42 };
+    bar(&f);
+}
+
+fn bar(f: *Foo) void {
+    f.float = 12.34;
+    std.debug.print("value: {}\n", .{f.float});
+}
Shell
$ zig build-exe runtime_wrong_union_field_access.zig
+$ ./runtime_wrong_union_field_access
+thread 1085377 panic: access of union field 'float' while field 'int' is active
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_wrong_union_field_access.zig:14:6: 0x10e43c8 in bar (runtime_wrong_union_field_access)
+    f.float = 12.34;
+     ^
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_wrong_union_field_access.zig:10:8: 0x10e3b1c in main (runtime_wrong_union_field_access)
+    bar(&f);
+       ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10e3502 in posixCallMainAndExit (runtime_wrong_union_field_access)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10e30dd in _start (runtime_wrong_union_field_access)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ +

+ This safety is not available for extern or packed unions. +

+

+ To change the active field of a union, assign the entire union, like this: +

+
change_active_union_field.zig
const std = @import("std");
+
+const Foo = union {
+    float: f32,
+    int: u32,
+};
+
+pub fn main() void {
+    var f = Foo{ .int = 42 };
+    bar(&f);
+}
+
+fn bar(f: *Foo) void {
+    f.* = Foo{ .float = 12.34 };
+    std.debug.print("value: {}\n", .{f.float});
+}
Shell
$ zig build-exe change_active_union_field.zig
+$ ./change_active_union_field
+value: 1.234e1
+
+ +

+ To change the active field of a union when a meaningful value for the field is not known, + use undefined, like this: +

+
undefined_active_union_field.zig
const std = @import("std");
+
+const Foo = union {
+    float: f32,
+    int: u32,
+};
+
+pub fn main() void {
+    var f = Foo{ .int = 42 };
+    f = Foo{ .float = undefined };
+    bar(&f);
+    std.debug.print("value: {}\n", .{f.float});
+}
+
+fn bar(f: *Foo) void {
+    f.float = 12.34;
+}
Shell
$ zig build-exe undefined_active_union_field.zig
+$ ./undefined_active_union_field
+value: 1.234e1
+
+ +

See also:

+ + + +

Out of Bounds Float to Integer Cast §

+ +

+ This happens when casting a float to an integer where the float has a value outside the + integer type's range. +

+

At compile-time:

+
test_comptime_out_of_bounds_float_to_integer_cast.zig
comptime {
+    const float: f32 = 4294967296;
+    const int: i32 = @intFromFloat(float);
+    _ = int;
+}
Shell
$ zig test test_comptime_out_of_bounds_float_to_integer_cast.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_out_of_bounds_float_to_integer_cast.zig:3:36: error: float value '4294967296' cannot be stored in integer type 'i32'
+    const int: i32 = @intFromFloat(float);
+                                   ^~~~~
+
+
+ +

At runtime:

+
runtime_out_of_bounds_float_to_integer_cast.zig
pub fn main() void {
+    var float: f32 = 4294967296; // runtime-known
+    _ = &float;
+    const int: i32 = @intFromFloat(float);
+    _ = int;
+}
Shell
$ zig build-exe runtime_out_of_bounds_float_to_integer_cast.zig
+$ ./runtime_out_of_bounds_float_to_integer_cast
+thread 1086034 panic: integer part of floating point value out of bounds
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_out_of_bounds_float_to_integer_cast.zig:4:22: 0x10de229 in main (runtime_out_of_bounds_float_to_integer_cast)
+    const int: i32 = @intFromFloat(float);
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddbc2 in posixCallMainAndExit (runtime_out_of_bounds_float_to_integer_cast)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd79d in _start (runtime_out_of_bounds_float_to_integer_cast)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + + +

Pointer Cast Invalid Null §

+ +

+ This happens when casting a pointer with the address 0 to a pointer which may not have the address 0. + For example, C Pointers, Optional Pointers, and allowzero pointers + allow address zero, but normal Pointers do not. +

+

At compile-time:

+
test_comptime_invalid_null_pointer_cast.zig
comptime {
+    const opt_ptr: ?*i32 = null;
+    const ptr: *i32 = @ptrCast(opt_ptr);
+    _ = ptr;
+}
Shell
$ zig test test_comptime_invalid_null_pointer_cast.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_null_pointer_cast.zig:3:32: error: null pointer casted to type '*i32'
+    const ptr: *i32 = @ptrCast(opt_ptr);
+                               ^~~~~~~
+
+
+ +

At runtime:

+
runtime_invalid_null_pointer_cast.zig
pub fn main() void {
+    var opt_ptr: ?*i32 = null;
+    _ = &opt_ptr;
+    const ptr: *i32 = @ptrCast(opt_ptr);
+    _ = ptr;
+}
Shell
$ zig build-exe runtime_invalid_null_pointer_cast.zig
+$ ./runtime_invalid_null_pointer_cast
+thread 1084319 panic: cast causes pointer to be null
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/runtime_invalid_null_pointer_cast.zig:4:23: 0x10de19c in main (runtime_invalid_null_pointer_cast)
+    const ptr: *i32 = @ptrCast(opt_ptr);
+                      ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:651:22: 0x10ddb62 in posixCallMainAndExit (runtime_invalid_null_pointer_cast)
+            root.main();
+                     ^
+/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:271:5: 0x10dd73d in _start (runtime_invalid_null_pointer_cast)
+    asm volatile (switch (native_arch) {
+    ^
+???:?:?: 0x0 in ??? (???)
+(process terminated by signal)
+
+ + + + +

Memory §

+ +

+ The Zig language performs no memory management on behalf of the programmer. This is + why Zig has no runtime, and why Zig code works seamlessly in so many environments, + including real-time software, operating system kernels, embedded devices, and + low latency servers. As a consequence, Zig programmers must always be able to answer + the question: +

+

Where are the bytes?

+

+ Like Zig, the C programming language has manual memory management. However, unlike Zig, + C has a default allocator - malloc, realloc, and free. + When linking against libc, Zig exposes this allocator with std.heap.c_allocator. + However, by convention, there is no default allocator in Zig. Instead, functions which need to + allocate accept an Allocator parameter. Likewise, data structures such as + std.ArrayList accept an Allocator parameter in + their initialization functions: +

+
test_allocator.zig
const std = @import("std");
+const Allocator = std.mem.Allocator;
+const expect = std.testing.expect;
+
+test "using an allocator" {
+    var buffer: [100]u8 = undefined;
+    var fba = std.heap.FixedBufferAllocator.init(&buffer);
+    const allocator = fba.allocator();
+    const result = try concat(allocator, "foo", "bar");
+    try expect(std.mem.eql(u8, "foobar", result));
+}
+
+fn concat(allocator: Allocator, a: []const u8, b: []const u8) ![]u8 {
+    const result = try allocator.alloc(u8, a.len + b.len);
+    @memcpy(result[0..a.len], a);
+    @memcpy(result[a.len..], b);
+    return result;
+}
Shell
$ zig test test_allocator.zig
+1/1 test_allocator.test.using an allocator...OK
+All 1 tests passed.
+
+ +

+ In the above example, 100 bytes of stack memory are used to initialize a + FixedBufferAllocator, which is then passed to a function. + As a convenience there is a global FixedBufferAllocator + available for quick tests at std.testing.allocator, + which will also perform basic leak detection. +

+

+ Zig has a general purpose allocator available to be imported + with std.heap.GeneralPurposeAllocator. However, it is still recommended to + follow the Choosing an Allocator guide. +

+ +

Choosing an Allocator §

+ +

What allocator to use depends on a number of factors. Here is a flow chart to help you decide: +

+
    +
  1. + Are you making a library? In this case, best to accept an Allocator + as a parameter and allow your library's users to decide what allocator to use. +
  2. +
  3. Are you linking libc? In this case, std.heap.c_allocator is likely + the right choice, at least for your main allocator.
  4. +
  5. + Need to use the same allocator in multiple threads? Use one of your choice + wrapped around std.heap.ThreadSafeAllocator +
  6. +
  7. + Is the maximum number of bytes that you will need bounded by a number known at + comptime? In this case, use std.heap.FixedBufferAllocator. +
  8. +
  9. + Is your program a command line application which runs from start to end without any fundamental + cyclical pattern (such as a video game main loop, or a web server request handler), + such that it would make sense to free everything at once at the end? + In this case, it is recommended to follow this pattern: +
    cli_allocation.zig
    const std = @import("std");
    +
    +pub fn main() !void {
    +    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    +    defer arena.deinit();
    +
    +    const allocator = arena.allocator();
    +
    +    const ptr = try allocator.create(i32);
    +    std.debug.print("ptr={*}\n", .{ptr});
    +}
    Shell
    $ zig build-exe cli_allocation.zig
    +$ ./cli_allocation
    +ptr=i32@7f8c0f09d010
    +
    + + When using this kind of allocator, there is no need to free anything manually. Everything + gets freed at once with the call to arena.deinit(). +
  10. +
  11. + Are the allocations part of a cyclical pattern such as a video game main loop, or a web + server request handler? If the allocations can all be freed at once, at the end of the cycle, + for example once the video game frame has been fully rendered, or the web server request has + been served, then std.heap.ArenaAllocator is a great candidate. As + demonstrated in the previous bullet point, this allows you to free entire arenas at once. + Note also that if an upper bound of memory can be established, then + std.heap.FixedBufferAllocator can be used as a further optimization. +
  12. +
  13. + Are you writing a test, and you want to make sure error.OutOfMemory + is handled correctly? In this case, use std.testing.FailingAllocator. +
  14. +
  15. + Are you writing a test? In this case, use std.testing.allocator. +
  16. +
  17. + Finally, if none of the above apply, you need a general purpose allocator. + Zig's general purpose allocator is available as a function that takes a comptime + struct of configuration options and returns a type. + Generally, you will set up one std.heap.GeneralPurposeAllocator in + your main function, and then pass it or sub-allocators around to various parts of your + application. +
  18. +
  19. + You can also consider Implementing an Allocator. +
  20. +
+ + +

Where are the bytes? §

+ +

String literals such as "hello" are in the global constant data section. + This is why it is an error to pass a string literal to a mutable slice, like this: +

+
test_string_literal_to_slice.zig
fn foo(s: []u8) void {
+    _ = s;
+}
+
+test "string literal to mutable slice" {
+    foo("hello");
+}
Shell
$ zig test test_string_literal_to_slice.zig
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_string_literal_to_slice.zig:6:9: error: expected type '[]u8', found '*const [5:0]u8'
+    foo("hello");
+        ^~~~~~~
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_string_literal_to_slice.zig:6:9: note: cast discards const qualifier
+/home/ci/actions-runner/_work/zig-bootstrap/zig/doc/langref/test_string_literal_to_slice.zig:1:11: note: parameter type declared here
+fn foo(s: []u8) void {
+          ^~~~
+
+
+ +

However if you make the slice constant, then it works:

+
test_string_literal_to_const_slice.zig
fn foo(s: []const u8) void {
+    _ = s;
+}
+
+test "string literal to constant slice" {
+    foo("hello");
+}
Shell
$ zig test test_string_literal_to_const_slice.zig
+1/1 test_string_literal_to_const_slice.test.string literal to constant slice...OK
+All 1 tests passed.
+
+ +

+ Just like string literals, const declarations, when the value is known at comptime, + are stored in the global constant data section. Also Compile Time Variables are stored + in the global constant data section. +

+

+ var declarations inside functions are stored in the function's stack frame. Once a function returns, + any Pointers to variables in the function's stack frame become invalid references, and + dereferencing them becomes unchecked Illegal Behavior. +

+

+ var declarations at the top level or in struct declarations are stored in the global + data section. +

+

+ The location of memory allocated with allocator.alloc or + allocator.create is determined by the allocator's implementation. +

+

TODO: thread local variables

+ + +

Implementing an Allocator §

+ +

Zig programmers can implement their own allocators by fulfilling the Allocator interface. + In order to do this one must read carefully the documentation comments in std/mem.zig and + then supply a allocFn and a resizeFn. +

+

+ There are many example allocators to look at for inspiration. Look at std/heap.zig and + std.heap.GeneralPurposeAllocator. +

+ + +

Heap Allocation Failure §

+ +

+ Many programming languages choose to handle the possibility of heap allocation failure by + unconditionally crashing. By convention, Zig programmers do not consider this to be a + satisfactory solution. Instead, error.OutOfMemory represents + heap allocation failure, and Zig libraries return this error code whenever heap allocation + failure prevented an operation from completing successfully. +

+

+ Some have argued that because some operating systems such as Linux have memory overcommit enabled by + default, it is pointless to handle heap allocation failure. There are many problems with this reasoning: +

+
    +
  • Only some operating systems have an overcommit feature. +
      +
    • Linux has it enabled by default, but it is configurable.
    • +
    • Windows does not overcommit.
    • +
    • Embedded systems do not have overcommit.
    • +
    • Hobby operating systems may or may not have overcommit.
    • +
    +
  • +
  • + For real-time systems, not only is there no overcommit, but typically the maximum amount + of memory per application is determined ahead of time. +
  • +
  • + When writing a library, one of the main goals is code reuse. By making code handle + allocation failure correctly, a library becomes eligible to be reused in + more contexts. +
  • +
  • + Although some software has grown to depend on overcommit being enabled, its existence + is the source of countless user experience disasters. When a system with overcommit enabled, + such as Linux on default settings, comes close to memory exhaustion, the system locks up + and becomes unusable. At this point, the OOM Killer selects an application to kill + based on heuristics. This non-deterministic decision often results in an important process + being killed, and often fails to return the system back to working order. +
  • +
+ + +

Recursion §

+ +

+ Recursion is a fundamental tool in modeling software. However it has an often-overlooked problem: + unbounded memory allocation. +

+

+ Recursion is an area of active experimentation in Zig and so the documentation here is not final. + You can read a + summary of recursion status in the 0.3.0 release notes. +

+

+ The short summary is that currently recursion works normally as you would expect. Although Zig code + is not yet protected from stack overflow, it is planned that a future version of Zig will provide + such protection, with some degree of cooperation from Zig code required. +

+ + +

Lifetime and Ownership §

+ +

+ It is the Zig programmer's responsibility to ensure that a pointer is not + accessed when the memory pointed to is no longer available. Note that a slice + is a form of pointer, in that it references other memory. +

+

+ In order to prevent bugs, there are some helpful conventions to follow when dealing with pointers. + In general, when a function returns a pointer, the documentation for the function should explain + who "owns" the pointer. This concept helps the programmer decide when it is appropriate, if ever, + to free the pointer. +

+

+ For example, the function's documentation may say "caller owns the returned memory", in which case + the code that calls the function must have a plan for when to free that memory. Probably in this situation, + the function will accept an Allocator parameter. +

+

+ Sometimes the lifetime of a pointer may be more complicated. For example, the + std.ArrayList(T).items slice has a lifetime that remains + valid until the next time the list is resized, such as by appending new elements. +

+

+ The API documentation for functions and data structures should take great care to explain + the ownership and lifetime semantics of pointers. Ownership determines whose responsibility it + is to free the memory referenced by the pointer, and lifetime determines the point at which + the memory becomes inaccessible (lest Illegal Behavior occur). +

+ + + +

Compile Variables §

+ +

+ Compile variables are accessible by importing the "builtin" package, + which the compiler makes available to every Zig source file. It contains + compile-time constants such as the current target, endianness, and release mode. +

+
compile_variables.zig
const builtin = @import("builtin");
+const separator = if (builtin.os.tag == .windows) '\\' else '/';
+ +

+ Example of what is imported with @import("builtin"): +

+
@import("builtin")
const std = @import("std");
+/// Zig version. When writing code that supports multiple versions of Zig, prefer
+/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
+pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable;
+pub const zig_version_string = "0.14.1";
+pub const zig_backend = std.builtin.CompilerBackend.stage2_llvm;
+
+pub const output_mode: std.builtin.OutputMode = .Exe;
+pub const link_mode: std.builtin.LinkMode = .static;
+pub const unwind_tables: std.builtin.UnwindTables = .@"async";
+pub const is_test = false;
+pub const single_threaded = false;
+pub const abi: std.Target.Abi = .gnu;
+pub const cpu: std.Target.Cpu = .{
+    .arch = .x86_64,
+    .model = &std.Target.x86.cpu.znver2,
+    .features = std.Target.x86.featureSet(&.{
+        .@"64bit",
+        .adx,
+        .aes,
+        .allow_light_256_bit,
+        .avx,
+        .avx2,
+        .bmi,
+        .bmi2,
+        .branchfusion,
+        .clflushopt,
+        .clwb,
+        .clzero,
+        .cmov,
+        .crc32,
+        .cx16,
+        .cx8,
+        .f16c,
+        .fast_15bytenop,
+        .fast_bextr,
+        .fast_imm16,
+        .fast_lzcnt,
+        .fast_movbe,
+        .fast_scalar_fsqrt,
+        .fast_scalar_shift_masks,
+        .fast_variable_perlane_shuffle,
+        .fast_vector_fsqrt,
+        .fma,
+        .fsgsbase,
+        .fxsr,
+        .idivq_to_divl,
+        .lzcnt,
+        .mmx,
+        .movbe,
+        .mwaitx,
+        .nopl,
+        .pclmul,
+        .popcnt,
+        .prfchw,
+        .rdpid,
+        .rdpru,
+        .rdrnd,
+        .rdseed,
+        .sahf,
+        .sbb_dep_breaking,
+        .sha,
+        .slow_shld,
+        .smap,
+        .smep,
+        .sse,
+        .sse2,
+        .sse3,
+        .sse4_1,
+        .sse4_2,
+        .sse4a,
+        .ssse3,
+        .vzeroupper,
+        .wbnoinvd,
+        .x87,
+        .xsave,
+        .xsavec,
+        .xsaveopt,
+        .xsaves,
+    }),
+};
+pub const os: std.Target.Os = .{
+    .tag = .linux,
+    .version_range = .{ .linux = .{
+        .range = .{
+            .min = .{
+                .major = 5,
+                .minor = 10,
+                .patch = 0,
+            },
+            .max = .{
+                .major = 5,
+                .minor = 10,
+                .patch = 0,
+            },
+        },
+        .glibc = .{
+            .major = 2,
+            .minor = 31,
+            .patch = 0,
+        },
+        .android = 14,
+    }},
+};
+pub const target: std.Target = .{
+    .cpu = cpu,
+    .os = os,
+    .abi = abi,
+    .ofmt = object_format,
+    .dynamic_linker = .init("/lib64/ld-linux-x86-64.so.2"),
+};
+pub const object_format: std.Target.ObjectFormat = .elf;
+pub const mode: std.builtin.OptimizeMode = .Debug;
+pub const link_libc = false;
+pub const link_libcpp = false;
+pub const have_error_return_tracing = true;
+pub const valgrind_support = true;
+pub const sanitize_thread = false;
+pub const fuzz = false;
+pub const position_independent_code = false;
+pub const position_independent_executable = false;
+pub const strip_debug_info = false;
+pub const code_model: std.builtin.CodeModel = .default;
+pub const omit_frame_pointer = false;
+

See also:

+ + +

Compilation Model §

+ +

+ A Zig compilation is separated into modules. Each module is a collection of Zig source files, + one of which is the module's root source file. Each module can depend on any number of + other modules, forming a directed graph (dependency loops between modules are allowed). If module A + depends on module B, then any Zig source file in module A can import the root source file of + module B using @import with the module's name. In essence, a module acts as an + alias to import a Zig source file (which might exist in a completely separate part of the filesystem). +

+

+ A simple Zig program compiled with zig build-exe has two key modules: the one containing your + code, known as the "main" or "root" module, and the standard library. Your module depends on + the standard library module under the name "std", which is what allows you to write + @import("std")! In fact, every single module in a Zig compilation — including + the standard library itself — implicitly depends on the standard library module under the name "std". +

+

+ The "root module" (the one provided by you in the zig build-exe example) has a special + property. Like the standard library, it is implicitly made available to all modules (including itself), + this time under the name "root". So, @import("root") will always be equivalent to + @import of your "main" source file (often, but not necessarily, named + main.zig). +

+

Source File Structs §

+ +

+ Every Zig source file is implicitly a struct declaration; you can imagine that + the file's contents are literally surrounded by struct { ... }. This means that + as well as declarations, the top level of a file is permitted to contain fields: +

+
TopLevelFields.zig
//! Because this file contains fields, it is a type which is intended to be instantiated, and so
+//! is named in TitleCase instead of snake_case by convention.
+
+foo: u32,
+bar: u64,
+
+/// `@This()` can be used to refer to this struct type. In files with fields, it is quite common to
+/// name the type here, so it can be easily referenced by other declarations in this file.
+const TopLevelFields = @This();
+
+pub fn init(val: u32) TopLevelFields {
+    return .{
+        .foo = val,
+        .bar = val * 10,
+    };
+}
+

+ Such files can be instantiated just like any other struct type. A file's "root + struct type" can be referred to within that file using @This. +

+ +

File and Declaration Discovery §

+ +

+ Zig places importance on the concept of whether any piece of code is semantically analyzed; in + essence, whether the compiler "looks at" it. What code is analyzed is based on what files and + declarations are "discovered" from a certain point. This process of "discovery" is based on a simple set + of recursive rules: +

+
    +
  • If a call to @import is analyzed, the file being imported is analyzed.
  • +
  • If a type (including a file) is analyzed, all comptime, usingnamespace, and export declarations within it are analyzed.
  • +
  • If a type (including a file) is analyzed, and the compilation is for a test, and the module the type is within is the root module of the compilation, then all test declarations within it are also analyzed.
  • +
  • If a reference to a named declaration (i.e. a usage of it) is analyzed, the declaration being referenced is analyzed. Declarations are order-independent, so this reference may be above or below the declaration being referenced, or even in another file entirely.
  • +
+

+ That's it! Those rules define how Zig files and declarations are discovered. All that remains is to + understand where this process starts. +

+

+ The answer to that is the root of the standard library: every Zig compilation begins by analyzing the + file lib/std/std.zig. This file contains a comptime declaration + which imports lib/std/start.zig, and that file in turn uses + @import("root") to reference the "root module"; so, the file you provide as your + main module's root source file is effectively also a root, because the standard library will always + reference it. +

+

+ It is often desirable to make sure that certain declarations — particularly test + or export declarations — are discovered. Based on the above rules, a common + strategy for this is to use @import within a comptime or + test block: +

+
force_file_discovery.zig
comptime {
+    // This will ensure that the file 'api.zig' is always discovered (as long as this file is discovered).
+    // It is useful if 'api.zig' contains important exported declarations.
+    _ = @import("api.zig");
+
+    // We could also have a file which contains declarations we only want to export depending on a comptime
+    // condition. In that case, we can use an `if` statement here:
+    if (builtin.os.tag == .windows) {
+        _ = @import("windows_api.zig");
+    }
+}
+
+test {
+    // This will ensure that the file 'tests.zig' is always discovered (as long as this file is discovered),
+    // if this compilation is a test. It is useful if 'tests.zig' contains tests we want to ensure are run.
+    _ = @import("tests.zig");
+
+    // We could also have a file which contains tests we only want to run depending on a comptime condition.
+    // In that case, we can use an `if` statement here:
+    if (builtin.os.tag == .windows) {
+        _ = @import("windows_tests.zig");
+    }
+}
+
+const builtin = @import("builtin");
+ +

Special Root Declarations §

+ +

+ Because the root module's root source file is always accessible using + @import("root"), is is sometimes used by libraries — including the Zig Standard + Library — as a place for the program to expose some "global" information to that library. The Zig + Standard Library will look for several declarations in this file. +

+

Entry Point §

+ +

+ When building an executable, the most important thing to be looked up in this file is the program's + entry point. Most commonly, this is a function named main, which + std.start will call just after performing important initialization work. +

+

+ Alternatively, the presence of a declaration named _start (for instance, + pub const _start = {};) will disable the default std.start + logic, allowing your root source file to export a low-level entry point as needed. +

+
entry_point.zig
/// `std.start` imports this file using `@import("root")`, and uses this declaration as the program's
+/// user-provided entry point. It can return any of the following types:
+/// * `void`
+/// * `E!void`, for any error set `E`
+/// * `u8`
+/// * `E!u8`, for any error set `E`
+/// Returning a `void` value from this function will exit with code 0.
+/// Returning a `u8` value from this function will exit with the given status code.
+/// Returning an error value from this function will print an Error Return Trace and exit with code 1.
+pub fn main() void {
+    std.debug.print("Hello, World!\n", .{});
+}
+
+// If uncommented, this declaration would suppress the usual std.start logic, causing
+// the `main` declaration above to be ignored.
+//pub const _start = {};
+
+const std = @import("std");
Shell
$ zig build-exe entry_point.zig
+$ ./entry_point
+Hello, World!
+
+

+ If the Zig compilation links libc, the main function can optionally be an + export fn which matches the signature of the C main function: +

+
libc_export_entry_point.zig
pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int {
+    const args = argv[0..@intCast(argc)];
+    std.debug.print("Hello! argv[0] is '{s}'\n", .{args[0]});
+    return 0;
+}
+
+const std = @import("std");
Shell
$ zig build-exe libc_export_entry_point.zig -lc
+$ ./libc_export_entry_point
+Hello! argv[0] is './libc_export_entry_point'
+
+

+ std.start may also use other entry point declarations in certain situations, such + as wWinMain or EfiMain. Refer to the + lib/std/start.zig logic for details of these declarations. +

+ +

Standard Library Options §

+ +

+ The standard library also looks for a declaration in the root module's root source file named + std_options. If present, this declaration is expected to be a struct of type + std.Options, and allows the program to customize some standard library + functionality, such as the std.log implementation. +

+
std_options.zig
/// The presence of this declaration allows the program to override certain behaviors of the standard library.
+/// For a full list of available options, see the documentation for `std.Options`.
+pub const std_options: std.Options = .{
+    // By default, in safe build modes, the standard library will attach a segfault handler to the program to
+    // print a helpful stack trace if a segmentation fault occurs. Here, we can disable this, or even enable
+    // it in unsafe build modes.
+    .enable_segfault_handler = true,
+    // This is the logging function used by `std.log`.
+    .logFn = myLogFn,
+};
+
+fn myLogFn(
+    comptime level: std.log.Level,
+    comptime scope: @Type(.enum_literal),
+    comptime format: []const u8,
+    args: anytype,
+) void {
+    // We could do anything we want here!
+    // ...but actually, let's just call the default implementation.
+    std.log.defaultLog(level, scope, format, args);
+}
+
+const std = @import("std");
+ +

Panic Handler §

+ +

+ The Zig Standard Library looks for a declaration named panic in the root module's + root source file. If present, it is expected to be a namespace (container type) with declarations + providing different panic handlers. +

+

+ See std.debug.simple_panic for a basic implementation of this namespace. +

+

+ Overriding how the panic handler actually outputs messages, but keeping the formatted safety panics + which are enabled by default, can be easily achieved with std.debug.FullPanic: +

+
panic_handler.zig
pub fn main() void {
+    @setRuntimeSafety(true);
+    var x: u8 = 255;
+    // Let's overflow this integer!
+    x += 1;
+}
+
+pub const panic = std.debug.FullPanic(myPanic);
+
+fn myPanic(msg: []const u8, first_trace_addr: ?usize) noreturn {
+    _ = first_trace_addr;
+    std.debug.print("Panic! {s}\n", .{msg});
+    std.process.exit(1);
+}
+
+const std = @import("std");
Shell
$ zig build-exe panic_handler.zig
+$ ./panic_handler
+Panic! integer overflow
+
+ + + +

Zig Build System §

+ +

+ The Zig Build System provides a cross-platform, dependency-free way to declare + the logic required to build a project. With this system, the logic to build + a project is written in a build.zig file, using the Zig Build System API to + declare and configure build artifacts and other tasks. +

+

+ Some examples of tasks the build system can help with: +

+
    +
  • Performing tasks in parallel and caching the results.
  • +
  • Depending on other projects.
  • +
  • Providing a package for other projects to depend on.
  • +
  • Creating build artifacts by executing the Zig compiler. This includes + building Zig source code as well as C and C++ source code.
  • +
  • Capturing user-configured options and using those options to configure + the build.
  • +
  • Surfacing build configuration as comptime values by providing a + file that can be imported by Zig code.
  • +
  • Caching build artifacts to avoid unnecessarily repeating steps.
  • +
  • Executing build artifacts or system-installed tools.
  • +
  • Running tests and verifying the output of executing a build artifact matches + the expected value.
  • +
  • Running zig fmt on a codebase or a subset of it.
  • +
  • Custom tasks.
  • +
+

+ To use the build system, run zig build --help + to see a command-line usage help menu. This will include project-specific + options that were declared in the build.zig script. +

+

+ For the time being, the build system documentation is hosted externally: + Build System Documentation +

+ +

C §

+ +

+ Although Zig is independent of C, and, unlike most other languages, does not depend on libc, + Zig acknowledges the importance of interacting with existing C code. +

+

+ There are a few ways that Zig facilitates C interop. +

+

C Type Primitives §

+ +

+ These have guaranteed C ABI compatibility and can be used like any other type. +

+
    +
  • c_char
  • +
  • c_short
  • +
  • c_ushort
  • +
  • c_int
  • +
  • c_uint
  • +
  • c_long
  • +
  • c_ulong
  • +
  • c_longlong
  • +
  • c_ulonglong
  • +
  • c_longdouble
  • +
+

+ To interop with the C void type, use anyopaque. +

+

See also:

+ + +

Import from C Header File §

+ +

+ The @cImport builtin function can be used + to directly import symbols from .h files: +

+
cImport_builtin.zig
const c = @cImport({
+    // See https://github.com/ziglang/zig/issues/515
+    @cDefine("_NO_CRT_STDIO_INLINE", "1");
+    @cInclude("stdio.h");
+});
+pub fn main() void {
+    _ = c.printf("hello\n");
+}
Shell
$ zig build-exe cImport_builtin.zig -lc
+$ ./cImport_builtin
+hello
+
+ +

+ The @cImport function takes an expression as a parameter. + This expression is evaluated at compile-time and is used to control + preprocessor directives and include multiple .h files: +

+
@cImport Expression
const builtin = @import("builtin");
+
+const c = @cImport({
+    @cDefine("NDEBUG", builtin.mode == .ReleaseFast);
+    if (something) {
+        @cDefine("_GNU_SOURCE", {});
+    }
+    @cInclude("stdlib.h");
+    if (something) {
+        @cUndef("_GNU_SOURCE");
+    }
+    @cInclude("soundio.h");
+});
+

See also:

+ + + +

C Translation CLI §

+ +

+ Zig's C translation capability is available as a CLI tool via zig translate-c. + It requires a single filename as an argument. It may also take a set of optional flags that are + forwarded to clang. It writes the translated file to stdout. +

+

Command line flags §

+ +
    +
  • + -I: + Specify a search directory for include files. May be used multiple times. Equivalent to + + clang's -I flag. The current directory is not included by default; + use -I. to include it. +
  • +
  • + -D: Define a preprocessor macro. Equivalent to + + clang's -D flag. +
  • +
  • + -cflags [flags] --: Pass arbitrary additional + command line + flags to clang. Note: the list of flags must end with -- +
  • +
  • + -target: The target triple for the translated Zig code. + If no target is specified, the current host target will be used. +
  • +
+ +

Using -target and -cflags §

+ +

+ Important! When translating C code with zig translate-c, + you must use the same -target triple that you will use when compiling + the translated code. In addition, you must ensure that the -cflags used, + if any, match the cflags used by code on the target system. Using the incorrect -target + or -cflags could result in clang or Zig parse failures, or subtle ABI incompatibilities + when linking with C code. +

+
varytarget.h
long FOO = __LONG_MAX__;
+
Shell
$ zig translate-c -target thumb-freestanding-gnueabihf varytarget.h|grep FOO
+pub export var FOO: c_long = 2147483647;
+$ zig translate-c -target x86_64-macos-gnu varytarget.h|grep FOO
+pub export var FOO: c_long = 9223372036854775807;
+
+
varycflags.h
enum FOO { BAR };
+int do_something(enum FOO foo);
+
Shell
$ zig translate-c varycflags.h|grep -B1 do_something
+pub const enum_FOO = c_uint;
+pub extern fn do_something(foo: enum_FOO) c_int;
+$ zig translate-c -cflags -fshort-enums -- varycflags.h|grep -B1 do_something
+pub const enum_FOO = u8;
+pub extern fn do_something(foo: enum_FOO) c_int;
+
+ +

@cImport vs translate-c §

+ +

@cImport and zig translate-c use the same underlying + C translation functionality, so on a technical level they are equivalent. In practice, + @cImport is useful as a way to quickly and easily access numeric constants, typedefs, + and record types without needing any extra setup. If you need to pass cflags + to clang, or if you would like to edit the translated code, it is recommended to use + zig translate-c and save the results to a file. Common reasons for editing + the generated code include: changing anytype parameters in function-like macros to more + specific types; changing [*c]T pointers to [*]T or + *T pointers for improved type safety; and + enabling or disabling runtime safety within specific functions. +

+ +

See also:

+ + +

C Translation Caching §

+ +

+ The C translation feature (whether used via zig translate-c or + @cImport) integrates with the Zig caching system. Subsequent runs with + the same source file, target, and cflags will use the cache instead of repeatedly translating + the same code. +

+

+ To see where the cached files are stored when compiling code that uses @cImport, + use the --verbose-cimport flag: +

+
verbose_cimport_flag.zig
const c = @cImport({
+    @cDefine("_NO_CRT_STDIO_INLINE", "1");
+    @cInclude("stdio.h");
+});
+pub fn main() void {
+    _ = c;
+}
Shell
$ zig build-exe verbose_cimport_flag.zig -lc --verbose-cimport
+$ ./verbose_cimport_flag
+
+ +

+ cimport.h contains the file to translate (constructed from calls to + @cInclude, @cDefine, and @cUndef), + cimport.h.d is the list of file dependencies, and + cimport.zig contains the translated output. +

+

See also:

+ + +

Translation failures §

+ +

+ Some C constructs cannot be translated to Zig - for example, goto, + structs with bitfields, and token-pasting macros. Zig employs demotion to allow translation + to continue in the face of non-translatable entities. +

+

+ Demotion comes in three varieties - opaque, extern, and + @compileError. + + C structs and unions that cannot be translated correctly will be translated as opaque{}. + Functions that contain opaque types or code constructs that cannot be translated will be demoted + to extern declarations. + + Thus, non-translatable types can still be used as pointers, and non-translatable functions + can be called so long as the linker is aware of the compiled function. +

+

+ @compileError is used when top-level definitions (global variables, + function prototypes, macros) cannot be translated or demoted. Since Zig uses lazy analysis for + top-level declarations, untranslatable entities will not cause a compile error in your code unless + you actually use them. +

+

See also:

+ + +

C Macros §

+ +

+ C Translation makes a best-effort attempt to translate function-like macros into equivalent + Zig functions. Since C macros operate at the level of lexical tokens, not all C macros + can be translated to Zig. Macros that cannot be translated will be demoted to + @compileError. Note that C code which uses macros will be + translated without any additional issues (since Zig operates on the pre-processed source + with macros expanded). It is merely the macros themselves which may not be translatable to + Zig. +

+

Consider the following example:

+
macro.c
#define MAKELOCAL(NAME, INIT) int NAME = INIT
+int foo(void) {
+   MAKELOCAL(a, 1);
+   MAKELOCAL(b, 2);
+   return a + b;
+}
+
Shell
$ zig translate-c macro.c > macro.zig
+
+
macro.zig
pub export fn foo() c_int {
+    var a: c_int = 1;
+    _ = &a;
+    var b: c_int = 2;
+    _ = &b;
+    return a + b;
+}
+pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected token .Equal"); // macro.c:1:9
+ +

Note that foo was translated correctly despite using a non-translatable + macro. MAKELOCAL was demoted to @compileError since + it cannot be expressed as a Zig function; this simply means that you cannot directly use + MAKELOCAL from Zig. +

+

See also:

+ + + +

C Pointers §

+ +

+ This type is to be avoided whenever possible. The only valid reason for using a C pointer is in + auto-generated code from translating C code. +

+

+ When importing C header files, it is ambiguous whether pointers should be translated as + single-item pointers (*T) or many-item pointers ([*]T). + C pointers are a compromise so that Zig code can utilize translated header files directly. +

+

[*c]T - C pointer.

+
    +
  • Supports all the syntax of the other two pointer types (*T) and ([*]T).
  • +
  • Coerces to other pointer types, as well as Optional Pointers. + When a C pointer is coerced to a non-optional pointer, safety-checked + Illegal Behavior occurs if the address is 0. +
  • +
  • Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked + Illegal Behavior. Optional C pointers introduce another bit to keep track of + null, just like ?usize. Note that creating an optional C pointer + is unnecessary as one can use normal Optional Pointers. +
  • +
  • Supports Type Coercion to and from integers.
  • +
  • Supports comparison with integers.
  • +
  • Does not support Zig-only pointer attributes such as alignment. Use normal Pointers + please!
  • +
+

When a C pointer is pointing to a single struct (not an array), dereference the C pointer to + access the struct's fields or member data. That syntax looks like + this:

+

ptr_to_struct.*.struct_member

+

This is comparable to doing -> in C.

+

When a C pointer is pointing to an array of structs, the syntax reverts to this:

+

ptr_to_struct_array[index].struct_member

+ + +

C Variadic Functions §

+ +

Zig supports extern variadic functions.

+
test_variadic_function.zig
const std = @import("std");
+const testing = std.testing;
+
+pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
+
+test "variadic function" {
+    try testing.expect(printf("Hello, world!\n") == 14);
+    try testing.expect(@typeInfo(@TypeOf(printf)).@"fn".is_var_args);
+}
Shell
$ zig test test_variadic_function.zig -lc
+1/1 test_variadic_function.test.variadic function...OK
+All 1 tests passed.
+Hello, world!
+
+ +

+ Variadic functions can be implemented using @cVaStart, @cVaEnd, @cVaArg and @cVaCopy. +

+
test_defining_variadic_function.zig
const std = @import("std");
+const testing = std.testing;
+const builtin = @import("builtin");
+
+fn add(count: c_int, ...) callconv(.C) c_int {
+    var ap = @cVaStart();
+    defer @cVaEnd(&ap);
+    var i: usize = 0;
+    var sum: c_int = 0;
+    while (i < count) : (i += 1) {
+        sum += @cVaArg(&ap, c_int);
+    }
+    return sum;
+}
+
+test "defining a variadic function" {
+    if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .macos) {
+        // https://github.com/ziglang/zig/issues/14096
+        return error.SkipZigTest;
+    }
+    if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) {
+        // https://github.com/ziglang/zig/issues/16961
+        return error.SkipZigTest;
+    }
+
+    try std.testing.expectEqual(@as(c_int, 0), add(0));
+    try std.testing.expectEqual(@as(c_int, 1), add(1, @as(c_int, 1)));
+    try std.testing.expectEqual(@as(c_int, 3), add(2, @as(c_int, 1), @as(c_int, 2)));
+}
Shell
$ zig test test_defining_variadic_function.zig
+1/1 test_defining_variadic_function.test.defining a variadic function...OK
+All 1 tests passed.
+
+ + +

Exporting a C Library §

+ +

+ One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages + to call into. The export keyword in front of functions, variables, and types causes them to + be part of the library API: +

+
mathtest.zig
export fn add(a: i32, b: i32) i32 {
+    return a + b;
+}
+ +

To make a static library:

+
Shell
$ zig build-lib mathtest.zig
+
+

To make a shared library:

+
Shell
$ zig build-lib mathtest.zig -dynamic
+
+

Here is an example with the Zig Build System:

+
test.c
// This header is generated by zig from mathtest.zig
+#include "mathtest.h"
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+    int32_t result = add(42, 1337);
+    printf("%d\n", result);
+    return 0;
+}
+
build_c.zig
const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+    const lib = b.addSharedLibrary(.{
+        .name = "mathtest",
+        .root_source_file = b.path("mathtest.zig"),
+        .version = .{ .major = 1, .minor = 0, .patch = 0 },
+    });
+    const exe = b.addExecutable(.{
+        .name = "test",
+    });
+    exe.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
+    exe.linkLibrary(lib);
+    exe.linkSystemLibrary("c");
+
+    b.default_step.dependOn(&exe.step);
+
+    const run_cmd = exe.run();
+
+    const test_step = b.step("test", "Test the program");
+    test_step.dependOn(&run_cmd.step);
+}
+ +
Shell
$ zig build test
+1379
+
+

See also:

+ + +

Mixing Object Files §

+ +

+ You can mix Zig object files with any other object files that respect the C ABI. Example: +

+
base64.zig
const base64 = @import("std").base64;
+
+export fn decode_base_64(
+    dest_ptr: [*]u8,
+    dest_len: usize,
+    source_ptr: [*]const u8,
+    source_len: usize,
+) usize {
+    const src = source_ptr[0..source_len];
+    const dest = dest_ptr[0..dest_len];
+    const base64_decoder = base64.standard.Decoder;
+    const decoded_size = base64_decoder.calcSizeForSlice(src) catch unreachable;
+    base64_decoder.decode(dest[0..decoded_size], src) catch unreachable;
+    return decoded_size;
+}
+ +
test.c
// This header is generated by zig from base64.zig
+#include "base64.h"
+
+#include <string.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+    const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz";
+    char buf[200];
+
+    size_t len = decode_base_64(buf, 200, encoded, strlen(encoded));
+    buf[len] = 0;
+    puts(buf);
+
+    return 0;
+}
+
build_object.zig
const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+    const obj = b.addObject(.{
+        .name = "base64",
+        .root_source_file = b.path("base64.zig"),
+    });
+
+    const exe = b.addExecutable(.{
+        .name = "test",
+    });
+    exe.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
+    exe.addObject(obj);
+    exe.linkSystemLibrary("c");
+    b.installArtifact(exe);
+}
+ +
Shell
$ zig build
+$ ./zig-out/bin/test
+all your base are belong to us
+
+

See also:

+ + + +

WebAssembly §

+ +

Zig supports building for WebAssembly out of the box.

+

Freestanding §

+ +

For host environments like the web browser and nodejs, build as an executable using the freestanding + OS target. Here's an example of running Zig code compiled to WebAssembly with nodejs.

+
math.zig
extern fn print(i32) void;
+
+export fn add(a: i32, b: i32) void {
+    print(a + b);
+}
Shell
$ zig build-exe math.zig -target wasm32-freestanding -fno-entry --export=add
+
+ +
test.js
const fs = require('fs');
+const source = fs.readFileSync("./math.wasm");
+const typedArray = new Uint8Array(source);
+
+WebAssembly.instantiate(typedArray, {
+  env: {
+    print: (result) => { console.log(`The result is ${result}`); }
+  }}).then(result => {
+  const add = result.instance.exports.add;
+  add(1, 2);
+});
+
Shell
$ node test.js
+The result is 3
+
+ +

WASI §

+ +

Zig's support for WebAssembly System Interface (WASI) is under active development. + Example of using the standard library and reading command line arguments:

+
wasi_args.zig
const std = @import("std");
+
+pub fn main() !void {
+    var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init;
+    const gpa = general_purpose_allocator.allocator();
+    const args = try std.process.argsAlloc(gpa);
+    defer std.process.argsFree(gpa, args);
+
+    for (args, 0..) |arg, i| {
+        std.debug.print("{}: {s}\n", .{ i, arg });
+    }
+}
Shell
$ zig build-exe wasi_args.zig -target wasm32-wasi
+
+ +
Shell
$ wasmtime wasi_args.wasm 123 hello
+0: wasi_args.wasm
+1: 123
+2: hello
+
+

A more interesting example would be extracting the list of preopens from the runtime. + This is now supported in the standard library via std.fs.wasi.Preopens:

+
wasi_preopens.zig
const std = @import("std");
+const fs = std.fs;
+
+pub fn main() !void {
+    var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init;
+    const gpa = general_purpose_allocator.allocator();
+
+    var arena_instance = std.heap.ArenaAllocator.init(gpa);
+    defer arena_instance.deinit();
+    const arena = arena_instance.allocator();
+
+    const preopens = try fs.wasi.preopensAlloc(arena);
+
+    for (preopens.names, 0..) |preopen, i| {
+        std.debug.print("{}: {s}\n", .{ i, preopen });
+    }
+}
Shell
$ zig build-exe wasi_preopens.zig -target wasm32-wasi
+
+ +
Shell
$ wasmtime --dir=. wasi_preopens.wasm
+0: stdin
+1: stdout
+2: stderr
+3: .
+
+ + +

Targets §

+ +

+ Target refers to the computer that will be used to run an executable. + It is composed of the CPU architecture, the set of enabled CPU features, operating system, + minimum and maximum operating system version, ABI, and ABI version. +

+

+ Zig is a general-purpose programming language which means that it is designed to + generate optimal code for a large set of targets. The command zig targets + provides information about all of the targets the compiler is aware of.

+

When no target option is provided to the compiler, the default choice + is to target the host computer, meaning that the + resulting executable will be unsuitable for copying to a different + computer. In order to copy an executable to another computer, the compiler + needs to know about the target requirements via the -target option. +

+

+ The Zig Standard Library (@import("std")) has + cross-platform abstractions, making the same source code viable on many targets. + Some code is more portable than other code. In general, Zig code is extremely + portable compared to other programming languages. +

+

+ Each platform requires its own implementations to make Zig's + cross-platform abstractions work. These implementations are at various + degrees of completion. Each tagged release of the compiler comes with + release notes that provide the full support table for each target. +

+ +

Style Guide §

+ +

+These coding conventions are not enforced by the compiler, but they are shipped in +this documentation along with the compiler in order to provide a point of +reference, should anyone wish to point to an authority on agreed upon Zig +coding style. +

+

Avoid Redundancy in Names §

+ +

Avoid these words in type names:

+
    +
  • Value
  • +
  • Data
  • +
  • Context
  • +
  • Manager
  • +
  • utils, misc, or somebody's initials
  • +
+

Everything is a value, all types are data, everything is context, all logic manages state. + Nothing is communicated by using a word that applies to all types.

+

Temptation to use "utilities", "miscellaneous", or somebody's initials + is a failure to categorize, or more commonly, overcategorization. Such + declarations can live at the root of a module that needs them with no + namespace needed.

+ + +

Avoid Redundant Names in Fully-Qualified Namespaces §

+ +

Every declaration is assigned a fully qualified + namespace by the compiler, creating a tree structure. Choose names based + on the fully-qualified namespace, and avoid redundant name segments.

+
redundant_fqn.zig
const std = @import("std");
+
+pub const json = struct {
+    pub const JsonValue = union(enum) {
+        number: f64,
+        boolean: bool,
+        // ...
+    };
+};
+
+pub fn main() void {
+    std.debug.print("{s}\n", .{@typeName(json.JsonValue)});
+}
Shell
$ zig build-exe redundant_fqn.zig
+$ ./redundant_fqn
+redundant_fqn.json.JsonValue
+
+ +

In this example, "json" is repeated in the fully-qualified namespace. The solution + is to delete Json from JsonValue. In this example we have + an empty struct named json but remember that files also act + as part of the fully-qualified namespace.

+

This example is an exception to the rule specified in Avoid Redundancy in Names. + The meaning of the type has been reduced to its core: it is a json value. The name + cannot be any more specific without being incorrect.

+ + +

Whitespace §

+ +
    +
  • + 4 space indentation +
  • +
  • + Open braces on same line, unless you need to wrap. +
  • +
  • If a list of things is longer than 2, put each item on its own line and + exercise the ability to put an extra comma at the end. +
  • +
  • + Line length: aim for 100; use common sense. +
  • +
+ +

Names §

+ +

+ Roughly speaking: camelCaseFunctionName, TitleCaseTypeName, + snake_case_variable_name. More precisely: +

+
    +
  • + If x is a type + then x should be TitleCase, unless it + is a struct with 0 fields and is never meant to be instantiated, + in which case it is considered to be a "namespace" and uses snake_case. +
  • +
  • + If x is callable, and x's return type is + type, then x should be TitleCase. +
  • +
  • + If x is otherwise callable, then x should + be camelCase. +
  • +
  • + Otherwise, x should be snake_case. +
  • +
+

+ Acronyms, initialisms, proper nouns, or any other word that has capitalization + rules in written English are subject to naming conventions just like any other + word. Even acronyms that are only 2 letters long are subject to these + conventions. +

+

+ File names fall into two categories: types and namespaces. If the file + (implicitly a struct) has top level fields, it should be named like any + other struct with fields using TitleCase. Otherwise, + it should use snake_case. Directory names should be + snake_case. +

+

+ These are general rules of thumb; if it makes sense to do something different, + do what makes sense. For example, if there is an established convention such as + ENOENT, follow the established convention. +

+ +

Examples §

+ +
style_example.zig
const namespace_name = @import("dir_name/file_name.zig");
+const TypeName = @import("dir_name/TypeName.zig");
+var global_var: i32 = undefined;
+const const_name = 42;
+const primitive_type_alias = f32;
+const string_alias = []u8;
+
+const StructName = struct {
+    field: i32,
+};
+const StructAlias = StructName;
+
+fn functionName(param_name: TypeName) void {
+    var functionPointer = functionName;
+    functionPointer();
+    functionPointer = otherFunction;
+    functionPointer();
+}
+const functionAlias = functionName;
+
+fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) type {
+    return List(ChildType, fixed_size);
+}
+
+fn ShortList(comptime T: type, comptime n: usize) type {
+    return struct {
+        field_name: [n]T,
+        fn methodName() void {}
+    };
+}
+
+// The word XML loses its casing when used in Zig identifiers.
+const xml_document =
+    \\<?xml version="1.0" encoding="UTF-8"?>
+    \\<document>
+    \\</document>
+;
+const XmlParser = struct {
+    field: i32,
+};
+
+// The initials BE (Big Endian) are just another word in Zig identifier names.
+fn readU32Be() u32 {}
+

+ See the Zig Standard Library for more examples. +

+ +

Doc Comment Guidance §

+ +
    +
  • Omit any information that is redundant based on the name of the thing being documented.
  • +
  • Duplicating information onto multiple similar functions is encouraged because it helps IDEs and other tools provide better help text.
  • +
  • Use the word assume to indicate invariants that cause unchecked Illegal Behavior when violated.
  • +
  • Use the word assert to indicate invariants that cause safety-checked Illegal Behavior when violated.
  • +
+ + +

Source Encoding §

+ +

Zig source code is encoded in UTF-8. An invalid UTF-8 byte sequence results in a compile error.

+

Throughout all zig source code (including in comments), some code points are never allowed:

+
    +
  • Ascii control characters, except for U+000a (LF), U+000d (CR), and U+0009 (HT): U+0000 - U+0008, U+000b - U+000c, U+000e - U+0001f, U+007f.
  • +
  • Non-Ascii Unicode line endings: U+0085 (NEL), U+2028 (LS), U+2029 (PS).
  • +
+

+ LF (byte value 0x0a, code point U+000a, '\n') is the line terminator in Zig source code. + This byte value terminates every line of zig source code except the last line of the file. + It is recommended that non-empty source files end with an empty line, which means the last byte would be 0x0a (LF). +

+

+ Each LF may be immediately preceded by a single CR (byte value 0x0d, code point U+000d, '\r') + to form a Windows style line ending, but this is discouraged. Note that in multiline strings, CRLF sequences will + be encoded as LF when compiled into a zig program. + A CR in any other context is not allowed. +

+

+ HT hard tabs (byte value 0x09, code point U+0009, '\t') are interchangeable with + SP spaces (byte value 0x20, code point U+0020, ' ') as a token separator, + but use of hard tabs is discouraged. See Grammar. +

+

+ For compatibility with other tools, the compiler ignores a UTF-8-encoded byte order mark (U+FEFF) + if it is the first Unicode code point in the source text. A byte order mark is not allowed anywhere else in the source. +

+

+ Note that running zig fmt on a source file will implement all recommendations mentioned here. +

+

+ Note that a tool reading Zig source code can make assumptions if the source code is assumed to be correct Zig code. + For example, when identifying the ends of lines, a tool can use a naive search such as /\n/, + or an advanced + search such as /\r\n?|[\n\u0085\u2028\u2029]/, and in either case line endings will be correctly identified. + For another example, when identifying the whitespace before the first token on a line, + a tool can either use a naive search such as /[ \t]/, + or an advanced search such as /\s/, + and in either case whitespace will be correctly identified. +

+ + +

Keyword Reference §

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeywordDescription
+
addrspace
+
+ The addrspace keyword. +
    +
  • TODO add documentation for addrspace
  • +
+
+
align
+
+ align can be used to specify the alignment of a pointer. + It can also be used after a variable or function declaration to specify the alignment of pointers to that variable or function. + +
+
allowzero
+
+ The pointer attribute allowzero allows a pointer to have address zero. + +
+
and
+
+ The boolean operator and. + +
+
anyframe
+
+ anyframe can be used as a type for variables which hold pointers to function frames. + +
+
anytype
+
+ Function parameters can be declared with anytype in place of the type. + The type will be inferred where the function is called. + +
+
asm
+
+ asm begins an inline assembly expression. This allows for directly controlling the machine code generated on compilation. + +
+
async
+
+ async can be used before a function call to get a pointer to the function's frame when it suspends. + +
+
await
+
+ await can be used to suspend the current function until the frame provided after the await completes. + await copies the value returned from the target function's frame to the caller. + +
+
break
+
+ break can be used with a block label to return a value from the block. + It can also be used to exit a loop before iteration completes naturally. + +
+
callconv
+
+ callconv can be used to specify the calling convention in a function type. + +
+
catch
+
+ catch can be used to evaluate an expression if the expression before it evaluates to an error. + The expression after the catch can optionally capture the error value. + +
+
comptime
+
+ comptime before a declaration can be used to label variables or function parameters as known at compile time. + It can also be used to guarantee an expression is run at compile time. + +
+
const
+
+ const declares a variable that can not be modified. + Used as a pointer attribute, it denotes the value referenced by the pointer cannot be modified. + +
+
continue
+
+ continue can be used in a loop to jump back to the beginning of the loop. + +
+
defer
+
+ defer will execute an expression when control flow leaves the current block. + +
+
else
+
+ else can be used to provide an alternate branch for if, switch, + while, and for expressions. +
    +
  • If used after an if expression, the else branch will be executed if the test value returns false, null, or an error.
  • +
  • If used within a switch expression, the else branch will be executed if the test value matches no other cases.
  • +
  • If used after a loop expression, the else branch will be executed if the loop finishes without breaking.
  • +
  • See also if, switch, while, for
  • +
+
+
enum
+
+ enum defines an enum type. + +
+
errdefer
+
+ errdefer will execute an expression when control flow leaves the current block if the function returns an error, the errdefer expression can capture the unwrapped value. + +
+
error
+
+ error defines an error type. + +
+
export
+
+ export makes a function or variable externally visible in the generated object file. + Exported functions default to the C calling convention. + +
+
extern
+
+ extern can be used to declare a function or variable that will be resolved at link time, when linking statically + or at runtime, when linking dynamically. + +
+
fn
+
+ fn declares a function. + +
+
for
+
+ A for expression can be used to iterate over the elements of a slice, array, or tuple. +
    +
  • See also for
  • +
+
+
if
+
+ An if expression can test boolean expressions, optional values, or error unions. + For optional values or error unions, the if expression can capture the unwrapped value. +
    +
  • See also if
  • +
+
+
inline
+
+ inline can be used to label a loop expression such that it will be unrolled at compile time. + It can also be used to force a function to be inlined at all call sites. + +
+
linksection
+
+ The linksection keyword can be used to specify what section the function or global variable will be put into (e.g. .text). +
+
noalias
+
+ The noalias keyword. +
    +
  • TODO add documentation for noalias
  • +
+
+
noinline
+
+ noinline disallows function to be inlined in all call sites. + +
+
nosuspend
+
+ The nosuspend keyword can be used in front of a block, statement or expression, to mark a scope where no suspension points are reached. + In particular, inside a nosuspend scope: +
    +
  • Using the suspend keyword results in a compile error.
  • +
  • Using await on a function frame which hasn't completed yet results in safety-checked Illegal Behavior.
  • +
  • Calling an async function may result in safety-checked Illegal Behavior, because it's equivalent to await async some_async_fn(), which contains an await.
  • +
+ Code inside a nosuspend scope does not cause the enclosing function to become an async function. + +
+
opaque
+
+ opaque defines an opaque type. + +
+
or
+
+ The boolean operator or. + +
+
orelse
+
+ orelse can be used to evaluate an expression if the expression before it evaluates to null. + +
+
packed
+
+ The packed keyword before a struct definition changes the struct's in-memory layout + to the guaranteed packed layout. + +
+
pub
+
+ The pub in front of a top level declaration makes the declaration available + to reference from a different file than the one it is declared in. + +
+
resume
+
+ resume will continue execution of a function frame after the point the function was suspended. +
+
return
+
+ return exits a function with a value. + +
+
struct
+
+ struct defines a struct. + +
+
suspend
+
+ suspend will cause control flow to return to the call site or resumer of the function. + suspend can also be used before a block within a function, + to allow the function access to its frame before control flow returns to the call site. +
+
switch
+
+ A switch expression can be used to test values of a common type. + switch cases can capture field values of a Tagged union. + +
+
test
+
+ The test keyword can be used to denote a top-level block of code + used to make sure behavior meets expectations. + +
+
threadlocal
+
+ threadlocal can be used to specify a variable as thread-local. + +
+
try
+
+ try evaluates an error union expression. + If it is an error, it returns from the current function with the same error. + Otherwise, the expression results in the unwrapped value. +
    +
  • See also try
  • +
+
+
union
+
+ union defines a union. + +
+
unreachable
+
+ unreachable can be used to assert that control flow will never happen upon a particular location. + Depending on the build mode, unreachable may emit a panic. +
    +
  • Emits a panic in Debug and ReleaseSafe mode, or when using zig test.
  • +
  • Does not emit a panic in ReleaseFast and ReleaseSmall mode.
  • +
  • See also unreachable
  • +
+
+
usingnamespace
+
+ usingnamespace is a top-level declaration that imports all the public declarations of the operand, + which must be a struct, union, or enum, into the current scope. + +
+
var
+
+ var declares a variable that may be modified. + +
+
volatile
+
+ volatile can be used to denote loads or stores of a pointer have side effects. + It can also modify an inline assembly expression to denote it has side effects. + +
+
while
+
+ A while expression can be used to repeatedly test a boolean, optional, or error union expression, + and cease looping when that expression evaluates to false, null, or an error, respectively. + +
+
+ + +

Appendix §

+ +

Containers §

+ +

+ A container in Zig is any syntactical construct that acts as a namespace to hold variable and function declarations. + Containers are also type definitions which can be instantiated. + Structs, enums, unions, opaques, and even Zig source files themselves are containers. +

+

+ Although containers (except Zig source files) use curly braces to surround their definition, they should not be confused with blocks or functions. + Containers do not contain statements. +

+ + +

Grammar §

+ +
grammar.y
Root <- skip container_doc_comment? ContainerMembers eof
+
+# *** Top level ***
+ContainerMembers <- ContainerDeclaration* (ContainerField COMMA)* (ContainerField / ContainerDeclaration*)
+
+ContainerDeclaration <- TestDecl / ComptimeDecl / doc_comment? KEYWORD_pub? Decl
+
+TestDecl <- KEYWORD_test (STRINGLITERALSINGLE / IDENTIFIER)? Block
+
+ComptimeDecl <- KEYWORD_comptime Block
+
+Decl
+    <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block)
+     / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? GlobalVarDecl
+     / KEYWORD_usingnamespace Expr SEMICOLON
+
+FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr
+
+VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? AddrSpace? LinkSection?
+
+GlobalVarDecl <- VarDeclProto (EQUAL Expr)? SEMICOLON
+
+ContainerField <- doc_comment? KEYWORD_comptime? !KEYWORD_fn (IDENTIFIER COLON)? TypeExpr ByteAlign? (EQUAL Expr)?
+
+# *** Block Level ***
+Statement
+    <- KEYWORD_comptime ComptimeStatement
+     / KEYWORD_nosuspend BlockExprStatement
+     / KEYWORD_suspend BlockExprStatement
+     / KEYWORD_defer BlockExprStatement
+     / KEYWORD_errdefer Payload? BlockExprStatement
+     / IfStatement
+     / LabeledStatement
+     / SwitchExpr
+     / VarDeclExprStatement
+
+ComptimeStatement
+    <- BlockExpr
+     / VarDeclExprStatement
+
+IfStatement
+    <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
+     / IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
+
+LabeledStatement <- BlockLabel? (Block / LoopStatement)
+
+LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
+
+ForStatement
+    <- ForPrefix BlockExpr ( KEYWORD_else Statement )?
+     / ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement )
+
+WhileStatement
+    <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
+     / WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement )
+
+BlockExprStatement
+    <- BlockExpr
+     / AssignExpr SEMICOLON
+
+BlockExpr <- BlockLabel? Block
+
+# An expression, assignment, or any destructure, as a statement.
+VarDeclExprStatement
+    <- VarDeclProto (COMMA (VarDeclProto / Expr))* EQUAL Expr SEMICOLON
+     / Expr (AssignOp Expr / (COMMA (VarDeclProto / Expr))+ EQUAL Expr)? SEMICOLON
+
+# *** Expression Level ***
+
+# An assignment or a destructure whose LHS are all lvalue expressions.
+AssignExpr <- Expr (AssignOp Expr / (COMMA Expr)+ EQUAL Expr)?
+
+SingleAssignExpr <- Expr (AssignOp Expr)?
+
+Expr <- BoolOrExpr
+
+BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)*
+
+BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)*
+
+CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
+
+BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
+
+BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)*
+
+AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)*
+
+MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)*
+
+PrefixExpr <- PrefixOp* PrimaryExpr
+
+PrimaryExpr
+    <- AsmExpr
+     / IfExpr
+     / KEYWORD_break BreakLabel? Expr?
+     / KEYWORD_comptime Expr
+     / KEYWORD_nosuspend Expr
+     / KEYWORD_continue BreakLabel?
+     / KEYWORD_resume Expr
+     / KEYWORD_return Expr?
+     / BlockLabel? LoopExpr
+     / Block
+     / CurlySuffixExpr
+
+IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)?
+
+Block <- LBRACE Statement* RBRACE
+
+LoopExpr <- KEYWORD_inline? (ForExpr / WhileExpr)
+
+ForExpr <- ForPrefix Expr (KEYWORD_else Expr)?
+
+WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
+
+CurlySuffixExpr <- TypeExpr InitList?
+
+InitList
+    <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
+     / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
+     / LBRACE RBRACE
+
+TypeExpr <- PrefixTypeOp* ErrorUnionExpr
+
+ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
+
+SuffixExpr
+    <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
+     / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
+
+PrimaryTypeExpr
+    <- BUILTINIDENTIFIER FnCallArguments
+     / CHAR_LITERAL
+     / ContainerDecl
+     / DOT IDENTIFIER
+     / DOT InitList
+     / ErrorSetDecl
+     / FLOAT
+     / FnProto
+     / GroupedExpr
+     / LabeledTypeExpr
+     / IDENTIFIER
+     / IfTypeExpr
+     / INTEGER
+     / KEYWORD_comptime TypeExpr
+     / KEYWORD_error DOT IDENTIFIER
+     / KEYWORD_anyframe
+     / KEYWORD_unreachable
+     / STRINGLITERAL
+     / SwitchExpr
+
+ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
+
+ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
+
+GroupedExpr <- LPAREN Expr RPAREN
+
+IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
+
+LabeledTypeExpr
+    <- BlockLabel Block
+     / BlockLabel? LoopTypeExpr
+
+LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
+
+ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
+
+WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
+
+SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
+
+# *** Assembly ***
+AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN Expr AsmOutput? RPAREN
+
+AsmOutput <- COLON AsmOutputList AsmInput?
+
+AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
+
+AsmInput <- COLON AsmInputList AsmClobbers?
+
+AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
+
+AsmClobbers <- COLON StringList
+
+# *** Helper grammar ***
+BreakLabel <- COLON IDENTIFIER
+
+BlockLabel <- IDENTIFIER COLON
+
+FieldInit <- DOT IDENTIFIER EQUAL Expr
+
+WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
+
+LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
+
+AddrSpace <- KEYWORD_addrspace LPAREN Expr RPAREN
+
+# Fn specific
+CallConv <- KEYWORD_callconv LPAREN Expr RPAREN
+
+ParamDecl
+    <- doc_comment? (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
+     / DOT3
+
+ParamType
+    <- KEYWORD_anytype
+     / TypeExpr
+
+# Control flow prefixes
+IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
+
+WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
+
+ForPrefix <- KEYWORD_for LPAREN ForArgumentsList RPAREN PtrListPayload
+
+# Payloads
+Payload <- PIPE IDENTIFIER PIPE
+
+PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
+
+PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
+
+PtrListPayload <- PIPE ASTERISK? IDENTIFIER (COMMA ASTERISK? IDENTIFIER)* COMMA? PIPE
+
+# Switch specific
+SwitchProng <- KEYWORD_inline? SwitchCase EQUALRARROW PtrIndexPayload? SingleAssignExpr
+
+SwitchCase
+    <- SwitchItem (COMMA SwitchItem)* COMMA?
+     / KEYWORD_else
+
+SwitchItem <- Expr (DOT3 Expr)?
+
+# For specific
+ForArgumentsList <- ForItem (COMMA ForItem)* COMMA?
+
+ForItem <- Expr (DOT2 Expr?)?
+
+# Operators
+AssignOp
+    <- ASTERISKEQUAL
+     / ASTERISKPIPEEQUAL
+     / SLASHEQUAL
+     / PERCENTEQUAL
+     / PLUSEQUAL
+     / PLUSPIPEEQUAL
+     / MINUSEQUAL
+     / MINUSPIPEEQUAL
+     / LARROW2EQUAL
+     / LARROW2PIPEEQUAL
+     / RARROW2EQUAL
+     / AMPERSANDEQUAL
+     / CARETEQUAL
+     / PIPEEQUAL
+     / ASTERISKPERCENTEQUAL
+     / PLUSPERCENTEQUAL
+     / MINUSPERCENTEQUAL
+     / EQUAL
+
+CompareOp
+    <- EQUALEQUAL
+     / EXCLAMATIONMARKEQUAL
+     / LARROW
+     / RARROW
+     / LARROWEQUAL
+     / RARROWEQUAL
+
+BitwiseOp
+    <- AMPERSAND
+     / CARET
+     / PIPE
+     / KEYWORD_orelse
+     / KEYWORD_catch Payload?
+
+BitShiftOp
+    <- LARROW2
+     / RARROW2
+     / LARROW2PIPE
+
+AdditionOp
+    <- PLUS
+     / MINUS
+     / PLUS2
+     / PLUSPERCENT
+     / MINUSPERCENT
+     / PLUSPIPE
+     / MINUSPIPE
+
+MultiplyOp
+    <- PIPE2
+     / ASTERISK
+     / SLASH
+     / PERCENT
+     / ASTERISK2
+     / ASTERISKPERCENT
+     / ASTERISKPIPE
+
+PrefixOp
+    <- EXCLAMATIONMARK
+     / MINUS
+     / TILDE
+     / MINUSPERCENT
+     / AMPERSAND
+     / KEYWORD_try
+     / KEYWORD_await
+
+PrefixTypeOp
+    <- QUESTIONMARK
+     / KEYWORD_anyframe MINUSRARROW
+     / SliceTypeStart (ByteAlign / AddrSpace / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
+     / PtrTypeStart (AddrSpace / KEYWORD_align LPAREN Expr (COLON Expr COLON Expr)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
+     / ArrayTypeStart
+
+SuffixOp
+    <- LBRACKET Expr (DOT2 (Expr? (COLON Expr)?)?)? RBRACKET
+     / DOT IDENTIFIER
+     / DOTASTERISK
+     / DOTQUESTIONMARK
+
+FnCallArguments <- LPAREN ExprList RPAREN
+
+# Ptr specific
+SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET
+
+PtrTypeStart
+    <- ASTERISK
+     / ASTERISK2
+     / LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET
+
+ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET
+
+# ContainerDecl specific
+ContainerDeclAuto <- ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE
+
+ContainerDeclType
+    <- KEYWORD_struct (LPAREN Expr RPAREN)?
+     / KEYWORD_opaque
+     / KEYWORD_enum (LPAREN Expr RPAREN)?
+     / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
+
+# Alignment
+ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
+
+# Lists
+IdentifierList <- (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)?
+
+SwitchProngList <- (SwitchProng COMMA)* SwitchProng?
+
+AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem?
+
+AsmInputList <- (AsmInputItem COMMA)* AsmInputItem?
+
+StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL?
+
+ParamDeclList <- (ParamDecl COMMA)* ParamDecl?
+
+ExprList <- (Expr COMMA)* Expr?
+
+# *** Tokens ***
+eof <- !.
+bin <- [01]
+bin_ <- '_'? bin
+oct <- [0-7]
+oct_ <- '_'? oct
+hex <- [0-9a-fA-F]
+hex_ <- '_'? hex
+dec <- [0-9]
+dec_ <- '_'? dec
+
+bin_int <- bin bin_*
+oct_int <- oct oct_*
+dec_int <- dec dec_*
+hex_int <- hex hex_*
+
+ox80_oxBF <- [\200-\277]
+oxF4 <- '\364'
+ox80_ox8F <- [\200-\217]
+oxF1_oxF3 <- [\361-\363]
+oxF0 <- '\360'
+ox90_0xBF <- [\220-\277]
+oxEE_oxEF <- [\356-\357]
+oxED <- '\355'
+ox80_ox9F <- [\200-\237]
+oxE1_oxEC <- [\341-\354]
+oxE0 <- '\340'
+oxA0_oxBF <- [\240-\277]
+oxC2_oxDF <- [\302-\337]
+
+# From https://lemire.me/blog/2018/05/09/how-quickly-can-you-check-that-a-string-is-valid-unicode-utf-8/
+# First Byte      Second Byte     Third Byte      Fourth Byte
+# [0x00,0x7F]
+# [0xC2,0xDF]     [0x80,0xBF]
+#    0xE0         [0xA0,0xBF]     [0x80,0xBF]
+# [0xE1,0xEC]     [0x80,0xBF]     [0x80,0xBF]
+#    0xED         [0x80,0x9F]     [0x80,0xBF]
+# [0xEE,0xEF]     [0x80,0xBF]     [0x80,0xBF]
+#    0xF0         [0x90,0xBF]     [0x80,0xBF]     [0x80,0xBF]
+# [0xF1,0xF3]     [0x80,0xBF]     [0x80,0xBF]     [0x80,0xBF]
+#    0xF4         [0x80,0x8F]     [0x80,0xBF]     [0x80,0xBF]
+
+mb_utf8_literal <-
+       oxF4      ox80_ox8F ox80_oxBF ox80_oxBF
+     / oxF1_oxF3 ox80_oxBF ox80_oxBF ox80_oxBF
+     / oxF0      ox90_0xBF ox80_oxBF ox80_oxBF
+     / oxEE_oxEF ox80_oxBF ox80_oxBF
+     / oxED      ox80_ox9F ox80_oxBF
+     / oxE1_oxEC ox80_oxBF ox80_oxBF
+     / oxE0      oxA0_oxBF ox80_oxBF
+     / oxC2_oxDF ox80_oxBF
+
+ascii_char_not_nl_slash_squote <- [\000-\011\013-\046\050-\133\135-\177]
+
+char_escape
+    <- "\\x" hex hex
+     / "\\u{" hex+ "}"
+     / "\\" [nr\\t'"]
+char_char
+    <- mb_utf8_literal
+     / char_escape
+     / ascii_char_not_nl_slash_squote
+
+string_char
+    <- char_escape
+     / [^\\"\n]
+
+container_doc_comment <- ('//!' [^\n]* [ \n]* skip)+
+doc_comment <- ('///' [^\n]* [ \n]* skip)+
+line_comment <- '//' ![!/][^\n]* / '////' [^\n]*
+line_string <- ("\\\\" [^\n]* [ \n]*)+
+skip <- ([ \n] / line_comment)*
+
+CHAR_LITERAL <- "'" char_char "'" skip
+FLOAT
+    <- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? skip
+     /      dec_int "." dec_int ([eE] [-+]? dec_int)? skip
+     / "0x" hex_int [pP] [-+]? dec_int skip
+     /      dec_int [eE] [-+]? dec_int skip
+INTEGER
+    <- "0b" bin_int skip
+     / "0o" oct_int skip
+     / "0x" hex_int skip
+     /      dec_int   skip
+STRINGLITERALSINGLE <- "\"" string_char* "\"" skip
+STRINGLITERAL
+    <- STRINGLITERALSINGLE
+     / (line_string                 skip)+
+IDENTIFIER
+    <- !keyword [A-Za-z_] [A-Za-z0-9_]* skip
+     / "@" STRINGLITERALSINGLE
+BUILTINIDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
+
+
+AMPERSAND            <- '&'      ![=]      skip
+AMPERSANDEQUAL       <- '&='               skip
+ASTERISK             <- '*'      ![*%=|]   skip
+ASTERISK2            <- '**'               skip
+ASTERISKEQUAL        <- '*='               skip
+ASTERISKPERCENT      <- '*%'     ![=]      skip
+ASTERISKPERCENTEQUAL <- '*%='              skip
+ASTERISKPIPE         <- '*|'     ![=]      skip
+ASTERISKPIPEEQUAL    <- '*|='              skip
+CARET                <- '^'      ![=]      skip
+CARETEQUAL           <- '^='               skip
+COLON                <- ':'                skip
+COMMA                <- ','                skip
+DOT                  <- '.'      ![*.?]    skip
+DOT2                 <- '..'     ![.]      skip
+DOT3                 <- '...'              skip
+DOTASTERISK          <- '.*'               skip
+DOTQUESTIONMARK      <- '.?'               skip
+EQUAL                <- '='      ![>=]     skip
+EQUALEQUAL           <- '=='               skip
+EQUALRARROW          <- '=>'               skip
+EXCLAMATIONMARK      <- '!'      ![=]      skip
+EXCLAMATIONMARKEQUAL <- '!='               skip
+LARROW               <- '<'      ![<=]     skip
+LARROW2              <- '<<'     ![=|]     skip
+LARROW2EQUAL         <- '<<='              skip
+LARROW2PIPE          <- '<<|'    ![=]      skip
+LARROW2PIPEEQUAL     <- '<<|='             skip
+LARROWEQUAL          <- '<='               skip
+LBRACE               <- '{'                skip
+LBRACKET             <- '['                skip
+LPAREN               <- '('                skip
+MINUS                <- '-'      ![%=>|]   skip
+MINUSEQUAL           <- '-='               skip
+MINUSPERCENT         <- '-%'     ![=]      skip
+MINUSPERCENTEQUAL    <- '-%='              skip
+MINUSPIPE            <- '-|'     ![=]      skip
+MINUSPIPEEQUAL       <- '-|='              skip
+MINUSRARROW          <- '->'               skip
+PERCENT              <- '%'      ![=]      skip
+PERCENTEQUAL         <- '%='               skip
+PIPE                 <- '|'      ![|=]     skip
+PIPE2                <- '||'               skip
+PIPEEQUAL            <- '|='               skip
+PLUS                 <- '+'      ![%+=|]   skip
+PLUS2                <- '++'               skip
+PLUSEQUAL            <- '+='               skip
+PLUSPERCENT          <- '+%'     ![=]      skip
+PLUSPERCENTEQUAL     <- '+%='              skip
+PLUSPIPE             <- '+|'     ![=]      skip
+PLUSPIPEEQUAL        <- '+|='              skip
+LETTERC              <- 'c'                skip
+QUESTIONMARK         <- '?'                skip
+RARROW               <- '>'      ![>=]     skip
+RARROW2              <- '>>'     ![=]      skip
+RARROW2EQUAL         <- '>>='              skip
+RARROWEQUAL          <- '>='               skip
+RBRACE               <- '}'                skip
+RBRACKET             <- ']'                skip
+RPAREN               <- ')'                skip
+SEMICOLON            <- ';'                skip
+SLASH                <- '/'      ![=]      skip
+SLASHEQUAL           <- '/='               skip
+TILDE                <- '~'                skip
+
+end_of_word <- ![a-zA-Z0-9_] skip
+KEYWORD_addrspace   <- 'addrspace'   end_of_word
+KEYWORD_align       <- 'align'       end_of_word
+KEYWORD_allowzero   <- 'allowzero'   end_of_word
+KEYWORD_and         <- 'and'         end_of_word
+KEYWORD_anyframe    <- 'anyframe'    end_of_word
+KEYWORD_anytype     <- 'anytype'     end_of_word
+KEYWORD_asm         <- 'asm'         end_of_word
+KEYWORD_async       <- 'async'       end_of_word
+KEYWORD_await       <- 'await'       end_of_word
+KEYWORD_break       <- 'break'       end_of_word
+KEYWORD_callconv    <- 'callconv'    end_of_word
+KEYWORD_catch       <- 'catch'       end_of_word
+KEYWORD_comptime    <- 'comptime'    end_of_word
+KEYWORD_const       <- 'const'       end_of_word
+KEYWORD_continue    <- 'continue'    end_of_word
+KEYWORD_defer       <- 'defer'       end_of_word
+KEYWORD_else        <- 'else'        end_of_word
+KEYWORD_enum        <- 'enum'        end_of_word
+KEYWORD_errdefer    <- 'errdefer'    end_of_word
+KEYWORD_error       <- 'error'       end_of_word
+KEYWORD_export      <- 'export'      end_of_word
+KEYWORD_extern      <- 'extern'      end_of_word
+KEYWORD_fn          <- 'fn'          end_of_word
+KEYWORD_for         <- 'for'         end_of_word
+KEYWORD_if          <- 'if'          end_of_word
+KEYWORD_inline      <- 'inline'      end_of_word
+KEYWORD_noalias     <- 'noalias'     end_of_word
+KEYWORD_nosuspend   <- 'nosuspend'   end_of_word
+KEYWORD_noinline    <- 'noinline'    end_of_word
+KEYWORD_opaque      <- 'opaque'      end_of_word
+KEYWORD_or          <- 'or'          end_of_word
+KEYWORD_orelse      <- 'orelse'      end_of_word
+KEYWORD_packed      <- 'packed'      end_of_word
+KEYWORD_pub         <- 'pub'         end_of_word
+KEYWORD_resume      <- 'resume'      end_of_word
+KEYWORD_return      <- 'return'      end_of_word
+KEYWORD_linksection <- 'linksection' end_of_word
+KEYWORD_struct      <- 'struct'      end_of_word
+KEYWORD_suspend     <- 'suspend'     end_of_word
+KEYWORD_switch      <- 'switch'      end_of_word
+KEYWORD_test        <- 'test'        end_of_word
+KEYWORD_threadlocal <- 'threadlocal' end_of_word
+KEYWORD_try         <- 'try'         end_of_word
+KEYWORD_union       <- 'union'       end_of_word
+KEYWORD_unreachable <- 'unreachable' end_of_word
+KEYWORD_usingnamespace <- 'usingnamespace' end_of_word
+KEYWORD_var         <- 'var'         end_of_word
+KEYWORD_volatile    <- 'volatile'    end_of_word
+KEYWORD_while       <- 'while'       end_of_word
+
+keyword <- KEYWORD_addrspace / KEYWORD_align / KEYWORD_allowzero / KEYWORD_and
+         / KEYWORD_anyframe / KEYWORD_anytype / KEYWORD_asm / KEYWORD_async
+         / KEYWORD_await / KEYWORD_break / KEYWORD_callconv / KEYWORD_catch
+         / KEYWORD_comptime / KEYWORD_const / KEYWORD_continue / KEYWORD_defer
+         / KEYWORD_else / KEYWORD_enum / KEYWORD_errdefer / KEYWORD_error / KEYWORD_export
+         / KEYWORD_extern / KEYWORD_fn / KEYWORD_for / KEYWORD_if
+         / KEYWORD_inline / KEYWORD_noalias / KEYWORD_nosuspend / KEYWORD_noinline
+         / KEYWORD_opaque / KEYWORD_or / KEYWORD_orelse / KEYWORD_packed
+         / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
+         / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test
+         / KEYWORD_threadlocal / KEYWORD_try / KEYWORD_union / KEYWORD_unreachable
+         / KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while
+ +

Zen §

+ +
    +
  • Communicate intent precisely.
  • +
  • Edge cases matter.
  • +
  • Favor reading code over writing code.
  • +
  • Only one obvious way to do things.
  • +
  • Runtime crashes are better than bugs.
  • +
  • Compile errors are better than runtime crashes.
  • +
  • Incremental improvements.
  • +
  • Avoid local maximums.
  • +
  • Reduce the amount one must remember.
  • +
  • Focus on code rather than style.
  • +
  • Resource allocation may fail; resource deallocation must succeed.
  • +
  • Memory is a resource.
  • +
  • Together we serve the users.
  • +
+ + +
+
+ + diff --git a/tools/zig-x86_64-windows-0.14.1/lib/c.zig b/tools/zig-x86_64-windows-0.14.1/lib/c.zig new file mode 100644 index 00000000..734940ff --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/c.zig @@ -0,0 +1,180 @@ +//! This is Zig's multi-target implementation of libc. +//! When builtin.link_libc is true, we need to export all the functions and +//! provide an entire C API. + +const std = @import("std"); +const builtin = @import("builtin"); +const math = std.math; +const isNan = std.math.isNan; +const maxInt = std.math.maxInt; +const native_os = builtin.os.tag; +const native_arch = builtin.cpu.arch; +const native_abi = builtin.abi; + +const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .internal else .strong; + +const is_wasm = switch (native_arch) { + .wasm32, .wasm64 => true, + else => false, +}; +const is_freestanding = switch (native_os) { + .freestanding, .other => true, + else => false, +}; + +comptime { + if (is_freestanding and is_wasm and builtin.link_libc) { + @export(&wasm_start, .{ .name = "_start", .linkage = .strong }); + } + + if (builtin.link_libc) { + @export(&strcmp, .{ .name = "strcmp", .linkage = linkage }); + @export(&strncmp, .{ .name = "strncmp", .linkage = linkage }); + @export(&strerror, .{ .name = "strerror", .linkage = linkage }); + @export(&strlen, .{ .name = "strlen", .linkage = linkage }); + @export(&strcpy, .{ .name = "strcpy", .linkage = linkage }); + @export(&strncpy, .{ .name = "strncpy", .linkage = linkage }); + @export(&strcat, .{ .name = "strcat", .linkage = linkage }); + @export(&strncat, .{ .name = "strncat", .linkage = linkage }); + } +} + +// Avoid dragging in the runtime safety mechanisms into this .o file, +// unless we're trying to test this file. +pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { + @branchHint(.cold); + _ = error_return_trace; + if (builtin.is_test) { + std.debug.panic("{s}", .{msg}); + } + switch (native_os) { + .freestanding, .other, .amdhsa, .amdpal => while (true) {}, + else => std.os.abort(), + } +} + +extern fn main(argc: c_int, argv: [*:null]?[*:0]u8) c_int; +fn wasm_start() callconv(.C) void { + _ = main(0, undefined); +} + +fn strcpy(dest: [*:0]u8, src: [*:0]const u8) callconv(.C) [*:0]u8 { + var i: usize = 0; + while (src[i] != 0) : (i += 1) { + dest[i] = src[i]; + } + dest[i] = 0; + + return dest; +} + +test "strcpy" { + var s1: [9:0]u8 = undefined; + + s1[0] = 0; + _ = strcpy(&s1, "foobarbaz"); + try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0)); +} + +fn strncpy(dest: [*:0]u8, src: [*:0]const u8, n: usize) callconv(.C) [*:0]u8 { + var i: usize = 0; + while (i < n and src[i] != 0) : (i += 1) { + dest[i] = src[i]; + } + while (i < n) : (i += 1) { + dest[i] = 0; + } + + return dest; +} + +test "strncpy" { + var s1: [9:0]u8 = undefined; + + s1[0] = 0; + _ = strncpy(&s1, "foobarbaz", @sizeOf(@TypeOf(s1))); + try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0)); +} + +fn strcat(dest: [*:0]u8, src: [*:0]const u8) callconv(.C) [*:0]u8 { + var dest_end: usize = 0; + while (dest[dest_end] != 0) : (dest_end += 1) {} + + var i: usize = 0; + while (src[i] != 0) : (i += 1) { + dest[dest_end + i] = src[i]; + } + dest[dest_end + i] = 0; + + return dest; +} + +test "strcat" { + var s1: [9:0]u8 = undefined; + + s1[0] = 0; + _ = strcat(&s1, "foo"); + _ = strcat(&s1, "bar"); + _ = strcat(&s1, "baz"); + try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0)); +} + +fn strncat(dest: [*:0]u8, src: [*:0]const u8, avail: usize) callconv(.C) [*:0]u8 { + var dest_end: usize = 0; + while (dest[dest_end] != 0) : (dest_end += 1) {} + + var i: usize = 0; + while (i < avail and src[i] != 0) : (i += 1) { + dest[dest_end + i] = src[i]; + } + dest[dest_end + i] = 0; + + return dest; +} + +test "strncat" { + var s1: [9:0]u8 = undefined; + + s1[0] = 0; + _ = strncat(&s1, "foo1111", 3); + _ = strncat(&s1, "bar1111", 3); + _ = strncat(&s1, "baz1111", 3); + try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0)); +} + +fn strcmp(s1: [*:0]const u8, s2: [*:0]const u8) callconv(.C) c_int { + return switch (std.mem.orderZ(u8, s1, s2)) { + .lt => -1, + .eq => 0, + .gt => 1, + }; +} + +fn strlen(s: [*:0]const u8) callconv(.C) usize { + return std.mem.len(s); +} + +fn strncmp(_l: [*:0]const u8, _r: [*:0]const u8, _n: usize) callconv(.C) c_int { + if (_n == 0) return 0; + var l = _l; + var r = _r; + var n = _n - 1; + while (l[0] != 0 and r[0] != 0 and n != 0 and l[0] == r[0]) { + l += 1; + r += 1; + n -= 1; + } + return @as(c_int, l[0]) - @as(c_int, r[0]); +} + +fn strerror(errnum: c_int) callconv(.C) [*:0]const u8 { + _ = errnum; + return "TODO strerror implementation"; +} + +test "strncmp" { + try std.testing.expect(strncmp("a", "b", 1) < 0); + try std.testing.expect(strncmp("a", "c", 1) < 0); + try std.testing.expect(strncmp("b", "a", 1) > 0); + try std.testing.expect(strncmp("\xff", "\x02", 1) > 0); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro.zig new file mode 100644 index 00000000..8e3da2aa --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro.zig @@ -0,0 +1,39 @@ +pub const CodeGen = @import("aro/CodeGen.zig"); +pub const Compilation = @import("aro/Compilation.zig"); +pub const Diagnostics = @import("aro/Diagnostics.zig"); +pub const Driver = @import("aro/Driver.zig"); +pub const Parser = @import("aro/Parser.zig"); +pub const Preprocessor = @import("aro/Preprocessor.zig"); +pub const Source = @import("aro/Source.zig"); +pub const Tokenizer = @import("aro/Tokenizer.zig"); +pub const Toolchain = @import("aro/Toolchain.zig"); +pub const Tree = @import("aro/Tree.zig"); +pub const Type = @import("aro/Type.zig"); +pub const TypeMapper = @import("aro/StringInterner.zig").TypeMapper; +pub const target_util = @import("aro/target.zig"); +pub const Value = @import("aro/Value.zig"); + +const backend = @import("backend.zig"); +pub const Interner = backend.Interner; +pub const Ir = backend.Ir; +pub const Object = backend.Object; +pub const CallingConvention = backend.CallingConvention; + +pub const version_str = backend.version_str; +pub const version = backend.version; + +test { + _ = @import("aro/annex_g.zig"); + _ = @import("aro/Builtins.zig"); + _ = @import("aro/char_info.zig"); + _ = @import("aro/Compilation.zig"); + _ = @import("aro/Driver/Distro.zig"); + _ = @import("aro/Driver/Filesystem.zig"); + _ = @import("aro/Driver/GCCVersion.zig"); + _ = @import("aro/InitList.zig"); + _ = @import("aro/Preprocessor.zig"); + _ = @import("aro/target.zig"); + _ = @import("aro/Tokenizer.zig"); + _ = @import("aro/toolchains/Linux.zig"); + _ = @import("aro/Value.zig"); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Attribute.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Attribute.zig new file mode 100644 index 00000000..a5b78b84 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Attribute.zig @@ -0,0 +1,1120 @@ +const std = @import("std"); +const mem = std.mem; +const ZigType = std.builtin.Type; +const CallingConvention = @import("../backend.zig").CallingConvention; +const Compilation = @import("Compilation.zig"); +const Diagnostics = @import("Diagnostics.zig"); +const Parser = @import("Parser.zig"); +const Tree = @import("Tree.zig"); +const NodeIndex = Tree.NodeIndex; +const TokenIndex = Tree.TokenIndex; +const Type = @import("Type.zig"); +const Value = @import("Value.zig"); + +const Attribute = @This(); + +tag: Tag, +syntax: Syntax, +args: Arguments, + +pub const Syntax = enum { + c23, + declspec, + gnu, + keyword, +}; + +pub const Kind = enum { + c23, + declspec, + gnu, + + pub fn toSyntax(kind: Kind) Syntax { + return switch (kind) { + .c23 => .c23, + .declspec => .declspec, + .gnu => .gnu, + }; + } +}; + +pub const Iterator = struct { + source: union(enum) { + ty: Type, + slice: []const Attribute, + }, + index: usize, + + pub fn initSlice(slice: ?[]const Attribute) Iterator { + return .{ .source = .{ .slice = slice orelse &.{} }, .index = 0 }; + } + + pub fn initType(ty: Type) Iterator { + return .{ .source = .{ .ty = ty }, .index = 0 }; + } + + /// returns the next attribute as well as its index within the slice or current type + /// The index can be used to determine when a nested type has been recursed into + pub fn next(self: *Iterator) ?struct { Attribute, usize } { + switch (self.source) { + .slice => |slice| { + if (self.index < slice.len) { + defer self.index += 1; + return .{ slice[self.index], self.index }; + } + }, + .ty => |ty| { + switch (ty.specifier) { + .typeof_type => { + self.* = .{ .source = .{ .ty = ty.data.sub_type.* }, .index = 0 }; + return self.next(); + }, + .typeof_expr => { + self.* = .{ .source = .{ .ty = ty.data.expr.ty }, .index = 0 }; + return self.next(); + }, + .attributed => { + if (self.index < ty.data.attributed.attributes.len) { + defer self.index += 1; + return .{ ty.data.attributed.attributes[self.index], self.index }; + } + self.* = .{ .source = .{ .ty = ty.data.attributed.base }, .index = 0 }; + return self.next(); + }, + else => {}, + } + }, + } + return null; + } +}; + +pub const ArgumentType = enum { + string, + identifier, + int, + alignment, + float, + complex_float, + expression, + nullptr_t, + + pub fn toString(self: ArgumentType) []const u8 { + return switch (self) { + .string => "a string", + .identifier => "an identifier", + .int, .alignment => "an integer constant", + .nullptr_t => "nullptr", + .float => "a floating point number", + .complex_float => "a complex floating point number", + .expression => "an expression", + }; + } +}; + +/// number of required arguments +pub fn requiredArgCount(attr: Tag) u32 { + switch (attr) { + inline else => |tag| { + comptime var needed = 0; + comptime { + const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + for (fields) |arg_field| { + if (!mem.eql(u8, arg_field.name, "__name_tok") and @typeInfo(arg_field.type) != .optional) needed += 1; + } + } + return needed; + }, + } +} + +/// maximum number of args that can be passed +pub fn maxArgCount(attr: Tag) u32 { + switch (attr) { + inline else => |tag| { + comptime var max = 0; + comptime { + const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + for (fields) |arg_field| { + if (!mem.eql(u8, arg_field.name, "__name_tok")) max += 1; + } + } + return max; + }, + } +} + +fn UnwrapOptional(comptime T: type) type { + return switch (@typeInfo(T)) { + .optional => |optional| optional.child, + else => T, + }; +} + +pub const Formatting = struct { + /// The quote char (single or double) to use when printing identifiers/strings corresponding + /// to the enum in the first field of the `attr`. Identifier enums use single quotes, string enums + /// use double quotes + fn quoteChar(attr: Tag) []const u8 { + switch (attr) { + .calling_convention => unreachable, + inline else => |tag| { + const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + + if (fields.len == 0) unreachable; + const Unwrapped = UnwrapOptional(fields[0].type); + if (@typeInfo(Unwrapped) != .@"enum") unreachable; + + return if (Unwrapped.opts.enum_kind == .identifier) "'" else "\""; + }, + } + } + + /// returns a comma-separated string of quoted enum values, representing the valid + /// choices for the string or identifier enum of the first field of the `attr`. + pub fn choices(attr: Tag) []const u8 { + switch (attr) { + .calling_convention => unreachable, + inline else => |tag| { + const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + + if (fields.len == 0) unreachable; + const Unwrapped = UnwrapOptional(fields[0].type); + if (@typeInfo(Unwrapped) != .@"enum") unreachable; + + const enum_fields = @typeInfo(Unwrapped).@"enum".fields; + const quote = comptime quoteChar(@enumFromInt(@intFromEnum(tag))); + comptime var values: []const u8 = quote ++ enum_fields[0].name ++ quote; + inline for (enum_fields[1..]) |enum_field| { + values = values ++ ", "; + values = values ++ quote ++ enum_field.name ++ quote; + } + return values; + }, + } + } +}; + +/// Checks if the first argument (if it exists) is an identifier enum +pub fn wantsIdentEnum(attr: Tag) bool { + switch (attr) { + .calling_convention => return false, + inline else => |tag| { + const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + + if (fields.len == 0) return false; + const Unwrapped = UnwrapOptional(fields[0].type); + if (@typeInfo(Unwrapped) != .@"enum") return false; + + return Unwrapped.opts.enum_kind == .identifier; + }, + } +} + +pub fn diagnoseIdent(attr: Tag, arguments: *Arguments, ident: []const u8) ?Diagnostics.Message { + switch (attr) { + inline else => |tag| { + const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + if (fields.len == 0) unreachable; + const Unwrapped = UnwrapOptional(fields[0].type); + if (@typeInfo(Unwrapped) != .@"enum") unreachable; + if (std.meta.stringToEnum(Unwrapped, normalize(ident))) |enum_val| { + @field(@field(arguments, @tagName(tag)), fields[0].name) = enum_val; + return null; + } + return Diagnostics.Message{ + .tag = .unknown_attr_enum, + .extra = .{ .attr_enum = .{ .tag = attr } }, + }; + }, + } +} + +pub fn wantsAlignment(attr: Tag, idx: usize) bool { + switch (attr) { + inline else => |tag| { + const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + if (fields.len == 0) return false; + + return switch (idx) { + inline 0...fields.len - 1 => |i| UnwrapOptional(fields[i].type) == Alignment, + else => false, + }; + }, + } +} + +pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, p: *Parser) !?Diagnostics.Message { + switch (attr) { + inline else => |tag| { + const arg_fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + if (arg_fields.len == 0) unreachable; + + switch (arg_idx) { + inline 0...arg_fields.len - 1 => |arg_i| { + if (UnwrapOptional(arg_fields[arg_i].type) != Alignment) unreachable; + + if (!res.val.is(.int, p.comp)) return Diagnostics.Message{ .tag = .alignas_unavailable }; + if (res.val.compare(.lt, Value.zero, p.comp)) { + return Diagnostics.Message{ .tag = .negative_alignment, .extra = .{ .str = try res.str(p) } }; + } + const requested = res.val.toInt(u29, p.comp) orelse { + return Diagnostics.Message{ .tag = .maximum_alignment, .extra = .{ .str = try res.str(p) } }; + }; + if (!std.mem.isValidAlign(requested)) return Diagnostics.Message{ .tag = .non_pow2_align }; + + @field(@field(arguments, @tagName(tag)), arg_fields[arg_i].name) = Alignment{ .requested = requested }; + return null; + }, + else => unreachable, + } + }, + } +} + +fn diagnoseField( + comptime decl: ZigType.Declaration, + comptime field: ZigType.StructField, + comptime Wanted: type, + arguments: *Arguments, + res: Parser.Result, + node: Tree.Node, + p: *Parser, +) !?Diagnostics.Message { + if (res.val.opt_ref == .none) { + if (Wanted == Identifier and node.tag == .decl_ref_expr) { + @field(@field(arguments, decl.name), field.name) = Identifier{ .tok = node.data.decl_ref }; + return null; + } + return invalidArgMsg(Wanted, .expression); + } + const key = p.comp.interner.get(res.val.ref()); + switch (key) { + .int => { + if (@typeInfo(Wanted) == .int) { + @field(@field(arguments, decl.name), field.name) = res.val.toInt(Wanted, p.comp) orelse return .{ + .tag = .attribute_int_out_of_range, + .extra = .{ .str = try res.str(p) }, + }; + return null; + } + }, + .bytes => |bytes| { + if (Wanted == Value) { + if (node.tag != .string_literal_expr or (!node.ty.elemType().is(.char) and !node.ty.elemType().is(.uchar))) { + return .{ + .tag = .attribute_requires_string, + .extra = .{ .str = decl.name }, + }; + } + @field(@field(arguments, decl.name), field.name) = try p.removeNull(res.val); + return null; + } else if (@typeInfo(Wanted) == .@"enum" and @hasDecl(Wanted, "opts") and Wanted.opts.enum_kind == .string) { + const str = bytes[0 .. bytes.len - 1]; + if (std.meta.stringToEnum(Wanted, str)) |enum_val| { + @field(@field(arguments, decl.name), field.name) = enum_val; + return null; + } else { + return .{ + .tag = .unknown_attr_enum, + .extra = .{ .attr_enum = .{ .tag = std.meta.stringToEnum(Tag, decl.name).? } }, + }; + } + } + }, + else => {}, + } + return invalidArgMsg(Wanted, switch (key) { + .int => .int, + .bytes => .string, + .float => .float, + .complex => .complex_float, + .null => .nullptr_t, + .int_ty, + .float_ty, + .complex_ty, + .ptr_ty, + .noreturn_ty, + .void_ty, + .func_ty, + .array_ty, + .vector_ty, + .record_ty, + => unreachable, + }); +} + +fn invalidArgMsg(comptime Expected: type, actual: ArgumentType) Diagnostics.Message { + return .{ + .tag = .attribute_arg_invalid, + .extra = .{ .attr_arg_type = .{ .expected = switch (Expected) { + Value => .string, + Identifier => .identifier, + u32 => .int, + Alignment => .alignment, + CallingConvention => .identifier, + else => switch (@typeInfo(Expected)) { + .@"enum" => if (Expected.opts.enum_kind == .string) .string else .identifier, + else => unreachable, + }, + }, .actual = actual } }, + }; +} + +pub fn diagnose(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, node: Tree.Node, p: *Parser) !?Diagnostics.Message { + switch (attr) { + inline else => |tag| { + const decl = @typeInfo(attributes).@"struct".decls[@intFromEnum(tag)]; + const max_arg_count = comptime maxArgCount(tag); + if (arg_idx >= max_arg_count) return Diagnostics.Message{ + .tag = .attribute_too_many_args, + .extra = .{ .attr_arg_count = .{ .attribute = attr, .expected = max_arg_count } }, + }; + const arg_fields = @typeInfo(@field(attributes, decl.name)).@"struct".fields; + switch (arg_idx) { + inline 0...arg_fields.len - 1 => |arg_i| { + return diagnoseField(decl, arg_fields[arg_i], UnwrapOptional(arg_fields[arg_i].type), arguments, res, node, p); + }, + else => unreachable, + } + }, + } +} + +const EnumTypes = enum { + string, + identifier, +}; +pub const Alignment = struct { + node: NodeIndex = .none, + requested: u29, +}; +pub const Identifier = struct { + tok: TokenIndex = 0, +}; + +const attributes = struct { + pub const access = struct { + access_mode: enum { + read_only, + read_write, + write_only, + none, + + const opts = struct { + const enum_kind = .identifier; + }; + }, + ref_index: u32, + size_index: ?u32 = null, + }; + pub const alias = struct { + alias: Value, + }; + pub const aligned = struct { + alignment: ?Alignment = null, + __name_tok: TokenIndex, + }; + pub const alloc_align = struct { + position: u32, + }; + pub const alloc_size = struct { + position_1: u32, + position_2: ?u32 = null, + }; + pub const allocate = struct { + segname: Value, + }; + pub const allocator = struct {}; + pub const always_inline = struct {}; + pub const appdomain = struct {}; + pub const artificial = struct {}; + pub const assume_aligned = struct { + alignment: Alignment, + offset: ?u32 = null, + }; + pub const cleanup = struct { + function: Identifier, + }; + pub const code_seg = struct { + segname: Value, + }; + pub const cold = struct {}; + pub const common = struct {}; + pub const @"const" = struct {}; + pub const constructor = struct { + priority: ?u32 = null, + }; + pub const copy = struct { + function: Identifier, + }; + pub const deprecated = struct { + msg: ?Value = null, + __name_tok: TokenIndex, + }; + pub const designated_init = struct {}; + pub const destructor = struct { + priority: ?u32 = null, + }; + pub const dllexport = struct {}; + pub const dllimport = struct {}; + pub const @"error" = struct { + msg: Value, + __name_tok: TokenIndex, + }; + pub const externally_visible = struct {}; + pub const fallthrough = struct {}; + pub const flatten = struct {}; + pub const format = struct { + archetype: enum { + printf, + scanf, + strftime, + strfmon, + + const opts = struct { + const enum_kind = .identifier; + }; + }, + string_index: u32, + first_to_check: u32, + }; + pub const format_arg = struct { + string_index: u32, + }; + pub const gnu_inline = struct {}; + pub const hot = struct {}; + pub const ifunc = struct { + resolver: Value, + }; + pub const interrupt = struct {}; + pub const interrupt_handler = struct {}; + pub const jitintrinsic = struct {}; + pub const leaf = struct {}; + pub const malloc = struct {}; + pub const may_alias = struct {}; + pub const mode = struct { + mode: enum { + // zig fmt: off + byte, word, pointer, + BI, QI, HI, + PSI, SI, PDI, + DI, TI, OI, + XI, QF, HF, + TQF, SF, DF, + XF, SD, DD, + TD, TF, QQ, + HQ, SQ, DQ, + TQ, UQQ, UHQ, + USQ, UDQ, UTQ, + HA, SA, DA, + TA, UHA, USA, + UDA, UTA, CC, + BLK, VOID, QC, + HC, SC, DC, + XC, TC, CQI, + CHI, CSI, CDI, + CTI, COI, CPSI, + BND32, BND64, + // zig fmt: on + + const opts = struct { + const enum_kind = .identifier; + }; + }, + }; + pub const naked = struct {}; + pub const no_address_safety_analysis = struct {}; + pub const no_icf = struct {}; + pub const no_instrument_function = struct {}; + pub const no_profile_instrument_function = struct {}; + pub const no_reorder = struct {}; + pub const no_sanitize = struct { + /// Todo: represent args as union? + alignment: Value, + object_size: ?Value = null, + }; + pub const no_sanitize_address = struct {}; + pub const no_sanitize_coverage = struct {}; + pub const no_sanitize_thread = struct {}; + pub const no_sanitize_undefined = struct {}; + pub const no_split_stack = struct {}; + pub const no_stack_limit = struct {}; + pub const no_stack_protector = struct {}; + pub const @"noalias" = struct {}; + pub const noclone = struct {}; + pub const nocommon = struct {}; + pub const nodiscard = struct {}; + pub const noinit = struct {}; + pub const @"noinline" = struct {}; + pub const noipa = struct {}; + // TODO: arbitrary number of arguments + // const nonnull = struct { + // // arg_index: []const u32, + // }; + // }; + pub const nonstring = struct {}; + pub const noplt = struct {}; + pub const @"noreturn" = struct {}; + // TODO: union args ? + // const optimize = struct { + // // optimize, // u32 | []const u8 -- optimize? + // }; + // }; + pub const @"packed" = struct {}; + pub const patchable_function_entry = struct {}; + pub const persistent = struct {}; + pub const process = struct {}; + pub const pure = struct {}; + pub const reproducible = struct {}; + pub const restrict = struct {}; + pub const retain = struct {}; + pub const returns_nonnull = struct {}; + pub const returns_twice = struct {}; + pub const safebuffers = struct {}; + pub const scalar_storage_order = struct { + order: enum { + @"little-endian", + @"big-endian", + + const opts = struct { + const enum_kind = .string; + }; + }, + }; + pub const section = struct { + name: Value, + }; + pub const selectany = struct {}; + pub const sentinel = struct { + position: ?u32 = null, + }; + pub const simd = struct { + mask: ?enum { + notinbranch, + inbranch, + + const opts = struct { + const enum_kind = .string; + }; + } = null, + }; + pub const spectre = struct { + arg: enum { + nomitigation, + + const opts = struct { + const enum_kind = .identifier; + }; + }, + }; + pub const stack_protect = struct {}; + pub const symver = struct { + version: Value, // TODO: validate format "name2@nodename" + + }; + pub const target = struct { + options: Value, // TODO: multiple arguments + + }; + pub const target_clones = struct { + options: Value, // TODO: multiple arguments + + }; + pub const thread = struct {}; + pub const tls_model = struct { + model: enum { + @"global-dynamic", + @"local-dynamic", + @"initial-exec", + @"local-exec", + + const opts = struct { + const enum_kind = .string; + }; + }, + }; + pub const transparent_union = struct {}; + pub const unavailable = struct { + msg: ?Value = null, + __name_tok: TokenIndex, + }; + pub const uninitialized = struct {}; + pub const unsequenced = struct {}; + pub const unused = struct {}; + pub const used = struct {}; + pub const uuid = struct { + uuid: Value, + }; + pub const vector_size = struct { + bytes: u32, // TODO: validate "The bytes argument must be a positive power-of-two multiple of the base type size" + + }; + pub const visibility = struct { + visibility_type: enum { + default, + hidden, + internal, + protected, + + const opts = struct { + const enum_kind = .string; + }; + }, + }; + pub const warn_if_not_aligned = struct { + alignment: Alignment, + }; + pub const warn_unused_result = struct {}; + pub const warning = struct { + msg: Value, + __name_tok: TokenIndex, + }; + pub const weak = struct {}; + pub const weakref = struct { + target: ?Value = null, + }; + pub const zero_call_used_regs = struct { + choice: enum { + skip, + used, + @"used-gpr", + @"used-arg", + @"used-gpr-arg", + all, + @"all-gpr", + @"all-arg", + @"all-gpr-arg", + + const opts = struct { + const enum_kind = .string; + }; + }, + }; + pub const asm_label = struct { + name: Value, + }; + pub const calling_convention = struct { + cc: CallingConvention, + }; +}; + +pub const Tag = std.meta.DeclEnum(attributes); + +pub const Arguments = blk: { + const decls = @typeInfo(attributes).@"struct".decls; + var union_fields: [decls.len]ZigType.UnionField = undefined; + for (decls, &union_fields) |decl, *field| { + field.* = .{ + .name = decl.name, + .type = @field(attributes, decl.name), + .alignment = 0, + }; + } + + break :blk @Type(.{ + .@"union" = .{ + .layout = .auto, + .tag_type = null, + .fields = &union_fields, + .decls = &.{}, + }, + }); +}; + +pub fn ArgumentsForTag(comptime tag: Tag) type { + const decl = @typeInfo(attributes).@"struct".decls[@intFromEnum(tag)]; + return @field(attributes, decl.name); +} + +pub fn initArguments(tag: Tag, name_tok: TokenIndex) Arguments { + switch (tag) { + inline else => |arg_tag| { + const union_element = @field(attributes, @tagName(arg_tag)); + const init = std.mem.zeroInit(union_element, .{}); + var args = @unionInit(Arguments, @tagName(arg_tag), init); + if (@hasField(@field(attributes, @tagName(arg_tag)), "__name_tok")) { + @field(args, @tagName(arg_tag)).__name_tok = name_tok; + } + return args; + }, + } +} + +pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag { + const Properties = struct { + tag: Tag, + gnu: bool = false, + declspec: bool = false, + c23: bool = false, + }; + const attribute_names = @import("Attribute/names.zig").with(Properties); + + const normalized = normalize(name); + const actual_kind: Kind = if (namespace) |ns| blk: { + const normalized_ns = normalize(ns); + if (mem.eql(u8, normalized_ns, "gnu")) { + break :blk .gnu; + } + return null; + } else kind; + + const tag_and_opts = attribute_names.fromName(normalized) orelse return null; + switch (actual_kind) { + inline else => |tag| { + if (@field(tag_and_opts.properties, @tagName(tag))) + return tag_and_opts.properties.tag; + }, + } + return null; +} + +pub fn normalize(name: []const u8) []const u8 { + if (name.len >= 4 and mem.startsWith(u8, name, "__") and mem.endsWith(u8, name, "__")) { + return name[2 .. name.len - 2]; + } + return name; +} + +fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []const u8) !void { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + try p.strings.writer().print("attribute '{s}' ignored on {s}", .{ @tagName(attr), context }); + const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); + try p.errStr(.ignored_attribute, tok, str); +} + +pub const applyParameterAttributes = applyVariableAttributes; +pub fn applyVariableAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type { + const attrs = p.attr_buf.items(.attr)[attr_buf_start..]; + const toks = p.attr_buf.items(.tok)[attr_buf_start..]; + p.attr_application_buf.items.len = 0; + var base_ty = ty; + var common = false; + var nocommon = false; + for (attrs, toks) |attr, tok| switch (attr.tag) { + // zig fmt: off + .alias, .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .weak, .used, + .noinit, .retain, .persistent, .section, .mode, .asm_label, + => try p.attr_application_buf.append(p.gpa, attr), + // zig fmt: on + .common => if (nocommon) { + try p.errTok(.ignore_common, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + common = true; + }, + .nocommon => if (common) { + try p.errTok(.ignore_nocommon, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + nocommon = true; + }, + .vector_size => try attr.applyVectorSize(p, tok, &base_ty), + .aligned => try attr.applyAligned(p, base_ty, tag), + .nonstring => if (!base_ty.isArray() or !(base_ty.is(.char) or base_ty.is(.uchar) or base_ty.is(.schar))) { + try p.errStr(.non_string_ignored, tok, try p.typeStr(ty)); + } else { + try p.attr_application_buf.append(p.gpa, attr); + }, + .uninitialized => if (p.func.ty == null) { + try p.errStr(.local_variable_attribute, tok, "uninitialized"); + } else { + try p.attr_application_buf.append(p.gpa, attr); + }, + .cleanup => if (p.func.ty == null) { + try p.errStr(.local_variable_attribute, tok, "cleanup"); + } else { + try p.attr_application_buf.append(p.gpa, attr); + }, + .alloc_size, + .copy, + .tls_model, + .visibility, + => |t| try p.errExtra(.attribute_todo, tok, .{ .attribute_todo = .{ .tag = t, .kind = .variables } }), + else => try ignoredAttrErr(p, tok, attr.tag, "variables"), + }; + return base_ty.withAttributes(p.arena, p.attr_application_buf.items); +} + +pub fn applyFieldAttributes(p: *Parser, field_ty: *Type, attr_buf_start: usize) ![]const Attribute { + const attrs = p.attr_buf.items(.attr)[attr_buf_start..]; + const toks = p.attr_buf.items(.tok)[attr_buf_start..]; + p.attr_application_buf.items.len = 0; + for (attrs, toks) |attr, tok| switch (attr.tag) { + // zig fmt: off + .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode, .warn_unused_result, .nodiscard, + => try p.attr_application_buf.append(p.gpa, attr), + // zig fmt: on + .vector_size => try attr.applyVectorSize(p, tok, field_ty), + .aligned => try attr.applyAligned(p, field_ty.*, null), + else => try ignoredAttrErr(p, tok, attr.tag, "fields"), + }; + if (p.attr_application_buf.items.len == 0) return &[0]Attribute{}; + return p.arena.dupe(Attribute, p.attr_application_buf.items); +} + +pub fn applyTypeAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Diagnostics.Tag) !Type { + const attrs = p.attr_buf.items(.attr)[attr_buf_start..]; + const toks = p.attr_buf.items(.tok)[attr_buf_start..]; + p.attr_application_buf.items.len = 0; + var base_ty = ty; + for (attrs, toks) |attr, tok| switch (attr.tag) { + // zig fmt: off + .@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode, + => try p.attr_application_buf.append(p.gpa, attr), + // zig fmt: on + .transparent_union => try attr.applyTransparentUnion(p, tok, base_ty), + .vector_size => try attr.applyVectorSize(p, tok, &base_ty), + .aligned => try attr.applyAligned(p, base_ty, tag), + .designated_init => if (base_ty.is(.@"struct")) { + try p.attr_application_buf.append(p.gpa, attr); + } else { + try p.errTok(.designated_init_invalid, tok); + }, + .alloc_size, + .copy, + .scalar_storage_order, + .nonstring, + => |t| try p.errExtra(.attribute_todo, tok, .{ .attribute_todo = .{ .tag = t, .kind = .types } }), + else => try ignoredAttrErr(p, tok, attr.tag, "types"), + }; + return base_ty.withAttributes(p.arena, p.attr_application_buf.items); +} + +pub fn applyFunctionAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type { + const attrs = p.attr_buf.items(.attr)[attr_buf_start..]; + const toks = p.attr_buf.items(.tok)[attr_buf_start..]; + p.attr_application_buf.items.len = 0; + var base_ty = ty; + var hot = false; + var cold = false; + var @"noinline" = false; + var always_inline = false; + for (attrs, toks) |attr, tok| switch (attr.tag) { + // zig fmt: off + .noreturn, .unused, .used, .warning, .deprecated, .unavailable, .weak, .pure, .leaf, + .@"const", .warn_unused_result, .section, .returns_nonnull, .returns_twice, .@"error", + .externally_visible, .retain, .flatten, .gnu_inline, .alias, .asm_label, .nodiscard, + .reproducible, .unsequenced, + => try p.attr_application_buf.append(p.gpa, attr), + // zig fmt: on + .hot => if (cold) { + try p.errTok(.ignore_hot, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + hot = true; + }, + .cold => if (hot) { + try p.errTok(.ignore_cold, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + cold = true; + }, + .always_inline => if (@"noinline") { + try p.errTok(.ignore_always_inline, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + always_inline = true; + }, + .@"noinline" => if (always_inline) { + try p.errTok(.ignore_noinline, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + @"noinline" = true; + }, + .aligned => try attr.applyAligned(p, base_ty, null), + .format => try attr.applyFormat(p, base_ty), + .calling_convention => switch (attr.args.calling_convention.cc) { + .C => continue, + .stdcall, .thiscall => switch (p.comp.target.cpu.arch) { + .x86 => try p.attr_application_buf.append(p.gpa, attr), + else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?), + }, + .vectorcall => switch (p.comp.target.cpu.arch) { + .x86, .aarch64, .aarch64_be => try p.attr_application_buf.append(p.gpa, attr), + else => try p.errStr(.callconv_not_supported, tok, p.tok_ids[tok].lexeme().?), + }, + }, + .malloc => { + if (base_ty.returnType().isPtr()) { + try p.attr_application_buf.append(p.gpa, attr); + } else { + try ignoredAttrErr(p, tok, attr.tag, "functions that do not return pointers"); + } + }, + .access, + .alloc_align, + .alloc_size, + .artificial, + .assume_aligned, + .constructor, + .copy, + .destructor, + .format_arg, + .ifunc, + .interrupt, + .interrupt_handler, + .no_address_safety_analysis, + .no_icf, + .no_instrument_function, + .no_profile_instrument_function, + .no_reorder, + .no_sanitize, + .no_sanitize_address, + .no_sanitize_coverage, + .no_sanitize_thread, + .no_sanitize_undefined, + .no_split_stack, + .no_stack_limit, + .no_stack_protector, + .noclone, + .noipa, + // .nonnull, + .noplt, + // .optimize, + .patchable_function_entry, + .sentinel, + .simd, + .stack_protect, + .symver, + .target, + .target_clones, + .visibility, + .weakref, + .zero_call_used_regs, + => |t| try p.errExtra(.attribute_todo, tok, .{ .attribute_todo = .{ .tag = t, .kind = .functions } }), + else => try ignoredAttrErr(p, tok, attr.tag, "functions"), + }; + return ty.withAttributes(p.arena, p.attr_application_buf.items); +} + +pub fn applyLabelAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type { + const attrs = p.attr_buf.items(.attr)[attr_buf_start..]; + const toks = p.attr_buf.items(.tok)[attr_buf_start..]; + p.attr_application_buf.items.len = 0; + var hot = false; + var cold = false; + for (attrs, toks) |attr, tok| switch (attr.tag) { + .unused => try p.attr_application_buf.append(p.gpa, attr), + .hot => if (cold) { + try p.errTok(.ignore_hot, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + hot = true; + }, + .cold => if (hot) { + try p.errTok(.ignore_cold, tok); + } else { + try p.attr_application_buf.append(p.gpa, attr); + cold = true; + }, + else => try ignoredAttrErr(p, tok, attr.tag, "labels"), + }; + return ty.withAttributes(p.arena, p.attr_application_buf.items); +} + +pub fn applyStatementAttributes(p: *Parser, ty: Type, expr_start: TokenIndex, attr_buf_start: usize) !Type { + const attrs = p.attr_buf.items(.attr)[attr_buf_start..]; + const toks = p.attr_buf.items(.tok)[attr_buf_start..]; + p.attr_application_buf.items.len = 0; + for (attrs, toks) |attr, tok| switch (attr.tag) { + .fallthrough => if (p.tok_ids[p.tok_i] != .keyword_case and p.tok_ids[p.tok_i] != .keyword_default) { + // TODO: this condition is not completely correct; the last statement of a compound + // statement is also valid if it precedes a switch label (so intervening '}' are ok, + // but only if they close a compound statement) + try p.errTok(.invalid_fallthrough, expr_start); + } else { + try p.attr_application_buf.append(p.gpa, attr); + }, + else => try p.errStr(.cannot_apply_attribute_to_statement, tok, @tagName(attr.tag)), + }; + return ty.withAttributes(p.arena, p.attr_application_buf.items); +} + +pub fn applyEnumeratorAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type { + const attrs = p.attr_buf.items(.attr)[attr_buf_start..]; + const toks = p.attr_buf.items(.tok)[attr_buf_start..]; + p.attr_application_buf.items.len = 0; + for (attrs, toks) |attr, tok| switch (attr.tag) { + .deprecated, .unavailable => try p.attr_application_buf.append(p.gpa, attr), + else => try ignoredAttrErr(p, tok, attr.tag, "enums"), + }; + return ty.withAttributes(p.arena, p.attr_application_buf.items); +} + +fn applyAligned(attr: Attribute, p: *Parser, ty: Type, tag: ?Diagnostics.Tag) !void { + const base = ty.canonicalize(.standard); + if (attr.args.aligned.alignment) |alignment| alignas: { + if (attr.syntax != .keyword) break :alignas; + + const align_tok = attr.args.aligned.__name_tok; + if (tag) |t| try p.errTok(t, align_tok); + + const default_align = base.alignof(p.comp); + if (ty.isFunc()) { + try p.errTok(.alignas_on_func, align_tok); + } else if (alignment.requested < default_align) { + try p.errExtra(.minimum_alignment, align_tok, .{ .unsigned = default_align }); + } + } + try p.attr_application_buf.append(p.gpa, attr); +} + +fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type) !void { + const union_ty = ty.get(.@"union") orelse { + return p.errTok(.transparent_union_wrong_type, tok); + }; + // TODO validate union defined at end + if (union_ty.data.record.isIncomplete()) return; + const fields = union_ty.data.record.fields; + if (fields.len == 0) { + return p.errTok(.transparent_union_one_field, tok); + } + const first_field_size = fields[0].ty.bitSizeof(p.comp).?; + for (fields[1..]) |field| { + const field_size = field.ty.bitSizeof(p.comp).?; + if (field_size == first_field_size) continue; + const mapper = p.comp.string_interner.getSlowTypeMapper(); + const str = try std.fmt.allocPrint( + p.comp.diagnostics.arena.allocator(), + "'{s}' ({d}", + .{ mapper.lookup(field.name), field_size }, + ); + try p.errStr(.transparent_union_size, field.name_tok, str); + return p.errExtra(.transparent_union_size_note, fields[0].name_tok, .{ .unsigned = first_field_size }); + } + + try p.attr_application_buf.append(p.gpa, attr); +} + +fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !void { + const base = ty.base(); + const is_enum = ty.is(.@"enum"); + if (!(ty.isInt() or ty.isFloat()) or !ty.isReal() or (is_enum and p.comp.langopts.emulate == .gcc)) { + try p.errStr(.invalid_vec_elem_ty, tok, try p.typeStr(ty.*)); + return error.ParsingFailed; + } + if (is_enum) return; + + const vec_bytes = attr.args.vector_size.bytes; + const ty_size = ty.sizeof(p.comp).?; + if (vec_bytes % ty_size != 0) { + return p.errTok(.vec_size_not_multiple, tok); + } + const vec_size = vec_bytes / ty_size; + + const arr_ty = try p.arena.create(Type.Array); + arr_ty.* = .{ .elem = ty.*, .len = vec_size }; + base.* = .{ + .specifier = .vector, + .data = .{ .array = arr_ty }, + }; +} + +fn applyFormat(attr: Attribute, p: *Parser, ty: Type) !void { + // TODO validate + _ = ty; + try p.attr_application_buf.append(p.gpa, attr); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Attribute/names.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Attribute/names.zig new file mode 100644 index 00000000..c0732b61 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Attribute/names.zig @@ -0,0 +1,1002 @@ +//! Autogenerated by GenerateDef from src/aro/Attribute/names.def, do not edit +// zig fmt: off + +const std = @import("std"); + +pub fn with(comptime Properties: type) type { +return struct { + +tag: Tag, +properties: Properties, + +/// Integer starting at 0 derived from the unique index, +/// corresponds with the data array index. +pub const Tag = enum(u16) { _ }; + +const Self = @This(); + +pub fn fromName(name: []const u8) ?@This() { + const data_index = tagFromName(name) orelse return null; + return data[@intFromEnum(data_index)]; +} + +pub fn tagFromName(name: []const u8) ?Tag { + const unique_index = uniqueIndex(name) orelse return null; + return @enumFromInt(unique_index - 1); +} + +pub fn fromTag(tag: Tag) @This() { + return data[@intFromEnum(tag)]; +} + +pub fn nameFromTagIntoBuf(tag: Tag, name_buf: []u8) []u8 { + std.debug.assert(name_buf.len >= longest_name); + const unique_index = @intFromEnum(tag) + 1; + return nameFromUniqueIndex(unique_index, name_buf); +} + +pub fn nameFromTag(tag: Tag) NameBuf { + var name_buf: NameBuf = undefined; + const unique_index = @intFromEnum(tag) + 1; + const name = nameFromUniqueIndex(unique_index, &name_buf.buf); + name_buf.len = @intCast(name.len); + return name_buf; +} + +pub const NameBuf = struct { + buf: [longest_name]u8 = undefined, + len: std.math.IntFittingRange(0, longest_name), + + pub fn span(self: *const NameBuf) []const u8 { + return self.buf[0..self.len]; + } +}; + +pub fn exists(name: []const u8) bool { + if (name.len < shortest_name or name.len > longest_name) return false; + + var index: u16 = 0; + for (name) |c| { + index = findInList(dafsa[index].child_index, c) orelse return false; + } + return dafsa[index].end_of_word; +} + +pub const shortest_name = 3; +pub const longest_name = 30; + +/// Search siblings of `first_child_index` for the `char` +/// If found, returns the index of the node within the `dafsa` array. +/// Otherwise, returns `null`. +pub fn findInList(first_child_index: u16, char: u8) ?u16 { + @setEvalBranchQuota(206); + var index = first_child_index; + while (true) { + if (dafsa[index].char == char) return index; + if (dafsa[index].end_of_list) return null; + index += 1; + } + unreachable; +} + +/// Returns a unique (minimal perfect hash) index (starting at 1) for the `name`, +/// or null if the name was not found. +pub fn uniqueIndex(name: []const u8) ?u16 { + if (name.len < shortest_name or name.len > longest_name) return null; + + var index: u16 = 0; + var node_index: u16 = 0; + + for (name) |c| { + const child_index = findInList(dafsa[node_index].child_index, c) orelse return null; + var sibling_index = dafsa[node_index].child_index; + while (true) { + const sibling_c = dafsa[sibling_index].char; + std.debug.assert(sibling_c != 0); + if (sibling_c < c) { + index += dafsa[sibling_index].number; + } + if (dafsa[sibling_index].end_of_list) break; + sibling_index += 1; + } + node_index = child_index; + if (dafsa[node_index].end_of_word) index += 1; + } + + if (!dafsa[node_index].end_of_word) return null; + + return index; +} + +/// Returns a slice of `buf` with the name associated with the given `index`. +/// This function should only be called with an `index` that +/// is already known to exist within the `dafsa`, e.g. an index +/// returned from `uniqueIndex`. +pub fn nameFromUniqueIndex(index: u16, buf: []u8) []u8 { + std.debug.assert(index >= 1 and index <= data.len); + + var node_index: u16 = 0; + var count: u16 = index; + var fbs = std.io.fixedBufferStream(buf); + const w = fbs.writer(); + + while (true) { + var sibling_index = dafsa[node_index].child_index; + while (true) { + if (dafsa[sibling_index].number > 0 and dafsa[sibling_index].number < count) { + count -= dafsa[sibling_index].number; + } else { + w.writeByte(dafsa[sibling_index].char) catch unreachable; + node_index = sibling_index; + if (dafsa[node_index].end_of_word) { + count -= 1; + } + break; + } + + if (dafsa[sibling_index].end_of_list) break; + sibling_index += 1; + } + if (count == 0) break; + } + + return fbs.getWritten(); +} + +const Node = packed struct(u32) { + char: u8, + /// Nodes are numbered with "an integer which gives the number of words that + /// would be accepted by the automaton starting from that state." This numbering + /// allows calculating "a one-to-one correspondence between the integers 1 to L + /// (L is the number of words accepted by the automaton) and the words themselves." + /// + /// Essentially, this allows us to have a minimal perfect hashing scheme such that + /// it's possible to store & lookup the properties of each name using a separate array. + number: u8, + /// If true, this node is the end of a valid name. + /// Note: This does not necessarily mean that this node does not have child nodes. + end_of_word: bool, + /// If true, this node is the end of a sibling list. + /// If false, then (index + 1) will contain the next sibling. + end_of_list: bool, + /// Index of the first child of this node. + child_index: u14, +}; + +const dafsa = [_]Node{ + .{ .char = 0, .end_of_word = false, .end_of_list = true, .number = 0, .child_index = 1 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 21 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 26 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 28 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 30 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 32 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 35 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 36 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 37 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 39 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 40 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 41 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 43 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 45 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 49 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 50 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 57 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 61 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 64 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 66 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 68 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 69 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 70 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 73 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 74 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 75 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 76 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 77 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 82 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 84 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 85 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 86 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 87 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 88 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 89 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 90 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 92 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 93 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 94 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 95 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 96 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 98 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 99 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 23, .child_index = 100 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 108 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 110 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 111 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 112 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 113 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 116 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 117 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 118 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 121 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 122 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 123 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 124 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 125 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 126 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 127 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 128 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 129 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 133 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 134 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 135 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 136 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 137 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 138 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 139 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 140 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 141 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 143 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 144 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 145 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 146 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 147 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 148 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 149 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 150 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 151 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 152 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 154 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 155 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 157 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 159 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 160 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 161 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 162 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 163 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 164 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 165 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 166 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 167 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 168 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 169 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 170 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 173 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 178 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 179 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 181 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 182 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 184 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 185 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 186 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 99 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 187 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 188 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 69 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 189 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 190 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 191 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 193 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 194 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 195 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 196 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 197 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 198 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 199 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 200 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 201 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 202 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 203 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 204 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 205 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 206 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 207 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 208 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 209 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 211 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 212 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 213 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 214 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 215 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 216 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 217 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 218 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 219 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 220 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 221 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 222 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 223 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 224 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 225 }, + .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 226 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 227 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 228 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 229 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 230 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 231 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 232 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 233 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 234 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 235 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 236 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 237 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 238 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 239 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 240 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 241 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 242 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 243 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 244 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 246 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 247 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 248 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 251 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 252 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 253 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 254 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 255 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 257 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 258 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 259 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 260 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 261 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 262 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 263 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 264 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 265 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 266 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 267 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 268 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 269 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 270 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 271 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 272 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 273 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 274 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 275 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 276 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 277 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 278 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 279 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 280 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 281 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 282 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 283 }, + .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 285 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 286 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 287 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 288 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 290 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 293 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 294 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 295 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 297 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 298 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 299 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 300 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 301 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 301 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 302 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 303 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 304 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 305 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 306 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 307 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 308 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 237 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 309 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 310 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 168 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 312 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 313 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 314 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 315 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 316 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 317 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 318 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 151 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 319 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 91 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 320 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 321 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 322 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 324 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 325 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 326 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 327 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 328 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 329 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 224 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 330 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 331 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 112 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 332 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 231 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 333 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 334 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 335 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 336 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 337 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 338 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 339 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 340 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 341 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 343 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 345 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 346 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 348 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 164 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 349 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 350 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 351 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 353 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 300 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 354 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 355 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 356 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 357 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 358 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 359 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 360 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 361 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 362 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 363 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 364 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 365 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 366 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 367 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 368 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 369 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 370 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 371 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 372 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 318 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 373 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 374 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 375 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 376 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 377 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 378 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 379 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 380 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 381 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 382 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 383 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 384 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 385 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 386 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 387 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 388 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 389 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 390 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 391 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 392 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 393 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 394 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 395 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 168 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 396 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 397 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 398 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 399 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 264 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 401 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 402 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 395 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 403 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 404 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 405 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 406 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 407 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 408 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 409 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 320 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 410 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 411 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 413 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 414 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 415 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 416 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 417 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 418 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 419 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 420 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 343 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 421 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 422 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 423 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 424 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 425 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 426 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 427 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 428 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 429 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 430 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 383 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 431 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 432 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 433 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 434 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 435 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 436 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 437 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 438 }, + .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 439 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 440 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 441 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 231 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 442 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 443 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 444 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 159 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 445 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 446 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 447 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 448 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 449 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 452 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 453 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 273 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 454 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 455 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 456 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 150 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 460 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 462 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 464 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 465 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 466 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 467 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 468 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 469 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 398 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 470 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 471 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 472 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 473 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 474 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 428 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 475 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 476 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 477 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 478 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 395 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 479 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 480 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 208 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 481 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 482 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 483 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 484 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 485 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 486 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 488 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 467 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 489 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 490 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 491 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 492 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 493 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 494 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 495 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 497 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 498 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 499 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 500 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 296 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 501 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 502 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 503 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 504 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 505 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 506 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 507 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 508 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 509 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 510 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 511 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 512 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 513 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 514 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 515 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 516 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 517 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 518 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 520 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 522 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 523 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 524 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 525 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 526 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 527 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 528 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 237 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 529 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 530 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 531 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 532 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 533 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 534 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 535 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 536 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 537 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 538 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 539 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 378 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 540 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 541 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 351 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 542 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 543 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 133 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 544 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 545 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 546 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 547 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 548 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 549 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 550 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 554 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 555 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 556 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 557 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 558 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 559 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 560 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 561 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 562 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 555 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 563 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 564 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 565 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 566 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 567 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 568 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 570 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 571 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 91 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 573 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 574 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 575 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 576 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 577 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 578 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 581 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 582 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 583 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 126 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 584 }, + .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 356 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 428 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 586 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 268 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 587 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 588 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 273 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 589 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 590 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 591 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 592 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 593 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 594 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 313 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 595 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 596 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 597 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 598 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 140 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 599 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 600 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 601 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 185 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 602 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 603 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 604 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 605 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 606 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 607 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 608 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 609 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 195 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 610 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 525 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 611 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 612 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 172 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 613 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 614 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 615 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 616 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 617 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 618 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 619 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 620 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 153 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 621 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 215 }, +}; +pub const data = blk: { + @setEvalBranchQuota(721); + break :blk [_]@This(){ + // access + .{ .tag = @enumFromInt(0), .properties = .{ .tag = .access, .gnu = true } }, + // alias + .{ .tag = @enumFromInt(1), .properties = .{ .tag = .alias, .gnu = true } }, + // align + .{ .tag = @enumFromInt(2), .properties = .{ .tag = .aligned, .declspec = true } }, + // aligned + .{ .tag = @enumFromInt(3), .properties = .{ .tag = .aligned, .gnu = true } }, + // alloc_align + .{ .tag = @enumFromInt(4), .properties = .{ .tag = .alloc_align, .gnu = true } }, + // alloc_size + .{ .tag = @enumFromInt(5), .properties = .{ .tag = .alloc_size, .gnu = true } }, + // allocate + .{ .tag = @enumFromInt(6), .properties = .{ .tag = .allocate, .declspec = true } }, + // allocator + .{ .tag = @enumFromInt(7), .properties = .{ .tag = .allocator, .declspec = true } }, + // always_inline + .{ .tag = @enumFromInt(8), .properties = .{ .tag = .always_inline, .gnu = true } }, + // appdomain + .{ .tag = @enumFromInt(9), .properties = .{ .tag = .appdomain, .declspec = true } }, + // artificial + .{ .tag = @enumFromInt(10), .properties = .{ .tag = .artificial, .gnu = true } }, + // assume_aligned + .{ .tag = @enumFromInt(11), .properties = .{ .tag = .assume_aligned, .gnu = true } }, + // cleanup + .{ .tag = @enumFromInt(12), .properties = .{ .tag = .cleanup, .gnu = true } }, + // code_seg + .{ .tag = @enumFromInt(13), .properties = .{ .tag = .code_seg, .declspec = true } }, + // cold + .{ .tag = @enumFromInt(14), .properties = .{ .tag = .cold, .gnu = true } }, + // common + .{ .tag = @enumFromInt(15), .properties = .{ .tag = .common, .gnu = true } }, + // const + .{ .tag = @enumFromInt(16), .properties = .{ .tag = .@"const", .gnu = true } }, + // constructor + .{ .tag = @enumFromInt(17), .properties = .{ .tag = .constructor, .gnu = true } }, + // copy + .{ .tag = @enumFromInt(18), .properties = .{ .tag = .copy, .gnu = true } }, + // deprecated + .{ .tag = @enumFromInt(19), .properties = .{ .tag = .deprecated, .c23 = true, .gnu = true, .declspec = true } }, + // designated_init + .{ .tag = @enumFromInt(20), .properties = .{ .tag = .designated_init, .gnu = true } }, + // destructor + .{ .tag = @enumFromInt(21), .properties = .{ .tag = .destructor, .gnu = true } }, + // dllexport + .{ .tag = @enumFromInt(22), .properties = .{ .tag = .dllexport, .declspec = true } }, + // dllimport + .{ .tag = @enumFromInt(23), .properties = .{ .tag = .dllimport, .declspec = true } }, + // error + .{ .tag = @enumFromInt(24), .properties = .{ .tag = .@"error", .gnu = true } }, + // externally_visible + .{ .tag = @enumFromInt(25), .properties = .{ .tag = .externally_visible, .gnu = true } }, + // fallthrough + .{ .tag = @enumFromInt(26), .properties = .{ .tag = .fallthrough, .c23 = true, .gnu = true } }, + // flatten + .{ .tag = @enumFromInt(27), .properties = .{ .tag = .flatten, .gnu = true } }, + // format + .{ .tag = @enumFromInt(28), .properties = .{ .tag = .format, .gnu = true } }, + // format_arg + .{ .tag = @enumFromInt(29), .properties = .{ .tag = .format_arg, .gnu = true } }, + // gnu_inline + .{ .tag = @enumFromInt(30), .properties = .{ .tag = .gnu_inline, .gnu = true } }, + // hot + .{ .tag = @enumFromInt(31), .properties = .{ .tag = .hot, .gnu = true } }, + // ifunc + .{ .tag = @enumFromInt(32), .properties = .{ .tag = .ifunc, .gnu = true } }, + // interrupt + .{ .tag = @enumFromInt(33), .properties = .{ .tag = .interrupt, .gnu = true } }, + // interrupt_handler + .{ .tag = @enumFromInt(34), .properties = .{ .tag = .interrupt_handler, .gnu = true } }, + // jitintrinsic + .{ .tag = @enumFromInt(35), .properties = .{ .tag = .jitintrinsic, .declspec = true } }, + // leaf + .{ .tag = @enumFromInt(36), .properties = .{ .tag = .leaf, .gnu = true } }, + // malloc + .{ .tag = @enumFromInt(37), .properties = .{ .tag = .malloc, .gnu = true } }, + // may_alias + .{ .tag = @enumFromInt(38), .properties = .{ .tag = .may_alias, .gnu = true } }, + // maybe_unused + .{ .tag = @enumFromInt(39), .properties = .{ .tag = .unused, .c23 = true } }, + // mode + .{ .tag = @enumFromInt(40), .properties = .{ .tag = .mode, .gnu = true } }, + // naked + .{ .tag = @enumFromInt(41), .properties = .{ .tag = .naked, .declspec = true } }, + // no_address_safety_analysis + .{ .tag = @enumFromInt(42), .properties = .{ .tag = .no_address_safety_analysis, .gnu = true } }, + // no_icf + .{ .tag = @enumFromInt(43), .properties = .{ .tag = .no_icf, .gnu = true } }, + // no_instrument_function + .{ .tag = @enumFromInt(44), .properties = .{ .tag = .no_instrument_function, .gnu = true } }, + // no_profile_instrument_function + .{ .tag = @enumFromInt(45), .properties = .{ .tag = .no_profile_instrument_function, .gnu = true } }, + // no_reorder + .{ .tag = @enumFromInt(46), .properties = .{ .tag = .no_reorder, .gnu = true } }, + // no_sanitize + .{ .tag = @enumFromInt(47), .properties = .{ .tag = .no_sanitize, .gnu = true } }, + // no_sanitize_address + .{ .tag = @enumFromInt(48), .properties = .{ .tag = .no_sanitize_address, .gnu = true, .declspec = true } }, + // no_sanitize_coverage + .{ .tag = @enumFromInt(49), .properties = .{ .tag = .no_sanitize_coverage, .gnu = true } }, + // no_sanitize_thread + .{ .tag = @enumFromInt(50), .properties = .{ .tag = .no_sanitize_thread, .gnu = true } }, + // no_sanitize_undefined + .{ .tag = @enumFromInt(51), .properties = .{ .tag = .no_sanitize_undefined, .gnu = true } }, + // no_split_stack + .{ .tag = @enumFromInt(52), .properties = .{ .tag = .no_split_stack, .gnu = true } }, + // no_stack_limit + .{ .tag = @enumFromInt(53), .properties = .{ .tag = .no_stack_limit, .gnu = true } }, + // no_stack_protector + .{ .tag = @enumFromInt(54), .properties = .{ .tag = .no_stack_protector, .gnu = true } }, + // noalias + .{ .tag = @enumFromInt(55), .properties = .{ .tag = .@"noalias", .declspec = true } }, + // noclone + .{ .tag = @enumFromInt(56), .properties = .{ .tag = .noclone, .gnu = true } }, + // nocommon + .{ .tag = @enumFromInt(57), .properties = .{ .tag = .nocommon, .gnu = true } }, + // nodiscard + .{ .tag = @enumFromInt(58), .properties = .{ .tag = .nodiscard, .c23 = true } }, + // noinit + .{ .tag = @enumFromInt(59), .properties = .{ .tag = .noinit, .gnu = true } }, + // noinline + .{ .tag = @enumFromInt(60), .properties = .{ .tag = .@"noinline", .gnu = true, .declspec = true } }, + // noipa + .{ .tag = @enumFromInt(61), .properties = .{ .tag = .noipa, .gnu = true } }, + // nonstring + .{ .tag = @enumFromInt(62), .properties = .{ .tag = .nonstring, .gnu = true } }, + // noplt + .{ .tag = @enumFromInt(63), .properties = .{ .tag = .noplt, .gnu = true } }, + // noreturn + .{ .tag = @enumFromInt(64), .properties = .{ .tag = .@"noreturn", .c23 = true, .gnu = true, .declspec = true } }, + // packed + .{ .tag = @enumFromInt(65), .properties = .{ .tag = .@"packed", .gnu = true } }, + // patchable_function_entry + .{ .tag = @enumFromInt(66), .properties = .{ .tag = .patchable_function_entry, .gnu = true } }, + // persistent + .{ .tag = @enumFromInt(67), .properties = .{ .tag = .persistent, .gnu = true } }, + // process + .{ .tag = @enumFromInt(68), .properties = .{ .tag = .process, .declspec = true } }, + // pure + .{ .tag = @enumFromInt(69), .properties = .{ .tag = .pure, .gnu = true } }, + // reproducible + .{ .tag = @enumFromInt(70), .properties = .{ .tag = .reproducible, .c23 = true } }, + // restrict + .{ .tag = @enumFromInt(71), .properties = .{ .tag = .restrict, .declspec = true } }, + // retain + .{ .tag = @enumFromInt(72), .properties = .{ .tag = .retain, .gnu = true } }, + // returns_nonnull + .{ .tag = @enumFromInt(73), .properties = .{ .tag = .returns_nonnull, .gnu = true } }, + // returns_twice + .{ .tag = @enumFromInt(74), .properties = .{ .tag = .returns_twice, .gnu = true } }, + // safebuffers + .{ .tag = @enumFromInt(75), .properties = .{ .tag = .safebuffers, .declspec = true } }, + // scalar_storage_order + .{ .tag = @enumFromInt(76), .properties = .{ .tag = .scalar_storage_order, .gnu = true } }, + // section + .{ .tag = @enumFromInt(77), .properties = .{ .tag = .section, .gnu = true } }, + // selectany + .{ .tag = @enumFromInt(78), .properties = .{ .tag = .selectany, .declspec = true } }, + // sentinel + .{ .tag = @enumFromInt(79), .properties = .{ .tag = .sentinel, .gnu = true } }, + // simd + .{ .tag = @enumFromInt(80), .properties = .{ .tag = .simd, .gnu = true } }, + // spectre + .{ .tag = @enumFromInt(81), .properties = .{ .tag = .spectre, .declspec = true } }, + // stack_protect + .{ .tag = @enumFromInt(82), .properties = .{ .tag = .stack_protect, .gnu = true } }, + // symver + .{ .tag = @enumFromInt(83), .properties = .{ .tag = .symver, .gnu = true } }, + // target + .{ .tag = @enumFromInt(84), .properties = .{ .tag = .target, .gnu = true } }, + // target_clones + .{ .tag = @enumFromInt(85), .properties = .{ .tag = .target_clones, .gnu = true } }, + // thread + .{ .tag = @enumFromInt(86), .properties = .{ .tag = .thread, .declspec = true } }, + // tls_model + .{ .tag = @enumFromInt(87), .properties = .{ .tag = .tls_model, .gnu = true } }, + // transparent_union + .{ .tag = @enumFromInt(88), .properties = .{ .tag = .transparent_union, .gnu = true } }, + // unavailable + .{ .tag = @enumFromInt(89), .properties = .{ .tag = .unavailable, .gnu = true } }, + // uninitialized + .{ .tag = @enumFromInt(90), .properties = .{ .tag = .uninitialized, .gnu = true } }, + // unsequenced + .{ .tag = @enumFromInt(91), .properties = .{ .tag = .unsequenced, .c23 = true } }, + // unused + .{ .tag = @enumFromInt(92), .properties = .{ .tag = .unused, .gnu = true } }, + // used + .{ .tag = @enumFromInt(93), .properties = .{ .tag = .used, .gnu = true } }, + // uuid + .{ .tag = @enumFromInt(94), .properties = .{ .tag = .uuid, .declspec = true } }, + // vector_size + .{ .tag = @enumFromInt(95), .properties = .{ .tag = .vector_size, .gnu = true } }, + // visibility + .{ .tag = @enumFromInt(96), .properties = .{ .tag = .visibility, .gnu = true } }, + // warn_if_not_aligned + .{ .tag = @enumFromInt(97), .properties = .{ .tag = .warn_if_not_aligned, .gnu = true } }, + // warn_unused_result + .{ .tag = @enumFromInt(98), .properties = .{ .tag = .warn_unused_result, .gnu = true } }, + // warning + .{ .tag = @enumFromInt(99), .properties = .{ .tag = .warning, .gnu = true } }, + // weak + .{ .tag = @enumFromInt(100), .properties = .{ .tag = .weak, .gnu = true } }, + // weakref + .{ .tag = @enumFromInt(101), .properties = .{ .tag = .weakref, .gnu = true } }, + // zero_call_used_regs + .{ .tag = @enumFromInt(102), .properties = .{ .tag = .zero_call_used_regs, .gnu = true } }, + }; +}; +}; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins.zig new file mode 100644 index 00000000..6443a6b6 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins.zig @@ -0,0 +1,394 @@ +const std = @import("std"); +const Compilation = @import("Compilation.zig"); +const Type = @import("Type.zig"); +const TypeDescription = @import("Builtins/TypeDescription.zig"); +const target_util = @import("target.zig"); +const StringId = @import("StringInterner.zig").StringId; +const LangOpts = @import("LangOpts.zig"); +const Parser = @import("Parser.zig"); + +const Properties = @import("Builtins/Properties.zig"); +pub const Builtin = @import("Builtins/Builtin.zig").with(Properties); + +const Expanded = struct { + ty: Type, + builtin: Builtin, +}; + +const NameToTypeMap = std.StringHashMapUnmanaged(Type); + +const Builtins = @This(); + +_name_to_type_map: NameToTypeMap = .{}, + +pub fn deinit(b: *Builtins, gpa: std.mem.Allocator) void { + b._name_to_type_map.deinit(gpa); +} + +fn specForSize(comp: *const Compilation, size_bits: u32) Type.Builder.Specifier { + var ty = Type{ .specifier = .short }; + if (ty.sizeof(comp).? * 8 == size_bits) return .short; + + ty.specifier = .int; + if (ty.sizeof(comp).? * 8 == size_bits) return .int; + + ty.specifier = .long; + if (ty.sizeof(comp).? * 8 == size_bits) return .long; + + ty.specifier = .long_long; + if (ty.sizeof(comp).? * 8 == size_bits) return .long_long; + + unreachable; +} + +fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *const Compilation, allocator: std.mem.Allocator) !Type { + var builder: Type.Builder = .{ .error_on_invalid = true }; + var require_native_int32 = false; + var require_native_int64 = false; + for (desc.prefix) |prefix| { + switch (prefix) { + .L => builder.combine(undefined, .long, 0) catch unreachable, + .LL => { + builder.combine(undefined, .long, 0) catch unreachable; + builder.combine(undefined, .long, 0) catch unreachable; + }, + .LLL => { + switch (builder.specifier) { + .none => builder.specifier = .int128, + .signed => builder.specifier = .sint128, + .unsigned => builder.specifier = .uint128, + else => unreachable, + } + }, + .Z => require_native_int32 = true, + .W => require_native_int64 = true, + .N => { + std.debug.assert(desc.spec == .i); + if (!target_util.isLP64(comp.target)) { + builder.combine(undefined, .long, 0) catch unreachable; + } + }, + .O => { + builder.combine(undefined, .long, 0) catch unreachable; + if (comp.target.os.tag != .opencl) { + builder.combine(undefined, .long, 0) catch unreachable; + } + }, + .S => builder.combine(undefined, .signed, 0) catch unreachable, + .U => builder.combine(undefined, .unsigned, 0) catch unreachable, + .I => { + // Todo: compile-time constant integer + }, + } + } + switch (desc.spec) { + .v => builder.combine(undefined, .void, 0) catch unreachable, + .b => builder.combine(undefined, .bool, 0) catch unreachable, + .c => builder.combine(undefined, .char, 0) catch unreachable, + .s => builder.combine(undefined, .short, 0) catch unreachable, + .i => { + if (require_native_int32) { + builder.specifier = specForSize(comp, 32); + } else if (require_native_int64) { + builder.specifier = specForSize(comp, 64); + } else { + switch (builder.specifier) { + .int128, .sint128, .uint128 => {}, + else => builder.combine(undefined, .int, 0) catch unreachable, + } + } + }, + .h => builder.combine(undefined, .fp16, 0) catch unreachable, + .x => builder.combine(undefined, .float16, 0) catch unreachable, + .y => { + // Todo: __bf16 + return .{ .specifier = .invalid }; + }, + .f => builder.combine(undefined, .float, 0) catch unreachable, + .d => { + if (builder.specifier == .long_long) { + builder.specifier = .float128; + } else { + builder.combine(undefined, .double, 0) catch unreachable; + } + }, + .z => { + std.debug.assert(builder.specifier == .none); + builder.specifier = Type.Builder.fromType(comp.types.size); + }, + .w => { + std.debug.assert(builder.specifier == .none); + builder.specifier = Type.Builder.fromType(comp.types.wchar); + }, + .F => { + std.debug.assert(builder.specifier == .none); + builder.specifier = Type.Builder.fromType(comp.types.ns_constant_string.ty); + }, + .G => { + // Todo: id + return .{ .specifier = .invalid }; + }, + .H => { + // Todo: SEL + return .{ .specifier = .invalid }; + }, + .M => { + // Todo: struct objc_super + return .{ .specifier = .invalid }; + }, + .a => { + std.debug.assert(builder.specifier == .none); + std.debug.assert(desc.suffix.len == 0); + builder.specifier = Type.Builder.fromType(comp.types.va_list); + }, + .A => { + std.debug.assert(builder.specifier == .none); + std.debug.assert(desc.suffix.len == 0); + var va_list = comp.types.va_list; + if (va_list.isArray()) va_list.decayArray(); + builder.specifier = Type.Builder.fromType(va_list); + }, + .V => |element_count| { + std.debug.assert(desc.suffix.len == 0); + const child_desc = it.next().?; + const child_ty = try createType(child_desc, undefined, comp, allocator); + const arr_ty = try allocator.create(Type.Array); + arr_ty.* = .{ + .len = element_count, + .elem = child_ty, + }; + const vector_ty: Type = .{ .specifier = .vector, .data = .{ .array = arr_ty } }; + builder.specifier = Type.Builder.fromType(vector_ty); + }, + .q => { + // Todo: scalable vector + return .{ .specifier = .invalid }; + }, + .E => { + // Todo: ext_vector (OpenCL vector) + return .{ .specifier = .invalid }; + }, + .X => |child| { + builder.combine(undefined, .complex, 0) catch unreachable; + switch (child) { + .float => builder.combine(undefined, .float, 0) catch unreachable, + .double => builder.combine(undefined, .double, 0) catch unreachable, + .longdouble => { + builder.combine(undefined, .long, 0) catch unreachable; + builder.combine(undefined, .double, 0) catch unreachable; + }, + } + }, + .Y => { + std.debug.assert(builder.specifier == .none); + std.debug.assert(desc.suffix.len == 0); + builder.specifier = Type.Builder.fromType(comp.types.ptrdiff); + }, + .P => { + std.debug.assert(builder.specifier == .none); + if (comp.types.file.specifier == .invalid) { + return comp.types.file; + } + builder.specifier = Type.Builder.fromType(comp.types.file); + }, + .J => { + std.debug.assert(builder.specifier == .none); + std.debug.assert(desc.suffix.len == 0); + if (comp.types.jmp_buf.specifier == .invalid) { + return comp.types.jmp_buf; + } + builder.specifier = Type.Builder.fromType(comp.types.jmp_buf); + }, + .SJ => { + std.debug.assert(builder.specifier == .none); + std.debug.assert(desc.suffix.len == 0); + if (comp.types.sigjmp_buf.specifier == .invalid) { + return comp.types.sigjmp_buf; + } + builder.specifier = Type.Builder.fromType(comp.types.sigjmp_buf); + }, + .K => { + std.debug.assert(builder.specifier == .none); + if (comp.types.ucontext_t.specifier == .invalid) { + return comp.types.ucontext_t; + } + builder.specifier = Type.Builder.fromType(comp.types.ucontext_t); + }, + .p => { + std.debug.assert(builder.specifier == .none); + std.debug.assert(desc.suffix.len == 0); + builder.specifier = Type.Builder.fromType(comp.types.pid_t); + }, + .@"!" => return .{ .specifier = .invalid }, + } + for (desc.suffix) |suffix| { + switch (suffix) { + .@"*" => |address_space| { + _ = address_space; // TODO: handle address space + const elem_ty = try allocator.create(Type); + elem_ty.* = builder.finish(undefined) catch unreachable; + const ty = Type{ + .specifier = .pointer, + .data = .{ .sub_type = elem_ty }, + }; + builder.qual = .{}; + builder.specifier = Type.Builder.fromType(ty); + }, + .C => builder.qual.@"const" = 0, + .D => builder.qual.@"volatile" = 0, + .R => builder.qual.restrict = 0, + } + } + return builder.finish(undefined) catch unreachable; +} + +fn createBuiltin(comp: *const Compilation, builtin: Builtin, type_arena: std.mem.Allocator) !Type { + var it = TypeDescription.TypeIterator.init(builtin.properties.param_str); + + const ret_ty_desc = it.next().?; + if (ret_ty_desc.spec == .@"!") { + // Todo: handle target-dependent definition + } + const ret_ty = try createType(ret_ty_desc, &it, comp, type_arena); + var param_count: usize = 0; + var params: [Builtin.max_param_count]Type.Func.Param = undefined; + while (it.next()) |desc| : (param_count += 1) { + params[param_count] = .{ .name_tok = 0, .ty = try createType(desc, &it, comp, type_arena), .name = .empty }; + } + + const duped_params = try type_arena.dupe(Type.Func.Param, params[0..param_count]); + const func = try type_arena.create(Type.Func); + + func.* = .{ + .return_type = ret_ty, + .params = duped_params, + }; + return .{ + .specifier = if (builtin.properties.isVarArgs()) .var_args_func else .func, + .data = .{ .func = func }, + }; +} + +/// Asserts that the builtin has already been created +pub fn lookup(b: *const Builtins, name: []const u8) Expanded { + const builtin = Builtin.fromName(name).?; + const ty = b._name_to_type_map.get(name).?; + return .{ + .builtin = builtin, + .ty = ty, + }; +} + +pub fn getOrCreate(b: *Builtins, comp: *Compilation, name: []const u8, type_arena: std.mem.Allocator) !?Expanded { + const ty = b._name_to_type_map.get(name) orelse { + const builtin = Builtin.fromName(name) orelse return null; + if (!comp.hasBuiltinFunction(builtin)) return null; + + try b._name_to_type_map.ensureUnusedCapacity(comp.gpa, 1); + const ty = try createBuiltin(comp, builtin, type_arena); + b._name_to_type_map.putAssumeCapacity(name, ty); + + return .{ + .builtin = builtin, + .ty = ty, + }; + }; + const builtin = Builtin.fromName(name).?; + return .{ + .builtin = builtin, + .ty = ty, + }; +} + +pub const Iterator = struct { + index: u16 = 1, + name_buf: [Builtin.longest_name]u8 = undefined, + + pub const Entry = struct { + /// Memory of this slice is overwritten on every call to `next` + name: []const u8, + builtin: Builtin, + }; + + pub fn next(self: *Iterator) ?Entry { + if (self.index > Builtin.data.len) return null; + const index = self.index; + const data_index = index - 1; + self.index += 1; + return .{ + .name = Builtin.nameFromUniqueIndex(index, &self.name_buf), + .builtin = Builtin.data[data_index], + }; + } +}; + +test Iterator { + var it = Iterator{}; + + var seen = std.StringHashMap(Builtin).init(std.testing.allocator); + defer seen.deinit(); + + var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena_state.deinit(); + const arena = arena_state.allocator(); + + while (it.next()) |entry| { + const index = Builtin.uniqueIndex(entry.name).?; + var buf: [Builtin.longest_name]u8 = undefined; + const name_from_index = Builtin.nameFromUniqueIndex(index, &buf); + try std.testing.expectEqualStrings(entry.name, name_from_index); + + if (seen.contains(entry.name)) { + std.debug.print("iterated over {s} twice\n", .{entry.name}); + std.debug.print("current data: {}\n", .{entry.builtin}); + std.debug.print("previous data: {}\n", .{seen.get(entry.name).?}); + return error.TestExpectedUniqueEntries; + } + try seen.put(try arena.dupe(u8, entry.name), entry.builtin); + } + try std.testing.expectEqual(@as(usize, Builtin.data.len), seen.count()); +} + +test "All builtins" { + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + _ = try comp.generateBuiltinMacros(.include_system_defines); + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + + const type_arena = arena.allocator(); + + var builtin_it = Iterator{}; + while (builtin_it.next()) |entry| { + const name = try type_arena.dupe(u8, entry.name); + if (try comp.builtins.getOrCreate(&comp, name, type_arena)) |func_ty| { + const get_again = (try comp.builtins.getOrCreate(&comp, name, std.testing.failing_allocator)).?; + const found_by_lookup = comp.builtins.lookup(name); + try std.testing.expectEqual(func_ty.builtin.tag, get_again.builtin.tag); + try std.testing.expectEqual(func_ty.builtin.tag, found_by_lookup.builtin.tag); + } + } +} + +test "Allocation failures" { + const Test = struct { + fn testOne(allocator: std.mem.Allocator) !void { + var comp = Compilation.init(allocator, std.fs.cwd()); + defer comp.deinit(); + _ = try comp.generateBuiltinMacros(.include_system_defines); + var arena = std.heap.ArenaAllocator.init(comp.gpa); + defer arena.deinit(); + + const type_arena = arena.allocator(); + + const num_builtins = 40; + var builtin_it = Iterator{}; + for (0..num_builtins) |_| { + const entry = builtin_it.next().?; + _ = try comp.builtins.getOrCreate(&comp, entry.name, type_arena); + } + } + }; + + try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.testOne, .{}); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/Builtin.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/Builtin.zig new file mode 100644 index 00000000..6e5217b4 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/Builtin.zig @@ -0,0 +1,13146 @@ +//! Autogenerated by GenerateDef from src/aro/Builtins/Builtin.def, do not edit +// zig fmt: off + +const std = @import("std"); + +pub fn with(comptime Properties: type) type { +return struct { +const TargetSet = Properties.TargetSet; +pub const max_param_count = 12; + +tag: Tag, +properties: Properties, + +/// Integer starting at 0 derived from the unique index, +/// corresponds with the data array index. +pub const Tag = enum(u16) { _ }; + +const Self = @This(); + +pub fn fromName(name: []const u8) ?@This() { + const data_index = tagFromName(name) orelse return null; + return data[@intFromEnum(data_index)]; +} + +pub fn tagFromName(name: []const u8) ?Tag { + const unique_index = uniqueIndex(name) orelse return null; + return @enumFromInt(unique_index - 1); +} + +pub fn fromTag(tag: Tag) @This() { + return data[@intFromEnum(tag)]; +} + +pub fn nameFromTagIntoBuf(tag: Tag, name_buf: []u8) []u8 { + std.debug.assert(name_buf.len >= longest_name); + const unique_index = @intFromEnum(tag) + 1; + return nameFromUniqueIndex(unique_index, name_buf); +} + +pub fn nameFromTag(tag: Tag) NameBuf { + var name_buf: NameBuf = undefined; + const unique_index = @intFromEnum(tag) + 1; + const name = nameFromUniqueIndex(unique_index, &name_buf.buf); + name_buf.len = @intCast(name.len); + return name_buf; +} + +pub const NameBuf = struct { + buf: [longest_name]u8 = undefined, + len: std.math.IntFittingRange(0, longest_name), + + pub fn span(self: *const NameBuf) []const u8 { + return self.buf[0..self.len]; + } +}; + +pub fn exists(name: []const u8) bool { + if (name.len < shortest_name or name.len > longest_name) return false; + + var index: u16 = 0; + for (name) |c| { + index = findInList(dafsa[index].child_index, c) orelse return false; + } + return dafsa[index].end_of_word; +} + +pub const shortest_name = 3; +pub const longest_name = 43; + +/// Search siblings of `first_child_index` for the `char` +/// If found, returns the index of the node within the `dafsa` array. +/// Otherwise, returns `null`. +pub fn findInList(first_child_index: u16, char: u8) ?u16 { + @setEvalBranchQuota(7972); + var index = first_child_index; + while (true) { + if (dafsa[index].char == char) return index; + if (dafsa[index].end_of_list) return null; + index += 1; + } + unreachable; +} + +/// Returns a unique (minimal perfect hash) index (starting at 1) for the `name`, +/// or null if the name was not found. +pub fn uniqueIndex(name: []const u8) ?u16 { + if (name.len < shortest_name or name.len > longest_name) return null; + + var index: u16 = 0; + var node_index: u16 = 0; + + for (name) |c| { + const child_index = findInList(dafsa[node_index].child_index, c) orelse return null; + var sibling_index = dafsa[node_index].child_index; + while (true) { + const sibling_c = dafsa[sibling_index].char; + std.debug.assert(sibling_c != 0); + if (sibling_c < c) { + index += dafsa[sibling_index].number; + } + if (dafsa[sibling_index].end_of_list) break; + sibling_index += 1; + } + node_index = child_index; + if (dafsa[node_index].end_of_word) index += 1; + } + + if (!dafsa[node_index].end_of_word) return null; + + return index; +} + +/// Returns a slice of `buf` with the name associated with the given `index`. +/// This function should only be called with an `index` that +/// is already known to exist within the `dafsa`, e.g. an index +/// returned from `uniqueIndex`. +pub fn nameFromUniqueIndex(index: u16, buf: []u8) []u8 { + std.debug.assert(index >= 1 and index <= data.len); + + var node_index: u16 = 0; + var count: u16 = index; + var fbs = std.io.fixedBufferStream(buf); + const w = fbs.writer(); + + while (true) { + var sibling_index = dafsa[node_index].child_index; + while (true) { + if (dafsa[sibling_index].number > 0 and dafsa[sibling_index].number < count) { + count -= dafsa[sibling_index].number; + } else { + w.writeByte(dafsa[sibling_index].char) catch unreachable; + node_index = sibling_index; + if (dafsa[node_index].end_of_word) { + count -= 1; + } + break; + } + + if (dafsa[sibling_index].end_of_list) break; + sibling_index += 1; + } + if (count == 0) break; + } + + return fbs.getWritten(); +} + +/// We're 1 bit shy of being able to fit this in a u32: +/// - char only contains 0-9, a-z, A-Z, and _, so it could use a enum(u6) with a way to convert <-> u8 +/// (note: this would have a performance cost that may make the u32 not worth it) +/// - number has a max value of > 2047 and < 4095 (the first _ node has the largest number), +/// so it could fit into a u12 +/// - child_index currently has a max of > 4095 and < 8191, so it could fit into a u13 +/// +/// with the end_of_word/end_of_list 2 bools, that makes 33 bits total +const Node = packed struct(u64) { + char: u8, + /// Nodes are numbered with "an integer which gives the number of words that + /// would be accepted by the automaton starting from that state." This numbering + /// allows calculating "a one-to-one correspondence between the integers 1 to L + /// (L is the number of words accepted by the automaton) and the words themselves." + /// + /// Essentially, this allows us to have a minimal perfect hashing scheme such that + /// it's possible to store & lookup the properties of each builtin using a separate array. + number: u16, + /// If true, this node is the end of a valid builtin. + /// Note: This does not necessarily mean that this node does not have child nodes. + end_of_word: bool, + /// If true, this node is the end of a sibling list. + /// If false, then (index + 1) will contain the next sibling. + end_of_list: bool, + /// Padding bits to get to u64, unsure if there's some way to use these to improve something. + _extra: u22 = 0, + /// Index of the first child of this node. + child_index: u16, +}; + +const dafsa = [_]Node{ + .{ .char = 0, .end_of_word = false, .end_of_list = true, .number = 0, .child_index = 1 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3639, .child_index = 19 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 32 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 37 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 82, .child_index = 39 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 50 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 33, .child_index = 52 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 62 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 63 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 64 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 67 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 73 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 76 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 78 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 17, .child_index = 80 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 54, .child_index = 83 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 92 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 96 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 100 }, + .{ .char = 'B', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 102 }, + .{ .char = 'E', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 103 }, + .{ .char = 'I', .end_of_word = false, .end_of_list = false, .number = 29, .child_index = 104 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 105 }, + .{ .char = 'R', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 106 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3563, .child_index = 107 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 125 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 127 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 129 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 130 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 131 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 133 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 134 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 135 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 138 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 140 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 141 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 142 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 144 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 145 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 151 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 152 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 154 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 155 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 156 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 159 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 161 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 162 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 164 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 165 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 166 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 168 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 169 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 170 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 171 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 172 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 175 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 177 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 178 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 179 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 180 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 181 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 182 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 183 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 184 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 194 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 195 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 196 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 197 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 199 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 201 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 203 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 204 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 205 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 206 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 207 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 209 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 211 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 213 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 214 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 215 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 216 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 217 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 218 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 220 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 151 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 178 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 31, .child_index = 221 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 223 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 196 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 224 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 226 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 227 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 228 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 231 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 235 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 236 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 237 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 239 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 240 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 241 }, + .{ .char = 'G', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 242 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 34, .child_index = 243 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2967, .child_index = 248 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 249 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 252 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 255 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 257 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 259 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 260 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 390, .child_index = 262 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 264 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 265 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 113, .child_index = 266 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 269 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 270 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 271 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 273 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 274 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 275 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 276 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 277 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 278 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 279 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 281 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 282 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 283 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 284 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 285 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 286 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 287 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 288 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 289 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 223 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 290 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 293 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 294 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 295 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 296 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 140 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 164 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 298 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 300 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 296 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 301 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 302 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 209 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 306 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 307 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 223 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 151 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 223 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 308 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 312 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 294 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 316 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 317 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 318 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = false, .number = 6, .child_index = 319 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 206 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 322 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 324 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 327 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 328 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 329 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 330 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 331 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 332 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 333 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 334 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 335 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 336 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 337 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 338 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 339 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 341 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 342 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 343 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 345 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 346 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 194 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 201 }, + .{ .char = 'g', .end_of_word = true, .end_of_list = false, .number = 15, .child_index = 347 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 353 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 354 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 295 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 355 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 360 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 363 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 364 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 365 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 203 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 366 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 368 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 370 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 371 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 372 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 374 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 375 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 176 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 377 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 379 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 338 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 342 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 389 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 390 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 393 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 327 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 220 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 394 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 397 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 398 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 399 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 400 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 401 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 402 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 275 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 403 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 404 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 405 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 406 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 407 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 17, .child_index = 408 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 409 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 410 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 411 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 238 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 413 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 415 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 170 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 416 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 418 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 419 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 420 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 421 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 422 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 423 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 424 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 425 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 427 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 428 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 429 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 430 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 431 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 433 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 434 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 435 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 289 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 436 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 437 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 438 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 439 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 440 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 441 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 443 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 303 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 444 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 445 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 446 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 452 }, + .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 296 }, + .{ .char = 'j', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 453 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 301 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 298 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 454 }, + .{ .char = 'm', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 455 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 456 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 461 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 462 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 464 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 466 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 467 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 468 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 469 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 470 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 471 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 472 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 473 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 474 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 336 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 475 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 476 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 374 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 478 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 479 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 480 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 484 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 485 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 486 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 487 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 488 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 490 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 491 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 492 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 493 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 494 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 495 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 497 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 498 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 499 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 292 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 485 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 500 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 505 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 506 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 507 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 509 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 511 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 512 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 513 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 515 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 516 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 517 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 518 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 519 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 520 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 522 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 323 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 524 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 525 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 527 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 528 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 529 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 531 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 532 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 533 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 534 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 535 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 536 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 537 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 538 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 539 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 540 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 541 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 438 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 542 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 543 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 544 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 545 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 546 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 547 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 419 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 548 }, + .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 550 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 540 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 551 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 540 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 552 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 553 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 554 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 555 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 556 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 557 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 558 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 559 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 560 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 561 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 563 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 563 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 566 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 567 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 570 }, + .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 571 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 573 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 574 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 575 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 576 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 577 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 578 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 581 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 582 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 583 }, + .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 322 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 584 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 292 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 586 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 587 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 588 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 589 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 590 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 591 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 592 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 595 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 596 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 282 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 217 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 598 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 450 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 600 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 601 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 602 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 604 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 505 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 393 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 607 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 608 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 613 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 292 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 614 }, + .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 497 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 615 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 484 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 618 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 619 }, + .{ .char = 'F', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 620 }, + .{ .char = 'T', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 621 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 622 }, + .{ .char = 'E', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 623 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 624 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 625 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 626 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 627 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 628 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 629 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 630 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 631 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 632 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 633 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 634 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 635 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 636 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 637 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 638 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 499 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 639 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 520 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 641 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 642 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 643 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 644 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 645 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 646 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 647 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 }, + .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 650 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 651 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 652 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 653 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 656 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 657 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 658 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 659 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 660 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 661 }, + .{ .char = 'o', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 662 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 206 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 361 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 663 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 598 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'k', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 665 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 667 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 286 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 668 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 669 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 670 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 671 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 672 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 673 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 674 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 675 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 676 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 677 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 678 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 679 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 681 }, + .{ .char = '0', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 682 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 683 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 684 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 389, .child_index = 686 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 107, .child_index = 701 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 710 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 711 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 712 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 714 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 715 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 716 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 717 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 718 }, + .{ .char = '6', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '4', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 719 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 720 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 206 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 721 }, + .{ .char = 'm', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 353 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 722 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 723 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 722 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 724 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 524 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 725 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 726 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 727 }, + .{ .char = 'C', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 728 }, + .{ .char = 'A', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 729 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 730 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 731 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 732 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 733 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 734 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 735 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 736 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 737 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 738 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 739 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 48, .child_index = 740 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 742 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 744 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 40, .child_index = 746 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 748 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 58, .child_index = 749 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 753 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 84, .child_index = 755 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 23, .child_index = 759 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 761 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 53, .child_index = 762 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 29, .child_index = 766 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 770 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 771 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 773 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 774 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 776 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 40, .child_index = 777 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 778 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 779 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 780 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 781 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 784 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 785 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 786 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 787 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 788 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 789 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 790 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 791 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 793 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 794 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 795 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 796 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 797 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 456 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 798 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 206 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 799 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 800 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 671 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 801 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 802 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 803 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 804 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 805 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 806 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 818 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 819 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 820 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 821 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 822 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 823 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 824 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 825 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 826 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 827 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 828 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 26, .child_index = 830 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 834 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 835 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 34, .child_index = 836 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 840 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 841 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 842 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 844 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 846 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 72, .child_index = 847 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 835 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 849 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 850 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 851 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 852 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 853 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 854 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 33, .child_index = 855 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 856 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 857 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 858 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 860 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 861 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 862 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 863 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 849 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 864 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 865 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 866 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 866 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 867 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 868 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 869 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 870 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 871 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 872 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 873 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 874 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 875 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 780 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 876 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 877 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 878 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 879 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 880 }, + .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 881 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 882 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 883 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 884 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 203 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 322 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 885 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 886 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 887 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 888 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 889 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 890 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 891 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 892 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 895 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 897 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 898 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 899 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 900 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 901 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 903 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 904 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 905 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 908 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 910 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2967, .child_index = 911 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 932 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 933 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 934 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 935 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 936 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 937 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 938 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 940 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 941 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 942 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 943 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 944 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 945 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 946 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 947 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 949 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 950 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 951 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 944 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 952 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 953 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 955 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 956 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 957 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 959 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 960 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 960 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 961 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 962 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 962 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 844 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 963 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 964 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 967 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 970 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 971 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 972 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 973 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 974 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 975 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 976 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 943 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 977 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 978 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 849 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 979 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 871 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 875 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 980 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 981 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 866 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 982 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 871 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 983 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 984 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 985 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 986 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 987 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 988 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 989 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 990 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 991 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 992 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 993 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 994 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 995 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 996 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 997 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 998 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 999 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1000 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1001 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1002 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1001 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1003 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1004 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1005 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1006 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1007 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1008 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1009 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1010 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1011 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1013 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1014 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1015 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1016 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1017 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 904 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 1018 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 302, .child_index = 1019 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1028 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 114, .child_index = 1032 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1044 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 58, .child_index = 1049 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 49, .child_index = 1053 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1061 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1062 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 27, .child_index = 1064 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 52, .child_index = 1068 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 686, .child_index = 1074 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 1080 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1083 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 142, .child_index = 1086 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 52, .child_index = 1091 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 71, .child_index = 1095 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 1107 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 1111 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 1273, .child_index = 1115 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 22, .child_index = 1120 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1123 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1124 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1125 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1126 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 1127 }, + .{ .char = '0', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1128 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1129 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1130 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1132 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1133 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1134 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1135 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 960 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 960 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 946 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1138 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1140 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1141 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 944 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 944 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 952 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1142 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1126 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1143 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1144 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 1145 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1153 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1154 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 292 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 486 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1155 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1126 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1156 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1157 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1159 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1160 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1161 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1162 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1164 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1165 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 949 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1166 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1167 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1168 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1169 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1170 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1172 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1173 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1174 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1175 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1176 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1177 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1178 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1179 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1182 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1185 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1187 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1188 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 29, .child_index = 1189 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1196 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1198 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1199 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1200 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1201 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1202 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1203 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1204 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1205 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1206 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1001 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1207 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1208 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1209 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1012 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1210 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1211 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 1212 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 135 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1221 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1222 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1223 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 122, .child_index = 1225 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 403 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 134, .child_index = 1226 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1227 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1229 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 142 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1230 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1231 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 144 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 1232 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1239 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1240 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1242 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 154 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1243 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 1247 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1251 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 161 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 162 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1254 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1256 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1257 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1258 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1259 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1260 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1261 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 1262 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1263 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 23, .child_index = 1264 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1266 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1267 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1268 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1269 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 1271 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1274 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1276 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1279 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1280 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1281 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1282 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1283 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1284 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 1287 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1294 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1296 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1297 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1298 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 1300 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1302 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1304 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1306 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 135, .child_index = 1307 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1308 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 534, .child_index = 1309 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1310 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 1311 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1312 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1314 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1315 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1316 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1317 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1318 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1320 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 108, .child_index = 1322 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1323 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 1325 }, + .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1326 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 1327 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1331 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 1332 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1334 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1335 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1336 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1337 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1338 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1340 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 220 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1341 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1343 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1344 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 1346 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1349 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1350 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1297 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1351 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1352 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1334 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1340 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1354 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1357 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 227 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1263, .child_index = 1358 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1359 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 231 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 1361 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 235 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 236 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1362 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1363 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1364 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 1368 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1376 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1380 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1381 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1383 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1384 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1385 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1389 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 451 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1390 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1384 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1364 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1394 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1395 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1390 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1396 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1399 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1399 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1400 }, + .{ .char = 's', .end_of_word = true, .end_of_list = false, .number = 6, .child_index = 1402 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 1405 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1409 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1410 }, + .{ .char = '4', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 974 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1411 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1412 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1364 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1413 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 950 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1414 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1415 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1419 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1422 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1423 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1425 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1426 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1430 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1431 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1432 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1433 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1434 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1435 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1436 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1437 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1438 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1439 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1440 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1441 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1442 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1443 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1444 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1445 }, + .{ .char = 'A', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1446 }, + .{ .char = 'C', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1447 }, + .{ .char = 'D', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1448 }, + .{ .char = 'E', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 1449 }, + .{ .char = 'I', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1450 }, + .{ .char = 'O', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1451 }, + .{ .char = 'X', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1452 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1453 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1454 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1455 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1456 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1457 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1458 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1459 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1460 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1461 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1462 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1463 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1464 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1465 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1466 }, + .{ .char = 'C', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1467 }, + .{ .char = 'N', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1468 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1469 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1471 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1472 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1473 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 1474 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1477 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1480 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1481 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1483 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1484 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 1485 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 134, .child_index = 1486 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1350 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1487 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 1488 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1489 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1490 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 294 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 137 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1491 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1492 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 296 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 140 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 164 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1493 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1494 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 299 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1495 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1496 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 296 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1497 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1498 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1500 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1501 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1504 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 1505 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 209 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 306 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1508 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 223 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1498 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1509 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1510 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1511 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1512 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1513 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 1514 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1515 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 21, .child_index = 1518 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1524 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1526 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1527 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1529 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1530 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = false, .number = 10, .child_index = 1531 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1534 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1535 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1536 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1537 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1538 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1540 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1541 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1543 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1544 }, + .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1545 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1546 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1549 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1550 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1551 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1553 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1554 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1555 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1556 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1558 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1559 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1560 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1561 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 194 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1302 }, + .{ .char = 'g', .end_of_word = true, .end_of_list = false, .number = 23, .child_index = 1562 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 352 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1567 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1568 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 295 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1569 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1570 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 135, .child_index = 1574 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1575 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 534, .child_index = 1576 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1577 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 10, .child_index = 1578 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1581 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1582 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1583 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1585 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1587 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1588 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1589 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1590 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1591 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1592 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 1595 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1596 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 365 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 1598 }, + .{ .char = '0', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 1599 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1600 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1602 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1603 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1605 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1606 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1608 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1609 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1610 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 1611 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1613 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1618 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1619 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 9, .child_index = 1505 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1620 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1621 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 210 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1622 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 327 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1623 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1624 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 377 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1625 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1481 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1632 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1635 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1636 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1637 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1639 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1640 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1623 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 1641 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 176 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 178 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1642 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 17, .child_index = 1643 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1650 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1131 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1131 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1131 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1651 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1653 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1654 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1655 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 1656 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1658 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1659 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1660 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 519 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1662 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1663 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1664 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1665 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1666 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1667 }, + .{ .char = 'm', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1668 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1668 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1668 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1668 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1669 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1668 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1670 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '4', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '4', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1397 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1397 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1400 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1397 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1671 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1672 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1673 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1676 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1677 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1678 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1679 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1680 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1681 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1682 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1683 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1685 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1686 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1687 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1688 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1689 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1690 }, + .{ .char = '1', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1691 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '4', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1692 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1693 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1694 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1434 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1695 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1696 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1697 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1698 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1699 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1700 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1701 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1702 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1703 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1704 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1705 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1706 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1708 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1709 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1710 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1711 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1710 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1712 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1451 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1714 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1715 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1716 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 899 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1717 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1718 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1719 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1720 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1721 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1722 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1461 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1723 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1724 }, + .{ .char = 'F', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1725 }, + .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1725 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 409 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1473 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1726 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1727 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1728 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1473 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1729 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1473 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1731 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 8, .child_index = 1632 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1733 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1734 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1737 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1738 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 1739 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 134, .child_index = 1740 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1756 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 12, .child_index = 1757 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1761 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1762 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1763 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1765 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1768 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1769 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1770 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1771 }, + .{ .char = 'j', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1772 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1773 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1774 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1776 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1778 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1779 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1780 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1781 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1782 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 1783 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1785 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1786 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1787 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1788 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1789 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'm', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1790 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1791 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1792 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1793 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1794 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1795 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1796 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1493 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1797 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1798 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1799 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1800 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1801 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1802 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1803 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1804 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1805 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1806 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1807 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1808 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1794 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1809 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1810 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1493 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1812 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1813 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1814 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 484 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 485 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1817 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 135, .child_index = 1818 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 534, .child_index = 1819 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1733 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1834 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1835 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1837 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1838 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1839 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1840 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1841 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1842 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1843 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1844 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1845 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 361 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 108, .child_index = 1846 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1462 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1859 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 1860 }, + .{ .char = '0', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 1863 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1864 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 295 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 1866 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1867 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1868 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1869 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1870 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1871 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1872 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1874 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1875 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1876 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 497 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1877 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1878 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1872 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1879 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1872 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1880 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 500 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 505 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 323 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 509 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 511 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 512 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 513 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1881 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1882 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1883 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1884 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1885 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1886 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 1887 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 1888 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1889 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1890 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 898 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1891 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1893 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1894 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1896 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1897 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 1898 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1899 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1900 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1901 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1901 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 1902 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1903 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1905 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1906 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1658 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1907 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1908 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1909 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1910 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1911 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1912 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1913 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1914 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1915 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1918 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1920 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 1921 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1922 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1923 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1924 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1925 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1927 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 1928 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1929 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1930 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1931 }, + .{ .char = '6', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1932 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1933 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1934 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1935 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1936 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1937 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1438 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1938 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1939 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1940 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 286 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1941 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1942 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1943 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1712 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1944 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1945 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 1946 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1947 }, + .{ .char = 'I', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1443 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1948 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1949 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1950 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 1951 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1957 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1958 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1199 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1959 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1199 }, + .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1960 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1961 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1962 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1966 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 1967 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 1969 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1470 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1473 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1972 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1973 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1974 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 1975 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 1976 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1979 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1982 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1983 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 1984 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 1985 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 420 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1987 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 1988 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 1991 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 51, .child_index = 1993 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2000 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2003 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2008 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2009 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 274 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2011 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 1766 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2012 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2013 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2016 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2017 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1784 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2018 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2019 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 332 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2020 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2021 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2022 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2023 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2025 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2027 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2028 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2029 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2030 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2031 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2032 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 2033 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2034 }, + .{ .char = '0', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2035 }, + .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2036 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2037 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2038 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2039 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2040 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2041 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2042 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2043 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2044 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2045 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 328 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2046 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2047 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2048 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2049 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2050 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2051 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2052 }, + .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 5, .child_index = 1547 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2053 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2054 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 291 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2055 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2056 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 135, .child_index = 2057 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 50, .child_index = 2069 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 56, .child_index = 2073 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 50, .child_index = 2079 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 26, .child_index = 2084 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 106, .child_index = 2087 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2098 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2100 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2102 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 73, .child_index = 2103 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2108 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2110 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2111 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 97, .child_index = 2112 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2119 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2120 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2121 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2122 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2123 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2124 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2125 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2126 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2127 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2128 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2129 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2130 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2131 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2132 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2133 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2134 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2136 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2137 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 41, .child_index = 2138 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2144 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2145 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2147 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 2150 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2155 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2156 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2160 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2163 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2166 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2167 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2168 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2169 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 2170 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2172 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1876 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2173 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2174 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2175 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2176 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2177 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 10, .child_index = 2178 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1733 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2181 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2183 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2185 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2186 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2187 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2188 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2189 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2036 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 1547 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1589 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2190 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2191 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2192 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 2193 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 2194 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2196 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2197 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 238 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1007 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2198 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1013 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2199 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1017 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2200 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2202 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2203 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2204 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2204 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2205 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2206 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2207 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2211 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2212 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2213 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2214 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2215 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2216 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2217 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2218 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2219 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 2220 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2221 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2222 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2223 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2225 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 2226 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2227 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2228 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2229 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2231 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2232 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2233 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2234 }, + .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 }, + .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 }, + .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2235 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2236 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2237 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2238 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2239 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2240 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2241 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 582 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2242 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1464 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2243 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2245 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2247 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2248 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2249 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 656 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2250 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2251 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2252 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2253 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2255 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2256 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2257 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2258 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2259 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2256 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2260 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2262 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2262 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2263 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2264 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 2266 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 2267 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2268 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2269 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2272 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1940 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2273 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2274 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2277 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2278 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2280 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2281 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2283 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2284 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2286 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2287 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2288 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2290 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2293 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2295 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2297 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 2299 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2302 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2303 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 520 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2305 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2288 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2293 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2293 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 2306 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2302 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2308 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 431 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2287 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 2309 }, + .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 2310 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2311 }, + .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2312 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2313 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2314 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2315 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2316 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2317 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2318 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2319 }, + .{ .char = '6', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 238 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2320 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2321 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2322 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2323 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2325 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2326 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 2327 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2319 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2328 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2329 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2330 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2331 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2332 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2333 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2334 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2335 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2336 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2337 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2338 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2339 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2340 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2236 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 2341 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2344 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2345 }, + .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2346 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2346 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 19, .child_index = 2347 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2350 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2353 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2354 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2355 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2356 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2357 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2360 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 21, .child_index = 2365 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2368 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 25, .child_index = 2371 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2373 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2374 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2375 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2376 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2377 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2378 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2379 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2380 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 2382 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2384 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2385 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2386 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2387 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 32, .child_index = 2388 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2390 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2387 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2391 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2392 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2098 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2393 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 2394 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2400 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2401 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2402 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2404 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2405 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 2406 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2410 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 26, .child_index = 2413 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2420 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2423 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2424 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2425 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2426 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2427 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 2430 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 2432 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 2433 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2435 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2436 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2437 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2110 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2441 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2443 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2444 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2445 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2447 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 32, .child_index = 2448 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2450 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 2452 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2453 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2110 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2454 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2455 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2456 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2457 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2458 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2459 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2460 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2461 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2462 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2463 }, + .{ .char = 'y', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2464 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2465 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2466 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2467 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2468 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2469 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2470 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2472 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2473 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2474 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 2476 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2479 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2481 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2482 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2483 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2484 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2485 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2487 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2488 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2491 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2492 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2495 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2496 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2497 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2498 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2499 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2501 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2502 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2506 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1663 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2507 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2508 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2509 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2510 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2511 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2512 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2513 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2514 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2515 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2516 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2517 }, + .{ .char = 'o', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2040 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2518 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2520 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 3, .child_index = 1775 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1733 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1577 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2521 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2522 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2523 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 297 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2524 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 429 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2525 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2526 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2527 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1263, .child_index = 2528 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2540 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2543 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2544 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2545 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2546 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2547 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2548 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2549 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2550 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2551 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2552 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1904 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2553 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2554 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2555 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2556 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2557 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2559 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2560 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2561 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2562 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2566 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 2567 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1926 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2568 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2568 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2569 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 2570 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2571 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2572 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2573 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2574 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2575 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2576 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 674 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2577 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2578 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 584 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2579 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2580 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2581 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2582 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2583 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2584 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2585 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2586 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2587 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2588 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2259 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2589 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2590 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2259 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2591 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2592 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2589 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2591 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2589 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2260 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2593 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2594 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2595 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 122, .child_index = 2597 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 }, + .{ .char = 's', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1938 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1938 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2614 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2615 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 2616 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2618 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 2619 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 1399 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2621 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1207 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 1708 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2622 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1699 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 2623 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2625 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2615 }, + .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2288 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2626 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 14, .child_index = 2628 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2630 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2633 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2635 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 2616 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 332 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2618 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2636 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2638 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2639 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2640 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2641 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2635 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2644 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2645 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2647 }, + .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2648 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2649 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2650 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2651 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2652 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2653 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1534 }, + .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2654 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2655 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2656 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2657 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2658 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2659 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2660 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 2661 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2662 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2663 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1795 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2664 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2665 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 729 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2666 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1494 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2667 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2669 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2670 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2671 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2672 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2673 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2674 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2675 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2677 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 2678 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 2679 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2680 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 479 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2681 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2682 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2683 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2684 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2686 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2687 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2688 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2689 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2691 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2692 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2693 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 2694 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2695 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2696 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 2697 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2698 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2699 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2700 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 2701 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 2704 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2699 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 2705 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2708 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2709 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2711 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2712 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2713 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2714 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2385 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2715 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2717 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2724 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2725 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2725 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2727 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2729 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2730 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2731 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2733 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2736 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2737 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2738 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2741 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2742 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2745 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2746 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2748 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2749 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2750 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2752 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2753 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2754 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2755 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2756 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2757 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2731 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2758 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2736 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2737 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2760 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 2761 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2745 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2765 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2766 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2767 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2768 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2769 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2773 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2781 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 20, .child_index = 2782 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 20, .child_index = 2782 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2728 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2784 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2785 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2786 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2789 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2789 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2790 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2791 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2792 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2794 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2795 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2722 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2796 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 2797 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 2797 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 2800 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2802 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 1567 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2803 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2804 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2805 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2806 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2807 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2808 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2809 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2810 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2811 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2812 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2813 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2814 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2815 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2819 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2820 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2822 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2824 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2825 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2826 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2827 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 2830 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2835 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2836 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2837 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2838 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2839 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2840 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2841 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2840 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2842 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2843 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2844 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2845 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2842 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2846 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2843 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2844 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2847 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2848 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2850 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2851 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2852 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2853 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2855 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2856 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2857 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2858 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2856 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2859 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2860 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2861 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2862 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2863 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2864 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2865 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2866 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2868 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 2869 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2803 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2873 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2874 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 2875 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1530 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2653 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2876 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2877 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2878 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2879 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2880 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2881 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2883 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2885 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2886 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2890 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2892 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 393, .child_index = 2893 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2897 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2899 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 836, .child_index = 2901 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2915 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2916 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2917 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2918 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2919 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2920 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2921 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2922 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2923 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2924 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2925 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2926 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2927 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2928 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1671 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 506 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2929 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2930 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1131 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2931 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2932 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2933 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2934 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2935 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 2936 }, + .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2311 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 2937 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2944 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2945 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2946 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2947 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2948 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2949 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2950 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2951 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 2952 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2953 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 2954 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 897 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2955 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2956 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2957 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2958 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2960 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2961 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2962 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2963 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2964 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 2965 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2967 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 13, .child_index = 2968 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 2972 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2974 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 2976 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2980 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 2981 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2985 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2986 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 2989 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2992 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 11, .child_index = 2994 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 23, .child_index = 2997 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3003 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3004 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3006 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3008 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3009 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3010 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1399 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1712 }, + .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3011 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2635 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 3013 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3018 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3020 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3021 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3020 }, + .{ .char = 't', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3024 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3011 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3025 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3027 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3028 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3029 }, + .{ .char = 't', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3024 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3031 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1800 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3032 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3033 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3034 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3035 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 512 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3036 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3037 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3038 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3039 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3040 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3041 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3042 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3043 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3044 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3045 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3046 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1174 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3047 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3048 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3049 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3050 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3051 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3052 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3053 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3054 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3055 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3056 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3057 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3058 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3059 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3060 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 15, .child_index = 3061 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3065 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3066 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3067 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3068 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3071 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3071 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3075 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3077 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3078 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3079 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3080 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3081 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 14, .child_index = 3082 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3087 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3088 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3089 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3091 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3092 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3093 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3094 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3095 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 3096 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 13, .child_index = 3098 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3100 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3101 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3102 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3104 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2439 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2439 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'v', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3106 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3102 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3102 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3107 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3108 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2758 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3109 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3111 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3112 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3113 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3114 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3112 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2730 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3115 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3115 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3116 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3117 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2760 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3117 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2732 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2758 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3109 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3118 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3120 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3107 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3107 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3121 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3122 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3123 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3124 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2775 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3125 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2786 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3127 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2728 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3130 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2786 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3131 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3132 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3121 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3122 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3133 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3136 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2775 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3137 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3139 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3140 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3141 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3142 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3143 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3144 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3145 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3146 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 1528 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3147 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3148 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3149 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 }, + .{ .char = 't', .end_of_word = true, .end_of_list = false, .number = 4, .child_index = 3150 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3152 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3154 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3156 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3157 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3158 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3159 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2825 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 2829 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3160 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3161 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3162 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3163 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3164 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3166 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3169 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3170 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3172 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3174 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3175 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3176 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3177 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3177 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3178 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3179 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3180 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3181 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3182 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3183 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3184 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3185 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3186 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3187 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3188 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3189 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2243 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3190 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3193 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3194 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 1534 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3195 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3196 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3197 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3198 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3199 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3200 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3201 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3202 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3203 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3204 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3205 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3206 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3208 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3209 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3198 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3210 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3211 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3208 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3212 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 388, .child_index = 3213 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3204 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3225 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3208 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3227 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 3228 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 3230 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 71, .child_index = 3231 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 45, .child_index = 3234 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3235 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 294, .child_index = 3237 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 32, .child_index = 3244 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 35, .child_index = 3245 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 81, .child_index = 3246 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3251 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3252 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 42, .child_index = 3253 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 163, .child_index = 3259 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3267 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2892 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3269 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3270 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3271 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3272 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3273 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3274 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3275 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3276 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3277 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3278 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3279 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3280 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3281 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3282 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3283 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3284 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3285 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 3286 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3287 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2245 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3289 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3290 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3291 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3292 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3293 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3294 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3295 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3296 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3297 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3298 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3299 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3300 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3301 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3302 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3303 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3304 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3305 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 486 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3306 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3307 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3308 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2959 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3309 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3310 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3311 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3312 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3313 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3314 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3315 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3316 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3317 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3318 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3319 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3321 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3322 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3323 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3324 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1948 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3325 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3326 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3328 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3330 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2865 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3331 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3332 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3333 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3334 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3335 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3336 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3337 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3338 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3339 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3340 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3341 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3342 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3343 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3344 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3345 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3351 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3352 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3353 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3354 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3356 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3357 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3352 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3358 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3359 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3360 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3361 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3362 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3181 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3365 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3020 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3363 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3365 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3020 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3365 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3363 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3363 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 648 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 648 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3366 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 }, + .{ .char = '8', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2319 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3367 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3368 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3369 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3370 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3371 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3372 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3373 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3374 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 581 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3375 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3376 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3377 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3378 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3379 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3380 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3381 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3382 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3383 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3384 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3385 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3052 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3386 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3387 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3388 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3389 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3390 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3392 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 519 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3394 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3395 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3396 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3398 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3400 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3402 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3404 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3405 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3406 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3407 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3409 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2248 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3410 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3411 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3413 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3415 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3416 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3417 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 17, .child_index = 3419 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3065 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3421 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3422 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3423 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 7, .child_index = 3390 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3392 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3127 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 2722 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3424 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3426 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3125 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2765 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2746 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3427 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3428 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3431 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2794 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 2779 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2765 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3131 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 2722 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3102 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3432 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 1766 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2053 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3434 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3435 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3436 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3437 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3439 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3440 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 463 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3441 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3442 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3443 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3444 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3444 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2560 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2560 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3445 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3446 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3447 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3448 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3449 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 585 }, + .{ .char = '4', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'u', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3450 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3452 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3408 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3408 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3453 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3454 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3455 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3456 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3164 }, + .{ .char = 'v', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 3458 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3460 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3461 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3462 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3463 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3464 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3465 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3466 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3467 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 463 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3468 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3469 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2878 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3470 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 238 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3210 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3210 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3471 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3472 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3473 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3474 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3475 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3476 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3477 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3478 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3481 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3482 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3483 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3484 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3485 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3486 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3488 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 20, .child_index = 3489 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3491 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 242, .child_index = 3492 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 3497 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3498 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3500 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 3501 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3502 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 42, .child_index = 3504 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3508 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3509 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3510 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3511 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3512 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 15, .child_index = 3513 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3515 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3516 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 3517 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 45, .child_index = 3518 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3519 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3516 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3520 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3521 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3522 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 186, .child_index = 3523 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 3528 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3529 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 20, .child_index = 3530 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 32, .child_index = 3532 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 35, .child_index = 3536 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3542 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3543 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3544 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 34, .child_index = 3545 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3546 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3548 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3549 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3550 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3551 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3553 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3554 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3555 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3556 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3561 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3562 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3563 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3564 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 24, .child_index = 3564 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 48, .child_index = 3566 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 3572 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3251 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3574 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3575 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3576 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3577 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3578 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3579 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3369 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3583 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3584 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3585 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3586 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1665 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2640 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3588 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3056 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3589 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 3590 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3591 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3591 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3592 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3593 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2245 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3290 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3594 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3595 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3596 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3597 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3598 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'E', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3599 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3600 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 10, .child_index = 3601 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3606 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3607 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3608 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3609 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3610 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3611 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3612 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3613 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3614 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3615 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3616 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3617 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3618 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3619 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3620 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3626 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2555 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3627 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3628 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3629 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3630 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3631 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3632 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3633 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3634 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3636 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3637 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3638 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3640 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3641 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3642 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3643 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3644 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3645 }, + .{ .char = 'q', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 3646 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3648 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3649 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3651 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3652 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 3653 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3655 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3656 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3657 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3658 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3659 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3660 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3658 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3661 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3662 }, + .{ .char = 'T', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3663 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3664 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3456 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3665 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3579 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3666 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3667 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3668 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3669 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3670 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3671 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3672 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3673 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3674 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3675 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3676 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3677 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3442 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3678 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2672 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3679 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3680 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3681 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3682 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3683 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3684 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3686 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3687 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3690 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3691 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3692 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3693 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3695 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3400 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3696 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3699 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3700 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3701 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3401 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3702 }, + .{ .char = 'u', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3705 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3707 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3708 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3709 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3711 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3713 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3714 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 3716 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 7, .child_index = 3718 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3720 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3721 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3724 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3727 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3727 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3728 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3427 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3730 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3731 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3732 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3733 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3734 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3735 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3736 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3737 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3738 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3739 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3740 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3741 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3742 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3743 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3744 }, + .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3745 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3747 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3748 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3749 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3750 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3751 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3752 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3753 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3754 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3755 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3756 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3757 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3579 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3468 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3758 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3759 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3204 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3760 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3761 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3762 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3763 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3765 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3765 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3765 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3766 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3767 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3768 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3770 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3771 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3772 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3773 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3774 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3776 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3777 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3778 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3779 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3780 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 206, .child_index = 3781 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3786 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3787 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3788 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3789 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3790 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3792 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3793 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3794 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3795 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3796 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3796 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3798 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3500 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3799 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3800 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 3801 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3803 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 30, .child_index = 3801 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3808 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 40, .child_index = 3809 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 45, .child_index = 3813 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3815 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3816 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3817 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3818 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3820 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 114, .child_index = 3821 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3825 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3826 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 36, .child_index = 3827 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3829 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3831 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3832 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3834 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3835 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3837 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3838 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3840 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3841 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3842 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3845 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3846 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3849 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3849 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3850 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 34, .child_index = 3852 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3854 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3855 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3856 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3857 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3858 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 3860 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 3861 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3863 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3553 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3864 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3865 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3868 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3869 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3865 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3870 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3871 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3872 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 3873 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3875 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3876 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 16, .child_index = 3878 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3882 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3883 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 16, .child_index = 3878 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 3801 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3884 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3886 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3888 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3889 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3890 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2311 }, + .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 }, + .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3891 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3894 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3895 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2343 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3898 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 3899 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3591 }, + .{ .char = 'b', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3900 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3901 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 1699 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 3902 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3903 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 3024 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '8', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'A', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3904 }, + .{ .char = 'P', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3046 }, + .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3905 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3906 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3907 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 521 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3908 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3909 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3910 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3911 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3912 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3913 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3914 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3918 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3919 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3920 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3922 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3923 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3924 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 3925 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3927 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3928 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3929 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3930 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3659 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3931 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3932 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3933 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3934 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3935 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3936 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2934 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3937 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3938 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3939 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3940 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3942 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3943 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 3944 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3947 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3948 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3949 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3950 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3951 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3950 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3952 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3954 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3955 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3956 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3958 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3959 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3960 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3961 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 3962 }, + .{ .char = 'T', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 3964 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3966 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3967 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3968 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3969 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3970 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3971 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3972 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3973 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 3974 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3975 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3679 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3976 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3977 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3978 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2237 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3979 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3980 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3982 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3418 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3985 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2568 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3698 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3400 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3987 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3988 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 578 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3990 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3992 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3993 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3994 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3996 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3997 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3998 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3999 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4000 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4001 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4002 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4003 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4005 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4006 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4008 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4010 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3980 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4011 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2780 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2780 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4014 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4015 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4016 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4017 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4018 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4019 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4020 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4021 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4022 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4023 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 2829 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4024 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4025 }, + .{ .char = '4', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '8', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4026 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4027 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3748 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4028 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4029 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4030 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4031 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4032 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4033 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4035 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4036 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4037 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4038 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4041 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4042 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4043 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4044 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4045 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4046 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4047 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4049 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4050 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4051 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4052 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4054 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4056 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4057 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4054 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4060 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3773 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4062 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 15, .child_index = 4063 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4065 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = false, .number = 170, .child_index = 4066 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4069 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4070 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4071 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4073 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4057 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4074 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4074 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4075 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4076 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4078 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4079 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4082 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4082 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4054 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4083 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4085 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 4086 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4088 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4090 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4090 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4090 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4090 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4091 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4092 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4093 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4096 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4097 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 24, .child_index = 4099 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 27, .child_index = 4101 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4103 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 4107 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 4109 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 30, .child_index = 4113 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 4109 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 4109 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4107 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4105 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 18, .child_index = 4118 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 3825 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4119 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4120 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4121 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 4105 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4122 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4124 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4125 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4125 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4126 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3834 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3837 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4127 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4129 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4130 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4131 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4131 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4132 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3840 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3841 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3845 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4086 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4133 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4134 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 22, .child_index = 4135 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4088 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4137 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4138 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4140 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4140 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4141 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4142 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3877 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3864 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3868 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3869 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4143 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4145 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4146 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4147 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4148 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3875 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4149 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4151 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4152 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4155 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 3876 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3882 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3883 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4156 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4158 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3862 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4159 }, + .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2311 }, + .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 649 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4161 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4162 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4164 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1389 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 549 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3586 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3367 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 33, .child_index = 4165 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4173 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4174 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 4175 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4176 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 1708 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 2622 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4177 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4178 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4179 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4180 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4181 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4182 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4183 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 568 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 569 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4184 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4185 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4186 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4188 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2680 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3927 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4189 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4190 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4191 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4193 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4194 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4195 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4196 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4197 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4198 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4199 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4200 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4201 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4202 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4203 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4204 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4205 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4206 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4208 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4209 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4210 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4211 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4212 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4213 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4214 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4215 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4217 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4218 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4220 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4221 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4222 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3011 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4223 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 549 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4224 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4225 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4226 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4227 }, + .{ .char = 'A', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 4228 }, + .{ .char = 'T', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4229 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4230 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 4, .child_index = 4231 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4233 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1840 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4234 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 25, .child_index = 4235 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4247 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4248 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4249 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4250 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4251 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4254 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3981 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4256 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4257 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4258 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4260 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2507 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4261 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 656 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4262 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3997 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3998 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4263 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3981 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4264 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3997 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4005 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4265 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4266 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4267 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4268 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4271 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4256 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'h', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 2779 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4272 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4273 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4275 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4276 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4277 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3196 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4278 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4279 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4280 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4281 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3456 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3308 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4284 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4285 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4286 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4287 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4288 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4289 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4290 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4291 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3676 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4041 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4292 }, + .{ .char = 'i', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4292 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4293 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1197 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4294 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4295 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4296 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4296 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4297 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4298 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4299 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3791 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4300 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4301 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4302 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4303 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4304 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4305 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4306 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4307 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 84, .child_index = 4309 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 84, .child_index = 4309 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4306 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4314 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4069 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3791 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4315 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4057 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4317 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4318 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4146 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4319 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4320 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4321 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3761 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3547 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4322 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3547 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4324 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4325 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4326 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4327 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4077 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 12, .child_index = 4329 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4329 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4331 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4332 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4331 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4331 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3547 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4334 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4334 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4335 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4338 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4341 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4335 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4336 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4338 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 18, .child_index = 4107 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4343 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4343 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3858 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3862 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4345 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 3838 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 3834 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3841 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3845 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4346 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4347 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4127 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3841 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4349 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4351 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 4352 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4322 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4325 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4325 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4325 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 12, .child_index = 4354 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4356 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4357 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3864 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3869 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3864 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4361 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4362 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4363 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4363 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4364 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 3882 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3883 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4365 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3877 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3883 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3877 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4366 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4366 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4367 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4369 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4369 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4370 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4371 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4373 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4374 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 10, .child_index = 4375 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4379 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4380 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4381 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4382 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4383 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4384 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 10, .child_index = 4385 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4387 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4388 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4389 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4390 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4391 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4392 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4394 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4395 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4396 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4399 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4400 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4401 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4402 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 405 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4403 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4404 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4405 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4406 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4407 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4409 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4410 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4411 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4412 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4413 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4414 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4415 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4416 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4418 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2319 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4420 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4421 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4422 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4423 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3979 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4424 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4425 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4426 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4427 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 569 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4428 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4429 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4430 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4428 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4431 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4432 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4434 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3648 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4435 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4436 }, + .{ .char = 'T', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4437 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4438 }, + .{ .char = 'f', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 3024 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4439 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4440 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4441 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4443 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4444 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4447 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4448 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4450 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 2245 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4451 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3609 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4452 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4454 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4457 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4458 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4459 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4460 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4461 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 412 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 656 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4462 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4463 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3401 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3405 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4464 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2507 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4465 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4466 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3405 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4467 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3698 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4468 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4469 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4266 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4470 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4471 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4472 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1893 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4473 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4474 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4475 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4476 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4477 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4478 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 2137 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4479 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1379 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4480 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4481 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4482 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4483 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4484 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4485 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4486 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4487 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4488 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 344 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'M', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4489 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4490 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4491 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4492 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4493 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4494 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4496 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4497 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4497 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4498 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4499 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 36, .child_index = 4501 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 8, .child_index = 4504 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 4507 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4306 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4493 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4493 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4146 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4508 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3870 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3870 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4510 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4511 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4511 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4512 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4513 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4516 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4091 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4517 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 4518 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4518 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4519 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 9, .child_index = 4520 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4520 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4521 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4522 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4522 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4522 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4524 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4522 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4525 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4526 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4526 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4527 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4527 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4529 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4131 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4131 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4530 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4530 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4531 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 6, .child_index = 3855 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4533 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4527 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4534 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4536 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4508 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4508 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4538 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4539 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3875 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4540 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4536 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3862 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4542 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4543 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4544 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4545 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4546 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4547 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4548 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4549 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4380 }, + .{ .char = 't', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4381 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4382 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4550 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4554 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4555 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4556 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4557 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4558 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = false, .number = 5, .child_index = 4559 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4560 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4561 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4562 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4563 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4564 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4565 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 311 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4566 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4568 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4569 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4571 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2214 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4572 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4573 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3913 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4574 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4575 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4576 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 3637 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4577 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4578 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4579 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4580 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4582 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4583 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4584 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 1389 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4420 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4585 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4586 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4587 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4588 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4589 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3324 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 579 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4590 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4591 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1940 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4592 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2819 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 580 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3648 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4593 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4594 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4595 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4596 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4597 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4598 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4599 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 344 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4600 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4601 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4602 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 738 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4603 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 2268 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4605 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 568 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4606 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4607 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 580 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4608 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 457 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 286 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4609 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4610 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4611 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4612 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4613 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4614 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 412 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4261 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 561 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4615 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3701 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4616 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4617 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4261 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4618 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4619 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4620 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2199 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4621 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4622 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4623 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4624 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3301 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1129 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4627 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4628 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 8, .child_index = 4632 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4634 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4635 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4636 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4637 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4638 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4639 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4640 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4298 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4642 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4642 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4301 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4645 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4646 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4648 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4649 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4649 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4649 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4649 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 28, .child_index = 4109 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4649 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4651 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4649 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4652 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 28, .child_index = 4109 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4317 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4653 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4654 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 3547 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4513 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4516 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 3807 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4327 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4656 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4331 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 9, .child_index = 4658 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4660 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4661 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4662 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4662 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4295 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4663 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4663 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4664 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4667 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4668 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4668 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4669 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4670 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4670 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4512 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4346 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4513 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4513 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3609 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4671 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4673 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4674 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4381 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4675 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4676 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4546 }, + .{ .char = '0', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '1', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '2', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = '3', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 458 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4677 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4678 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 1171 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4679 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4680 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4681 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4682 }, + .{ .char = 'C', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4683 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4684 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4685 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4686 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4687 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4688 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4689 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3026 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4690 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4692 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4693 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3470 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4694 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4695 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4696 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4697 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4698 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 460 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4700 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4701 }, + .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4702 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4703 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4704 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4705 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4706 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4707 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4708 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4709 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4710 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4711 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4712 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4713 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4714 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4715 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4716 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4717 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4718 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4719 }, + .{ .char = 's', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 664 }, + .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 4720 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4722 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4723 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4716 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1663 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4724 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 585 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4725 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4726 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 561 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4727 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4728 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4730 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4731 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4732 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4733 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4734 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4735 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4736 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4738 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4739 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4740 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4741 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4742 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4743 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4744 }, + .{ .char = '2', .end_of_word = false, .end_of_list = false, .number = 4, .child_index = 4745 }, + .{ .char = '3', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4745 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4746 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4747 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4748 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4636 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4751 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4752 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4516 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4753 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4301 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4315 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = '_', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4754 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4755 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4756 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4756 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4757 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4642 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4642 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4325 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4540 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4091 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4138 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4356 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4524 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4660 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4758 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4359 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 655 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4759 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4760 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4762 }, + .{ .char = '3', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4763 }, + .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4764 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4765 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4766 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4554 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4767 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4769 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4554 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 873 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4560 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 5, .child_index = 4773 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4775 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4776 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4777 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4778 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4779 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4780 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4780 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4781 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '8', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4782 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4783 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 680 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3659 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4636 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4784 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 }, + .{ .char = '1', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 4785 }, + .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4785 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4786 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 496 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4787 }, + .{ .char = 'c', .end_of_word = true, .end_of_list = true, .number = 3, .child_index = 4788 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4789 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4790 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4791 }, + .{ .char = 'g', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4792 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4793 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3342 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4794 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4289 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4795 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4796 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4797 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4798 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4799 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4800 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2236 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4801 }, + .{ .char = '2', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4802 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4803 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4804 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4805 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4806 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4807 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4469 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4618 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4469 }, + .{ .char = 'q', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4266 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4808 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4809 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4810 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4811 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4812 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4812 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4813 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4814 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4815 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4816 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4817 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4818 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4819 }, + .{ .char = 'D', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4820 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4822 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'y', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4823 }, + .{ .char = '5', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4824 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4301 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4825 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4651 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4754 }, + .{ .char = 'x', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4077 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4359 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4146 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4146 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4826 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 }, + .{ .char = '4', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3268 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4828 }, + .{ .char = 'k', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 1938 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 458 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4829 }, + .{ .char = 'w', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'x', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'y', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'z', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4830 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = true, .number = 6, .child_index = 4833 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4837 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4838 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4839 }, + .{ .char = 'n', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4840 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 3886 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4841 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4842 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4843 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4844 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4845 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4846 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4847 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4416 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4210 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4848 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4849 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4850 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4851 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 6, .child_index = 4852 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4854 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4855 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4856 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4857 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4858 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4859 }, + .{ .char = '0', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4860 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4861 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4862 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4863 }, + .{ .char = 'j', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4864 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4865 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4867 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4868 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4869 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4739 }, + .{ .char = 'd', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4813 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 291 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4870 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4871 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4872 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4873 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4874 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4873 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4875 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4875 }, + .{ .char = 'D', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4877 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4880 }, + .{ .char = '1', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4881 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4882 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4757 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4757 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4884 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4885 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4886 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 496 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3366 }, + .{ .char = '1', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 648 }, + .{ .char = '6', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 649 }, + .{ .char = '8', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'P', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4887 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4888 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4889 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3052 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4890 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4891 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2568 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4892 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2808 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4894 }, + .{ .char = '6', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3941 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2790 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4895 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4896 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3961 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 3, .child_index = 4485 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 3, .child_index = 4409 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4897 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4898 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4899 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4900 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4901 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 471 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4902 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4903 }, + .{ .char = 'z', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4904 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4905 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 2, .child_index = 4906 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4906 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4907 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2877 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4908 }, + .{ .char = 'p', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4813 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 183 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4909 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4910 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4911 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4912 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4912 }, + .{ .char = 'f', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4912 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4912 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4693 }, + .{ .char = '2', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4914 }, + .{ .char = 'M', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 655 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4916 }, + .{ .char = 's', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4917 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4918 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4919 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4920 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 4, .child_index = 4921 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2963 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4925 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 3026 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3026 }, + .{ .char = 'm', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4926 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3366 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 311 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4927 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4928 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 451 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4929 }, + .{ .char = 'c', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4930 }, + .{ .char = 'v', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 323 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4931 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4932 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4017 }, + .{ .char = 'a', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4933 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4934 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4935 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 }, + .{ .char = 'h', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4936 }, + .{ .char = '_', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4912 }, + .{ .char = 'l', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 'u', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4937 }, + .{ .char = 'k', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4938 }, + .{ .char = 'q', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4939 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4940 }, + .{ .char = 'b', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4941 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4587 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 520 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 420 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4942 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4943 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4944 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4945 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3301 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4946 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4947 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3195 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4948 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2460 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4949 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4950 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 5, .child_index = 4952 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4955 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4956 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4957 }, + .{ .char = '1', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'n', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4958 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 3578 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 457 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 2230 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4959 }, + .{ .char = 'u', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 572 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4960 }, + .{ .char = 's', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4961 }, + .{ .char = 'w', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 821 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4918 }, + .{ .char = 'g', .end_of_word = false, .end_of_list = false, .number = 2, .child_index = 4962 }, + .{ .char = 'l', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4962 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4964 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4965 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4966 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4207 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 450 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4967 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4969 }, + .{ .char = 'e', .end_of_word = true, .end_of_list = false, .number = 1, .child_index = 0 }, + .{ .char = 't', .end_of_word = true, .end_of_list = true, .number = 1, .child_index = 0 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 2, .child_index = 4970 }, + .{ .char = 'S', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4971 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4972 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = false, .number = 1, .child_index = 4973 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4974 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1440 }, + .{ .char = 'r', .end_of_word = true, .end_of_list = true, .number = 2, .child_index = 4975 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4976 }, + .{ .char = 'o', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 654 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4977 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4978 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 459 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4979 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4980 }, + .{ .char = 'd', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4981 }, + .{ .char = 'i', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 1701 }, + .{ .char = 'a', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4982 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4983 }, + .{ .char = '_', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4984 }, + .{ .char = 'r', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 }, + .{ .char = 't', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4985 }, + .{ .char = 'y', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4986 }, + .{ .char = 'p', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4987 }, + .{ .char = 'e', .end_of_word = false, .end_of_list = true, .number = 1, .child_index = 4913 }, +}; +pub const data = blk: { + @setEvalBranchQuota(27902); + break :blk [_]@This(){ + // _Block_object_assign + .{ .tag = @enumFromInt(0), .properties = .{ .param_str = "vv*vC*iC", .header = .blocks, .attributes = .{ .lib_function_without_prefix = true } } }, + // _Block_object_dispose + .{ .tag = @enumFromInt(1), .properties = .{ .param_str = "vvC*iC", .header = .blocks, .attributes = .{ .lib_function_without_prefix = true } } }, + // _Exit + .{ .tag = @enumFromInt(2), .properties = .{ .param_str = "vi", .header = .stdlib, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } }, + // _InterlockedAnd + .{ .tag = @enumFromInt(3), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } }, + // _InterlockedAnd16 + .{ .tag = @enumFromInt(4), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } }, + // _InterlockedAnd8 + .{ .tag = @enumFromInt(5), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } }, + // _InterlockedCompareExchange + .{ .tag = @enumFromInt(6), .properties = .{ .param_str = "NiNiD*NiNi", .language = .all_ms_languages } }, + // _InterlockedCompareExchange16 + .{ .tag = @enumFromInt(7), .properties = .{ .param_str = "ssD*ss", .language = .all_ms_languages } }, + // _InterlockedCompareExchange64 + .{ .tag = @enumFromInt(8), .properties = .{ .param_str = "LLiLLiD*LLiLLi", .language = .all_ms_languages } }, + // _InterlockedCompareExchange8 + .{ .tag = @enumFromInt(9), .properties = .{ .param_str = "ccD*cc", .language = .all_ms_languages } }, + // _InterlockedCompareExchangePointer + .{ .tag = @enumFromInt(10), .properties = .{ .param_str = "v*v*D*v*v*", .language = .all_ms_languages } }, + // _InterlockedCompareExchangePointer_nf + .{ .tag = @enumFromInt(11), .properties = .{ .param_str = "v*v*D*v*v*", .language = .all_ms_languages } }, + // _InterlockedDecrement + .{ .tag = @enumFromInt(12), .properties = .{ .param_str = "NiNiD*", .language = .all_ms_languages } }, + // _InterlockedDecrement16 + .{ .tag = @enumFromInt(13), .properties = .{ .param_str = "ssD*", .language = .all_ms_languages } }, + // _InterlockedExchange + .{ .tag = @enumFromInt(14), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } }, + // _InterlockedExchange16 + .{ .tag = @enumFromInt(15), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } }, + // _InterlockedExchange8 + .{ .tag = @enumFromInt(16), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } }, + // _InterlockedExchangeAdd + .{ .tag = @enumFromInt(17), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } }, + // _InterlockedExchangeAdd16 + .{ .tag = @enumFromInt(18), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } }, + // _InterlockedExchangeAdd8 + .{ .tag = @enumFromInt(19), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } }, + // _InterlockedExchangePointer + .{ .tag = @enumFromInt(20), .properties = .{ .param_str = "v*v*D*v*", .language = .all_ms_languages } }, + // _InterlockedExchangeSub + .{ .tag = @enumFromInt(21), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } }, + // _InterlockedExchangeSub16 + .{ .tag = @enumFromInt(22), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } }, + // _InterlockedExchangeSub8 + .{ .tag = @enumFromInt(23), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } }, + // _InterlockedIncrement + .{ .tag = @enumFromInt(24), .properties = .{ .param_str = "NiNiD*", .language = .all_ms_languages } }, + // _InterlockedIncrement16 + .{ .tag = @enumFromInt(25), .properties = .{ .param_str = "ssD*", .language = .all_ms_languages } }, + // _InterlockedOr + .{ .tag = @enumFromInt(26), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } }, + // _InterlockedOr16 + .{ .tag = @enumFromInt(27), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } }, + // _InterlockedOr8 + .{ .tag = @enumFromInt(28), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } }, + // _InterlockedXor + .{ .tag = @enumFromInt(29), .properties = .{ .param_str = "NiNiD*Ni", .language = .all_ms_languages } }, + // _InterlockedXor16 + .{ .tag = @enumFromInt(30), .properties = .{ .param_str = "ssD*s", .language = .all_ms_languages } }, + // _InterlockedXor8 + .{ .tag = @enumFromInt(31), .properties = .{ .param_str = "ccD*c", .language = .all_ms_languages } }, + // _MoveFromCoprocessor + .{ .tag = @enumFromInt(32), .properties = .{ .param_str = "UiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } }, + // _MoveFromCoprocessor2 + .{ .tag = @enumFromInt(33), .properties = .{ .param_str = "UiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } }, + // _MoveToCoprocessor + .{ .tag = @enumFromInt(34), .properties = .{ .param_str = "vUiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } }, + // _MoveToCoprocessor2 + .{ .tag = @enumFromInt(35), .properties = .{ .param_str = "vUiIUiIUiIUiIUiIUi", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } }, + // _ReturnAddress + .{ .tag = @enumFromInt(36), .properties = .{ .param_str = "v*", .language = .all_ms_languages } }, + // __GetExceptionInfo + .{ .tag = @enumFromInt(37), .properties = .{ .param_str = "v*.", .language = .all_ms_languages, .attributes = .{ .custom_typecheck = true, .eval_args = false } } }, + // __abnormal_termination + .{ .tag = @enumFromInt(38), .properties = .{ .param_str = "i", .language = .all_ms_languages } }, + // __annotation + .{ .tag = @enumFromInt(39), .properties = .{ .param_str = "wC*.", .language = .all_ms_languages } }, + // __arithmetic_fence + .{ .tag = @enumFromInt(40), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } }, + // __assume + .{ .tag = @enumFromInt(41), .properties = .{ .param_str = "vb", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // __atomic_add_fetch + .{ .tag = @enumFromInt(42), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_always_lock_free + .{ .tag = @enumFromInt(43), .properties = .{ .param_str = "bzvCD*", .attributes = .{ .const_evaluable = true } } }, + // __atomic_and_fetch + .{ .tag = @enumFromInt(44), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_clear + .{ .tag = @enumFromInt(45), .properties = .{ .param_str = "vvD*i" } }, + // __atomic_compare_exchange + .{ .tag = @enumFromInt(46), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_compare_exchange_n + .{ .tag = @enumFromInt(47), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_exchange + .{ .tag = @enumFromInt(48), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_exchange_n + .{ .tag = @enumFromInt(49), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_add + .{ .tag = @enumFromInt(50), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_and + .{ .tag = @enumFromInt(51), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_max + .{ .tag = @enumFromInt(52), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_min + .{ .tag = @enumFromInt(53), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_nand + .{ .tag = @enumFromInt(54), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_or + .{ .tag = @enumFromInt(55), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_sub + .{ .tag = @enumFromInt(56), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_fetch_xor + .{ .tag = @enumFromInt(57), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_is_lock_free + .{ .tag = @enumFromInt(58), .properties = .{ .param_str = "bzvCD*", .attributes = .{ .const_evaluable = true } } }, + // __atomic_load + .{ .tag = @enumFromInt(59), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_load_n + .{ .tag = @enumFromInt(60), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_max_fetch + .{ .tag = @enumFromInt(61), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_min_fetch + .{ .tag = @enumFromInt(62), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_nand_fetch + .{ .tag = @enumFromInt(63), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_or_fetch + .{ .tag = @enumFromInt(64), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_signal_fence + .{ .tag = @enumFromInt(65), .properties = .{ .param_str = "vi" } }, + // __atomic_store + .{ .tag = @enumFromInt(66), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_store_n + .{ .tag = @enumFromInt(67), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_sub_fetch + .{ .tag = @enumFromInt(68), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __atomic_test_and_set + .{ .tag = @enumFromInt(69), .properties = .{ .param_str = "bvD*i" } }, + // __atomic_thread_fence + .{ .tag = @enumFromInt(70), .properties = .{ .param_str = "vi" } }, + // __atomic_xor_fetch + .{ .tag = @enumFromInt(71), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin___CFStringMakeConstantString + .{ .tag = @enumFromInt(72), .properties = .{ .param_str = "FC*cC*", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin___NSStringMakeConstantString + .{ .tag = @enumFromInt(73), .properties = .{ .param_str = "FC*cC*", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin___clear_cache + .{ .tag = @enumFromInt(74), .properties = .{ .param_str = "vc*c*" } }, + // __builtin___fprintf_chk + .{ .tag = @enumFromInt(75), .properties = .{ .param_str = "iP*RicC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 2 } } }, + // __builtin___get_unsafe_stack_bottom + .{ .tag = @enumFromInt(76), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___get_unsafe_stack_ptr + .{ .tag = @enumFromInt(77), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___get_unsafe_stack_start + .{ .tag = @enumFromInt(78), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___get_unsafe_stack_top + .{ .tag = @enumFromInt(79), .properties = .{ .param_str = "v*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___memccpy_chk + .{ .tag = @enumFromInt(80), .properties = .{ .param_str = "v*v*vC*izz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___memcpy_chk + .{ .tag = @enumFromInt(81), .properties = .{ .param_str = "v*v*vC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___memmove_chk + .{ .tag = @enumFromInt(82), .properties = .{ .param_str = "v*v*vC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___mempcpy_chk + .{ .tag = @enumFromInt(83), .properties = .{ .param_str = "v*v*vC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___memset_chk + .{ .tag = @enumFromInt(84), .properties = .{ .param_str = "v*v*izz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___printf_chk + .{ .tag = @enumFromInt(85), .properties = .{ .param_str = "iicC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 } } }, + // __builtin___snprintf_chk + .{ .tag = @enumFromInt(86), .properties = .{ .param_str = "ic*RzizcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 4 } } }, + // __builtin___sprintf_chk + .{ .tag = @enumFromInt(87), .properties = .{ .param_str = "ic*RizcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 3 } } }, + // __builtin___stpcpy_chk + .{ .tag = @enumFromInt(88), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___stpncpy_chk + .{ .tag = @enumFromInt(89), .properties = .{ .param_str = "c*c*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___strcat_chk + .{ .tag = @enumFromInt(90), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___strcpy_chk + .{ .tag = @enumFromInt(91), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___strlcat_chk + .{ .tag = @enumFromInt(92), .properties = .{ .param_str = "zc*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___strlcpy_chk + .{ .tag = @enumFromInt(93), .properties = .{ .param_str = "zc*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___strncat_chk + .{ .tag = @enumFromInt(94), .properties = .{ .param_str = "c*c*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___strncpy_chk + .{ .tag = @enumFromInt(95), .properties = .{ .param_str = "c*c*cC*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin___vfprintf_chk + .{ .tag = @enumFromInt(96), .properties = .{ .param_str = "iP*RicC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 2 } } }, + // __builtin___vprintf_chk + .{ .tag = @enumFromInt(97), .properties = .{ .param_str = "iicC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } }, + // __builtin___vsnprintf_chk + .{ .tag = @enumFromInt(98), .properties = .{ .param_str = "ic*RzizcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 4 } } }, + // __builtin___vsprintf_chk + .{ .tag = @enumFromInt(99), .properties = .{ .param_str = "ic*RizcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 3 } } }, + // __builtin_abort + .{ .tag = @enumFromInt(100), .properties = .{ .param_str = "v", .attributes = .{ .noreturn = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_abs + .{ .tag = @enumFromInt(101), .properties = .{ .param_str = "ii", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_acos + .{ .tag = @enumFromInt(102), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_acosf + .{ .tag = @enumFromInt(103), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_acosf128 + .{ .tag = @enumFromInt(104), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_acosh + .{ .tag = @enumFromInt(105), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_acoshf + .{ .tag = @enumFromInt(106), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_acoshf128 + .{ .tag = @enumFromInt(107), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_acoshl + .{ .tag = @enumFromInt(108), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_acosl + .{ .tag = @enumFromInt(109), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_add_overflow + .{ .tag = @enumFromInt(110), .properties = .{ .param_str = "b.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_addc + .{ .tag = @enumFromInt(111), .properties = .{ .param_str = "UiUiCUiCUiCUi*" } }, + // __builtin_addcb + .{ .tag = @enumFromInt(112), .properties = .{ .param_str = "UcUcCUcCUcCUc*" } }, + // __builtin_addcl + .{ .tag = @enumFromInt(113), .properties = .{ .param_str = "ULiULiCULiCULiCULi*" } }, + // __builtin_addcll + .{ .tag = @enumFromInt(114), .properties = .{ .param_str = "ULLiULLiCULLiCULLiCULLi*" } }, + // __builtin_addcs + .{ .tag = @enumFromInt(115), .properties = .{ .param_str = "UsUsCUsCUsCUs*" } }, + // __builtin_align_down + .{ .tag = @enumFromInt(116), .properties = .{ .param_str = "v*vC*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_align_up + .{ .tag = @enumFromInt(117), .properties = .{ .param_str = "v*vC*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_alloca + .{ .tag = @enumFromInt(118), .properties = .{ .param_str = "v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_alloca_uninitialized + .{ .tag = @enumFromInt(119), .properties = .{ .param_str = "v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_alloca_with_align + .{ .tag = @enumFromInt(120), .properties = .{ .param_str = "v*zIz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_alloca_with_align_uninitialized + .{ .tag = @enumFromInt(121), .properties = .{ .param_str = "v*zIz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_amdgcn_alignbit + .{ .tag = @enumFromInt(122), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_alignbyte + .{ .tag = @enumFromInt(123), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_atomic_dec32 + .{ .tag = @enumFromInt(124), .properties = .{ .param_str = "UZiUZiD*UZiUicC*", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_atomic_dec64 + .{ .tag = @enumFromInt(125), .properties = .{ .param_str = "UWiUWiD*UWiUicC*", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_atomic_inc32 + .{ .tag = @enumFromInt(126), .properties = .{ .param_str = "UZiUZiD*UZiUicC*", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_atomic_inc64 + .{ .tag = @enumFromInt(127), .properties = .{ .param_str = "UWiUWiD*UWiUicC*", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_buffer_wbinvl1 + .{ .tag = @enumFromInt(128), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_class + .{ .tag = @enumFromInt(129), .properties = .{ .param_str = "bdi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_classf + .{ .tag = @enumFromInt(130), .properties = .{ .param_str = "bfi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cosf + .{ .tag = @enumFromInt(131), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cubeid + .{ .tag = @enumFromInt(132), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cubema + .{ .tag = @enumFromInt(133), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cubesc + .{ .tag = @enumFromInt(134), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cubetc + .{ .tag = @enumFromInt(135), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cvt_pk_i16 + .{ .tag = @enumFromInt(136), .properties = .{ .param_str = "E2sii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cvt_pk_u16 + .{ .tag = @enumFromInt(137), .properties = .{ .param_str = "E2UsUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cvt_pk_u8_f32 + .{ .tag = @enumFromInt(138), .properties = .{ .param_str = "UifUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cvt_pknorm_i16 + .{ .tag = @enumFromInt(139), .properties = .{ .param_str = "E2sff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cvt_pknorm_u16 + .{ .tag = @enumFromInt(140), .properties = .{ .param_str = "E2Usff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_cvt_pkrtz + .{ .tag = @enumFromInt(141), .properties = .{ .param_str = "E2hff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_dispatch_ptr + .{ .tag = @enumFromInt(142), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_div_fixup + .{ .tag = @enumFromInt(143), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_div_fixupf + .{ .tag = @enumFromInt(144), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_div_fmas + .{ .tag = @enumFromInt(145), .properties = .{ .param_str = "ddddb", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_div_fmasf + .{ .tag = @enumFromInt(146), .properties = .{ .param_str = "ffffb", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_div_scale + .{ .tag = @enumFromInt(147), .properties = .{ .param_str = "dddbb*", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_div_scalef + .{ .tag = @enumFromInt(148), .properties = .{ .param_str = "fffbb*", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_ds_append + .{ .tag = @enumFromInt(149), .properties = .{ .param_str = "ii*3", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_ds_bpermute + .{ .tag = @enumFromInt(150), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_ds_consume + .{ .tag = @enumFromInt(151), .properties = .{ .param_str = "ii*3", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_ds_faddf + .{ .tag = @enumFromInt(152), .properties = .{ .param_str = "ff*3fIiIiIb", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_ds_fmaxf + .{ .tag = @enumFromInt(153), .properties = .{ .param_str = "ff*3fIiIiIb", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_ds_fminf + .{ .tag = @enumFromInt(154), .properties = .{ .param_str = "ff*3fIiIiIb", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_ds_permute + .{ .tag = @enumFromInt(155), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_ds_swizzle + .{ .tag = @enumFromInt(156), .properties = .{ .param_str = "iiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_endpgm + .{ .tag = @enumFromInt(157), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .noreturn = true } } }, + // __builtin_amdgcn_exp2f + .{ .tag = @enumFromInt(158), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_fcmp + .{ .tag = @enumFromInt(159), .properties = .{ .param_str = "WUiddIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_fcmpf + .{ .tag = @enumFromInt(160), .properties = .{ .param_str = "WUiffIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_fence + .{ .tag = @enumFromInt(161), .properties = .{ .param_str = "vUicC*", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_fmed3f + .{ .tag = @enumFromInt(162), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_fract + .{ .tag = @enumFromInt(163), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_fractf + .{ .tag = @enumFromInt(164), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_frexp_exp + .{ .tag = @enumFromInt(165), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_frexp_expf + .{ .tag = @enumFromInt(166), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_frexp_mant + .{ .tag = @enumFromInt(167), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_frexp_mantf + .{ .tag = @enumFromInt(168), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_grid_size_x + .{ .tag = @enumFromInt(169), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_grid_size_y + .{ .tag = @enumFromInt(170), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_grid_size_z + .{ .tag = @enumFromInt(171), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_groupstaticsize + .{ .tag = @enumFromInt(172), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_iglp_opt + .{ .tag = @enumFromInt(173), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_implicitarg_ptr + .{ .tag = @enumFromInt(174), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_interp_mov + .{ .tag = @enumFromInt(175), .properties = .{ .param_str = "fUiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_interp_p1 + .{ .tag = @enumFromInt(176), .properties = .{ .param_str = "ffUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_interp_p1_f16 + .{ .tag = @enumFromInt(177), .properties = .{ .param_str = "ffUiUibUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_interp_p2 + .{ .tag = @enumFromInt(178), .properties = .{ .param_str = "fffUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_interp_p2_f16 + .{ .tag = @enumFromInt(179), .properties = .{ .param_str = "hffUiUibUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_is_private + .{ .tag = @enumFromInt(180), .properties = .{ .param_str = "bvC*0", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_is_shared + .{ .tag = @enumFromInt(181), .properties = .{ .param_str = "bvC*0", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_kernarg_segment_ptr + .{ .tag = @enumFromInt(182), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_ldexp + .{ .tag = @enumFromInt(183), .properties = .{ .param_str = "ddi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_ldexpf + .{ .tag = @enumFromInt(184), .properties = .{ .param_str = "ffi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_lerp + .{ .tag = @enumFromInt(185), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_log_clampf + .{ .tag = @enumFromInt(186), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_logf + .{ .tag = @enumFromInt(187), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_mbcnt_hi + .{ .tag = @enumFromInt(188), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_mbcnt_lo + .{ .tag = @enumFromInt(189), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_mqsad_pk_u16_u8 + .{ .tag = @enumFromInt(190), .properties = .{ .param_str = "WUiWUiUiWUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_mqsad_u32_u8 + .{ .tag = @enumFromInt(191), .properties = .{ .param_str = "V4UiWUiUiV4Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_msad_u8 + .{ .tag = @enumFromInt(192), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_qsad_pk_u16_u8 + .{ .tag = @enumFromInt(193), .properties = .{ .param_str = "WUiWUiUiWUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_queue_ptr + .{ .tag = @enumFromInt(194), .properties = .{ .param_str = "v*4", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_rcp + .{ .tag = @enumFromInt(195), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_rcpf + .{ .tag = @enumFromInt(196), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_read_exec + .{ .tag = @enumFromInt(197), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_read_exec_hi + .{ .tag = @enumFromInt(198), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_read_exec_lo + .{ .tag = @enumFromInt(199), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_readfirstlane + .{ .tag = @enumFromInt(200), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_readlane + .{ .tag = @enumFromInt(201), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_rsq + .{ .tag = @enumFromInt(202), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_rsq_clamp + .{ .tag = @enumFromInt(203), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_rsq_clampf + .{ .tag = @enumFromInt(204), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_rsqf + .{ .tag = @enumFromInt(205), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_s_barrier + .{ .tag = @enumFromInt(206), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_dcache_inv + .{ .tag = @enumFromInt(207), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_decperflevel + .{ .tag = @enumFromInt(208), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_getpc + .{ .tag = @enumFromInt(209), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_getreg + .{ .tag = @enumFromInt(210), .properties = .{ .param_str = "UiIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_incperflevel + .{ .tag = @enumFromInt(211), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_sendmsg + .{ .tag = @enumFromInt(212), .properties = .{ .param_str = "vIiUi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_sendmsghalt + .{ .tag = @enumFromInt(213), .properties = .{ .param_str = "vIiUi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_setprio + .{ .tag = @enumFromInt(214), .properties = .{ .param_str = "vIs", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_setreg + .{ .tag = @enumFromInt(215), .properties = .{ .param_str = "vIiUi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_sleep + .{ .tag = @enumFromInt(216), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_s_waitcnt + .{ .tag = @enumFromInt(217), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_sad_hi_u8 + .{ .tag = @enumFromInt(218), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sad_u16 + .{ .tag = @enumFromInt(219), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sad_u8 + .{ .tag = @enumFromInt(220), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sbfe + .{ .tag = @enumFromInt(221), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sched_barrier + .{ .tag = @enumFromInt(222), .properties = .{ .param_str = "vIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_sched_group_barrier + .{ .tag = @enumFromInt(223), .properties = .{ .param_str = "vIiIiIi", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_sicmp + .{ .tag = @enumFromInt(224), .properties = .{ .param_str = "WUiiiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sicmpl + .{ .tag = @enumFromInt(225), .properties = .{ .param_str = "WUiWiWiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sinf + .{ .tag = @enumFromInt(226), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sqrt + .{ .tag = @enumFromInt(227), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_sqrtf + .{ .tag = @enumFromInt(228), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_trig_preop + .{ .tag = @enumFromInt(229), .properties = .{ .param_str = "ddi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_trig_preopf + .{ .tag = @enumFromInt(230), .properties = .{ .param_str = "ffi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_ubfe + .{ .tag = @enumFromInt(231), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_uicmp + .{ .tag = @enumFromInt(232), .properties = .{ .param_str = "WUiUiUiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_uicmpl + .{ .tag = @enumFromInt(233), .properties = .{ .param_str = "WUiWUiWUiIi", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_wave_barrier + .{ .tag = @enumFromInt(234), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.amdgpu) } }, + // __builtin_amdgcn_workgroup_id_x + .{ .tag = @enumFromInt(235), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workgroup_id_y + .{ .tag = @enumFromInt(236), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workgroup_id_z + .{ .tag = @enumFromInt(237), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workgroup_size_x + .{ .tag = @enumFromInt(238), .properties = .{ .param_str = "Us", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workgroup_size_y + .{ .tag = @enumFromInt(239), .properties = .{ .param_str = "Us", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workgroup_size_z + .{ .tag = @enumFromInt(240), .properties = .{ .param_str = "Us", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workitem_id_x + .{ .tag = @enumFromInt(241), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workitem_id_y + .{ .tag = @enumFromInt(242), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_amdgcn_workitem_id_z + .{ .tag = @enumFromInt(243), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_annotation + .{ .tag = @enumFromInt(244), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_arm_cdp + .{ .tag = @enumFromInt(245), .properties = .{ .param_str = "vUIiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_cdp2 + .{ .tag = @enumFromInt(246), .properties = .{ .param_str = "vUIiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_clrex + .{ .tag = @enumFromInt(247), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __builtin_arm_cls + .{ .tag = @enumFromInt(248), .properties = .{ .param_str = "UiZUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_cls64 + .{ .tag = @enumFromInt(249), .properties = .{ .param_str = "UiWUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_clz + .{ .tag = @enumFromInt(250), .properties = .{ .param_str = "UiZUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_clz64 + .{ .tag = @enumFromInt(251), .properties = .{ .param_str = "UiWUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_cmse_TT + .{ .tag = @enumFromInt(252), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_cmse_TTA + .{ .tag = @enumFromInt(253), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_cmse_TTAT + .{ .tag = @enumFromInt(254), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_cmse_TTT + .{ .tag = @enumFromInt(255), .properties = .{ .param_str = "Uiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_dbg + .{ .tag = @enumFromInt(256), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_dmb + .{ .tag = @enumFromInt(257), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_dsb + .{ .tag = @enumFromInt(258), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_get_fpscr + .{ .tag = @enumFromInt(259), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_isb + .{ .tag = @enumFromInt(260), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_ldaex + .{ .tag = @enumFromInt(261), .properties = .{ .param_str = "v.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_arm_ldc + .{ .tag = @enumFromInt(262), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_ldc2 + .{ .tag = @enumFromInt(263), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_ldc2l + .{ .tag = @enumFromInt(264), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_ldcl + .{ .tag = @enumFromInt(265), .properties = .{ .param_str = "vUIiUIivC*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_ldrex + .{ .tag = @enumFromInt(266), .properties = .{ .param_str = "v.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_arm_ldrexd + .{ .tag = @enumFromInt(267), .properties = .{ .param_str = "LLUiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mcr + .{ .tag = @enumFromInt(268), .properties = .{ .param_str = "vUIiUIiUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mcr2 + .{ .tag = @enumFromInt(269), .properties = .{ .param_str = "vUIiUIiUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mcrr + .{ .tag = @enumFromInt(270), .properties = .{ .param_str = "vUIiUIiLLUiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mcrr2 + .{ .tag = @enumFromInt(271), .properties = .{ .param_str = "vUIiUIiLLUiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mrc + .{ .tag = @enumFromInt(272), .properties = .{ .param_str = "UiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mrc2 + .{ .tag = @enumFromInt(273), .properties = .{ .param_str = "UiUIiUIiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mrrc + .{ .tag = @enumFromInt(274), .properties = .{ .param_str = "LLUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_mrrc2 + .{ .tag = @enumFromInt(275), .properties = .{ .param_str = "LLUiUIiUIiUIi", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_nop + .{ .tag = @enumFromInt(276), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __builtin_arm_prefetch + .{ .tag = @enumFromInt(277), .properties = .{ .param_str = "!", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qadd + .{ .tag = @enumFromInt(278), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qadd16 + .{ .tag = @enumFromInt(279), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qadd8 + .{ .tag = @enumFromInt(280), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qasx + .{ .tag = @enumFromInt(281), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qdbl + .{ .tag = @enumFromInt(282), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qsax + .{ .tag = @enumFromInt(283), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qsub + .{ .tag = @enumFromInt(284), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qsub16 + .{ .tag = @enumFromInt(285), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_qsub8 + .{ .tag = @enumFromInt(286), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_rbit + .{ .tag = @enumFromInt(287), .properties = .{ .param_str = "UiUi", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_rbit64 + .{ .tag = @enumFromInt(288), .properties = .{ .param_str = "WUiWUi", .target_set = TargetSet.initOne(.aarch64), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_rsr + .{ .tag = @enumFromInt(289), .properties = .{ .param_str = "UicC*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_rsr64 + .{ .tag = @enumFromInt(290), .properties = .{ .param_str = "!", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_rsrp + .{ .tag = @enumFromInt(291), .properties = .{ .param_str = "v*cC*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_sadd16 + .{ .tag = @enumFromInt(292), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_sadd8 + .{ .tag = @enumFromInt(293), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_sasx + .{ .tag = @enumFromInt(294), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_sel + .{ .tag = @enumFromInt(295), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_set_fpscr + .{ .tag = @enumFromInt(296), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_sev + .{ .tag = @enumFromInt(297), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __builtin_arm_sevl + .{ .tag = @enumFromInt(298), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __builtin_arm_shadd16 + .{ .tag = @enumFromInt(299), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_shadd8 + .{ .tag = @enumFromInt(300), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_shasx + .{ .tag = @enumFromInt(301), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_shsax + .{ .tag = @enumFromInt(302), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_shsub16 + .{ .tag = @enumFromInt(303), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_shsub8 + .{ .tag = @enumFromInt(304), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlabb + .{ .tag = @enumFromInt(305), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlabt + .{ .tag = @enumFromInt(306), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlad + .{ .tag = @enumFromInt(307), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smladx + .{ .tag = @enumFromInt(308), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlald + .{ .tag = @enumFromInt(309), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlaldx + .{ .tag = @enumFromInt(310), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlatb + .{ .tag = @enumFromInt(311), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlatt + .{ .tag = @enumFromInt(312), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlawb + .{ .tag = @enumFromInt(313), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlawt + .{ .tag = @enumFromInt(314), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlsd + .{ .tag = @enumFromInt(315), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlsdx + .{ .tag = @enumFromInt(316), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlsld + .{ .tag = @enumFromInt(317), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smlsldx + .{ .tag = @enumFromInt(318), .properties = .{ .param_str = "LLiiiLLi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smuad + .{ .tag = @enumFromInt(319), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smuadx + .{ .tag = @enumFromInt(320), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smulbb + .{ .tag = @enumFromInt(321), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smulbt + .{ .tag = @enumFromInt(322), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smultb + .{ .tag = @enumFromInt(323), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smultt + .{ .tag = @enumFromInt(324), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smulwb + .{ .tag = @enumFromInt(325), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smulwt + .{ .tag = @enumFromInt(326), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smusd + .{ .tag = @enumFromInt(327), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_smusdx + .{ .tag = @enumFromInt(328), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_ssat + .{ .tag = @enumFromInt(329), .properties = .{ .param_str = "iiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_ssat16 + .{ .tag = @enumFromInt(330), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_ssax + .{ .tag = @enumFromInt(331), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_ssub16 + .{ .tag = @enumFromInt(332), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_ssub8 + .{ .tag = @enumFromInt(333), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_stc + .{ .tag = @enumFromInt(334), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_stc2 + .{ .tag = @enumFromInt(335), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_stc2l + .{ .tag = @enumFromInt(336), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_stcl + .{ .tag = @enumFromInt(337), .properties = .{ .param_str = "vUIiUIiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_stlex + .{ .tag = @enumFromInt(338), .properties = .{ .param_str = "i.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_arm_strex + .{ .tag = @enumFromInt(339), .properties = .{ .param_str = "i.", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_arm_strexd + .{ .tag = @enumFromInt(340), .properties = .{ .param_str = "iLLUiv*", .target_set = TargetSet.initOne(.arm) } }, + // __builtin_arm_sxtab16 + .{ .tag = @enumFromInt(341), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_sxtb16 + .{ .tag = @enumFromInt(342), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_tcancel + .{ .tag = @enumFromInt(343), .properties = .{ .param_str = "vWUIi", .target_set = TargetSet.initOne(.aarch64) } }, + // __builtin_arm_tcommit + .{ .tag = @enumFromInt(344), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.aarch64) } }, + // __builtin_arm_tstart + .{ .tag = @enumFromInt(345), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.aarch64), .attributes = .{ .returns_twice = true } } }, + // __builtin_arm_ttest + .{ .tag = @enumFromInt(346), .properties = .{ .param_str = "WUi", .target_set = TargetSet.initOne(.aarch64), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uadd16 + .{ .tag = @enumFromInt(347), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uadd8 + .{ .tag = @enumFromInt(348), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uasx + .{ .tag = @enumFromInt(349), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uhadd16 + .{ .tag = @enumFromInt(350), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uhadd8 + .{ .tag = @enumFromInt(351), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uhasx + .{ .tag = @enumFromInt(352), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uhsax + .{ .tag = @enumFromInt(353), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uhsub16 + .{ .tag = @enumFromInt(354), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uhsub8 + .{ .tag = @enumFromInt(355), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uqadd16 + .{ .tag = @enumFromInt(356), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uqadd8 + .{ .tag = @enumFromInt(357), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uqasx + .{ .tag = @enumFromInt(358), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uqsax + .{ .tag = @enumFromInt(359), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uqsub16 + .{ .tag = @enumFromInt(360), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uqsub8 + .{ .tag = @enumFromInt(361), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_usad8 + .{ .tag = @enumFromInt(362), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_usada8 + .{ .tag = @enumFromInt(363), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_usat + .{ .tag = @enumFromInt(364), .properties = .{ .param_str = "UiiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_usat16 + .{ .tag = @enumFromInt(365), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_usax + .{ .tag = @enumFromInt(366), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_usub16 + .{ .tag = @enumFromInt(367), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_usub8 + .{ .tag = @enumFromInt(368), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uxtab16 + .{ .tag = @enumFromInt(369), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_uxtb16 + .{ .tag = @enumFromInt(370), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_vcvtr_d + .{ .tag = @enumFromInt(371), .properties = .{ .param_str = "fdi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_vcvtr_f + .{ .tag = @enumFromInt(372), .properties = .{ .param_str = "ffi", .target_set = TargetSet.initOne(.arm), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_wfe + .{ .tag = @enumFromInt(373), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __builtin_arm_wfi + .{ .tag = @enumFromInt(374), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __builtin_arm_wsr + .{ .tag = @enumFromInt(375), .properties = .{ .param_str = "vcC*Ui", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_wsr64 + .{ .tag = @enumFromInt(376), .properties = .{ .param_str = "!", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_wsrp + .{ .tag = @enumFromInt(377), .properties = .{ .param_str = "vcC*vC*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_arm_yield + .{ .tag = @enumFromInt(378), .properties = .{ .param_str = "v", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __builtin_asin + .{ .tag = @enumFromInt(379), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_asinf + .{ .tag = @enumFromInt(380), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_asinf128 + .{ .tag = @enumFromInt(381), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_asinh + .{ .tag = @enumFromInt(382), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_asinhf + .{ .tag = @enumFromInt(383), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_asinhf128 + .{ .tag = @enumFromInt(384), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_asinhl + .{ .tag = @enumFromInt(385), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_asinl + .{ .tag = @enumFromInt(386), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_assume + .{ .tag = @enumFromInt(387), .properties = .{ .param_str = "vb", .attributes = .{ .const_evaluable = true } } }, + // __builtin_assume_aligned + .{ .tag = @enumFromInt(388), .properties = .{ .param_str = "v*vC*z.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_assume_separate_storage + .{ .tag = @enumFromInt(389), .properties = .{ .param_str = "vvCD*vCD*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_atan + .{ .tag = @enumFromInt(390), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atan2 + .{ .tag = @enumFromInt(391), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atan2f + .{ .tag = @enumFromInt(392), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atan2f128 + .{ .tag = @enumFromInt(393), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atan2l + .{ .tag = @enumFromInt(394), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atanf + .{ .tag = @enumFromInt(395), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atanf128 + .{ .tag = @enumFromInt(396), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atanh + .{ .tag = @enumFromInt(397), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atanhf + .{ .tag = @enumFromInt(398), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atanhf128 + .{ .tag = @enumFromInt(399), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atanhl + .{ .tag = @enumFromInt(400), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_atanl + .{ .tag = @enumFromInt(401), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_bcmp + .{ .tag = @enumFromInt(402), .properties = .{ .param_str = "ivC*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_bcopy + .{ .tag = @enumFromInt(403), .properties = .{ .param_str = "vvC*v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_bitrev + .{ .tag = @enumFromInt(404), .properties = .{ .param_str = "UiUi", .target_set = TargetSet.initOne(.xcore), .attributes = .{ .@"const" = true } } }, + // __builtin_bitreverse16 + .{ .tag = @enumFromInt(405), .properties = .{ .param_str = "UsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_bitreverse32 + .{ .tag = @enumFromInt(406), .properties = .{ .param_str = "UZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_bitreverse64 + .{ .tag = @enumFromInt(407), .properties = .{ .param_str = "UWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_bitreverse8 + .{ .tag = @enumFromInt(408), .properties = .{ .param_str = "UcUc", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_bswap16 + .{ .tag = @enumFromInt(409), .properties = .{ .param_str = "UsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_bswap32 + .{ .tag = @enumFromInt(410), .properties = .{ .param_str = "UZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_bswap64 + .{ .tag = @enumFromInt(411), .properties = .{ .param_str = "UWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_bzero + .{ .tag = @enumFromInt(412), .properties = .{ .param_str = "vv*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_cabs + .{ .tag = @enumFromInt(413), .properties = .{ .param_str = "dXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cabsf + .{ .tag = @enumFromInt(414), .properties = .{ .param_str = "fXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cabsl + .{ .tag = @enumFromInt(415), .properties = .{ .param_str = "LdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cacos + .{ .tag = @enumFromInt(416), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cacosf + .{ .tag = @enumFromInt(417), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cacosh + .{ .tag = @enumFromInt(418), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cacoshf + .{ .tag = @enumFromInt(419), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cacoshl + .{ .tag = @enumFromInt(420), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cacosl + .{ .tag = @enumFromInt(421), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_call_with_static_chain + .{ .tag = @enumFromInt(422), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_calloc + .{ .tag = @enumFromInt(423), .properties = .{ .param_str = "v*zz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_canonicalize + .{ .tag = @enumFromInt(424), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true } } }, + // __builtin_canonicalizef + .{ .tag = @enumFromInt(425), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true } } }, + // __builtin_canonicalizef16 + .{ .tag = @enumFromInt(426), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true } } }, + // __builtin_canonicalizel + .{ .tag = @enumFromInt(427), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true } } }, + // __builtin_carg + .{ .tag = @enumFromInt(428), .properties = .{ .param_str = "dXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cargf + .{ .tag = @enumFromInt(429), .properties = .{ .param_str = "fXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cargl + .{ .tag = @enumFromInt(430), .properties = .{ .param_str = "LdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_casin + .{ .tag = @enumFromInt(431), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_casinf + .{ .tag = @enumFromInt(432), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_casinh + .{ .tag = @enumFromInt(433), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_casinhf + .{ .tag = @enumFromInt(434), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_casinhl + .{ .tag = @enumFromInt(435), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_casinl + .{ .tag = @enumFromInt(436), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_catan + .{ .tag = @enumFromInt(437), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_catanf + .{ .tag = @enumFromInt(438), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_catanh + .{ .tag = @enumFromInt(439), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_catanhf + .{ .tag = @enumFromInt(440), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_catanhl + .{ .tag = @enumFromInt(441), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_catanl + .{ .tag = @enumFromInt(442), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cbrt + .{ .tag = @enumFromInt(443), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cbrtf + .{ .tag = @enumFromInt(444), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cbrtf128 + .{ .tag = @enumFromInt(445), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cbrtl + .{ .tag = @enumFromInt(446), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_ccos + .{ .tag = @enumFromInt(447), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ccosf + .{ .tag = @enumFromInt(448), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ccosh + .{ .tag = @enumFromInt(449), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ccoshf + .{ .tag = @enumFromInt(450), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ccoshl + .{ .tag = @enumFromInt(451), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ccosl + .{ .tag = @enumFromInt(452), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ceil + .{ .tag = @enumFromInt(453), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_ceilf + .{ .tag = @enumFromInt(454), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_ceilf128 + .{ .tag = @enumFromInt(455), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_ceilf16 + .{ .tag = @enumFromInt(456), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_ceill + .{ .tag = @enumFromInt(457), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cexp + .{ .tag = @enumFromInt(458), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cexpf + .{ .tag = @enumFromInt(459), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cexpl + .{ .tag = @enumFromInt(460), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_char_memchr + .{ .tag = @enumFromInt(461), .properties = .{ .param_str = "c*cC*iz", .attributes = .{ .const_evaluable = true } } }, + // __builtin_cimag + .{ .tag = @enumFromInt(462), .properties = .{ .param_str = "dXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cimagf + .{ .tag = @enumFromInt(463), .properties = .{ .param_str = "fXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cimagl + .{ .tag = @enumFromInt(464), .properties = .{ .param_str = "LdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_classify_type + .{ .tag = @enumFromInt(465), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .eval_args = false, .const_evaluable = true } } }, + // __builtin_clog + .{ .tag = @enumFromInt(466), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_clogf + .{ .tag = @enumFromInt(467), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_clogl + .{ .tag = @enumFromInt(468), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_clrsb + .{ .tag = @enumFromInt(469), .properties = .{ .param_str = "ii", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_clrsbl + .{ .tag = @enumFromInt(470), .properties = .{ .param_str = "iLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_clrsbll + .{ .tag = @enumFromInt(471), .properties = .{ .param_str = "iLLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_clz + .{ .tag = @enumFromInt(472), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_clzl + .{ .tag = @enumFromInt(473), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_clzll + .{ .tag = @enumFromInt(474), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_clzs + .{ .tag = @enumFromInt(475), .properties = .{ .param_str = "iUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_complex + .{ .tag = @enumFromInt(476), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_conj + .{ .tag = @enumFromInt(477), .properties = .{ .param_str = "XdXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_conjf + .{ .tag = @enumFromInt(478), .properties = .{ .param_str = "XfXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_conjl + .{ .tag = @enumFromInt(479), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_constant_p + .{ .tag = @enumFromInt(480), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .eval_args = false, .const_evaluable = true } } }, + // __builtin_convertvector + .{ .tag = @enumFromInt(481), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_copysign + .{ .tag = @enumFromInt(482), .properties = .{ .param_str = "ddd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_copysignf + .{ .tag = @enumFromInt(483), .properties = .{ .param_str = "fff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_copysignf128 + .{ .tag = @enumFromInt(484), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_copysignf16 + .{ .tag = @enumFromInt(485), .properties = .{ .param_str = "hhh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_copysignl + .{ .tag = @enumFromInt(486), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_cos + .{ .tag = @enumFromInt(487), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cosf + .{ .tag = @enumFromInt(488), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cosf128 + .{ .tag = @enumFromInt(489), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cosf16 + .{ .tag = @enumFromInt(490), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cosh + .{ .tag = @enumFromInt(491), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_coshf + .{ .tag = @enumFromInt(492), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_coshf128 + .{ .tag = @enumFromInt(493), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_coshl + .{ .tag = @enumFromInt(494), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cosl + .{ .tag = @enumFromInt(495), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cpow + .{ .tag = @enumFromInt(496), .properties = .{ .param_str = "XdXdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cpowf + .{ .tag = @enumFromInt(497), .properties = .{ .param_str = "XfXfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cpowl + .{ .tag = @enumFromInt(498), .properties = .{ .param_str = "XLdXLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_cproj + .{ .tag = @enumFromInt(499), .properties = .{ .param_str = "XdXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cprojf + .{ .tag = @enumFromInt(500), .properties = .{ .param_str = "XfXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cprojl + .{ .tag = @enumFromInt(501), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_cpu_init + .{ .tag = @enumFromInt(502), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.x86) } }, + // __builtin_cpu_is + .{ .tag = @enumFromInt(503), .properties = .{ .param_str = "bcC*", .target_set = TargetSet.initOne(.x86), .attributes = .{ .@"const" = true } } }, + // __builtin_cpu_supports + .{ .tag = @enumFromInt(504), .properties = .{ .param_str = "bcC*", .target_set = TargetSet.initOne(.x86), .attributes = .{ .@"const" = true } } }, + // __builtin_creal + .{ .tag = @enumFromInt(505), .properties = .{ .param_str = "dXd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_crealf + .{ .tag = @enumFromInt(506), .properties = .{ .param_str = "fXf", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_creall + .{ .tag = @enumFromInt(507), .properties = .{ .param_str = "LdXLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_csin + .{ .tag = @enumFromInt(508), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csinf + .{ .tag = @enumFromInt(509), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csinh + .{ .tag = @enumFromInt(510), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csinhf + .{ .tag = @enumFromInt(511), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csinhl + .{ .tag = @enumFromInt(512), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csinl + .{ .tag = @enumFromInt(513), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csqrt + .{ .tag = @enumFromInt(514), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csqrtf + .{ .tag = @enumFromInt(515), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_csqrtl + .{ .tag = @enumFromInt(516), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ctan + .{ .tag = @enumFromInt(517), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ctanf + .{ .tag = @enumFromInt(518), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ctanh + .{ .tag = @enumFromInt(519), .properties = .{ .param_str = "XdXd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ctanhf + .{ .tag = @enumFromInt(520), .properties = .{ .param_str = "XfXf", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ctanhl + .{ .tag = @enumFromInt(521), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ctanl + .{ .tag = @enumFromInt(522), .properties = .{ .param_str = "XLdXLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ctz + .{ .tag = @enumFromInt(523), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_ctzl + .{ .tag = @enumFromInt(524), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_ctzll + .{ .tag = @enumFromInt(525), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_ctzs + .{ .tag = @enumFromInt(526), .properties = .{ .param_str = "iUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_dcbf + .{ .tag = @enumFromInt(527), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_debugtrap + .{ .tag = @enumFromInt(528), .properties = .{ .param_str = "v" } }, + // __builtin_dump_struct + .{ .tag = @enumFromInt(529), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_dwarf_cfa + .{ .tag = @enumFromInt(530), .properties = .{ .param_str = "v*" } }, + // __builtin_dwarf_sp_column + .{ .tag = @enumFromInt(531), .properties = .{ .param_str = "Ui" } }, + // __builtin_dynamic_object_size + .{ .tag = @enumFromInt(532), .properties = .{ .param_str = "zvC*i", .attributes = .{ .eval_args = false, .const_evaluable = true } } }, + // __builtin_eh_return + .{ .tag = @enumFromInt(533), .properties = .{ .param_str = "vzv*", .attributes = .{ .noreturn = true } } }, + // __builtin_eh_return_data_regno + .{ .tag = @enumFromInt(534), .properties = .{ .param_str = "iIi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_elementwise_abs + .{ .tag = @enumFromInt(535), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_add_sat + .{ .tag = @enumFromInt(536), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_bitreverse + .{ .tag = @enumFromInt(537), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_canonicalize + .{ .tag = @enumFromInt(538), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_ceil + .{ .tag = @enumFromInt(539), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_copysign + .{ .tag = @enumFromInt(540), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_cos + .{ .tag = @enumFromInt(541), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_exp + .{ .tag = @enumFromInt(542), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_exp2 + .{ .tag = @enumFromInt(543), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_floor + .{ .tag = @enumFromInt(544), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_fma + .{ .tag = @enumFromInt(545), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_log + .{ .tag = @enumFromInt(546), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_log10 + .{ .tag = @enumFromInt(547), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_log2 + .{ .tag = @enumFromInt(548), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_max + .{ .tag = @enumFromInt(549), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_min + .{ .tag = @enumFromInt(550), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_nearbyint + .{ .tag = @enumFromInt(551), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_pow + .{ .tag = @enumFromInt(552), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_rint + .{ .tag = @enumFromInt(553), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_round + .{ .tag = @enumFromInt(554), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_roundeven + .{ .tag = @enumFromInt(555), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_sin + .{ .tag = @enumFromInt(556), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_sqrt + .{ .tag = @enumFromInt(557), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_sub_sat + .{ .tag = @enumFromInt(558), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_elementwise_trunc + .{ .tag = @enumFromInt(559), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_erf + .{ .tag = @enumFromInt(560), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_erfc + .{ .tag = @enumFromInt(561), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_erfcf + .{ .tag = @enumFromInt(562), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_erfcf128 + .{ .tag = @enumFromInt(563), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_erfcl + .{ .tag = @enumFromInt(564), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_erff + .{ .tag = @enumFromInt(565), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_erff128 + .{ .tag = @enumFromInt(566), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_erfl + .{ .tag = @enumFromInt(567), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp + .{ .tag = @enumFromInt(568), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp10 + .{ .tag = @enumFromInt(569), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp10f + .{ .tag = @enumFromInt(570), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp10f128 + .{ .tag = @enumFromInt(571), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp10f16 + .{ .tag = @enumFromInt(572), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp10l + .{ .tag = @enumFromInt(573), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp2 + .{ .tag = @enumFromInt(574), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp2f + .{ .tag = @enumFromInt(575), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp2f128 + .{ .tag = @enumFromInt(576), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp2f16 + .{ .tag = @enumFromInt(577), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_exp2l + .{ .tag = @enumFromInt(578), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expect + .{ .tag = @enumFromInt(579), .properties = .{ .param_str = "LiLiLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_expect_with_probability + .{ .tag = @enumFromInt(580), .properties = .{ .param_str = "LiLiLid", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_expf + .{ .tag = @enumFromInt(581), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expf128 + .{ .tag = @enumFromInt(582), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expf16 + .{ .tag = @enumFromInt(583), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expl + .{ .tag = @enumFromInt(584), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expm1 + .{ .tag = @enumFromInt(585), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expm1f + .{ .tag = @enumFromInt(586), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expm1f128 + .{ .tag = @enumFromInt(587), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_expm1l + .{ .tag = @enumFromInt(588), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_extend_pointer + .{ .tag = @enumFromInt(589), .properties = .{ .param_str = "ULLiv*" } }, + // __builtin_extract_return_addr + .{ .tag = @enumFromInt(590), .properties = .{ .param_str = "v*v*" } }, + // __builtin_fabs + .{ .tag = @enumFromInt(591), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fabsf + .{ .tag = @enumFromInt(592), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fabsf128 + .{ .tag = @enumFromInt(593), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fabsf16 + .{ .tag = @enumFromInt(594), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_fabsl + .{ .tag = @enumFromInt(595), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fdim + .{ .tag = @enumFromInt(596), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fdimf + .{ .tag = @enumFromInt(597), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fdimf128 + .{ .tag = @enumFromInt(598), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fdiml + .{ .tag = @enumFromInt(599), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ffs + .{ .tag = @enumFromInt(600), .properties = .{ .param_str = "ii", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_ffsl + .{ .tag = @enumFromInt(601), .properties = .{ .param_str = "iLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_ffsll + .{ .tag = @enumFromInt(602), .properties = .{ .param_str = "iLLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_floor + .{ .tag = @enumFromInt(603), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_floorf + .{ .tag = @enumFromInt(604), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_floorf128 + .{ .tag = @enumFromInt(605), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_floorf16 + .{ .tag = @enumFromInt(606), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_floorl + .{ .tag = @enumFromInt(607), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_flt_rounds + .{ .tag = @enumFromInt(608), .properties = .{ .param_str = "i" } }, + // __builtin_fma + .{ .tag = @enumFromInt(609), .properties = .{ .param_str = "dddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmaf + .{ .tag = @enumFromInt(610), .properties = .{ .param_str = "ffff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmaf128 + .{ .tag = @enumFromInt(611), .properties = .{ .param_str = "LLdLLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmaf16 + .{ .tag = @enumFromInt(612), .properties = .{ .param_str = "hhhh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmal + .{ .tag = @enumFromInt(613), .properties = .{ .param_str = "LdLdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmax + .{ .tag = @enumFromInt(614), .properties = .{ .param_str = "ddd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fmaxf + .{ .tag = @enumFromInt(615), .properties = .{ .param_str = "fff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fmaxf128 + .{ .tag = @enumFromInt(616), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fmaxf16 + .{ .tag = @enumFromInt(617), .properties = .{ .param_str = "hhh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fmaxl + .{ .tag = @enumFromInt(618), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fmin + .{ .tag = @enumFromInt(619), .properties = .{ .param_str = "ddd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fminf + .{ .tag = @enumFromInt(620), .properties = .{ .param_str = "fff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fminf128 + .{ .tag = @enumFromInt(621), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fminf16 + .{ .tag = @enumFromInt(622), .properties = .{ .param_str = "hhh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fminl + .{ .tag = @enumFromInt(623), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fmod + .{ .tag = @enumFromInt(624), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmodf + .{ .tag = @enumFromInt(625), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmodf128 + .{ .tag = @enumFromInt(626), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmodf16 + .{ .tag = @enumFromInt(627), .properties = .{ .param_str = "hhh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fmodl + .{ .tag = @enumFromInt(628), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_fpclassify + .{ .tag = @enumFromInt(629), .properties = .{ .param_str = "iiiiii.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_fprintf + .{ .tag = @enumFromInt(630), .properties = .{ .param_str = "iP*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 } } }, + // __builtin_frame_address + .{ .tag = @enumFromInt(631), .properties = .{ .param_str = "v*IUi" } }, + // __builtin_free + .{ .tag = @enumFromInt(632), .properties = .{ .param_str = "vv*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_frexp + .{ .tag = @enumFromInt(633), .properties = .{ .param_str = "ddi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_frexpf + .{ .tag = @enumFromInt(634), .properties = .{ .param_str = "ffi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_frexpf128 + .{ .tag = @enumFromInt(635), .properties = .{ .param_str = "LLdLLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_frexpf16 + .{ .tag = @enumFromInt(636), .properties = .{ .param_str = "hhi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_frexpl + .{ .tag = @enumFromInt(637), .properties = .{ .param_str = "LdLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_frob_return_addr + .{ .tag = @enumFromInt(638), .properties = .{ .param_str = "v*v*" } }, + // __builtin_fscanf + .{ .tag = @enumFromInt(639), .properties = .{ .param_str = "iP*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } }, + // __builtin_getid + .{ .tag = @enumFromInt(640), .properties = .{ .param_str = "Si", .target_set = TargetSet.initOne(.xcore), .attributes = .{ .@"const" = true } } }, + // __builtin_getps + .{ .tag = @enumFromInt(641), .properties = .{ .param_str = "UiUi", .target_set = TargetSet.initOne(.xcore) } }, + // __builtin_huge_val + .{ .tag = @enumFromInt(642), .properties = .{ .param_str = "d", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_huge_valf + .{ .tag = @enumFromInt(643), .properties = .{ .param_str = "f", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_huge_valf128 + .{ .tag = @enumFromInt(644), .properties = .{ .param_str = "LLd", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_huge_valf16 + .{ .tag = @enumFromInt(645), .properties = .{ .param_str = "x", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_huge_vall + .{ .tag = @enumFromInt(646), .properties = .{ .param_str = "Ld", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_hypot + .{ .tag = @enumFromInt(647), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_hypotf + .{ .tag = @enumFromInt(648), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_hypotf128 + .{ .tag = @enumFromInt(649), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_hypotl + .{ .tag = @enumFromInt(650), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ia32_rdpmc + .{ .tag = @enumFromInt(651), .properties = .{ .param_str = "UOii", .target_set = TargetSet.initOne(.x86) } }, + // __builtin_ia32_rdtsc + .{ .tag = @enumFromInt(652), .properties = .{ .param_str = "UOi", .target_set = TargetSet.initOne(.x86) } }, + // __builtin_ia32_rdtscp + .{ .tag = @enumFromInt(653), .properties = .{ .param_str = "UOiUi*", .target_set = TargetSet.initOne(.x86) } }, + // __builtin_ilogb + .{ .tag = @enumFromInt(654), .properties = .{ .param_str = "id", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ilogbf + .{ .tag = @enumFromInt(655), .properties = .{ .param_str = "if", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ilogbf128 + .{ .tag = @enumFromInt(656), .properties = .{ .param_str = "iLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ilogbl + .{ .tag = @enumFromInt(657), .properties = .{ .param_str = "iLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_index + .{ .tag = @enumFromInt(658), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_inf + .{ .tag = @enumFromInt(659), .properties = .{ .param_str = "d", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_inff + .{ .tag = @enumFromInt(660), .properties = .{ .param_str = "f", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_inff128 + .{ .tag = @enumFromInt(661), .properties = .{ .param_str = "LLd", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_inff16 + .{ .tag = @enumFromInt(662), .properties = .{ .param_str = "x", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_infl + .{ .tag = @enumFromInt(663), .properties = .{ .param_str = "Ld", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_init_dwarf_reg_size_table + .{ .tag = @enumFromInt(664), .properties = .{ .param_str = "vv*" } }, + // __builtin_is_aligned + .{ .tag = @enumFromInt(665), .properties = .{ .param_str = "bvC*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_isfinite + .{ .tag = @enumFromInt(666), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_isfpclass + .{ .tag = @enumFromInt(667), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_isgreater + .{ .tag = @enumFromInt(668), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_isgreaterequal + .{ .tag = @enumFromInt(669), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_isinf + .{ .tag = @enumFromInt(670), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_isinf_sign + .{ .tag = @enumFromInt(671), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_isless + .{ .tag = @enumFromInt(672), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_islessequal + .{ .tag = @enumFromInt(673), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_islessgreater + .{ .tag = @enumFromInt(674), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_isnan + .{ .tag = @enumFromInt(675), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_isnormal + .{ .tag = @enumFromInt(676), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_isunordered + .{ .tag = @enumFromInt(677), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_labs + .{ .tag = @enumFromInt(678), .properties = .{ .param_str = "LiLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_launder + .{ .tag = @enumFromInt(679), .properties = .{ .param_str = "v*v*", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_ldexp + .{ .tag = @enumFromInt(680), .properties = .{ .param_str = "ddi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ldexpf + .{ .tag = @enumFromInt(681), .properties = .{ .param_str = "ffi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ldexpf128 + .{ .tag = @enumFromInt(682), .properties = .{ .param_str = "LLdLLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ldexpf16 + .{ .tag = @enumFromInt(683), .properties = .{ .param_str = "hhi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ldexpl + .{ .tag = @enumFromInt(684), .properties = .{ .param_str = "LdLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lgamma + .{ .tag = @enumFromInt(685), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_lgammaf + .{ .tag = @enumFromInt(686), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_lgammaf128 + .{ .tag = @enumFromInt(687), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_lgammal + .{ .tag = @enumFromInt(688), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_llabs + .{ .tag = @enumFromInt(689), .properties = .{ .param_str = "LLiLLi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_llrint + .{ .tag = @enumFromInt(690), .properties = .{ .param_str = "LLid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_llrintf + .{ .tag = @enumFromInt(691), .properties = .{ .param_str = "LLif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_llrintf128 + .{ .tag = @enumFromInt(692), .properties = .{ .param_str = "LLiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_llrintl + .{ .tag = @enumFromInt(693), .properties = .{ .param_str = "LLiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_llround + .{ .tag = @enumFromInt(694), .properties = .{ .param_str = "LLid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_llroundf + .{ .tag = @enumFromInt(695), .properties = .{ .param_str = "LLif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_llroundf128 + .{ .tag = @enumFromInt(696), .properties = .{ .param_str = "LLiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_llroundl + .{ .tag = @enumFromInt(697), .properties = .{ .param_str = "LLiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log + .{ .tag = @enumFromInt(698), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log10 + .{ .tag = @enumFromInt(699), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log10f + .{ .tag = @enumFromInt(700), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log10f128 + .{ .tag = @enumFromInt(701), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log10f16 + .{ .tag = @enumFromInt(702), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log10l + .{ .tag = @enumFromInt(703), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log1p + .{ .tag = @enumFromInt(704), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log1pf + .{ .tag = @enumFromInt(705), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log1pf128 + .{ .tag = @enumFromInt(706), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log1pl + .{ .tag = @enumFromInt(707), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log2 + .{ .tag = @enumFromInt(708), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log2f + .{ .tag = @enumFromInt(709), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log2f128 + .{ .tag = @enumFromInt(710), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log2f16 + .{ .tag = @enumFromInt(711), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_log2l + .{ .tag = @enumFromInt(712), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logb + .{ .tag = @enumFromInt(713), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logbf + .{ .tag = @enumFromInt(714), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logbf128 + .{ .tag = @enumFromInt(715), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logbl + .{ .tag = @enumFromInt(716), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logf + .{ .tag = @enumFromInt(717), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logf128 + .{ .tag = @enumFromInt(718), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logf16 + .{ .tag = @enumFromInt(719), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_logl + .{ .tag = @enumFromInt(720), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_longjmp + .{ .tag = @enumFromInt(721), .properties = .{ .param_str = "vv**i", .attributes = .{ .noreturn = true } } }, + // __builtin_lrint + .{ .tag = @enumFromInt(722), .properties = .{ .param_str = "Lid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lrintf + .{ .tag = @enumFromInt(723), .properties = .{ .param_str = "Lif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lrintf128 + .{ .tag = @enumFromInt(724), .properties = .{ .param_str = "LiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lrintl + .{ .tag = @enumFromInt(725), .properties = .{ .param_str = "LiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lround + .{ .tag = @enumFromInt(726), .properties = .{ .param_str = "Lid", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lroundf + .{ .tag = @enumFromInt(727), .properties = .{ .param_str = "Lif", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lroundf128 + .{ .tag = @enumFromInt(728), .properties = .{ .param_str = "LiLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_lroundl + .{ .tag = @enumFromInt(729), .properties = .{ .param_str = "LiLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_malloc + .{ .tag = @enumFromInt(730), .properties = .{ .param_str = "v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_matrix_column_major_load + .{ .tag = @enumFromInt(731), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_matrix_column_major_store + .{ .tag = @enumFromInt(732), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_matrix_transpose + .{ .tag = @enumFromInt(733), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_memchr + .{ .tag = @enumFromInt(734), .properties = .{ .param_str = "v*vC*iz", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_memcmp + .{ .tag = @enumFromInt(735), .properties = .{ .param_str = "ivC*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_memcpy + .{ .tag = @enumFromInt(736), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_memcpy_inline + .{ .tag = @enumFromInt(737), .properties = .{ .param_str = "vv*vC*Iz" } }, + // __builtin_memmove + .{ .tag = @enumFromInt(738), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_mempcpy + .{ .tag = @enumFromInt(739), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_memset + .{ .tag = @enumFromInt(740), .properties = .{ .param_str = "v*v*iz", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_memset_inline + .{ .tag = @enumFromInt(741), .properties = .{ .param_str = "vv*iIz" } }, + // __builtin_mips_absq_s_ph + .{ .tag = @enumFromInt(742), .properties = .{ .param_str = "V2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_absq_s_qb + .{ .tag = @enumFromInt(743), .properties = .{ .param_str = "V4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_absq_s_w + .{ .tag = @enumFromInt(744), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addq_ph + .{ .tag = @enumFromInt(745), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addq_s_ph + .{ .tag = @enumFromInt(746), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addq_s_w + .{ .tag = @enumFromInt(747), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addqh_ph + .{ .tag = @enumFromInt(748), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_addqh_r_ph + .{ .tag = @enumFromInt(749), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_addqh_r_w + .{ .tag = @enumFromInt(750), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_addqh_w + .{ .tag = @enumFromInt(751), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_addsc + .{ .tag = @enumFromInt(752), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addu_ph + .{ .tag = @enumFromInt(753), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addu_qb + .{ .tag = @enumFromInt(754), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addu_s_ph + .{ .tag = @enumFromInt(755), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_addu_s_qb + .{ .tag = @enumFromInt(756), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_adduh_qb + .{ .tag = @enumFromInt(757), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_adduh_r_qb + .{ .tag = @enumFromInt(758), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_addwc + .{ .tag = @enumFromInt(759), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_append + .{ .tag = @enumFromInt(760), .properties = .{ .param_str = "iiiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_balign + .{ .tag = @enumFromInt(761), .properties = .{ .param_str = "iiiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_bitrev + .{ .tag = @enumFromInt(762), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_bposge32 + .{ .tag = @enumFromInt(763), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmp_eq_ph + .{ .tag = @enumFromInt(764), .properties = .{ .param_str = "vV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmp_le_ph + .{ .tag = @enumFromInt(765), .properties = .{ .param_str = "vV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmp_lt_ph + .{ .tag = @enumFromInt(766), .properties = .{ .param_str = "vV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpgdu_eq_qb + .{ .tag = @enumFromInt(767), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpgdu_le_qb + .{ .tag = @enumFromInt(768), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpgdu_lt_qb + .{ .tag = @enumFromInt(769), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpgu_eq_qb + .{ .tag = @enumFromInt(770), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpgu_le_qb + .{ .tag = @enumFromInt(771), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpgu_lt_qb + .{ .tag = @enumFromInt(772), .properties = .{ .param_str = "iV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpu_eq_qb + .{ .tag = @enumFromInt(773), .properties = .{ .param_str = "vV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpu_le_qb + .{ .tag = @enumFromInt(774), .properties = .{ .param_str = "vV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_cmpu_lt_qb + .{ .tag = @enumFromInt(775), .properties = .{ .param_str = "vV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpa_w_ph + .{ .tag = @enumFromInt(776), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_dpaq_s_w_ph + .{ .tag = @enumFromInt(777), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpaq_sa_l_w + .{ .tag = @enumFromInt(778), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpaqx_s_w_ph + .{ .tag = @enumFromInt(779), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpaqx_sa_w_ph + .{ .tag = @enumFromInt(780), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpau_h_qbl + .{ .tag = @enumFromInt(781), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_dpau_h_qbr + .{ .tag = @enumFromInt(782), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_dpax_w_ph + .{ .tag = @enumFromInt(783), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_dps_w_ph + .{ .tag = @enumFromInt(784), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_dpsq_s_w_ph + .{ .tag = @enumFromInt(785), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpsq_sa_l_w + .{ .tag = @enumFromInt(786), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpsqx_s_w_ph + .{ .tag = @enumFromInt(787), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpsqx_sa_w_ph + .{ .tag = @enumFromInt(788), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_dpsu_h_qbl + .{ .tag = @enumFromInt(789), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_dpsu_h_qbr + .{ .tag = @enumFromInt(790), .properties = .{ .param_str = "LLiLLiV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_dpsx_w_ph + .{ .tag = @enumFromInt(791), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_extp + .{ .tag = @enumFromInt(792), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_extpdp + .{ .tag = @enumFromInt(793), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_extr_r_w + .{ .tag = @enumFromInt(794), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_extr_rs_w + .{ .tag = @enumFromInt(795), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_extr_s_h + .{ .tag = @enumFromInt(796), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_extr_w + .{ .tag = @enumFromInt(797), .properties = .{ .param_str = "iLLii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_insv + .{ .tag = @enumFromInt(798), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_lbux + .{ .tag = @enumFromInt(799), .properties = .{ .param_str = "iv*i", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_lhx + .{ .tag = @enumFromInt(800), .properties = .{ .param_str = "iv*i", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_lwx + .{ .tag = @enumFromInt(801), .properties = .{ .param_str = "iv*i", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_madd + .{ .tag = @enumFromInt(802), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_maddu + .{ .tag = @enumFromInt(803), .properties = .{ .param_str = "LLiLLiUiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_maq_s_w_phl + .{ .tag = @enumFromInt(804), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_maq_s_w_phr + .{ .tag = @enumFromInt(805), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_maq_sa_w_phl + .{ .tag = @enumFromInt(806), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_maq_sa_w_phr + .{ .tag = @enumFromInt(807), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_modsub + .{ .tag = @enumFromInt(808), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_msub + .{ .tag = @enumFromInt(809), .properties = .{ .param_str = "LLiLLiii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_msubu + .{ .tag = @enumFromInt(810), .properties = .{ .param_str = "LLiLLiUiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_mthlip + .{ .tag = @enumFromInt(811), .properties = .{ .param_str = "LLiLLii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mul_ph + .{ .tag = @enumFromInt(812), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mul_s_ph + .{ .tag = @enumFromInt(813), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_muleq_s_w_phl + .{ .tag = @enumFromInt(814), .properties = .{ .param_str = "iV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_muleq_s_w_phr + .{ .tag = @enumFromInt(815), .properties = .{ .param_str = "iV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_muleu_s_ph_qbl + .{ .tag = @enumFromInt(816), .properties = .{ .param_str = "V2sV4ScV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_muleu_s_ph_qbr + .{ .tag = @enumFromInt(817), .properties = .{ .param_str = "V2sV4ScV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mulq_rs_ph + .{ .tag = @enumFromInt(818), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mulq_rs_w + .{ .tag = @enumFromInt(819), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mulq_s_ph + .{ .tag = @enumFromInt(820), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mulq_s_w + .{ .tag = @enumFromInt(821), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mulsa_w_ph + .{ .tag = @enumFromInt(822), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_mulsaq_s_w_ph + .{ .tag = @enumFromInt(823), .properties = .{ .param_str = "LLiLLiV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_mult + .{ .tag = @enumFromInt(824), .properties = .{ .param_str = "LLiii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_multu + .{ .tag = @enumFromInt(825), .properties = .{ .param_str = "LLiUiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_packrl_ph + .{ .tag = @enumFromInt(826), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_pick_ph + .{ .tag = @enumFromInt(827), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_pick_qb + .{ .tag = @enumFromInt(828), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_preceq_w_phl + .{ .tag = @enumFromInt(829), .properties = .{ .param_str = "iV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_preceq_w_phr + .{ .tag = @enumFromInt(830), .properties = .{ .param_str = "iV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precequ_ph_qbl + .{ .tag = @enumFromInt(831), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precequ_ph_qbla + .{ .tag = @enumFromInt(832), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precequ_ph_qbr + .{ .tag = @enumFromInt(833), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precequ_ph_qbra + .{ .tag = @enumFromInt(834), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_preceu_ph_qbl + .{ .tag = @enumFromInt(835), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_preceu_ph_qbla + .{ .tag = @enumFromInt(836), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_preceu_ph_qbr + .{ .tag = @enumFromInt(837), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_preceu_ph_qbra + .{ .tag = @enumFromInt(838), .properties = .{ .param_str = "V2sV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precr_qb_ph + .{ .tag = @enumFromInt(839), .properties = .{ .param_str = "V4ScV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_precr_sra_ph_w + .{ .tag = @enumFromInt(840), .properties = .{ .param_str = "V2siiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precr_sra_r_ph_w + .{ .tag = @enumFromInt(841), .properties = .{ .param_str = "V2siiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precrq_ph_w + .{ .tag = @enumFromInt(842), .properties = .{ .param_str = "V2sii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precrq_qb_ph + .{ .tag = @enumFromInt(843), .properties = .{ .param_str = "V4ScV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_precrq_rs_ph_w + .{ .tag = @enumFromInt(844), .properties = .{ .param_str = "V2sii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_precrqu_s_qb_ph + .{ .tag = @enumFromInt(845), .properties = .{ .param_str = "V4ScV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_prepend + .{ .tag = @enumFromInt(846), .properties = .{ .param_str = "iiiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_raddu_w_qb + .{ .tag = @enumFromInt(847), .properties = .{ .param_str = "iV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_rddsp + .{ .tag = @enumFromInt(848), .properties = .{ .param_str = "iIi", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_repl_ph + .{ .tag = @enumFromInt(849), .properties = .{ .param_str = "V2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_repl_qb + .{ .tag = @enumFromInt(850), .properties = .{ .param_str = "V4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shilo + .{ .tag = @enumFromInt(851), .properties = .{ .param_str = "LLiLLii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shll_ph + .{ .tag = @enumFromInt(852), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_shll_qb + .{ .tag = @enumFromInt(853), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_shll_s_ph + .{ .tag = @enumFromInt(854), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_shll_s_w + .{ .tag = @enumFromInt(855), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_shra_ph + .{ .tag = @enumFromInt(856), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shra_qb + .{ .tag = @enumFromInt(857), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shra_r_ph + .{ .tag = @enumFromInt(858), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shra_r_qb + .{ .tag = @enumFromInt(859), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shra_r_w + .{ .tag = @enumFromInt(860), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shrl_ph + .{ .tag = @enumFromInt(861), .properties = .{ .param_str = "V2sV2si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_shrl_qb + .{ .tag = @enumFromInt(862), .properties = .{ .param_str = "V4ScV4Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_subq_ph + .{ .tag = @enumFromInt(863), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_subq_s_ph + .{ .tag = @enumFromInt(864), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_subq_s_w + .{ .tag = @enumFromInt(865), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_subqh_ph + .{ .tag = @enumFromInt(866), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_subqh_r_ph + .{ .tag = @enumFromInt(867), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_subqh_r_w + .{ .tag = @enumFromInt(868), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_subqh_w + .{ .tag = @enumFromInt(869), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_subu_ph + .{ .tag = @enumFromInt(870), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_subu_qb + .{ .tag = @enumFromInt(871), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_subu_s_ph + .{ .tag = @enumFromInt(872), .properties = .{ .param_str = "V2sV2sV2s", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_subu_s_qb + .{ .tag = @enumFromInt(873), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_mips_subuh_qb + .{ .tag = @enumFromInt(874), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_subuh_r_qb + .{ .tag = @enumFromInt(875), .properties = .{ .param_str = "V4ScV4ScV4Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mips_wrdsp + .{ .tag = @enumFromInt(876), .properties = .{ .param_str = "viIi", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_modf + .{ .tag = @enumFromInt(877), .properties = .{ .param_str = "ddd*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_modff + .{ .tag = @enumFromInt(878), .properties = .{ .param_str = "fff*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_modff128 + .{ .tag = @enumFromInt(879), .properties = .{ .param_str = "LLdLLdLLd*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_modfl + .{ .tag = @enumFromInt(880), .properties = .{ .param_str = "LdLdLd*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_msa_add_a_b + .{ .tag = @enumFromInt(881), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_add_a_d + .{ .tag = @enumFromInt(882), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_add_a_h + .{ .tag = @enumFromInt(883), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_add_a_w + .{ .tag = @enumFromInt(884), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_a_b + .{ .tag = @enumFromInt(885), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_a_d + .{ .tag = @enumFromInt(886), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_a_h + .{ .tag = @enumFromInt(887), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_a_w + .{ .tag = @enumFromInt(888), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_s_b + .{ .tag = @enumFromInt(889), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_s_d + .{ .tag = @enumFromInt(890), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_s_h + .{ .tag = @enumFromInt(891), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_s_w + .{ .tag = @enumFromInt(892), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_u_b + .{ .tag = @enumFromInt(893), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_u_d + .{ .tag = @enumFromInt(894), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_u_h + .{ .tag = @enumFromInt(895), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_adds_u_w + .{ .tag = @enumFromInt(896), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addv_b + .{ .tag = @enumFromInt(897), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addv_d + .{ .tag = @enumFromInt(898), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addv_h + .{ .tag = @enumFromInt(899), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addv_w + .{ .tag = @enumFromInt(900), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addvi_b + .{ .tag = @enumFromInt(901), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addvi_d + .{ .tag = @enumFromInt(902), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addvi_h + .{ .tag = @enumFromInt(903), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_addvi_w + .{ .tag = @enumFromInt(904), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_and_v + .{ .tag = @enumFromInt(905), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_andi_b + .{ .tag = @enumFromInt(906), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_s_b + .{ .tag = @enumFromInt(907), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_s_d + .{ .tag = @enumFromInt(908), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_s_h + .{ .tag = @enumFromInt(909), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_s_w + .{ .tag = @enumFromInt(910), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_u_b + .{ .tag = @enumFromInt(911), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_u_d + .{ .tag = @enumFromInt(912), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_u_h + .{ .tag = @enumFromInt(913), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_asub_u_w + .{ .tag = @enumFromInt(914), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_s_b + .{ .tag = @enumFromInt(915), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_s_d + .{ .tag = @enumFromInt(916), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_s_h + .{ .tag = @enumFromInt(917), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_s_w + .{ .tag = @enumFromInt(918), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_u_b + .{ .tag = @enumFromInt(919), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_u_d + .{ .tag = @enumFromInt(920), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_u_h + .{ .tag = @enumFromInt(921), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ave_u_w + .{ .tag = @enumFromInt(922), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_s_b + .{ .tag = @enumFromInt(923), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_s_d + .{ .tag = @enumFromInt(924), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_s_h + .{ .tag = @enumFromInt(925), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_s_w + .{ .tag = @enumFromInt(926), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_u_b + .{ .tag = @enumFromInt(927), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_u_d + .{ .tag = @enumFromInt(928), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_u_h + .{ .tag = @enumFromInt(929), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_aver_u_w + .{ .tag = @enumFromInt(930), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclr_b + .{ .tag = @enumFromInt(931), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclr_d + .{ .tag = @enumFromInt(932), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclr_h + .{ .tag = @enumFromInt(933), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclr_w + .{ .tag = @enumFromInt(934), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclri_b + .{ .tag = @enumFromInt(935), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclri_d + .{ .tag = @enumFromInt(936), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclri_h + .{ .tag = @enumFromInt(937), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bclri_w + .{ .tag = @enumFromInt(938), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsl_b + .{ .tag = @enumFromInt(939), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsl_d + .{ .tag = @enumFromInt(940), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsl_h + .{ .tag = @enumFromInt(941), .properties = .{ .param_str = "V8UsV8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsl_w + .{ .tag = @enumFromInt(942), .properties = .{ .param_str = "V4UiV4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsli_b + .{ .tag = @enumFromInt(943), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsli_d + .{ .tag = @enumFromInt(944), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsli_h + .{ .tag = @enumFromInt(945), .properties = .{ .param_str = "V8UsV8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsli_w + .{ .tag = @enumFromInt(946), .properties = .{ .param_str = "V4UiV4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsr_b + .{ .tag = @enumFromInt(947), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsr_d + .{ .tag = @enumFromInt(948), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsr_h + .{ .tag = @enumFromInt(949), .properties = .{ .param_str = "V8UsV8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsr_w + .{ .tag = @enumFromInt(950), .properties = .{ .param_str = "V4UiV4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsri_b + .{ .tag = @enumFromInt(951), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsri_d + .{ .tag = @enumFromInt(952), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsri_h + .{ .tag = @enumFromInt(953), .properties = .{ .param_str = "V8UsV8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_binsri_w + .{ .tag = @enumFromInt(954), .properties = .{ .param_str = "V4UiV4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bmnz_v + .{ .tag = @enumFromInt(955), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bmnzi_b + .{ .tag = @enumFromInt(956), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bmz_v + .{ .tag = @enumFromInt(957), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bmzi_b + .{ .tag = @enumFromInt(958), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bneg_b + .{ .tag = @enumFromInt(959), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bneg_d + .{ .tag = @enumFromInt(960), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bneg_h + .{ .tag = @enumFromInt(961), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bneg_w + .{ .tag = @enumFromInt(962), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnegi_b + .{ .tag = @enumFromInt(963), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnegi_d + .{ .tag = @enumFromInt(964), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnegi_h + .{ .tag = @enumFromInt(965), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnegi_w + .{ .tag = @enumFromInt(966), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnz_b + .{ .tag = @enumFromInt(967), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnz_d + .{ .tag = @enumFromInt(968), .properties = .{ .param_str = "iV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnz_h + .{ .tag = @enumFromInt(969), .properties = .{ .param_str = "iV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnz_v + .{ .tag = @enumFromInt(970), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bnz_w + .{ .tag = @enumFromInt(971), .properties = .{ .param_str = "iV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bsel_v + .{ .tag = @enumFromInt(972), .properties = .{ .param_str = "V16UcV16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bseli_b + .{ .tag = @enumFromInt(973), .properties = .{ .param_str = "V16UcV16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bset_b + .{ .tag = @enumFromInt(974), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bset_d + .{ .tag = @enumFromInt(975), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bset_h + .{ .tag = @enumFromInt(976), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bset_w + .{ .tag = @enumFromInt(977), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bseti_b + .{ .tag = @enumFromInt(978), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bseti_d + .{ .tag = @enumFromInt(979), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bseti_h + .{ .tag = @enumFromInt(980), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bseti_w + .{ .tag = @enumFromInt(981), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bz_b + .{ .tag = @enumFromInt(982), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bz_d + .{ .tag = @enumFromInt(983), .properties = .{ .param_str = "iV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bz_h + .{ .tag = @enumFromInt(984), .properties = .{ .param_str = "iV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bz_v + .{ .tag = @enumFromInt(985), .properties = .{ .param_str = "iV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_bz_w + .{ .tag = @enumFromInt(986), .properties = .{ .param_str = "iV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceq_b + .{ .tag = @enumFromInt(987), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceq_d + .{ .tag = @enumFromInt(988), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceq_h + .{ .tag = @enumFromInt(989), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceq_w + .{ .tag = @enumFromInt(990), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceqi_b + .{ .tag = @enumFromInt(991), .properties = .{ .param_str = "V16ScV16ScISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceqi_d + .{ .tag = @enumFromInt(992), .properties = .{ .param_str = "V2SLLiV2SLLiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceqi_h + .{ .tag = @enumFromInt(993), .properties = .{ .param_str = "V8SsV8SsISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ceqi_w + .{ .tag = @enumFromInt(994), .properties = .{ .param_str = "V4SiV4SiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cfcmsa + .{ .tag = @enumFromInt(995), .properties = .{ .param_str = "iIi", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_msa_cle_s_b + .{ .tag = @enumFromInt(996), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cle_s_d + .{ .tag = @enumFromInt(997), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cle_s_h + .{ .tag = @enumFromInt(998), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cle_s_w + .{ .tag = @enumFromInt(999), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cle_u_b + .{ .tag = @enumFromInt(1000), .properties = .{ .param_str = "V16ScV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cle_u_d + .{ .tag = @enumFromInt(1001), .properties = .{ .param_str = "V2SLLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cle_u_h + .{ .tag = @enumFromInt(1002), .properties = .{ .param_str = "V8SsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_cle_u_w + .{ .tag = @enumFromInt(1003), .properties = .{ .param_str = "V4SiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_s_b + .{ .tag = @enumFromInt(1004), .properties = .{ .param_str = "V16ScV16ScISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_s_d + .{ .tag = @enumFromInt(1005), .properties = .{ .param_str = "V2SLLiV2SLLiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_s_h + .{ .tag = @enumFromInt(1006), .properties = .{ .param_str = "V8SsV8SsISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_s_w + .{ .tag = @enumFromInt(1007), .properties = .{ .param_str = "V4SiV4SiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_u_b + .{ .tag = @enumFromInt(1008), .properties = .{ .param_str = "V16ScV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_u_d + .{ .tag = @enumFromInt(1009), .properties = .{ .param_str = "V2SLLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_u_h + .{ .tag = @enumFromInt(1010), .properties = .{ .param_str = "V8SsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clei_u_w + .{ .tag = @enumFromInt(1011), .properties = .{ .param_str = "V4SiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_s_b + .{ .tag = @enumFromInt(1012), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_s_d + .{ .tag = @enumFromInt(1013), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_s_h + .{ .tag = @enumFromInt(1014), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_s_w + .{ .tag = @enumFromInt(1015), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_u_b + .{ .tag = @enumFromInt(1016), .properties = .{ .param_str = "V16ScV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_u_d + .{ .tag = @enumFromInt(1017), .properties = .{ .param_str = "V2SLLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_u_h + .{ .tag = @enumFromInt(1018), .properties = .{ .param_str = "V8SsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clt_u_w + .{ .tag = @enumFromInt(1019), .properties = .{ .param_str = "V4SiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_s_b + .{ .tag = @enumFromInt(1020), .properties = .{ .param_str = "V16ScV16ScISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_s_d + .{ .tag = @enumFromInt(1021), .properties = .{ .param_str = "V2SLLiV2SLLiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_s_h + .{ .tag = @enumFromInt(1022), .properties = .{ .param_str = "V8SsV8SsISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_s_w + .{ .tag = @enumFromInt(1023), .properties = .{ .param_str = "V4SiV4SiISi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_u_b + .{ .tag = @enumFromInt(1024), .properties = .{ .param_str = "V16ScV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_u_d + .{ .tag = @enumFromInt(1025), .properties = .{ .param_str = "V2SLLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_u_h + .{ .tag = @enumFromInt(1026), .properties = .{ .param_str = "V8SsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_clti_u_w + .{ .tag = @enumFromInt(1027), .properties = .{ .param_str = "V4SiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_s_b + .{ .tag = @enumFromInt(1028), .properties = .{ .param_str = "iV16ScIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_s_d + .{ .tag = @enumFromInt(1029), .properties = .{ .param_str = "LLiV2SLLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_s_h + .{ .tag = @enumFromInt(1030), .properties = .{ .param_str = "iV8SsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_s_w + .{ .tag = @enumFromInt(1031), .properties = .{ .param_str = "iV4SiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_u_b + .{ .tag = @enumFromInt(1032), .properties = .{ .param_str = "iV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_u_d + .{ .tag = @enumFromInt(1033), .properties = .{ .param_str = "LLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_u_h + .{ .tag = @enumFromInt(1034), .properties = .{ .param_str = "iV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_copy_u_w + .{ .tag = @enumFromInt(1035), .properties = .{ .param_str = "iV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ctcmsa + .{ .tag = @enumFromInt(1036), .properties = .{ .param_str = "vIii", .target_set = TargetSet.initOne(.mips) } }, + // __builtin_msa_div_s_b + .{ .tag = @enumFromInt(1037), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_div_s_d + .{ .tag = @enumFromInt(1038), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_div_s_h + .{ .tag = @enumFromInt(1039), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_div_s_w + .{ .tag = @enumFromInt(1040), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_div_u_b + .{ .tag = @enumFromInt(1041), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_div_u_d + .{ .tag = @enumFromInt(1042), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_div_u_h + .{ .tag = @enumFromInt(1043), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_div_u_w + .{ .tag = @enumFromInt(1044), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dotp_s_d + .{ .tag = @enumFromInt(1045), .properties = .{ .param_str = "V2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dotp_s_h + .{ .tag = @enumFromInt(1046), .properties = .{ .param_str = "V8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dotp_s_w + .{ .tag = @enumFromInt(1047), .properties = .{ .param_str = "V4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dotp_u_d + .{ .tag = @enumFromInt(1048), .properties = .{ .param_str = "V2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dotp_u_h + .{ .tag = @enumFromInt(1049), .properties = .{ .param_str = "V8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dotp_u_w + .{ .tag = @enumFromInt(1050), .properties = .{ .param_str = "V4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpadd_s_d + .{ .tag = @enumFromInt(1051), .properties = .{ .param_str = "V2SLLiV2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpadd_s_h + .{ .tag = @enumFromInt(1052), .properties = .{ .param_str = "V8SsV8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpadd_s_w + .{ .tag = @enumFromInt(1053), .properties = .{ .param_str = "V4SiV4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpadd_u_d + .{ .tag = @enumFromInt(1054), .properties = .{ .param_str = "V2ULLiV2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpadd_u_h + .{ .tag = @enumFromInt(1055), .properties = .{ .param_str = "V8UsV8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpadd_u_w + .{ .tag = @enumFromInt(1056), .properties = .{ .param_str = "V4UiV4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpsub_s_d + .{ .tag = @enumFromInt(1057), .properties = .{ .param_str = "V2SLLiV2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpsub_s_h + .{ .tag = @enumFromInt(1058), .properties = .{ .param_str = "V8SsV8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpsub_s_w + .{ .tag = @enumFromInt(1059), .properties = .{ .param_str = "V4SiV4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpsub_u_d + .{ .tag = @enumFromInt(1060), .properties = .{ .param_str = "V2ULLiV2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpsub_u_h + .{ .tag = @enumFromInt(1061), .properties = .{ .param_str = "V8UsV8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_dpsub_u_w + .{ .tag = @enumFromInt(1062), .properties = .{ .param_str = "V4UiV4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fadd_d + .{ .tag = @enumFromInt(1063), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fadd_w + .{ .tag = @enumFromInt(1064), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcaf_d + .{ .tag = @enumFromInt(1065), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcaf_w + .{ .tag = @enumFromInt(1066), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fceq_d + .{ .tag = @enumFromInt(1067), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fceq_w + .{ .tag = @enumFromInt(1068), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fclass_d + .{ .tag = @enumFromInt(1069), .properties = .{ .param_str = "V2LLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fclass_w + .{ .tag = @enumFromInt(1070), .properties = .{ .param_str = "V4iV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcle_d + .{ .tag = @enumFromInt(1071), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcle_w + .{ .tag = @enumFromInt(1072), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fclt_d + .{ .tag = @enumFromInt(1073), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fclt_w + .{ .tag = @enumFromInt(1074), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcne_d + .{ .tag = @enumFromInt(1075), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcne_w + .{ .tag = @enumFromInt(1076), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcor_d + .{ .tag = @enumFromInt(1077), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcor_w + .{ .tag = @enumFromInt(1078), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcueq_d + .{ .tag = @enumFromInt(1079), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcueq_w + .{ .tag = @enumFromInt(1080), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcule_d + .{ .tag = @enumFromInt(1081), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcule_w + .{ .tag = @enumFromInt(1082), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcult_d + .{ .tag = @enumFromInt(1083), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcult_w + .{ .tag = @enumFromInt(1084), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcun_d + .{ .tag = @enumFromInt(1085), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcun_w + .{ .tag = @enumFromInt(1086), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcune_d + .{ .tag = @enumFromInt(1087), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fcune_w + .{ .tag = @enumFromInt(1088), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fdiv_d + .{ .tag = @enumFromInt(1089), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fdiv_w + .{ .tag = @enumFromInt(1090), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexdo_h + .{ .tag = @enumFromInt(1091), .properties = .{ .param_str = "V8hV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexdo_w + .{ .tag = @enumFromInt(1092), .properties = .{ .param_str = "V4fV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexp2_d + .{ .tag = @enumFromInt(1093), .properties = .{ .param_str = "V2dV2dV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexp2_w + .{ .tag = @enumFromInt(1094), .properties = .{ .param_str = "V4fV4fV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexupl_d + .{ .tag = @enumFromInt(1095), .properties = .{ .param_str = "V2dV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexupl_w + .{ .tag = @enumFromInt(1096), .properties = .{ .param_str = "V4fV8h", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexupr_d + .{ .tag = @enumFromInt(1097), .properties = .{ .param_str = "V2dV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fexupr_w + .{ .tag = @enumFromInt(1098), .properties = .{ .param_str = "V4fV8h", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffint_s_d + .{ .tag = @enumFromInt(1099), .properties = .{ .param_str = "V2dV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffint_s_w + .{ .tag = @enumFromInt(1100), .properties = .{ .param_str = "V4fV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffint_u_d + .{ .tag = @enumFromInt(1101), .properties = .{ .param_str = "V2dV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffint_u_w + .{ .tag = @enumFromInt(1102), .properties = .{ .param_str = "V4fV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffql_d + .{ .tag = @enumFromInt(1103), .properties = .{ .param_str = "V2dV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffql_w + .{ .tag = @enumFromInt(1104), .properties = .{ .param_str = "V4fV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffqr_d + .{ .tag = @enumFromInt(1105), .properties = .{ .param_str = "V2dV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ffqr_w + .{ .tag = @enumFromInt(1106), .properties = .{ .param_str = "V4fV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fill_b + .{ .tag = @enumFromInt(1107), .properties = .{ .param_str = "V16Sci", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fill_d + .{ .tag = @enumFromInt(1108), .properties = .{ .param_str = "V2SLLiLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fill_h + .{ .tag = @enumFromInt(1109), .properties = .{ .param_str = "V8Ssi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fill_w + .{ .tag = @enumFromInt(1110), .properties = .{ .param_str = "V4Sii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_flog2_d + .{ .tag = @enumFromInt(1111), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_flog2_w + .{ .tag = @enumFromInt(1112), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmadd_d + .{ .tag = @enumFromInt(1113), .properties = .{ .param_str = "V2dV2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmadd_w + .{ .tag = @enumFromInt(1114), .properties = .{ .param_str = "V4fV4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmax_a_d + .{ .tag = @enumFromInt(1115), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmax_a_w + .{ .tag = @enumFromInt(1116), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmax_d + .{ .tag = @enumFromInt(1117), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmax_w + .{ .tag = @enumFromInt(1118), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmin_a_d + .{ .tag = @enumFromInt(1119), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmin_a_w + .{ .tag = @enumFromInt(1120), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmin_d + .{ .tag = @enumFromInt(1121), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmin_w + .{ .tag = @enumFromInt(1122), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmsub_d + .{ .tag = @enumFromInt(1123), .properties = .{ .param_str = "V2dV2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmsub_w + .{ .tag = @enumFromInt(1124), .properties = .{ .param_str = "V4fV4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmul_d + .{ .tag = @enumFromInt(1125), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fmul_w + .{ .tag = @enumFromInt(1126), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_frcp_d + .{ .tag = @enumFromInt(1127), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_frcp_w + .{ .tag = @enumFromInt(1128), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_frint_d + .{ .tag = @enumFromInt(1129), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_frint_w + .{ .tag = @enumFromInt(1130), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_frsqrt_d + .{ .tag = @enumFromInt(1131), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_frsqrt_w + .{ .tag = @enumFromInt(1132), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsaf_d + .{ .tag = @enumFromInt(1133), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsaf_w + .{ .tag = @enumFromInt(1134), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fseq_d + .{ .tag = @enumFromInt(1135), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fseq_w + .{ .tag = @enumFromInt(1136), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsle_d + .{ .tag = @enumFromInt(1137), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsle_w + .{ .tag = @enumFromInt(1138), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fslt_d + .{ .tag = @enumFromInt(1139), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fslt_w + .{ .tag = @enumFromInt(1140), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsne_d + .{ .tag = @enumFromInt(1141), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsne_w + .{ .tag = @enumFromInt(1142), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsor_d + .{ .tag = @enumFromInt(1143), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsor_w + .{ .tag = @enumFromInt(1144), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsqrt_d + .{ .tag = @enumFromInt(1145), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsqrt_w + .{ .tag = @enumFromInt(1146), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsub_d + .{ .tag = @enumFromInt(1147), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsub_w + .{ .tag = @enumFromInt(1148), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsueq_d + .{ .tag = @enumFromInt(1149), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsueq_w + .{ .tag = @enumFromInt(1150), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsule_d + .{ .tag = @enumFromInt(1151), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsule_w + .{ .tag = @enumFromInt(1152), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsult_d + .{ .tag = @enumFromInt(1153), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsult_w + .{ .tag = @enumFromInt(1154), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsun_d + .{ .tag = @enumFromInt(1155), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsun_w + .{ .tag = @enumFromInt(1156), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsune_d + .{ .tag = @enumFromInt(1157), .properties = .{ .param_str = "V2LLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_fsune_w + .{ .tag = @enumFromInt(1158), .properties = .{ .param_str = "V4iV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftint_s_d + .{ .tag = @enumFromInt(1159), .properties = .{ .param_str = "V2SLLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftint_s_w + .{ .tag = @enumFromInt(1160), .properties = .{ .param_str = "V4SiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftint_u_d + .{ .tag = @enumFromInt(1161), .properties = .{ .param_str = "V2ULLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftint_u_w + .{ .tag = @enumFromInt(1162), .properties = .{ .param_str = "V4UiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftq_h + .{ .tag = @enumFromInt(1163), .properties = .{ .param_str = "V4UiV4fV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftq_w + .{ .tag = @enumFromInt(1164), .properties = .{ .param_str = "V2ULLiV2dV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftrunc_s_d + .{ .tag = @enumFromInt(1165), .properties = .{ .param_str = "V2SLLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftrunc_s_w + .{ .tag = @enumFromInt(1166), .properties = .{ .param_str = "V4SiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftrunc_u_d + .{ .tag = @enumFromInt(1167), .properties = .{ .param_str = "V2ULLiV2d", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ftrunc_u_w + .{ .tag = @enumFromInt(1168), .properties = .{ .param_str = "V4UiV4f", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hadd_s_d + .{ .tag = @enumFromInt(1169), .properties = .{ .param_str = "V2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hadd_s_h + .{ .tag = @enumFromInt(1170), .properties = .{ .param_str = "V8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hadd_s_w + .{ .tag = @enumFromInt(1171), .properties = .{ .param_str = "V4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hadd_u_d + .{ .tag = @enumFromInt(1172), .properties = .{ .param_str = "V2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hadd_u_h + .{ .tag = @enumFromInt(1173), .properties = .{ .param_str = "V8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hadd_u_w + .{ .tag = @enumFromInt(1174), .properties = .{ .param_str = "V4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hsub_s_d + .{ .tag = @enumFromInt(1175), .properties = .{ .param_str = "V2SLLiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hsub_s_h + .{ .tag = @enumFromInt(1176), .properties = .{ .param_str = "V8SsV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hsub_s_w + .{ .tag = @enumFromInt(1177), .properties = .{ .param_str = "V4SiV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hsub_u_d + .{ .tag = @enumFromInt(1178), .properties = .{ .param_str = "V2ULLiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hsub_u_h + .{ .tag = @enumFromInt(1179), .properties = .{ .param_str = "V8UsV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_hsub_u_w + .{ .tag = @enumFromInt(1180), .properties = .{ .param_str = "V4UiV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvev_b + .{ .tag = @enumFromInt(1181), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvev_d + .{ .tag = @enumFromInt(1182), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvev_h + .{ .tag = @enumFromInt(1183), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvev_w + .{ .tag = @enumFromInt(1184), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvl_b + .{ .tag = @enumFromInt(1185), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvl_d + .{ .tag = @enumFromInt(1186), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvl_h + .{ .tag = @enumFromInt(1187), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvl_w + .{ .tag = @enumFromInt(1188), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvod_b + .{ .tag = @enumFromInt(1189), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvod_d + .{ .tag = @enumFromInt(1190), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvod_h + .{ .tag = @enumFromInt(1191), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvod_w + .{ .tag = @enumFromInt(1192), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvr_b + .{ .tag = @enumFromInt(1193), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvr_d + .{ .tag = @enumFromInt(1194), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvr_h + .{ .tag = @enumFromInt(1195), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ilvr_w + .{ .tag = @enumFromInt(1196), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insert_b + .{ .tag = @enumFromInt(1197), .properties = .{ .param_str = "V16ScV16ScIUii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insert_d + .{ .tag = @enumFromInt(1198), .properties = .{ .param_str = "V2SLLiV2SLLiIUiLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insert_h + .{ .tag = @enumFromInt(1199), .properties = .{ .param_str = "V8SsV8SsIUii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insert_w + .{ .tag = @enumFromInt(1200), .properties = .{ .param_str = "V4SiV4SiIUii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insve_b + .{ .tag = @enumFromInt(1201), .properties = .{ .param_str = "V16ScV16ScIUiV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insve_d + .{ .tag = @enumFromInt(1202), .properties = .{ .param_str = "V2SLLiV2SLLiIUiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insve_h + .{ .tag = @enumFromInt(1203), .properties = .{ .param_str = "V8SsV8SsIUiV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_insve_w + .{ .tag = @enumFromInt(1204), .properties = .{ .param_str = "V4SiV4SiIUiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ld_b + .{ .tag = @enumFromInt(1205), .properties = .{ .param_str = "V16Scv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ld_d + .{ .tag = @enumFromInt(1206), .properties = .{ .param_str = "V2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ld_h + .{ .tag = @enumFromInt(1207), .properties = .{ .param_str = "V8Ssv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ld_w + .{ .tag = @enumFromInt(1208), .properties = .{ .param_str = "V4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ldi_b + .{ .tag = @enumFromInt(1209), .properties = .{ .param_str = "V16cIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ldi_d + .{ .tag = @enumFromInt(1210), .properties = .{ .param_str = "V2LLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ldi_h + .{ .tag = @enumFromInt(1211), .properties = .{ .param_str = "V8sIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ldi_w + .{ .tag = @enumFromInt(1212), .properties = .{ .param_str = "V4iIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ldr_d + .{ .tag = @enumFromInt(1213), .properties = .{ .param_str = "V2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ldr_w + .{ .tag = @enumFromInt(1214), .properties = .{ .param_str = "V4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_madd_q_h + .{ .tag = @enumFromInt(1215), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_madd_q_w + .{ .tag = @enumFromInt(1216), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maddr_q_h + .{ .tag = @enumFromInt(1217), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maddr_q_w + .{ .tag = @enumFromInt(1218), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maddv_b + .{ .tag = @enumFromInt(1219), .properties = .{ .param_str = "V16ScV16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maddv_d + .{ .tag = @enumFromInt(1220), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maddv_h + .{ .tag = @enumFromInt(1221), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maddv_w + .{ .tag = @enumFromInt(1222), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_a_b + .{ .tag = @enumFromInt(1223), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_a_d + .{ .tag = @enumFromInt(1224), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_a_h + .{ .tag = @enumFromInt(1225), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_a_w + .{ .tag = @enumFromInt(1226), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_s_b + .{ .tag = @enumFromInt(1227), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_s_d + .{ .tag = @enumFromInt(1228), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_s_h + .{ .tag = @enumFromInt(1229), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_s_w + .{ .tag = @enumFromInt(1230), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_u_b + .{ .tag = @enumFromInt(1231), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_u_d + .{ .tag = @enumFromInt(1232), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_u_h + .{ .tag = @enumFromInt(1233), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_max_u_w + .{ .tag = @enumFromInt(1234), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_s_b + .{ .tag = @enumFromInt(1235), .properties = .{ .param_str = "V16ScV16ScIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_s_d + .{ .tag = @enumFromInt(1236), .properties = .{ .param_str = "V2SLLiV2SLLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_s_h + .{ .tag = @enumFromInt(1237), .properties = .{ .param_str = "V8SsV8SsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_s_w + .{ .tag = @enumFromInt(1238), .properties = .{ .param_str = "V4SiV4SiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_u_b + .{ .tag = @enumFromInt(1239), .properties = .{ .param_str = "V16UcV16UcIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_u_d + .{ .tag = @enumFromInt(1240), .properties = .{ .param_str = "V2ULLiV2ULLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_u_h + .{ .tag = @enumFromInt(1241), .properties = .{ .param_str = "V8UsV8UsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_maxi_u_w + .{ .tag = @enumFromInt(1242), .properties = .{ .param_str = "V4UiV4UiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_a_b + .{ .tag = @enumFromInt(1243), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_a_d + .{ .tag = @enumFromInt(1244), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_a_h + .{ .tag = @enumFromInt(1245), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_a_w + .{ .tag = @enumFromInt(1246), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_s_b + .{ .tag = @enumFromInt(1247), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_s_d + .{ .tag = @enumFromInt(1248), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_s_h + .{ .tag = @enumFromInt(1249), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_s_w + .{ .tag = @enumFromInt(1250), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_u_b + .{ .tag = @enumFromInt(1251), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_u_d + .{ .tag = @enumFromInt(1252), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_u_h + .{ .tag = @enumFromInt(1253), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_min_u_w + .{ .tag = @enumFromInt(1254), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_s_b + .{ .tag = @enumFromInt(1255), .properties = .{ .param_str = "V16ScV16ScIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_s_d + .{ .tag = @enumFromInt(1256), .properties = .{ .param_str = "V2SLLiV2SLLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_s_h + .{ .tag = @enumFromInt(1257), .properties = .{ .param_str = "V8SsV8SsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_s_w + .{ .tag = @enumFromInt(1258), .properties = .{ .param_str = "V4SiV4SiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_u_b + .{ .tag = @enumFromInt(1259), .properties = .{ .param_str = "V16UcV16UcIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_u_d + .{ .tag = @enumFromInt(1260), .properties = .{ .param_str = "V2ULLiV2ULLiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_u_h + .{ .tag = @enumFromInt(1261), .properties = .{ .param_str = "V8UsV8UsIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mini_u_w + .{ .tag = @enumFromInt(1262), .properties = .{ .param_str = "V4UiV4UiIi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_s_b + .{ .tag = @enumFromInt(1263), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_s_d + .{ .tag = @enumFromInt(1264), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_s_h + .{ .tag = @enumFromInt(1265), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_s_w + .{ .tag = @enumFromInt(1266), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_u_b + .{ .tag = @enumFromInt(1267), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_u_d + .{ .tag = @enumFromInt(1268), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_u_h + .{ .tag = @enumFromInt(1269), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mod_u_w + .{ .tag = @enumFromInt(1270), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_move_v + .{ .tag = @enumFromInt(1271), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msub_q_h + .{ .tag = @enumFromInt(1272), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msub_q_w + .{ .tag = @enumFromInt(1273), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msubr_q_h + .{ .tag = @enumFromInt(1274), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msubr_q_w + .{ .tag = @enumFromInt(1275), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msubv_b + .{ .tag = @enumFromInt(1276), .properties = .{ .param_str = "V16ScV16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msubv_d + .{ .tag = @enumFromInt(1277), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msubv_h + .{ .tag = @enumFromInt(1278), .properties = .{ .param_str = "V8SsV8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_msubv_w + .{ .tag = @enumFromInt(1279), .properties = .{ .param_str = "V4SiV4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mul_q_h + .{ .tag = @enumFromInt(1280), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mul_q_w + .{ .tag = @enumFromInt(1281), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mulr_q_h + .{ .tag = @enumFromInt(1282), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mulr_q_w + .{ .tag = @enumFromInt(1283), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mulv_b + .{ .tag = @enumFromInt(1284), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mulv_d + .{ .tag = @enumFromInt(1285), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mulv_h + .{ .tag = @enumFromInt(1286), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_mulv_w + .{ .tag = @enumFromInt(1287), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nloc_b + .{ .tag = @enumFromInt(1288), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nloc_d + .{ .tag = @enumFromInt(1289), .properties = .{ .param_str = "V2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nloc_h + .{ .tag = @enumFromInt(1290), .properties = .{ .param_str = "V8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nloc_w + .{ .tag = @enumFromInt(1291), .properties = .{ .param_str = "V4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nlzc_b + .{ .tag = @enumFromInt(1292), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nlzc_d + .{ .tag = @enumFromInt(1293), .properties = .{ .param_str = "V2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nlzc_h + .{ .tag = @enumFromInt(1294), .properties = .{ .param_str = "V8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nlzc_w + .{ .tag = @enumFromInt(1295), .properties = .{ .param_str = "V4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nor_v + .{ .tag = @enumFromInt(1296), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_nori_b + .{ .tag = @enumFromInt(1297), .properties = .{ .param_str = "V16UcV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_or_v + .{ .tag = @enumFromInt(1298), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_ori_b + .{ .tag = @enumFromInt(1299), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckev_b + .{ .tag = @enumFromInt(1300), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckev_d + .{ .tag = @enumFromInt(1301), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckev_h + .{ .tag = @enumFromInt(1302), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckev_w + .{ .tag = @enumFromInt(1303), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckod_b + .{ .tag = @enumFromInt(1304), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckod_d + .{ .tag = @enumFromInt(1305), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckod_h + .{ .tag = @enumFromInt(1306), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pckod_w + .{ .tag = @enumFromInt(1307), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pcnt_b + .{ .tag = @enumFromInt(1308), .properties = .{ .param_str = "V16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pcnt_d + .{ .tag = @enumFromInt(1309), .properties = .{ .param_str = "V2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pcnt_h + .{ .tag = @enumFromInt(1310), .properties = .{ .param_str = "V8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_pcnt_w + .{ .tag = @enumFromInt(1311), .properties = .{ .param_str = "V4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_s_b + .{ .tag = @enumFromInt(1312), .properties = .{ .param_str = "V16ScV16ScIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_s_d + .{ .tag = @enumFromInt(1313), .properties = .{ .param_str = "V2SLLiV2SLLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_s_h + .{ .tag = @enumFromInt(1314), .properties = .{ .param_str = "V8SsV8SsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_s_w + .{ .tag = @enumFromInt(1315), .properties = .{ .param_str = "V4SiV4SiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_u_b + .{ .tag = @enumFromInt(1316), .properties = .{ .param_str = "V16UcV16UcIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_u_d + .{ .tag = @enumFromInt(1317), .properties = .{ .param_str = "V2ULLiV2ULLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_u_h + .{ .tag = @enumFromInt(1318), .properties = .{ .param_str = "V8UsV8UsIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sat_u_w + .{ .tag = @enumFromInt(1319), .properties = .{ .param_str = "V4UiV4UiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_shf_b + .{ .tag = @enumFromInt(1320), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_shf_h + .{ .tag = @enumFromInt(1321), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_shf_w + .{ .tag = @enumFromInt(1322), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sld_b + .{ .tag = @enumFromInt(1323), .properties = .{ .param_str = "V16cV16cV16cUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sld_d + .{ .tag = @enumFromInt(1324), .properties = .{ .param_str = "V2LLiV2LLiV2LLiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sld_h + .{ .tag = @enumFromInt(1325), .properties = .{ .param_str = "V8sV8sV8sUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sld_w + .{ .tag = @enumFromInt(1326), .properties = .{ .param_str = "V4iV4iV4iUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sldi_b + .{ .tag = @enumFromInt(1327), .properties = .{ .param_str = "V16cV16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sldi_d + .{ .tag = @enumFromInt(1328), .properties = .{ .param_str = "V2LLiV2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sldi_h + .{ .tag = @enumFromInt(1329), .properties = .{ .param_str = "V8sV8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sldi_w + .{ .tag = @enumFromInt(1330), .properties = .{ .param_str = "V4iV4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sll_b + .{ .tag = @enumFromInt(1331), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sll_d + .{ .tag = @enumFromInt(1332), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sll_h + .{ .tag = @enumFromInt(1333), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sll_w + .{ .tag = @enumFromInt(1334), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_slli_b + .{ .tag = @enumFromInt(1335), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_slli_d + .{ .tag = @enumFromInt(1336), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_slli_h + .{ .tag = @enumFromInt(1337), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_slli_w + .{ .tag = @enumFromInt(1338), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splat_b + .{ .tag = @enumFromInt(1339), .properties = .{ .param_str = "V16cV16cUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splat_d + .{ .tag = @enumFromInt(1340), .properties = .{ .param_str = "V2LLiV2LLiUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splat_h + .{ .tag = @enumFromInt(1341), .properties = .{ .param_str = "V8sV8sUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splat_w + .{ .tag = @enumFromInt(1342), .properties = .{ .param_str = "V4iV4iUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splati_b + .{ .tag = @enumFromInt(1343), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splati_d + .{ .tag = @enumFromInt(1344), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splati_h + .{ .tag = @enumFromInt(1345), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_splati_w + .{ .tag = @enumFromInt(1346), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sra_b + .{ .tag = @enumFromInt(1347), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sra_d + .{ .tag = @enumFromInt(1348), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sra_h + .{ .tag = @enumFromInt(1349), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_sra_w + .{ .tag = @enumFromInt(1350), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srai_b + .{ .tag = @enumFromInt(1351), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srai_d + .{ .tag = @enumFromInt(1352), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srai_h + .{ .tag = @enumFromInt(1353), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srai_w + .{ .tag = @enumFromInt(1354), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srar_b + .{ .tag = @enumFromInt(1355), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srar_d + .{ .tag = @enumFromInt(1356), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srar_h + .{ .tag = @enumFromInt(1357), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srar_w + .{ .tag = @enumFromInt(1358), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srari_b + .{ .tag = @enumFromInt(1359), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srari_d + .{ .tag = @enumFromInt(1360), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srari_h + .{ .tag = @enumFromInt(1361), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srari_w + .{ .tag = @enumFromInt(1362), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srl_b + .{ .tag = @enumFromInt(1363), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srl_d + .{ .tag = @enumFromInt(1364), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srl_h + .{ .tag = @enumFromInt(1365), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srl_w + .{ .tag = @enumFromInt(1366), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srli_b + .{ .tag = @enumFromInt(1367), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srli_d + .{ .tag = @enumFromInt(1368), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srli_h + .{ .tag = @enumFromInt(1369), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srli_w + .{ .tag = @enumFromInt(1370), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlr_b + .{ .tag = @enumFromInt(1371), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlr_d + .{ .tag = @enumFromInt(1372), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlr_h + .{ .tag = @enumFromInt(1373), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlr_w + .{ .tag = @enumFromInt(1374), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlri_b + .{ .tag = @enumFromInt(1375), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlri_d + .{ .tag = @enumFromInt(1376), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlri_h + .{ .tag = @enumFromInt(1377), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_srlri_w + .{ .tag = @enumFromInt(1378), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_st_b + .{ .tag = @enumFromInt(1379), .properties = .{ .param_str = "vV16Scv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_st_d + .{ .tag = @enumFromInt(1380), .properties = .{ .param_str = "vV2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_st_h + .{ .tag = @enumFromInt(1381), .properties = .{ .param_str = "vV8Ssv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_st_w + .{ .tag = @enumFromInt(1382), .properties = .{ .param_str = "vV4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_str_d + .{ .tag = @enumFromInt(1383), .properties = .{ .param_str = "vV2SLLiv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_str_w + .{ .tag = @enumFromInt(1384), .properties = .{ .param_str = "vV4Siv*Ii", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_s_b + .{ .tag = @enumFromInt(1385), .properties = .{ .param_str = "V16ScV16ScV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_s_d + .{ .tag = @enumFromInt(1386), .properties = .{ .param_str = "V2SLLiV2SLLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_s_h + .{ .tag = @enumFromInt(1387), .properties = .{ .param_str = "V8SsV8SsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_s_w + .{ .tag = @enumFromInt(1388), .properties = .{ .param_str = "V4SiV4SiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_u_b + .{ .tag = @enumFromInt(1389), .properties = .{ .param_str = "V16UcV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_u_d + .{ .tag = @enumFromInt(1390), .properties = .{ .param_str = "V2ULLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_u_h + .{ .tag = @enumFromInt(1391), .properties = .{ .param_str = "V8UsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subs_u_w + .{ .tag = @enumFromInt(1392), .properties = .{ .param_str = "V4UiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsus_u_b + .{ .tag = @enumFromInt(1393), .properties = .{ .param_str = "V16UcV16UcV16Sc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsus_u_d + .{ .tag = @enumFromInt(1394), .properties = .{ .param_str = "V2ULLiV2ULLiV2SLLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsus_u_h + .{ .tag = @enumFromInt(1395), .properties = .{ .param_str = "V8UsV8UsV8Ss", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsus_u_w + .{ .tag = @enumFromInt(1396), .properties = .{ .param_str = "V4UiV4UiV4Si", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsuu_s_b + .{ .tag = @enumFromInt(1397), .properties = .{ .param_str = "V16ScV16UcV16Uc", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsuu_s_d + .{ .tag = @enumFromInt(1398), .properties = .{ .param_str = "V2SLLiV2ULLiV2ULLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsuu_s_h + .{ .tag = @enumFromInt(1399), .properties = .{ .param_str = "V8SsV8UsV8Us", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subsuu_s_w + .{ .tag = @enumFromInt(1400), .properties = .{ .param_str = "V4SiV4UiV4Ui", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subv_b + .{ .tag = @enumFromInt(1401), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subv_d + .{ .tag = @enumFromInt(1402), .properties = .{ .param_str = "V2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subv_h + .{ .tag = @enumFromInt(1403), .properties = .{ .param_str = "V8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subv_w + .{ .tag = @enumFromInt(1404), .properties = .{ .param_str = "V4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subvi_b + .{ .tag = @enumFromInt(1405), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subvi_d + .{ .tag = @enumFromInt(1406), .properties = .{ .param_str = "V2LLiV2LLiIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subvi_h + .{ .tag = @enumFromInt(1407), .properties = .{ .param_str = "V8sV8sIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_subvi_w + .{ .tag = @enumFromInt(1408), .properties = .{ .param_str = "V4iV4iIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_vshf_b + .{ .tag = @enumFromInt(1409), .properties = .{ .param_str = "V16cV16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_vshf_d + .{ .tag = @enumFromInt(1410), .properties = .{ .param_str = "V2LLiV2LLiV2LLiV2LLi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_vshf_h + .{ .tag = @enumFromInt(1411), .properties = .{ .param_str = "V8sV8sV8sV8s", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_vshf_w + .{ .tag = @enumFromInt(1412), .properties = .{ .param_str = "V4iV4iV4iV4i", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_xor_v + .{ .tag = @enumFromInt(1413), .properties = .{ .param_str = "V16cV16cV16c", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_msa_xori_b + .{ .tag = @enumFromInt(1414), .properties = .{ .param_str = "V16cV16cIUi", .target_set = TargetSet.initOne(.mips), .attributes = .{ .@"const" = true } } }, + // __builtin_mul_overflow + .{ .tag = @enumFromInt(1415), .properties = .{ .param_str = "b.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_nan + .{ .tag = @enumFromInt(1416), .properties = .{ .param_str = "dcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nanf + .{ .tag = @enumFromInt(1417), .properties = .{ .param_str = "fcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nanf128 + .{ .tag = @enumFromInt(1418), .properties = .{ .param_str = "LLdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nanf16 + .{ .tag = @enumFromInt(1419), .properties = .{ .param_str = "xcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nanl + .{ .tag = @enumFromInt(1420), .properties = .{ .param_str = "LdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nans + .{ .tag = @enumFromInt(1421), .properties = .{ .param_str = "dcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nansf + .{ .tag = @enumFromInt(1422), .properties = .{ .param_str = "fcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nansf128 + .{ .tag = @enumFromInt(1423), .properties = .{ .param_str = "LLdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nansf16 + .{ .tag = @enumFromInt(1424), .properties = .{ .param_str = "xcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nansl + .{ .tag = @enumFromInt(1425), .properties = .{ .param_str = "LdcC*", .attributes = .{ .pure = true, .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_nearbyint + .{ .tag = @enumFromInt(1426), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_nearbyintf + .{ .tag = @enumFromInt(1427), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_nearbyintf128 + .{ .tag = @enumFromInt(1428), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_nearbyintl + .{ .tag = @enumFromInt(1429), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_nextafter + .{ .tag = @enumFromInt(1430), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nextafterf + .{ .tag = @enumFromInt(1431), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nextafterf128 + .{ .tag = @enumFromInt(1432), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nextafterl + .{ .tag = @enumFromInt(1433), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nexttoward + .{ .tag = @enumFromInt(1434), .properties = .{ .param_str = "ddLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nexttowardf + .{ .tag = @enumFromInt(1435), .properties = .{ .param_str = "ffLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nexttowardf128 + .{ .tag = @enumFromInt(1436), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nexttowardl + .{ .tag = @enumFromInt(1437), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_nondeterministic_value + .{ .tag = @enumFromInt(1438), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_nontemporal_load + .{ .tag = @enumFromInt(1439), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_nontemporal_store + .{ .tag = @enumFromInt(1440), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_objc_memmove_collectable + .{ .tag = @enumFromInt(1441), .properties = .{ .param_str = "v*v*vC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_object_size + .{ .tag = @enumFromInt(1442), .properties = .{ .param_str = "zvC*i", .attributes = .{ .eval_args = false, .const_evaluable = true } } }, + // __builtin_operator_delete + .{ .tag = @enumFromInt(1443), .properties = .{ .param_str = "vv*", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_operator_new + .{ .tag = @enumFromInt(1444), .properties = .{ .param_str = "v*z", .attributes = .{ .@"const" = true, .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_os_log_format + .{ .tag = @enumFromInt(1445), .properties = .{ .param_str = "v*v*cC*.", .attributes = .{ .custom_typecheck = true, .format_kind = .printf } } }, + // __builtin_os_log_format_buffer_size + .{ .tag = @enumFromInt(1446), .properties = .{ .param_str = "zcC*.", .attributes = .{ .custom_typecheck = true, .format_kind = .printf, .eval_args = false, .const_evaluable = true } } }, + // __builtin_pack_longdouble + .{ .tag = @enumFromInt(1447), .properties = .{ .param_str = "Lddd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_parity + .{ .tag = @enumFromInt(1448), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_parityl + .{ .tag = @enumFromInt(1449), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_parityll + .{ .tag = @enumFromInt(1450), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_popcount + .{ .tag = @enumFromInt(1451), .properties = .{ .param_str = "iUi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_popcountl + .{ .tag = @enumFromInt(1452), .properties = .{ .param_str = "iULi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_popcountll + .{ .tag = @enumFromInt(1453), .properties = .{ .param_str = "iULLi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_pow + .{ .tag = @enumFromInt(1454), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_powf + .{ .tag = @enumFromInt(1455), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_powf128 + .{ .tag = @enumFromInt(1456), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_powf16 + .{ .tag = @enumFromInt(1457), .properties = .{ .param_str = "hhh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_powi + .{ .tag = @enumFromInt(1458), .properties = .{ .param_str = "ddi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_powif + .{ .tag = @enumFromInt(1459), .properties = .{ .param_str = "ffi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_powil + .{ .tag = @enumFromInt(1460), .properties = .{ .param_str = "LdLdi", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_powl + .{ .tag = @enumFromInt(1461), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_ppc_alignx + .{ .tag = @enumFromInt(1462), .properties = .{ .param_str = "vIivC*", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .@"const" = true } } }, + // __builtin_ppc_cmpb + .{ .tag = @enumFromInt(1463), .properties = .{ .param_str = "LLiLLiLLi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_compare_and_swap + .{ .tag = @enumFromInt(1464), .properties = .{ .param_str = "iiD*i*i", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_compare_and_swaplp + .{ .tag = @enumFromInt(1465), .properties = .{ .param_str = "iLiD*Li*Li", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbfl + .{ .tag = @enumFromInt(1466), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbflp + .{ .tag = @enumFromInt(1467), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbst + .{ .tag = @enumFromInt(1468), .properties = .{ .param_str = "vvC*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbt + .{ .tag = @enumFromInt(1469), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbtst + .{ .tag = @enumFromInt(1470), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbtstt + .{ .tag = @enumFromInt(1471), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbtt + .{ .tag = @enumFromInt(1472), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_dcbz + .{ .tag = @enumFromInt(1473), .properties = .{ .param_str = "vv*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_eieio + .{ .tag = @enumFromInt(1474), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fcfid + .{ .tag = @enumFromInt(1475), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fcfud + .{ .tag = @enumFromInt(1476), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fctid + .{ .tag = @enumFromInt(1477), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fctidz + .{ .tag = @enumFromInt(1478), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fctiw + .{ .tag = @enumFromInt(1479), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fctiwz + .{ .tag = @enumFromInt(1480), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fctudz + .{ .tag = @enumFromInt(1481), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fctuwz + .{ .tag = @enumFromInt(1482), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_add + .{ .tag = @enumFromInt(1483), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_addlp + .{ .tag = @enumFromInt(1484), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_and + .{ .tag = @enumFromInt(1485), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_andlp + .{ .tag = @enumFromInt(1486), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_or + .{ .tag = @enumFromInt(1487), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_orlp + .{ .tag = @enumFromInt(1488), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_swap + .{ .tag = @enumFromInt(1489), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fetch_and_swaplp + .{ .tag = @enumFromInt(1490), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fmsub + .{ .tag = @enumFromInt(1491), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fmsubs + .{ .tag = @enumFromInt(1492), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fnabs + .{ .tag = @enumFromInt(1493), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fnabss + .{ .tag = @enumFromInt(1494), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fnmadd + .{ .tag = @enumFromInt(1495), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fnmadds + .{ .tag = @enumFromInt(1496), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fnmsub + .{ .tag = @enumFromInt(1497), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fnmsubs + .{ .tag = @enumFromInt(1498), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fre + .{ .tag = @enumFromInt(1499), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fres + .{ .tag = @enumFromInt(1500), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fric + .{ .tag = @enumFromInt(1501), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frim + .{ .tag = @enumFromInt(1502), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frims + .{ .tag = @enumFromInt(1503), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frin + .{ .tag = @enumFromInt(1504), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frins + .{ .tag = @enumFromInt(1505), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frip + .{ .tag = @enumFromInt(1506), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frips + .{ .tag = @enumFromInt(1507), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_friz + .{ .tag = @enumFromInt(1508), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frizs + .{ .tag = @enumFromInt(1509), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frsqrte + .{ .tag = @enumFromInt(1510), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_frsqrtes + .{ .tag = @enumFromInt(1511), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fsel + .{ .tag = @enumFromInt(1512), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fsels + .{ .tag = @enumFromInt(1513), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fsqrt + .{ .tag = @enumFromInt(1514), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_fsqrts + .{ .tag = @enumFromInt(1515), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_get_timebase + .{ .tag = @enumFromInt(1516), .properties = .{ .param_str = "ULLi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_iospace_eieio + .{ .tag = @enumFromInt(1517), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_iospace_lwsync + .{ .tag = @enumFromInt(1518), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_iospace_sync + .{ .tag = @enumFromInt(1519), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_isync + .{ .tag = @enumFromInt(1520), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_ldarx + .{ .tag = @enumFromInt(1521), .properties = .{ .param_str = "LiLiD*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_load2r + .{ .tag = @enumFromInt(1522), .properties = .{ .param_str = "UsUs*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_load4r + .{ .tag = @enumFromInt(1523), .properties = .{ .param_str = "UiUi*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_lwarx + .{ .tag = @enumFromInt(1524), .properties = .{ .param_str = "iiD*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_lwsync + .{ .tag = @enumFromInt(1525), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_maxfe + .{ .tag = @enumFromInt(1526), .properties = .{ .param_str = "LdLdLdLd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_ppc_maxfl + .{ .tag = @enumFromInt(1527), .properties = .{ .param_str = "dddd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_ppc_maxfs + .{ .tag = @enumFromInt(1528), .properties = .{ .param_str = "ffff.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_ppc_mfmsr + .{ .tag = @enumFromInt(1529), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mfspr + .{ .tag = @enumFromInt(1530), .properties = .{ .param_str = "ULiIi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mftbu + .{ .tag = @enumFromInt(1531), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_minfe + .{ .tag = @enumFromInt(1532), .properties = .{ .param_str = "LdLdLdLd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_ppc_minfl + .{ .tag = @enumFromInt(1533), .properties = .{ .param_str = "dddd.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_ppc_minfs + .{ .tag = @enumFromInt(1534), .properties = .{ .param_str = "ffff.", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .custom_typecheck = true } } }, + // __builtin_ppc_mtfsb0 + .{ .tag = @enumFromInt(1535), .properties = .{ .param_str = "vUIi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mtfsb1 + .{ .tag = @enumFromInt(1536), .properties = .{ .param_str = "vUIi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mtfsf + .{ .tag = @enumFromInt(1537), .properties = .{ .param_str = "vUIiUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mtfsfi + .{ .tag = @enumFromInt(1538), .properties = .{ .param_str = "vUIiUIi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mtmsr + .{ .tag = @enumFromInt(1539), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mtspr + .{ .tag = @enumFromInt(1540), .properties = .{ .param_str = "vIiULi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mulhd + .{ .tag = @enumFromInt(1541), .properties = .{ .param_str = "LLiLiLi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mulhdu + .{ .tag = @enumFromInt(1542), .properties = .{ .param_str = "ULLiULiULi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mulhw + .{ .tag = @enumFromInt(1543), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_mulhwu + .{ .tag = @enumFromInt(1544), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_popcntb + .{ .tag = @enumFromInt(1545), .properties = .{ .param_str = "ULiULi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_poppar4 + .{ .tag = @enumFromInt(1546), .properties = .{ .param_str = "iUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_poppar8 + .{ .tag = @enumFromInt(1547), .properties = .{ .param_str = "iULLi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_rdlam + .{ .tag = @enumFromInt(1548), .properties = .{ .param_str = "UWiUWiUWiUWIi", .target_set = TargetSet.initOne(.ppc), .attributes = .{ .@"const" = true } } }, + // __builtin_ppc_recipdivd + .{ .tag = @enumFromInt(1549), .properties = .{ .param_str = "V2dV2dV2d", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_recipdivf + .{ .tag = @enumFromInt(1550), .properties = .{ .param_str = "V4fV4fV4f", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_rldimi + .{ .tag = @enumFromInt(1551), .properties = .{ .param_str = "ULLiULLiULLiIUiIULLi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_rlwimi + .{ .tag = @enumFromInt(1552), .properties = .{ .param_str = "UiUiUiIUiIUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_rlwnm + .{ .tag = @enumFromInt(1553), .properties = .{ .param_str = "UiUiUiIUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_rsqrtd + .{ .tag = @enumFromInt(1554), .properties = .{ .param_str = "V2dV2d", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_rsqrtf + .{ .tag = @enumFromInt(1555), .properties = .{ .param_str = "V4fV4f", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_stdcx + .{ .tag = @enumFromInt(1556), .properties = .{ .param_str = "iLiD*Li", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_stfiw + .{ .tag = @enumFromInt(1557), .properties = .{ .param_str = "viC*d", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_store2r + .{ .tag = @enumFromInt(1558), .properties = .{ .param_str = "vUiUs*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_store4r + .{ .tag = @enumFromInt(1559), .properties = .{ .param_str = "vUiUi*", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_stwcx + .{ .tag = @enumFromInt(1560), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_swdiv + .{ .tag = @enumFromInt(1561), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_swdiv_nochk + .{ .tag = @enumFromInt(1562), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_swdivs + .{ .tag = @enumFromInt(1563), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_swdivs_nochk + .{ .tag = @enumFromInt(1564), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_sync + .{ .tag = @enumFromInt(1565), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_tdw + .{ .tag = @enumFromInt(1566), .properties = .{ .param_str = "vLLiLLiIUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_trap + .{ .tag = @enumFromInt(1567), .properties = .{ .param_str = "vi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_trapd + .{ .tag = @enumFromInt(1568), .properties = .{ .param_str = "vLi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_ppc_tw + .{ .tag = @enumFromInt(1569), .properties = .{ .param_str = "viiIUi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_prefetch + .{ .tag = @enumFromInt(1570), .properties = .{ .param_str = "vvC*.", .attributes = .{ .@"const" = true } } }, + // __builtin_preserve_access_index + .{ .tag = @enumFromInt(1571), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_printf + .{ .tag = @enumFromInt(1572), .properties = .{ .param_str = "icC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf } } }, + // __builtin_ptx_get_image_channel_data_typei_ + .{ .tag = @enumFromInt(1573), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_get_image_channel_orderi_ + .{ .tag = @enumFromInt(1574), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_get_image_depthi_ + .{ .tag = @enumFromInt(1575), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_get_image_heighti_ + .{ .tag = @enumFromInt(1576), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_get_image_widthi_ + .{ .tag = @enumFromInt(1577), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image2Dff_ + .{ .tag = @enumFromInt(1578), .properties = .{ .param_str = "V4fiiff", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image2Dfi_ + .{ .tag = @enumFromInt(1579), .properties = .{ .param_str = "V4fiiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image2Dif_ + .{ .tag = @enumFromInt(1580), .properties = .{ .param_str = "V4iiiff", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image2Dii_ + .{ .tag = @enumFromInt(1581), .properties = .{ .param_str = "V4iiiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image3Dff_ + .{ .tag = @enumFromInt(1582), .properties = .{ .param_str = "V4fiiffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image3Dfi_ + .{ .tag = @enumFromInt(1583), .properties = .{ .param_str = "V4fiiiiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image3Dif_ + .{ .tag = @enumFromInt(1584), .properties = .{ .param_str = "V4iiiffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_read_image3Dii_ + .{ .tag = @enumFromInt(1585), .properties = .{ .param_str = "V4iiiiiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_write_image2Df_ + .{ .tag = @enumFromInt(1586), .properties = .{ .param_str = "viiiffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_write_image2Di_ + .{ .tag = @enumFromInt(1587), .properties = .{ .param_str = "viiiiiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_ptx_write_image2Dui_ + .{ .tag = @enumFromInt(1588), .properties = .{ .param_str = "viiiUiUiUiUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __builtin_r600_implicitarg_ptr + .{ .tag = @enumFromInt(1589), .properties = .{ .param_str = "Uc*7", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_read_tgid_x + .{ .tag = @enumFromInt(1590), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_read_tgid_y + .{ .tag = @enumFromInt(1591), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_read_tgid_z + .{ .tag = @enumFromInt(1592), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_read_tidig_x + .{ .tag = @enumFromInt(1593), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_read_tidig_y + .{ .tag = @enumFromInt(1594), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_read_tidig_z + .{ .tag = @enumFromInt(1595), .properties = .{ .param_str = "Ui", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_recipsqrt_ieee + .{ .tag = @enumFromInt(1596), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_r600_recipsqrt_ieeef + .{ .tag = @enumFromInt(1597), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.amdgpu), .attributes = .{ .@"const" = true } } }, + // __builtin_readcyclecounter + .{ .tag = @enumFromInt(1598), .properties = .{ .param_str = "ULLi" } }, + // __builtin_readflm + .{ .tag = @enumFromInt(1599), .properties = .{ .param_str = "d", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_realloc + .{ .tag = @enumFromInt(1600), .properties = .{ .param_str = "v*v*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_reduce_add + .{ .tag = @enumFromInt(1601), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_reduce_and + .{ .tag = @enumFromInt(1602), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_reduce_max + .{ .tag = @enumFromInt(1603), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_reduce_min + .{ .tag = @enumFromInt(1604), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_reduce_mul + .{ .tag = @enumFromInt(1605), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_reduce_or + .{ .tag = @enumFromInt(1606), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_reduce_xor + .{ .tag = @enumFromInt(1607), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_remainder + .{ .tag = @enumFromInt(1608), .properties = .{ .param_str = "ddd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_remainderf + .{ .tag = @enumFromInt(1609), .properties = .{ .param_str = "fff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_remainderf128 + .{ .tag = @enumFromInt(1610), .properties = .{ .param_str = "LLdLLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_remainderl + .{ .tag = @enumFromInt(1611), .properties = .{ .param_str = "LdLdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_remquo + .{ .tag = @enumFromInt(1612), .properties = .{ .param_str = "dddi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_remquof + .{ .tag = @enumFromInt(1613), .properties = .{ .param_str = "fffi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_remquof128 + .{ .tag = @enumFromInt(1614), .properties = .{ .param_str = "LLdLLdLLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_remquol + .{ .tag = @enumFromInt(1615), .properties = .{ .param_str = "LdLdLdi*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_return_address + .{ .tag = @enumFromInt(1616), .properties = .{ .param_str = "v*IUi" } }, + // __builtin_rindex + .{ .tag = @enumFromInt(1617), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_rint + .{ .tag = @enumFromInt(1618), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_rintf + .{ .tag = @enumFromInt(1619), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_rintf128 + .{ .tag = @enumFromInt(1620), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_rintf16 + .{ .tag = @enumFromInt(1621), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_rintl + .{ .tag = @enumFromInt(1622), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_rotateleft16 + .{ .tag = @enumFromInt(1623), .properties = .{ .param_str = "UsUsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_rotateleft32 + .{ .tag = @enumFromInt(1624), .properties = .{ .param_str = "UZiUZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_rotateleft64 + .{ .tag = @enumFromInt(1625), .properties = .{ .param_str = "UWiUWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_rotateleft8 + .{ .tag = @enumFromInt(1626), .properties = .{ .param_str = "UcUcUc", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_rotateright16 + .{ .tag = @enumFromInt(1627), .properties = .{ .param_str = "UsUsUs", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_rotateright32 + .{ .tag = @enumFromInt(1628), .properties = .{ .param_str = "UZiUZiUZi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_rotateright64 + .{ .tag = @enumFromInt(1629), .properties = .{ .param_str = "UWiUWiUWi", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_rotateright8 + .{ .tag = @enumFromInt(1630), .properties = .{ .param_str = "UcUcUc", .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __builtin_round + .{ .tag = @enumFromInt(1631), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundeven + .{ .tag = @enumFromInt(1632), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundevenf + .{ .tag = @enumFromInt(1633), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundevenf128 + .{ .tag = @enumFromInt(1634), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundevenf16 + .{ .tag = @enumFromInt(1635), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundevenl + .{ .tag = @enumFromInt(1636), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundf + .{ .tag = @enumFromInt(1637), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundf128 + .{ .tag = @enumFromInt(1638), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundf16 + .{ .tag = @enumFromInt(1639), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_roundl + .{ .tag = @enumFromInt(1640), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_sadd_overflow + .{ .tag = @enumFromInt(1641), .properties = .{ .param_str = "bSiCSiCSi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_saddl_overflow + .{ .tag = @enumFromInt(1642), .properties = .{ .param_str = "bSLiCSLiCSLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_saddll_overflow + .{ .tag = @enumFromInt(1643), .properties = .{ .param_str = "bSLLiCSLLiCSLLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_scalbln + .{ .tag = @enumFromInt(1644), .properties = .{ .param_str = "ddLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scalblnf + .{ .tag = @enumFromInt(1645), .properties = .{ .param_str = "ffLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scalblnf128 + .{ .tag = @enumFromInt(1646), .properties = .{ .param_str = "LLdLLdLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scalblnl + .{ .tag = @enumFromInt(1647), .properties = .{ .param_str = "LdLdLi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scalbn + .{ .tag = @enumFromInt(1648), .properties = .{ .param_str = "ddi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scalbnf + .{ .tag = @enumFromInt(1649), .properties = .{ .param_str = "ffi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scalbnf128 + .{ .tag = @enumFromInt(1650), .properties = .{ .param_str = "LLdLLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scalbnl + .{ .tag = @enumFromInt(1651), .properties = .{ .param_str = "LdLdi", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_scanf + .{ .tag = @enumFromInt(1652), .properties = .{ .param_str = "icC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf } } }, + // __builtin_set_flt_rounds + .{ .tag = @enumFromInt(1653), .properties = .{ .param_str = "vi" } }, + // __builtin_setflm + .{ .tag = @enumFromInt(1654), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_setjmp + .{ .tag = @enumFromInt(1655), .properties = .{ .param_str = "iv**", .attributes = .{ .returns_twice = true } } }, + // __builtin_setps + .{ .tag = @enumFromInt(1656), .properties = .{ .param_str = "vUiUi", .target_set = TargetSet.initOne(.xcore) } }, + // __builtin_setrnd + .{ .tag = @enumFromInt(1657), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_shufflevector + .{ .tag = @enumFromInt(1658), .properties = .{ .param_str = "v.", .attributes = .{ .@"const" = true, .custom_typecheck = true } } }, + // __builtin_signbit + .{ .tag = @enumFromInt(1659), .properties = .{ .param_str = "i.", .attributes = .{ .@"const" = true, .custom_typecheck = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_signbitf + .{ .tag = @enumFromInt(1660), .properties = .{ .param_str = "if", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_signbitl + .{ .tag = @enumFromInt(1661), .properties = .{ .param_str = "iLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_sin + .{ .tag = @enumFromInt(1662), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinf + .{ .tag = @enumFromInt(1663), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinf128 + .{ .tag = @enumFromInt(1664), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinf16 + .{ .tag = @enumFromInt(1665), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinh + .{ .tag = @enumFromInt(1666), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinhf + .{ .tag = @enumFromInt(1667), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinhf128 + .{ .tag = @enumFromInt(1668), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinhl + .{ .tag = @enumFromInt(1669), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sinl + .{ .tag = @enumFromInt(1670), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_smul_overflow + .{ .tag = @enumFromInt(1671), .properties = .{ .param_str = "bSiCSiCSi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_smull_overflow + .{ .tag = @enumFromInt(1672), .properties = .{ .param_str = "bSLiCSLiCSLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_smulll_overflow + .{ .tag = @enumFromInt(1673), .properties = .{ .param_str = "bSLLiCSLLiCSLLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_snprintf + .{ .tag = @enumFromInt(1674), .properties = .{ .param_str = "ic*RzcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 2 } } }, + // __builtin_sponentry + .{ .tag = @enumFromInt(1675), .properties = .{ .param_str = "v*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __builtin_sprintf + .{ .tag = @enumFromInt(1676), .properties = .{ .param_str = "ic*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .printf, .format_string_position = 1 } } }, + // __builtin_sqrt + .{ .tag = @enumFromInt(1677), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sqrtf + .{ .tag = @enumFromInt(1678), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sqrtf128 + .{ .tag = @enumFromInt(1679), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sqrtf16 + .{ .tag = @enumFromInt(1680), .properties = .{ .param_str = "hh", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sqrtl + .{ .tag = @enumFromInt(1681), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_sscanf + .{ .tag = @enumFromInt(1682), .properties = .{ .param_str = "icC*RcC*R.", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } }, + // __builtin_ssub_overflow + .{ .tag = @enumFromInt(1683), .properties = .{ .param_str = "bSiCSiCSi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_ssubl_overflow + .{ .tag = @enumFromInt(1684), .properties = .{ .param_str = "bSLiCSLiCSLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_ssubll_overflow + .{ .tag = @enumFromInt(1685), .properties = .{ .param_str = "bSLLiCSLLiCSLLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_stdarg_start + .{ .tag = @enumFromInt(1686), .properties = .{ .param_str = "vA.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_stpcpy + .{ .tag = @enumFromInt(1687), .properties = .{ .param_str = "c*c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_stpncpy + .{ .tag = @enumFromInt(1688), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strcasecmp + .{ .tag = @enumFromInt(1689), .properties = .{ .param_str = "icC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strcat + .{ .tag = @enumFromInt(1690), .properties = .{ .param_str = "c*c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strchr + .{ .tag = @enumFromInt(1691), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_strcmp + .{ .tag = @enumFromInt(1692), .properties = .{ .param_str = "icC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_strcpy + .{ .tag = @enumFromInt(1693), .properties = .{ .param_str = "c*c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strcspn + .{ .tag = @enumFromInt(1694), .properties = .{ .param_str = "zcC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strdup + .{ .tag = @enumFromInt(1695), .properties = .{ .param_str = "c*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strlen + .{ .tag = @enumFromInt(1696), .properties = .{ .param_str = "zcC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_strncasecmp + .{ .tag = @enumFromInt(1697), .properties = .{ .param_str = "icC*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strncat + .{ .tag = @enumFromInt(1698), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strncmp + .{ .tag = @enumFromInt(1699), .properties = .{ .param_str = "icC*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_strncpy + .{ .tag = @enumFromInt(1700), .properties = .{ .param_str = "c*c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strndup + .{ .tag = @enumFromInt(1701), .properties = .{ .param_str = "c*cC*z", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strpbrk + .{ .tag = @enumFromInt(1702), .properties = .{ .param_str = "c*cC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strrchr + .{ .tag = @enumFromInt(1703), .properties = .{ .param_str = "c*cC*i", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strspn + .{ .tag = @enumFromInt(1704), .properties = .{ .param_str = "zcC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_strstr + .{ .tag = @enumFromInt(1705), .properties = .{ .param_str = "c*cC*cC*", .attributes = .{ .lib_function_with_builtin_prefix = true } } }, + // __builtin_sub_overflow + .{ .tag = @enumFromInt(1706), .properties = .{ .param_str = "b.", .attributes = .{ .custom_typecheck = true, .const_evaluable = true } } }, + // __builtin_subc + .{ .tag = @enumFromInt(1707), .properties = .{ .param_str = "UiUiCUiCUiCUi*" } }, + // __builtin_subcb + .{ .tag = @enumFromInt(1708), .properties = .{ .param_str = "UcUcCUcCUcCUc*" } }, + // __builtin_subcl + .{ .tag = @enumFromInt(1709), .properties = .{ .param_str = "ULiULiCULiCULiCULi*" } }, + // __builtin_subcll + .{ .tag = @enumFromInt(1710), .properties = .{ .param_str = "ULLiULLiCULLiCULLiCULLi*" } }, + // __builtin_subcs + .{ .tag = @enumFromInt(1711), .properties = .{ .param_str = "UsUsCUsCUsCUs*" } }, + // __builtin_tan + .{ .tag = @enumFromInt(1712), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tanf + .{ .tag = @enumFromInt(1713), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tanf128 + .{ .tag = @enumFromInt(1714), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tanh + .{ .tag = @enumFromInt(1715), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tanhf + .{ .tag = @enumFromInt(1716), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tanhf128 + .{ .tag = @enumFromInt(1717), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tanhl + .{ .tag = @enumFromInt(1718), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tanl + .{ .tag = @enumFromInt(1719), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tgamma + .{ .tag = @enumFromInt(1720), .properties = .{ .param_str = "dd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tgammaf + .{ .tag = @enumFromInt(1721), .properties = .{ .param_str = "ff", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tgammaf128 + .{ .tag = @enumFromInt(1722), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_tgammal + .{ .tag = @enumFromInt(1723), .properties = .{ .param_str = "LdLd", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __builtin_thread_pointer + .{ .tag = @enumFromInt(1724), .properties = .{ .param_str = "v*", .attributes = .{ .@"const" = true } } }, + // __builtin_trap + .{ .tag = @enumFromInt(1725), .properties = .{ .param_str = "v", .attributes = .{ .noreturn = true } } }, + // __builtin_trunc + .{ .tag = @enumFromInt(1726), .properties = .{ .param_str = "dd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_truncf + .{ .tag = @enumFromInt(1727), .properties = .{ .param_str = "ff", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_truncf128 + .{ .tag = @enumFromInt(1728), .properties = .{ .param_str = "LLdLLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_truncf16 + .{ .tag = @enumFromInt(1729), .properties = .{ .param_str = "hh", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_truncl + .{ .tag = @enumFromInt(1730), .properties = .{ .param_str = "LdLd", .attributes = .{ .@"const" = true, .lib_function_with_builtin_prefix = true } } }, + // __builtin_uadd_overflow + .{ .tag = @enumFromInt(1731), .properties = .{ .param_str = "bUiCUiCUi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_uaddl_overflow + .{ .tag = @enumFromInt(1732), .properties = .{ .param_str = "bULiCULiCULi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_uaddll_overflow + .{ .tag = @enumFromInt(1733), .properties = .{ .param_str = "bULLiCULLiCULLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_umul_overflow + .{ .tag = @enumFromInt(1734), .properties = .{ .param_str = "bUiCUiCUi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_umull_overflow + .{ .tag = @enumFromInt(1735), .properties = .{ .param_str = "bULiCULiCULi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_umulll_overflow + .{ .tag = @enumFromInt(1736), .properties = .{ .param_str = "bULLiCULLiCULLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_unpack_longdouble + .{ .tag = @enumFromInt(1737), .properties = .{ .param_str = "dLdIi", .target_set = TargetSet.initOne(.ppc) } }, + // __builtin_unpredictable + .{ .tag = @enumFromInt(1738), .properties = .{ .param_str = "LiLi", .attributes = .{ .@"const" = true } } }, + // __builtin_unreachable + .{ .tag = @enumFromInt(1739), .properties = .{ .param_str = "v", .attributes = .{ .noreturn = true } } }, + // __builtin_unwind_init + .{ .tag = @enumFromInt(1740), .properties = .{ .param_str = "v" } }, + // __builtin_usub_overflow + .{ .tag = @enumFromInt(1741), .properties = .{ .param_str = "bUiCUiCUi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_usubl_overflow + .{ .tag = @enumFromInt(1742), .properties = .{ .param_str = "bULiCULiCULi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_usubll_overflow + .{ .tag = @enumFromInt(1743), .properties = .{ .param_str = "bULLiCULLiCULLi*", .attributes = .{ .const_evaluable = true } } }, + // __builtin_va_copy + .{ .tag = @enumFromInt(1744), .properties = .{ .param_str = "vAA" } }, + // __builtin_va_end + .{ .tag = @enumFromInt(1745), .properties = .{ .param_str = "vA" } }, + // __builtin_va_start + .{ .tag = @enumFromInt(1746), .properties = .{ .param_str = "vA.", .attributes = .{ .custom_typecheck = true } } }, + // __builtin_ve_vl_andm_MMM + .{ .tag = @enumFromInt(1747), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_andm_mmm + .{ .tag = @enumFromInt(1748), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_eqvm_MMM + .{ .tag = @enumFromInt(1749), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_eqvm_mmm + .{ .tag = @enumFromInt(1750), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_extract_vm512l + .{ .tag = @enumFromInt(1751), .properties = .{ .param_str = "V256bV512b", .target_set = TargetSet.initOne(.ve) } }, + // __builtin_ve_vl_extract_vm512u + .{ .tag = @enumFromInt(1752), .properties = .{ .param_str = "V256bV512b", .target_set = TargetSet.initOne(.ve) } }, + // __builtin_ve_vl_fencec_s + .{ .tag = @enumFromInt(1753), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_fencei + .{ .tag = @enumFromInt(1754), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_fencem_s + .{ .tag = @enumFromInt(1755), .properties = .{ .param_str = "vUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_fidcr_sss + .{ .tag = @enumFromInt(1756), .properties = .{ .param_str = "LUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_insert_vm512l + .{ .tag = @enumFromInt(1757), .properties = .{ .param_str = "V512bV512bV256b", .target_set = TargetSet.initOne(.ve) } }, + // __builtin_ve_vl_insert_vm512u + .{ .tag = @enumFromInt(1758), .properties = .{ .param_str = "V512bV512bV256b", .target_set = TargetSet.initOne(.ve) } }, + // __builtin_ve_vl_lcr_sss + .{ .tag = @enumFromInt(1759), .properties = .{ .param_str = "LUiLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_lsv_vvss + .{ .tag = @enumFromInt(1760), .properties = .{ .param_str = "V256dV256dUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_lvm_MMss + .{ .tag = @enumFromInt(1761), .properties = .{ .param_str = "V512bV512bLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_lvm_mmss + .{ .tag = @enumFromInt(1762), .properties = .{ .param_str = "V256bV256bLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_lvsd_svs + .{ .tag = @enumFromInt(1763), .properties = .{ .param_str = "dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_lvsl_svs + .{ .tag = @enumFromInt(1764), .properties = .{ .param_str = "LUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_lvss_svs + .{ .tag = @enumFromInt(1765), .properties = .{ .param_str = "fV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_lzvm_sml + .{ .tag = @enumFromInt(1766), .properties = .{ .param_str = "LUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_negm_MM + .{ .tag = @enumFromInt(1767), .properties = .{ .param_str = "V512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_negm_mm + .{ .tag = @enumFromInt(1768), .properties = .{ .param_str = "V256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_nndm_MMM + .{ .tag = @enumFromInt(1769), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_nndm_mmm + .{ .tag = @enumFromInt(1770), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_orm_MMM + .{ .tag = @enumFromInt(1771), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_orm_mmm + .{ .tag = @enumFromInt(1772), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pack_f32a + .{ .tag = @enumFromInt(1773), .properties = .{ .param_str = "ULifC*", .target_set = TargetSet.initOne(.ve) } }, + // __builtin_ve_vl_pack_f32p + .{ .tag = @enumFromInt(1774), .properties = .{ .param_str = "ULifC*fC*", .target_set = TargetSet.initOne(.ve) } }, + // __builtin_ve_vl_pcvm_sml + .{ .tag = @enumFromInt(1775), .properties = .{ .param_str = "LUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pfchv_ssl + .{ .tag = @enumFromInt(1776), .properties = .{ .param_str = "vLivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pfchvnc_ssl + .{ .tag = @enumFromInt(1777), .properties = .{ .param_str = "vLivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvadds_vsvMvl + .{ .tag = @enumFromInt(1778), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvadds_vsvl + .{ .tag = @enumFromInt(1779), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvadds_vsvvl + .{ .tag = @enumFromInt(1780), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvadds_vvvMvl + .{ .tag = @enumFromInt(1781), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvadds_vvvl + .{ .tag = @enumFromInt(1782), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvadds_vvvvl + .{ .tag = @enumFromInt(1783), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvaddu_vsvMvl + .{ .tag = @enumFromInt(1784), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvaddu_vsvl + .{ .tag = @enumFromInt(1785), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvaddu_vsvvl + .{ .tag = @enumFromInt(1786), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvaddu_vvvMvl + .{ .tag = @enumFromInt(1787), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvaddu_vvvl + .{ .tag = @enumFromInt(1788), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvaddu_vvvvl + .{ .tag = @enumFromInt(1789), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvand_vsvMvl + .{ .tag = @enumFromInt(1790), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvand_vsvl + .{ .tag = @enumFromInt(1791), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvand_vsvvl + .{ .tag = @enumFromInt(1792), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvand_vvvMvl + .{ .tag = @enumFromInt(1793), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvand_vvvl + .{ .tag = @enumFromInt(1794), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvand_vvvvl + .{ .tag = @enumFromInt(1795), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrd_vsMvl + .{ .tag = @enumFromInt(1796), .properties = .{ .param_str = "V256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrd_vsl + .{ .tag = @enumFromInt(1797), .properties = .{ .param_str = "V256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrd_vsvl + .{ .tag = @enumFromInt(1798), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrv_vvMvl + .{ .tag = @enumFromInt(1799), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrv_vvl + .{ .tag = @enumFromInt(1800), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrv_vvvl + .{ .tag = @enumFromInt(1801), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrvlo_vvl + .{ .tag = @enumFromInt(1802), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrvlo_vvmvl + .{ .tag = @enumFromInt(1803), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrvlo_vvvl + .{ .tag = @enumFromInt(1804), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrvup_vvl + .{ .tag = @enumFromInt(1805), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrvup_vvmvl + .{ .tag = @enumFromInt(1806), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvbrvup_vvvl + .{ .tag = @enumFromInt(1807), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmps_vsvMvl + .{ .tag = @enumFromInt(1808), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmps_vsvl + .{ .tag = @enumFromInt(1809), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmps_vsvvl + .{ .tag = @enumFromInt(1810), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmps_vvvMvl + .{ .tag = @enumFromInt(1811), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmps_vvvl + .{ .tag = @enumFromInt(1812), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmps_vvvvl + .{ .tag = @enumFromInt(1813), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmpu_vsvMvl + .{ .tag = @enumFromInt(1814), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmpu_vsvl + .{ .tag = @enumFromInt(1815), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmpu_vsvvl + .{ .tag = @enumFromInt(1816), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmpu_vvvMvl + .{ .tag = @enumFromInt(1817), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmpu_vvvl + .{ .tag = @enumFromInt(1818), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcmpu_vvvvl + .{ .tag = @enumFromInt(1819), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtsw_vvl + .{ .tag = @enumFromInt(1820), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtsw_vvvl + .{ .tag = @enumFromInt(1821), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtws_vvMvl + .{ .tag = @enumFromInt(1822), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtws_vvl + .{ .tag = @enumFromInt(1823), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtws_vvvl + .{ .tag = @enumFromInt(1824), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtwsrz_vvMvl + .{ .tag = @enumFromInt(1825), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtwsrz_vvl + .{ .tag = @enumFromInt(1826), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvcvtwsrz_vvvl + .{ .tag = @enumFromInt(1827), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pveqv_vsvMvl + .{ .tag = @enumFromInt(1828), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pveqv_vsvl + .{ .tag = @enumFromInt(1829), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pveqv_vsvvl + .{ .tag = @enumFromInt(1830), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pveqv_vvvMvl + .{ .tag = @enumFromInt(1831), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pveqv_vvvl + .{ .tag = @enumFromInt(1832), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pveqv_vvvvl + .{ .tag = @enumFromInt(1833), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfadd_vsvMvl + .{ .tag = @enumFromInt(1834), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfadd_vsvl + .{ .tag = @enumFromInt(1835), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfadd_vsvvl + .{ .tag = @enumFromInt(1836), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfadd_vvvMvl + .{ .tag = @enumFromInt(1837), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfadd_vvvl + .{ .tag = @enumFromInt(1838), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfadd_vvvvl + .{ .tag = @enumFromInt(1839), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfcmp_vsvMvl + .{ .tag = @enumFromInt(1840), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfcmp_vsvl + .{ .tag = @enumFromInt(1841), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfcmp_vsvvl + .{ .tag = @enumFromInt(1842), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfcmp_vvvMvl + .{ .tag = @enumFromInt(1843), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfcmp_vvvl + .{ .tag = @enumFromInt(1844), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfcmp_vvvvl + .{ .tag = @enumFromInt(1845), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vsvvMvl + .{ .tag = @enumFromInt(1846), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vsvvl + .{ .tag = @enumFromInt(1847), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vsvvvl + .{ .tag = @enumFromInt(1848), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vvsvMvl + .{ .tag = @enumFromInt(1849), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vvsvl + .{ .tag = @enumFromInt(1850), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vvsvvl + .{ .tag = @enumFromInt(1851), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vvvvMvl + .{ .tag = @enumFromInt(1852), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vvvvl + .{ .tag = @enumFromInt(1853), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmad_vvvvvl + .{ .tag = @enumFromInt(1854), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmax_vsvMvl + .{ .tag = @enumFromInt(1855), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmax_vsvl + .{ .tag = @enumFromInt(1856), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmax_vsvvl + .{ .tag = @enumFromInt(1857), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmax_vvvMvl + .{ .tag = @enumFromInt(1858), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmax_vvvl + .{ .tag = @enumFromInt(1859), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmax_vvvvl + .{ .tag = @enumFromInt(1860), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmin_vsvMvl + .{ .tag = @enumFromInt(1861), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmin_vsvl + .{ .tag = @enumFromInt(1862), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmin_vsvvl + .{ .tag = @enumFromInt(1863), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmin_vvvMvl + .{ .tag = @enumFromInt(1864), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmin_vvvl + .{ .tag = @enumFromInt(1865), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmin_vvvvl + .{ .tag = @enumFromInt(1866), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkaf_Ml + .{ .tag = @enumFromInt(1867), .properties = .{ .param_str = "V512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkat_Ml + .{ .tag = @enumFromInt(1868), .properties = .{ .param_str = "V512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkseq_MvMl + .{ .tag = @enumFromInt(1869), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkseq_Mvl + .{ .tag = @enumFromInt(1870), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkseqnan_MvMl + .{ .tag = @enumFromInt(1871), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkseqnan_Mvl + .{ .tag = @enumFromInt(1872), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksge_MvMl + .{ .tag = @enumFromInt(1873), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksge_Mvl + .{ .tag = @enumFromInt(1874), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksgenan_MvMl + .{ .tag = @enumFromInt(1875), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksgenan_Mvl + .{ .tag = @enumFromInt(1876), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksgt_MvMl + .{ .tag = @enumFromInt(1877), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksgt_Mvl + .{ .tag = @enumFromInt(1878), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksgtnan_MvMl + .{ .tag = @enumFromInt(1879), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksgtnan_Mvl + .{ .tag = @enumFromInt(1880), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksle_MvMl + .{ .tag = @enumFromInt(1881), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksle_Mvl + .{ .tag = @enumFromInt(1882), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslenan_MvMl + .{ .tag = @enumFromInt(1883), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslenan_Mvl + .{ .tag = @enumFromInt(1884), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloeq_mvl + .{ .tag = @enumFromInt(1885), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloeq_mvml + .{ .tag = @enumFromInt(1886), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloeqnan_mvl + .{ .tag = @enumFromInt(1887), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloeqnan_mvml + .{ .tag = @enumFromInt(1888), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloge_mvl + .{ .tag = @enumFromInt(1889), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloge_mvml + .{ .tag = @enumFromInt(1890), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslogenan_mvl + .{ .tag = @enumFromInt(1891), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslogenan_mvml + .{ .tag = @enumFromInt(1892), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslogt_mvl + .{ .tag = @enumFromInt(1893), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslogt_mvml + .{ .tag = @enumFromInt(1894), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslogtnan_mvl + .{ .tag = @enumFromInt(1895), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslogtnan_mvml + .{ .tag = @enumFromInt(1896), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslole_mvl + .{ .tag = @enumFromInt(1897), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslole_mvml + .{ .tag = @enumFromInt(1898), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslolenan_mvl + .{ .tag = @enumFromInt(1899), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslolenan_mvml + .{ .tag = @enumFromInt(1900), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslolt_mvl + .{ .tag = @enumFromInt(1901), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslolt_mvml + .{ .tag = @enumFromInt(1902), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloltnan_mvl + .{ .tag = @enumFromInt(1903), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksloltnan_mvml + .{ .tag = @enumFromInt(1904), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslonan_mvl + .{ .tag = @enumFromInt(1905), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslonan_mvml + .{ .tag = @enumFromInt(1906), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslone_mvl + .{ .tag = @enumFromInt(1907), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslone_mvml + .{ .tag = @enumFromInt(1908), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslonenan_mvl + .{ .tag = @enumFromInt(1909), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslonenan_mvml + .{ .tag = @enumFromInt(1910), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslonum_mvl + .{ .tag = @enumFromInt(1911), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslonum_mvml + .{ .tag = @enumFromInt(1912), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslt_MvMl + .{ .tag = @enumFromInt(1913), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkslt_Mvl + .{ .tag = @enumFromInt(1914), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksltnan_MvMl + .{ .tag = @enumFromInt(1915), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksltnan_Mvl + .{ .tag = @enumFromInt(1916), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksnan_MvMl + .{ .tag = @enumFromInt(1917), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksnan_Mvl + .{ .tag = @enumFromInt(1918), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksne_MvMl + .{ .tag = @enumFromInt(1919), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksne_Mvl + .{ .tag = @enumFromInt(1920), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksnenan_MvMl + .{ .tag = @enumFromInt(1921), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksnenan_Mvl + .{ .tag = @enumFromInt(1922), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksnum_MvMl + .{ .tag = @enumFromInt(1923), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksnum_Mvl + .{ .tag = @enumFromInt(1924), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupeq_mvl + .{ .tag = @enumFromInt(1925), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupeq_mvml + .{ .tag = @enumFromInt(1926), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupeqnan_mvl + .{ .tag = @enumFromInt(1927), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupeqnan_mvml + .{ .tag = @enumFromInt(1928), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupge_mvl + .{ .tag = @enumFromInt(1929), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupge_mvml + .{ .tag = @enumFromInt(1930), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupgenan_mvl + .{ .tag = @enumFromInt(1931), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupgenan_mvml + .{ .tag = @enumFromInt(1932), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupgt_mvl + .{ .tag = @enumFromInt(1933), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupgt_mvml + .{ .tag = @enumFromInt(1934), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupgtnan_mvl + .{ .tag = @enumFromInt(1935), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupgtnan_mvml + .{ .tag = @enumFromInt(1936), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksuple_mvl + .{ .tag = @enumFromInt(1937), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksuple_mvml + .{ .tag = @enumFromInt(1938), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksuplenan_mvl + .{ .tag = @enumFromInt(1939), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksuplenan_mvml + .{ .tag = @enumFromInt(1940), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksuplt_mvl + .{ .tag = @enumFromInt(1941), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksuplt_mvml + .{ .tag = @enumFromInt(1942), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupltnan_mvl + .{ .tag = @enumFromInt(1943), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupltnan_mvml + .{ .tag = @enumFromInt(1944), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupnan_mvl + .{ .tag = @enumFromInt(1945), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupnan_mvml + .{ .tag = @enumFromInt(1946), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupne_mvl + .{ .tag = @enumFromInt(1947), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupne_mvml + .{ .tag = @enumFromInt(1948), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupnenan_mvl + .{ .tag = @enumFromInt(1949), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupnenan_mvml + .{ .tag = @enumFromInt(1950), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupnum_mvl + .{ .tag = @enumFromInt(1951), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmksupnum_mvml + .{ .tag = @enumFromInt(1952), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkweq_MvMl + .{ .tag = @enumFromInt(1953), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkweq_Mvl + .{ .tag = @enumFromInt(1954), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkweqnan_MvMl + .{ .tag = @enumFromInt(1955), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkweqnan_Mvl + .{ .tag = @enumFromInt(1956), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwge_MvMl + .{ .tag = @enumFromInt(1957), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwge_Mvl + .{ .tag = @enumFromInt(1958), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwgenan_MvMl + .{ .tag = @enumFromInt(1959), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwgenan_Mvl + .{ .tag = @enumFromInt(1960), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwgt_MvMl + .{ .tag = @enumFromInt(1961), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwgt_Mvl + .{ .tag = @enumFromInt(1962), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwgtnan_MvMl + .{ .tag = @enumFromInt(1963), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwgtnan_Mvl + .{ .tag = @enumFromInt(1964), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwle_MvMl + .{ .tag = @enumFromInt(1965), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwle_Mvl + .{ .tag = @enumFromInt(1966), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlenan_MvMl + .{ .tag = @enumFromInt(1967), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlenan_Mvl + .{ .tag = @enumFromInt(1968), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloeq_mvl + .{ .tag = @enumFromInt(1969), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloeq_mvml + .{ .tag = @enumFromInt(1970), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloeqnan_mvl + .{ .tag = @enumFromInt(1971), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloeqnan_mvml + .{ .tag = @enumFromInt(1972), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloge_mvl + .{ .tag = @enumFromInt(1973), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloge_mvml + .{ .tag = @enumFromInt(1974), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlogenan_mvl + .{ .tag = @enumFromInt(1975), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlogenan_mvml + .{ .tag = @enumFromInt(1976), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlogt_mvl + .{ .tag = @enumFromInt(1977), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlogt_mvml + .{ .tag = @enumFromInt(1978), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlogtnan_mvl + .{ .tag = @enumFromInt(1979), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlogtnan_mvml + .{ .tag = @enumFromInt(1980), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlole_mvl + .{ .tag = @enumFromInt(1981), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlole_mvml + .{ .tag = @enumFromInt(1982), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlolenan_mvl + .{ .tag = @enumFromInt(1983), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlolenan_mvml + .{ .tag = @enumFromInt(1984), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlolt_mvl + .{ .tag = @enumFromInt(1985), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlolt_mvml + .{ .tag = @enumFromInt(1986), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloltnan_mvl + .{ .tag = @enumFromInt(1987), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwloltnan_mvml + .{ .tag = @enumFromInt(1988), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlonan_mvl + .{ .tag = @enumFromInt(1989), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlonan_mvml + .{ .tag = @enumFromInt(1990), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlone_mvl + .{ .tag = @enumFromInt(1991), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlone_mvml + .{ .tag = @enumFromInt(1992), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlonenan_mvl + .{ .tag = @enumFromInt(1993), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlonenan_mvml + .{ .tag = @enumFromInt(1994), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlonum_mvl + .{ .tag = @enumFromInt(1995), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlonum_mvml + .{ .tag = @enumFromInt(1996), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlt_MvMl + .{ .tag = @enumFromInt(1997), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwlt_Mvl + .{ .tag = @enumFromInt(1998), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwltnan_MvMl + .{ .tag = @enumFromInt(1999), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwltnan_Mvl + .{ .tag = @enumFromInt(2000), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwnan_MvMl + .{ .tag = @enumFromInt(2001), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwnan_Mvl + .{ .tag = @enumFromInt(2002), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwne_MvMl + .{ .tag = @enumFromInt(2003), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwne_Mvl + .{ .tag = @enumFromInt(2004), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwnenan_MvMl + .{ .tag = @enumFromInt(2005), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwnenan_Mvl + .{ .tag = @enumFromInt(2006), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwnum_MvMl + .{ .tag = @enumFromInt(2007), .properties = .{ .param_str = "V512bV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwnum_Mvl + .{ .tag = @enumFromInt(2008), .properties = .{ .param_str = "V512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupeq_mvl + .{ .tag = @enumFromInt(2009), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupeq_mvml + .{ .tag = @enumFromInt(2010), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupeqnan_mvl + .{ .tag = @enumFromInt(2011), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupeqnan_mvml + .{ .tag = @enumFromInt(2012), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupge_mvl + .{ .tag = @enumFromInt(2013), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupge_mvml + .{ .tag = @enumFromInt(2014), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupgenan_mvl + .{ .tag = @enumFromInt(2015), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupgenan_mvml + .{ .tag = @enumFromInt(2016), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupgt_mvl + .{ .tag = @enumFromInt(2017), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupgt_mvml + .{ .tag = @enumFromInt(2018), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupgtnan_mvl + .{ .tag = @enumFromInt(2019), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupgtnan_mvml + .{ .tag = @enumFromInt(2020), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwuple_mvl + .{ .tag = @enumFromInt(2021), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwuple_mvml + .{ .tag = @enumFromInt(2022), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwuplenan_mvl + .{ .tag = @enumFromInt(2023), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwuplenan_mvml + .{ .tag = @enumFromInt(2024), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwuplt_mvl + .{ .tag = @enumFromInt(2025), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwuplt_mvml + .{ .tag = @enumFromInt(2026), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupltnan_mvl + .{ .tag = @enumFromInt(2027), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupltnan_mvml + .{ .tag = @enumFromInt(2028), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupnan_mvl + .{ .tag = @enumFromInt(2029), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupnan_mvml + .{ .tag = @enumFromInt(2030), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupne_mvl + .{ .tag = @enumFromInt(2031), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupne_mvml + .{ .tag = @enumFromInt(2032), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupnenan_mvl + .{ .tag = @enumFromInt(2033), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupnenan_mvml + .{ .tag = @enumFromInt(2034), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupnum_mvl + .{ .tag = @enumFromInt(2035), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmkwupnum_mvml + .{ .tag = @enumFromInt(2036), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vsvvMvl + .{ .tag = @enumFromInt(2037), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vsvvl + .{ .tag = @enumFromInt(2038), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vsvvvl + .{ .tag = @enumFromInt(2039), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vvsvMvl + .{ .tag = @enumFromInt(2040), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vvsvl + .{ .tag = @enumFromInt(2041), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vvsvvl + .{ .tag = @enumFromInt(2042), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vvvvMvl + .{ .tag = @enumFromInt(2043), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vvvvl + .{ .tag = @enumFromInt(2044), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmsb_vvvvvl + .{ .tag = @enumFromInt(2045), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmul_vsvMvl + .{ .tag = @enumFromInt(2046), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmul_vsvl + .{ .tag = @enumFromInt(2047), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmul_vsvvl + .{ .tag = @enumFromInt(2048), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmul_vvvMvl + .{ .tag = @enumFromInt(2049), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmul_vvvl + .{ .tag = @enumFromInt(2050), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfmul_vvvvl + .{ .tag = @enumFromInt(2051), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vsvvMvl + .{ .tag = @enumFromInt(2052), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vsvvl + .{ .tag = @enumFromInt(2053), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vsvvvl + .{ .tag = @enumFromInt(2054), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vvsvMvl + .{ .tag = @enumFromInt(2055), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vvsvl + .{ .tag = @enumFromInt(2056), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vvsvvl + .{ .tag = @enumFromInt(2057), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vvvvMvl + .{ .tag = @enumFromInt(2058), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vvvvl + .{ .tag = @enumFromInt(2059), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmad_vvvvvl + .{ .tag = @enumFromInt(2060), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vsvvMvl + .{ .tag = @enumFromInt(2061), .properties = .{ .param_str = "V256dLUiV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vsvvl + .{ .tag = @enumFromInt(2062), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vsvvvl + .{ .tag = @enumFromInt(2063), .properties = .{ .param_str = "V256dLUiV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vvsvMvl + .{ .tag = @enumFromInt(2064), .properties = .{ .param_str = "V256dV256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vvsvl + .{ .tag = @enumFromInt(2065), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vvsvvl + .{ .tag = @enumFromInt(2066), .properties = .{ .param_str = "V256dV256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vvvvMvl + .{ .tag = @enumFromInt(2067), .properties = .{ .param_str = "V256dV256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vvvvl + .{ .tag = @enumFromInt(2068), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfnmsb_vvvvvl + .{ .tag = @enumFromInt(2069), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfsub_vsvMvl + .{ .tag = @enumFromInt(2070), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfsub_vsvl + .{ .tag = @enumFromInt(2071), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfsub_vsvvl + .{ .tag = @enumFromInt(2072), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfsub_vvvMvl + .{ .tag = @enumFromInt(2073), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfsub_vvvl + .{ .tag = @enumFromInt(2074), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvfsub_vvvvl + .{ .tag = @enumFromInt(2075), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldz_vvMvl + .{ .tag = @enumFromInt(2076), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldz_vvl + .{ .tag = @enumFromInt(2077), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldz_vvvl + .{ .tag = @enumFromInt(2078), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldzlo_vvl + .{ .tag = @enumFromInt(2079), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldzlo_vvmvl + .{ .tag = @enumFromInt(2080), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldzlo_vvvl + .{ .tag = @enumFromInt(2081), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldzup_vvl + .{ .tag = @enumFromInt(2082), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldzup_vvmvl + .{ .tag = @enumFromInt(2083), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvldzup_vvvl + .{ .tag = @enumFromInt(2084), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmaxs_vsvMvl + .{ .tag = @enumFromInt(2085), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmaxs_vsvl + .{ .tag = @enumFromInt(2086), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmaxs_vsvvl + .{ .tag = @enumFromInt(2087), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmaxs_vvvMvl + .{ .tag = @enumFromInt(2088), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmaxs_vvvl + .{ .tag = @enumFromInt(2089), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmaxs_vvvvl + .{ .tag = @enumFromInt(2090), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmins_vsvMvl + .{ .tag = @enumFromInt(2091), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmins_vsvl + .{ .tag = @enumFromInt(2092), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmins_vsvvl + .{ .tag = @enumFromInt(2093), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmins_vvvMvl + .{ .tag = @enumFromInt(2094), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmins_vvvl + .{ .tag = @enumFromInt(2095), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvmins_vvvvl + .{ .tag = @enumFromInt(2096), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvor_vsvMvl + .{ .tag = @enumFromInt(2097), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvor_vsvl + .{ .tag = @enumFromInt(2098), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvor_vsvvl + .{ .tag = @enumFromInt(2099), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvor_vvvMvl + .{ .tag = @enumFromInt(2100), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvor_vvvl + .{ .tag = @enumFromInt(2101), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvor_vvvvl + .{ .tag = @enumFromInt(2102), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcnt_vvMvl + .{ .tag = @enumFromInt(2103), .properties = .{ .param_str = "V256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcnt_vvl + .{ .tag = @enumFromInt(2104), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcnt_vvvl + .{ .tag = @enumFromInt(2105), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcntlo_vvl + .{ .tag = @enumFromInt(2106), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcntlo_vvmvl + .{ .tag = @enumFromInt(2107), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcntlo_vvvl + .{ .tag = @enumFromInt(2108), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcntup_vvl + .{ .tag = @enumFromInt(2109), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcntup_vvmvl + .{ .tag = @enumFromInt(2110), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvpcntup_vvvl + .{ .tag = @enumFromInt(2111), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvrcp_vvl + .{ .tag = @enumFromInt(2112), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvrcp_vvvl + .{ .tag = @enumFromInt(2113), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvrsqrt_vvl + .{ .tag = @enumFromInt(2114), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvrsqrt_vvvl + .{ .tag = @enumFromInt(2115), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvrsqrtnex_vvl + .{ .tag = @enumFromInt(2116), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvrsqrtnex_vvvl + .{ .tag = @enumFromInt(2117), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvseq_vl + .{ .tag = @enumFromInt(2118), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvseq_vvl + .{ .tag = @enumFromInt(2119), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvseqlo_vl + .{ .tag = @enumFromInt(2120), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvseqlo_vvl + .{ .tag = @enumFromInt(2121), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsequp_vl + .{ .tag = @enumFromInt(2122), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsequp_vvl + .{ .tag = @enumFromInt(2123), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsla_vvsMvl + .{ .tag = @enumFromInt(2124), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsla_vvsl + .{ .tag = @enumFromInt(2125), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsla_vvsvl + .{ .tag = @enumFromInt(2126), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsla_vvvMvl + .{ .tag = @enumFromInt(2127), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsla_vvvl + .{ .tag = @enumFromInt(2128), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsla_vvvvl + .{ .tag = @enumFromInt(2129), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsll_vvsMvl + .{ .tag = @enumFromInt(2130), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsll_vvsl + .{ .tag = @enumFromInt(2131), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsll_vvsvl + .{ .tag = @enumFromInt(2132), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsll_vvvMvl + .{ .tag = @enumFromInt(2133), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsll_vvvl + .{ .tag = @enumFromInt(2134), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsll_vvvvl + .{ .tag = @enumFromInt(2135), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsra_vvsMvl + .{ .tag = @enumFromInt(2136), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsra_vvsl + .{ .tag = @enumFromInt(2137), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsra_vvsvl + .{ .tag = @enumFromInt(2138), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsra_vvvMvl + .{ .tag = @enumFromInt(2139), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsra_vvvl + .{ .tag = @enumFromInt(2140), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsra_vvvvl + .{ .tag = @enumFromInt(2141), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsrl_vvsMvl + .{ .tag = @enumFromInt(2142), .properties = .{ .param_str = "V256dV256dLUiV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsrl_vvsl + .{ .tag = @enumFromInt(2143), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsrl_vvsvl + .{ .tag = @enumFromInt(2144), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsrl_vvvMvl + .{ .tag = @enumFromInt(2145), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsrl_vvvl + .{ .tag = @enumFromInt(2146), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsrl_vvvvl + .{ .tag = @enumFromInt(2147), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubs_vsvMvl + .{ .tag = @enumFromInt(2148), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubs_vsvl + .{ .tag = @enumFromInt(2149), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubs_vsvvl + .{ .tag = @enumFromInt(2150), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubs_vvvMvl + .{ .tag = @enumFromInt(2151), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubs_vvvl + .{ .tag = @enumFromInt(2152), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubs_vvvvl + .{ .tag = @enumFromInt(2153), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubu_vsvMvl + .{ .tag = @enumFromInt(2154), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubu_vsvl + .{ .tag = @enumFromInt(2155), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubu_vsvvl + .{ .tag = @enumFromInt(2156), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubu_vvvMvl + .{ .tag = @enumFromInt(2157), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubu_vvvl + .{ .tag = @enumFromInt(2158), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvsubu_vvvvl + .{ .tag = @enumFromInt(2159), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvxor_vsvMvl + .{ .tag = @enumFromInt(2160), .properties = .{ .param_str = "V256dLUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvxor_vsvl + .{ .tag = @enumFromInt(2161), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvxor_vsvvl + .{ .tag = @enumFromInt(2162), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvxor_vvvMvl + .{ .tag = @enumFromInt(2163), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvxor_vvvl + .{ .tag = @enumFromInt(2164), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_pvxor_vvvvl + .{ .tag = @enumFromInt(2165), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_scr_sss + .{ .tag = @enumFromInt(2166), .properties = .{ .param_str = "vLUiLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_svm_sMs + .{ .tag = @enumFromInt(2167), .properties = .{ .param_str = "LUiV512bLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_svm_sms + .{ .tag = @enumFromInt(2168), .properties = .{ .param_str = "LUiV256bLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_svob + .{ .tag = @enumFromInt(2169), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_tovm_sml + .{ .tag = @enumFromInt(2170), .properties = .{ .param_str = "LUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_tscr_ssss + .{ .tag = @enumFromInt(2171), .properties = .{ .param_str = "LUiLUiLUiLUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddsl_vsvl + .{ .tag = @enumFromInt(2172), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddsl_vsvmvl + .{ .tag = @enumFromInt(2173), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddsl_vsvvl + .{ .tag = @enumFromInt(2174), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddsl_vvvl + .{ .tag = @enumFromInt(2175), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddsl_vvvmvl + .{ .tag = @enumFromInt(2176), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddsl_vvvvl + .{ .tag = @enumFromInt(2177), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswsx_vsvl + .{ .tag = @enumFromInt(2178), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswsx_vsvmvl + .{ .tag = @enumFromInt(2179), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswsx_vsvvl + .{ .tag = @enumFromInt(2180), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswsx_vvvl + .{ .tag = @enumFromInt(2181), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswsx_vvvmvl + .{ .tag = @enumFromInt(2182), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswsx_vvvvl + .{ .tag = @enumFromInt(2183), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswzx_vsvl + .{ .tag = @enumFromInt(2184), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswzx_vsvmvl + .{ .tag = @enumFromInt(2185), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswzx_vsvvl + .{ .tag = @enumFromInt(2186), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswzx_vvvl + .{ .tag = @enumFromInt(2187), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswzx_vvvmvl + .{ .tag = @enumFromInt(2188), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddswzx_vvvvl + .{ .tag = @enumFromInt(2189), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddul_vsvl + .{ .tag = @enumFromInt(2190), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddul_vsvmvl + .{ .tag = @enumFromInt(2191), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddul_vsvvl + .{ .tag = @enumFromInt(2192), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddul_vvvl + .{ .tag = @enumFromInt(2193), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddul_vvvmvl + .{ .tag = @enumFromInt(2194), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vaddul_vvvvl + .{ .tag = @enumFromInt(2195), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vadduw_vsvl + .{ .tag = @enumFromInt(2196), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vadduw_vsvmvl + .{ .tag = @enumFromInt(2197), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vadduw_vsvvl + .{ .tag = @enumFromInt(2198), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vadduw_vvvl + .{ .tag = @enumFromInt(2199), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vadduw_vvvmvl + .{ .tag = @enumFromInt(2200), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vadduw_vvvvl + .{ .tag = @enumFromInt(2201), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vand_vsvl + .{ .tag = @enumFromInt(2202), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vand_vsvmvl + .{ .tag = @enumFromInt(2203), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vand_vsvvl + .{ .tag = @enumFromInt(2204), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vand_vvvl + .{ .tag = @enumFromInt(2205), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vand_vvvmvl + .{ .tag = @enumFromInt(2206), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vand_vvvvl + .{ .tag = @enumFromInt(2207), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdd_vsl + .{ .tag = @enumFromInt(2208), .properties = .{ .param_str = "V256ddUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdd_vsmvl + .{ .tag = @enumFromInt(2209), .properties = .{ .param_str = "V256ddV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdd_vsvl + .{ .tag = @enumFromInt(2210), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdl_vsl + .{ .tag = @enumFromInt(2211), .properties = .{ .param_str = "V256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdl_vsmvl + .{ .tag = @enumFromInt(2212), .properties = .{ .param_str = "V256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdl_vsvl + .{ .tag = @enumFromInt(2213), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrds_vsl + .{ .tag = @enumFromInt(2214), .properties = .{ .param_str = "V256dfUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrds_vsmvl + .{ .tag = @enumFromInt(2215), .properties = .{ .param_str = "V256dfV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrds_vsvl + .{ .tag = @enumFromInt(2216), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdw_vsl + .{ .tag = @enumFromInt(2217), .properties = .{ .param_str = "V256diUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdw_vsmvl + .{ .tag = @enumFromInt(2218), .properties = .{ .param_str = "V256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrdw_vsvl + .{ .tag = @enumFromInt(2219), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrv_vvl + .{ .tag = @enumFromInt(2220), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrv_vvmvl + .{ .tag = @enumFromInt(2221), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vbrv_vvvl + .{ .tag = @enumFromInt(2222), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpsl_vsvl + .{ .tag = @enumFromInt(2223), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpsl_vsvmvl + .{ .tag = @enumFromInt(2224), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpsl_vsvvl + .{ .tag = @enumFromInt(2225), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpsl_vvvl + .{ .tag = @enumFromInt(2226), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpsl_vvvmvl + .{ .tag = @enumFromInt(2227), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpsl_vvvvl + .{ .tag = @enumFromInt(2228), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswsx_vsvl + .{ .tag = @enumFromInt(2229), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswsx_vsvmvl + .{ .tag = @enumFromInt(2230), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswsx_vsvvl + .{ .tag = @enumFromInt(2231), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswsx_vvvl + .{ .tag = @enumFromInt(2232), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswsx_vvvmvl + .{ .tag = @enumFromInt(2233), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswsx_vvvvl + .{ .tag = @enumFromInt(2234), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswzx_vsvl + .{ .tag = @enumFromInt(2235), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswzx_vsvmvl + .{ .tag = @enumFromInt(2236), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswzx_vsvvl + .{ .tag = @enumFromInt(2237), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswzx_vvvl + .{ .tag = @enumFromInt(2238), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswzx_vvvmvl + .{ .tag = @enumFromInt(2239), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpswzx_vvvvl + .{ .tag = @enumFromInt(2240), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpul_vsvl + .{ .tag = @enumFromInt(2241), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpul_vsvmvl + .{ .tag = @enumFromInt(2242), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpul_vsvvl + .{ .tag = @enumFromInt(2243), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpul_vvvl + .{ .tag = @enumFromInt(2244), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpul_vvvmvl + .{ .tag = @enumFromInt(2245), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpul_vvvvl + .{ .tag = @enumFromInt(2246), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpuw_vsvl + .{ .tag = @enumFromInt(2247), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpuw_vsvmvl + .{ .tag = @enumFromInt(2248), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpuw_vsvvl + .{ .tag = @enumFromInt(2249), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpuw_vvvl + .{ .tag = @enumFromInt(2250), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpuw_vvvmvl + .{ .tag = @enumFromInt(2251), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcmpuw_vvvvl + .{ .tag = @enumFromInt(2252), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcp_vvmvl + .{ .tag = @enumFromInt(2253), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtdl_vvl + .{ .tag = @enumFromInt(2254), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtdl_vvvl + .{ .tag = @enumFromInt(2255), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtds_vvl + .{ .tag = @enumFromInt(2256), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtds_vvvl + .{ .tag = @enumFromInt(2257), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtdw_vvl + .{ .tag = @enumFromInt(2258), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtdw_vvvl + .{ .tag = @enumFromInt(2259), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtld_vvl + .{ .tag = @enumFromInt(2260), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtld_vvmvl + .{ .tag = @enumFromInt(2261), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtld_vvvl + .{ .tag = @enumFromInt(2262), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtldrz_vvl + .{ .tag = @enumFromInt(2263), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtldrz_vvmvl + .{ .tag = @enumFromInt(2264), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtldrz_vvvl + .{ .tag = @enumFromInt(2265), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtsd_vvl + .{ .tag = @enumFromInt(2266), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtsd_vvvl + .{ .tag = @enumFromInt(2267), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtsw_vvl + .{ .tag = @enumFromInt(2268), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtsw_vvvl + .{ .tag = @enumFromInt(2269), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdsx_vvl + .{ .tag = @enumFromInt(2270), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdsx_vvmvl + .{ .tag = @enumFromInt(2271), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdsx_vvvl + .{ .tag = @enumFromInt(2272), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdsxrz_vvl + .{ .tag = @enumFromInt(2273), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdsxrz_vvmvl + .{ .tag = @enumFromInt(2274), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdsxrz_vvvl + .{ .tag = @enumFromInt(2275), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdzx_vvl + .{ .tag = @enumFromInt(2276), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdzx_vvmvl + .{ .tag = @enumFromInt(2277), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdzx_vvvl + .{ .tag = @enumFromInt(2278), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdzxrz_vvl + .{ .tag = @enumFromInt(2279), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdzxrz_vvmvl + .{ .tag = @enumFromInt(2280), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwdzxrz_vvvl + .{ .tag = @enumFromInt(2281), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwssx_vvl + .{ .tag = @enumFromInt(2282), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwssx_vvmvl + .{ .tag = @enumFromInt(2283), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwssx_vvvl + .{ .tag = @enumFromInt(2284), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwssxrz_vvl + .{ .tag = @enumFromInt(2285), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwssxrz_vvmvl + .{ .tag = @enumFromInt(2286), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwssxrz_vvvl + .{ .tag = @enumFromInt(2287), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwszx_vvl + .{ .tag = @enumFromInt(2288), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwszx_vvmvl + .{ .tag = @enumFromInt(2289), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwszx_vvvl + .{ .tag = @enumFromInt(2290), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwszxrz_vvl + .{ .tag = @enumFromInt(2291), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwszxrz_vvmvl + .{ .tag = @enumFromInt(2292), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vcvtwszxrz_vvvl + .{ .tag = @enumFromInt(2293), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vsvl + .{ .tag = @enumFromInt(2294), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vsvmvl + .{ .tag = @enumFromInt(2295), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vsvvl + .{ .tag = @enumFromInt(2296), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vvsl + .{ .tag = @enumFromInt(2297), .properties = .{ .param_str = "V256dV256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vvsmvl + .{ .tag = @enumFromInt(2298), .properties = .{ .param_str = "V256dV256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vvsvl + .{ .tag = @enumFromInt(2299), .properties = .{ .param_str = "V256dV256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vvvl + .{ .tag = @enumFromInt(2300), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vvvmvl + .{ .tag = @enumFromInt(2301), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivsl_vvvvl + .{ .tag = @enumFromInt(2302), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vsvl + .{ .tag = @enumFromInt(2303), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vsvmvl + .{ .tag = @enumFromInt(2304), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vsvvl + .{ .tag = @enumFromInt(2305), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vvsl + .{ .tag = @enumFromInt(2306), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vvsmvl + .{ .tag = @enumFromInt(2307), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vvsvl + .{ .tag = @enumFromInt(2308), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vvvl + .{ .tag = @enumFromInt(2309), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vvvmvl + .{ .tag = @enumFromInt(2310), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswsx_vvvvl + .{ .tag = @enumFromInt(2311), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vsvl + .{ .tag = @enumFromInt(2312), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vsvmvl + .{ .tag = @enumFromInt(2313), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vsvvl + .{ .tag = @enumFromInt(2314), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vvsl + .{ .tag = @enumFromInt(2315), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vvsmvl + .{ .tag = @enumFromInt(2316), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vvsvl + .{ .tag = @enumFromInt(2317), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vvvl + .{ .tag = @enumFromInt(2318), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vvvmvl + .{ .tag = @enumFromInt(2319), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivswzx_vvvvl + .{ .tag = @enumFromInt(2320), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vsvl + .{ .tag = @enumFromInt(2321), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vsvmvl + .{ .tag = @enumFromInt(2322), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vsvvl + .{ .tag = @enumFromInt(2323), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vvsl + .{ .tag = @enumFromInt(2324), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vvsmvl + .{ .tag = @enumFromInt(2325), .properties = .{ .param_str = "V256dV256dLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vvsvl + .{ .tag = @enumFromInt(2326), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vvvl + .{ .tag = @enumFromInt(2327), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vvvmvl + .{ .tag = @enumFromInt(2328), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivul_vvvvl + .{ .tag = @enumFromInt(2329), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vsvl + .{ .tag = @enumFromInt(2330), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vsvmvl + .{ .tag = @enumFromInt(2331), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vsvvl + .{ .tag = @enumFromInt(2332), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vvsl + .{ .tag = @enumFromInt(2333), .properties = .{ .param_str = "V256dV256dUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vvsmvl + .{ .tag = @enumFromInt(2334), .properties = .{ .param_str = "V256dV256dUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vvsvl + .{ .tag = @enumFromInt(2335), .properties = .{ .param_str = "V256dV256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vvvl + .{ .tag = @enumFromInt(2336), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vvvmvl + .{ .tag = @enumFromInt(2337), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vdivuw_vvvvl + .{ .tag = @enumFromInt(2338), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_veqv_vsvl + .{ .tag = @enumFromInt(2339), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_veqv_vsvmvl + .{ .tag = @enumFromInt(2340), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_veqv_vsvvl + .{ .tag = @enumFromInt(2341), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_veqv_vvvl + .{ .tag = @enumFromInt(2342), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_veqv_vvvmvl + .{ .tag = @enumFromInt(2343), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_veqv_vvvvl + .{ .tag = @enumFromInt(2344), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vex_vvmvl + .{ .tag = @enumFromInt(2345), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfaddd_vsvl + .{ .tag = @enumFromInt(2346), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfaddd_vsvmvl + .{ .tag = @enumFromInt(2347), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfaddd_vsvvl + .{ .tag = @enumFromInt(2348), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfaddd_vvvl + .{ .tag = @enumFromInt(2349), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfaddd_vvvmvl + .{ .tag = @enumFromInt(2350), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfaddd_vvvvl + .{ .tag = @enumFromInt(2351), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfadds_vsvl + .{ .tag = @enumFromInt(2352), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfadds_vsvmvl + .{ .tag = @enumFromInt(2353), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfadds_vsvvl + .{ .tag = @enumFromInt(2354), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfadds_vvvl + .{ .tag = @enumFromInt(2355), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfadds_vvvmvl + .{ .tag = @enumFromInt(2356), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfadds_vvvvl + .{ .tag = @enumFromInt(2357), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmpd_vsvl + .{ .tag = @enumFromInt(2358), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmpd_vsvmvl + .{ .tag = @enumFromInt(2359), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmpd_vsvvl + .{ .tag = @enumFromInt(2360), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmpd_vvvl + .{ .tag = @enumFromInt(2361), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmpd_vvvmvl + .{ .tag = @enumFromInt(2362), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmpd_vvvvl + .{ .tag = @enumFromInt(2363), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmps_vsvl + .{ .tag = @enumFromInt(2364), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmps_vsvmvl + .{ .tag = @enumFromInt(2365), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmps_vsvvl + .{ .tag = @enumFromInt(2366), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmps_vvvl + .{ .tag = @enumFromInt(2367), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmps_vvvmvl + .{ .tag = @enumFromInt(2368), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfcmps_vvvvl + .{ .tag = @enumFromInt(2369), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivd_vsvl + .{ .tag = @enumFromInt(2370), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivd_vsvmvl + .{ .tag = @enumFromInt(2371), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivd_vsvvl + .{ .tag = @enumFromInt(2372), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivd_vvvl + .{ .tag = @enumFromInt(2373), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivd_vvvmvl + .{ .tag = @enumFromInt(2374), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivd_vvvvl + .{ .tag = @enumFromInt(2375), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivs_vsvl + .{ .tag = @enumFromInt(2376), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivs_vsvmvl + .{ .tag = @enumFromInt(2377), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivs_vsvvl + .{ .tag = @enumFromInt(2378), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivs_vvvl + .{ .tag = @enumFromInt(2379), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivs_vvvmvl + .{ .tag = @enumFromInt(2380), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfdivs_vvvvl + .{ .tag = @enumFromInt(2381), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vsvvl + .{ .tag = @enumFromInt(2382), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vsvvmvl + .{ .tag = @enumFromInt(2383), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vsvvvl + .{ .tag = @enumFromInt(2384), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vvsvl + .{ .tag = @enumFromInt(2385), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vvsvmvl + .{ .tag = @enumFromInt(2386), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vvsvvl + .{ .tag = @enumFromInt(2387), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vvvvl + .{ .tag = @enumFromInt(2388), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vvvvmvl + .{ .tag = @enumFromInt(2389), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmadd_vvvvvl + .{ .tag = @enumFromInt(2390), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vsvvl + .{ .tag = @enumFromInt(2391), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vsvvmvl + .{ .tag = @enumFromInt(2392), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vsvvvl + .{ .tag = @enumFromInt(2393), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vvsvl + .{ .tag = @enumFromInt(2394), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vvsvmvl + .{ .tag = @enumFromInt(2395), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vvsvvl + .{ .tag = @enumFromInt(2396), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vvvvl + .{ .tag = @enumFromInt(2397), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vvvvmvl + .{ .tag = @enumFromInt(2398), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmads_vvvvvl + .{ .tag = @enumFromInt(2399), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxd_vsvl + .{ .tag = @enumFromInt(2400), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxd_vsvmvl + .{ .tag = @enumFromInt(2401), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxd_vsvvl + .{ .tag = @enumFromInt(2402), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxd_vvvl + .{ .tag = @enumFromInt(2403), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxd_vvvmvl + .{ .tag = @enumFromInt(2404), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxd_vvvvl + .{ .tag = @enumFromInt(2405), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxs_vsvl + .{ .tag = @enumFromInt(2406), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxs_vsvmvl + .{ .tag = @enumFromInt(2407), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxs_vsvvl + .{ .tag = @enumFromInt(2408), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxs_vvvl + .{ .tag = @enumFromInt(2409), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxs_vvvmvl + .{ .tag = @enumFromInt(2410), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmaxs_vvvvl + .{ .tag = @enumFromInt(2411), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmind_vsvl + .{ .tag = @enumFromInt(2412), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmind_vsvmvl + .{ .tag = @enumFromInt(2413), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmind_vsvvl + .{ .tag = @enumFromInt(2414), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmind_vvvl + .{ .tag = @enumFromInt(2415), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmind_vvvmvl + .{ .tag = @enumFromInt(2416), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmind_vvvvl + .{ .tag = @enumFromInt(2417), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmins_vsvl + .{ .tag = @enumFromInt(2418), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmins_vsvmvl + .{ .tag = @enumFromInt(2419), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmins_vsvvl + .{ .tag = @enumFromInt(2420), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmins_vvvl + .{ .tag = @enumFromInt(2421), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmins_vvvmvl + .{ .tag = @enumFromInt(2422), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmins_vvvvl + .{ .tag = @enumFromInt(2423), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdeq_mvl + .{ .tag = @enumFromInt(2424), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdeq_mvml + .{ .tag = @enumFromInt(2425), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdeqnan_mvl + .{ .tag = @enumFromInt(2426), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdeqnan_mvml + .{ .tag = @enumFromInt(2427), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdge_mvl + .{ .tag = @enumFromInt(2428), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdge_mvml + .{ .tag = @enumFromInt(2429), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdgenan_mvl + .{ .tag = @enumFromInt(2430), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdgenan_mvml + .{ .tag = @enumFromInt(2431), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdgt_mvl + .{ .tag = @enumFromInt(2432), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdgt_mvml + .{ .tag = @enumFromInt(2433), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdgtnan_mvl + .{ .tag = @enumFromInt(2434), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdgtnan_mvml + .{ .tag = @enumFromInt(2435), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdle_mvl + .{ .tag = @enumFromInt(2436), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdle_mvml + .{ .tag = @enumFromInt(2437), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdlenan_mvl + .{ .tag = @enumFromInt(2438), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdlenan_mvml + .{ .tag = @enumFromInt(2439), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdlt_mvl + .{ .tag = @enumFromInt(2440), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdlt_mvml + .{ .tag = @enumFromInt(2441), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdltnan_mvl + .{ .tag = @enumFromInt(2442), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdltnan_mvml + .{ .tag = @enumFromInt(2443), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdnan_mvl + .{ .tag = @enumFromInt(2444), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdnan_mvml + .{ .tag = @enumFromInt(2445), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdne_mvl + .{ .tag = @enumFromInt(2446), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdne_mvml + .{ .tag = @enumFromInt(2447), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdnenan_mvl + .{ .tag = @enumFromInt(2448), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdnenan_mvml + .{ .tag = @enumFromInt(2449), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdnum_mvl + .{ .tag = @enumFromInt(2450), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkdnum_mvml + .{ .tag = @enumFromInt(2451), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklaf_ml + .{ .tag = @enumFromInt(2452), .properties = .{ .param_str = "V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklat_ml + .{ .tag = @enumFromInt(2453), .properties = .{ .param_str = "V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkleq_mvl + .{ .tag = @enumFromInt(2454), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkleq_mvml + .{ .tag = @enumFromInt(2455), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkleqnan_mvl + .{ .tag = @enumFromInt(2456), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkleqnan_mvml + .{ .tag = @enumFromInt(2457), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklge_mvl + .{ .tag = @enumFromInt(2458), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklge_mvml + .{ .tag = @enumFromInt(2459), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklgenan_mvl + .{ .tag = @enumFromInt(2460), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklgenan_mvml + .{ .tag = @enumFromInt(2461), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklgt_mvl + .{ .tag = @enumFromInt(2462), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklgt_mvml + .{ .tag = @enumFromInt(2463), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklgtnan_mvl + .{ .tag = @enumFromInt(2464), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklgtnan_mvml + .{ .tag = @enumFromInt(2465), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklle_mvl + .{ .tag = @enumFromInt(2466), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklle_mvml + .{ .tag = @enumFromInt(2467), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkllenan_mvl + .{ .tag = @enumFromInt(2468), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkllenan_mvml + .{ .tag = @enumFromInt(2469), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkllt_mvl + .{ .tag = @enumFromInt(2470), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkllt_mvml + .{ .tag = @enumFromInt(2471), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklltnan_mvl + .{ .tag = @enumFromInt(2472), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklltnan_mvml + .{ .tag = @enumFromInt(2473), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklnan_mvl + .{ .tag = @enumFromInt(2474), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklnan_mvml + .{ .tag = @enumFromInt(2475), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklne_mvl + .{ .tag = @enumFromInt(2476), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklne_mvml + .{ .tag = @enumFromInt(2477), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklnenan_mvl + .{ .tag = @enumFromInt(2478), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklnenan_mvml + .{ .tag = @enumFromInt(2479), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklnum_mvl + .{ .tag = @enumFromInt(2480), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmklnum_mvml + .{ .tag = @enumFromInt(2481), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkseq_mvl + .{ .tag = @enumFromInt(2482), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkseq_mvml + .{ .tag = @enumFromInt(2483), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkseqnan_mvl + .{ .tag = @enumFromInt(2484), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkseqnan_mvml + .{ .tag = @enumFromInt(2485), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksge_mvl + .{ .tag = @enumFromInt(2486), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksge_mvml + .{ .tag = @enumFromInt(2487), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksgenan_mvl + .{ .tag = @enumFromInt(2488), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksgenan_mvml + .{ .tag = @enumFromInt(2489), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksgt_mvl + .{ .tag = @enumFromInt(2490), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksgt_mvml + .{ .tag = @enumFromInt(2491), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksgtnan_mvl + .{ .tag = @enumFromInt(2492), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksgtnan_mvml + .{ .tag = @enumFromInt(2493), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksle_mvl + .{ .tag = @enumFromInt(2494), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksle_mvml + .{ .tag = @enumFromInt(2495), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkslenan_mvl + .{ .tag = @enumFromInt(2496), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkslenan_mvml + .{ .tag = @enumFromInt(2497), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkslt_mvl + .{ .tag = @enumFromInt(2498), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkslt_mvml + .{ .tag = @enumFromInt(2499), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksltnan_mvl + .{ .tag = @enumFromInt(2500), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksltnan_mvml + .{ .tag = @enumFromInt(2501), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksnan_mvl + .{ .tag = @enumFromInt(2502), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksnan_mvml + .{ .tag = @enumFromInt(2503), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksne_mvl + .{ .tag = @enumFromInt(2504), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksne_mvml + .{ .tag = @enumFromInt(2505), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksnenan_mvl + .{ .tag = @enumFromInt(2506), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksnenan_mvml + .{ .tag = @enumFromInt(2507), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksnum_mvl + .{ .tag = @enumFromInt(2508), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmksnum_mvml + .{ .tag = @enumFromInt(2509), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkweq_mvl + .{ .tag = @enumFromInt(2510), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkweq_mvml + .{ .tag = @enumFromInt(2511), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkweqnan_mvl + .{ .tag = @enumFromInt(2512), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkweqnan_mvml + .{ .tag = @enumFromInt(2513), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwge_mvl + .{ .tag = @enumFromInt(2514), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwge_mvml + .{ .tag = @enumFromInt(2515), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwgenan_mvl + .{ .tag = @enumFromInt(2516), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwgenan_mvml + .{ .tag = @enumFromInt(2517), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwgt_mvl + .{ .tag = @enumFromInt(2518), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwgt_mvml + .{ .tag = @enumFromInt(2519), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwgtnan_mvl + .{ .tag = @enumFromInt(2520), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwgtnan_mvml + .{ .tag = @enumFromInt(2521), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwle_mvl + .{ .tag = @enumFromInt(2522), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwle_mvml + .{ .tag = @enumFromInt(2523), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwlenan_mvl + .{ .tag = @enumFromInt(2524), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwlenan_mvml + .{ .tag = @enumFromInt(2525), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwlt_mvl + .{ .tag = @enumFromInt(2526), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwlt_mvml + .{ .tag = @enumFromInt(2527), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwltnan_mvl + .{ .tag = @enumFromInt(2528), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwltnan_mvml + .{ .tag = @enumFromInt(2529), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwnan_mvl + .{ .tag = @enumFromInt(2530), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwnan_mvml + .{ .tag = @enumFromInt(2531), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwne_mvl + .{ .tag = @enumFromInt(2532), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwne_mvml + .{ .tag = @enumFromInt(2533), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwnenan_mvl + .{ .tag = @enumFromInt(2534), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwnenan_mvml + .{ .tag = @enumFromInt(2535), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwnum_mvl + .{ .tag = @enumFromInt(2536), .properties = .{ .param_str = "V256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmkwnum_mvml + .{ .tag = @enumFromInt(2537), .properties = .{ .param_str = "V256bV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vsvvl + .{ .tag = @enumFromInt(2538), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vsvvmvl + .{ .tag = @enumFromInt(2539), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vsvvvl + .{ .tag = @enumFromInt(2540), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vvsvl + .{ .tag = @enumFromInt(2541), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vvsvmvl + .{ .tag = @enumFromInt(2542), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vvsvvl + .{ .tag = @enumFromInt(2543), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vvvvl + .{ .tag = @enumFromInt(2544), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vvvvmvl + .{ .tag = @enumFromInt(2545), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbd_vvvvvl + .{ .tag = @enumFromInt(2546), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vsvvl + .{ .tag = @enumFromInt(2547), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vsvvmvl + .{ .tag = @enumFromInt(2548), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vsvvvl + .{ .tag = @enumFromInt(2549), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vvsvl + .{ .tag = @enumFromInt(2550), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vvsvmvl + .{ .tag = @enumFromInt(2551), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vvsvvl + .{ .tag = @enumFromInt(2552), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vvvvl + .{ .tag = @enumFromInt(2553), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vvvvmvl + .{ .tag = @enumFromInt(2554), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmsbs_vvvvvl + .{ .tag = @enumFromInt(2555), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuld_vsvl + .{ .tag = @enumFromInt(2556), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuld_vsvmvl + .{ .tag = @enumFromInt(2557), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuld_vsvvl + .{ .tag = @enumFromInt(2558), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuld_vvvl + .{ .tag = @enumFromInt(2559), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuld_vvvmvl + .{ .tag = @enumFromInt(2560), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuld_vvvvl + .{ .tag = @enumFromInt(2561), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuls_vsvl + .{ .tag = @enumFromInt(2562), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuls_vsvmvl + .{ .tag = @enumFromInt(2563), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuls_vsvvl + .{ .tag = @enumFromInt(2564), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuls_vvvl + .{ .tag = @enumFromInt(2565), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuls_vvvmvl + .{ .tag = @enumFromInt(2566), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfmuls_vvvvl + .{ .tag = @enumFromInt(2567), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vsvvl + .{ .tag = @enumFromInt(2568), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vsvvmvl + .{ .tag = @enumFromInt(2569), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vsvvvl + .{ .tag = @enumFromInt(2570), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vvsvl + .{ .tag = @enumFromInt(2571), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vvsvmvl + .{ .tag = @enumFromInt(2572), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vvsvvl + .{ .tag = @enumFromInt(2573), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vvvvl + .{ .tag = @enumFromInt(2574), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vvvvmvl + .{ .tag = @enumFromInt(2575), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmadd_vvvvvl + .{ .tag = @enumFromInt(2576), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vsvvl + .{ .tag = @enumFromInt(2577), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vsvvmvl + .{ .tag = @enumFromInt(2578), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vsvvvl + .{ .tag = @enumFromInt(2579), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vvsvl + .{ .tag = @enumFromInt(2580), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vvsvmvl + .{ .tag = @enumFromInt(2581), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vvsvvl + .{ .tag = @enumFromInt(2582), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vvvvl + .{ .tag = @enumFromInt(2583), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vvvvmvl + .{ .tag = @enumFromInt(2584), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmads_vvvvvl + .{ .tag = @enumFromInt(2585), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vsvvl + .{ .tag = @enumFromInt(2586), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vsvvmvl + .{ .tag = @enumFromInt(2587), .properties = .{ .param_str = "V256ddV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vsvvvl + .{ .tag = @enumFromInt(2588), .properties = .{ .param_str = "V256ddV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vvsvl + .{ .tag = @enumFromInt(2589), .properties = .{ .param_str = "V256dV256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vvsvmvl + .{ .tag = @enumFromInt(2590), .properties = .{ .param_str = "V256dV256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vvsvvl + .{ .tag = @enumFromInt(2591), .properties = .{ .param_str = "V256dV256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vvvvl + .{ .tag = @enumFromInt(2592), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vvvvmvl + .{ .tag = @enumFromInt(2593), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbd_vvvvvl + .{ .tag = @enumFromInt(2594), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vsvvl + .{ .tag = @enumFromInt(2595), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vsvvmvl + .{ .tag = @enumFromInt(2596), .properties = .{ .param_str = "V256dfV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vsvvvl + .{ .tag = @enumFromInt(2597), .properties = .{ .param_str = "V256dfV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vvsvl + .{ .tag = @enumFromInt(2598), .properties = .{ .param_str = "V256dV256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vvsvmvl + .{ .tag = @enumFromInt(2599), .properties = .{ .param_str = "V256dV256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vvsvvl + .{ .tag = @enumFromInt(2600), .properties = .{ .param_str = "V256dV256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vvvvl + .{ .tag = @enumFromInt(2601), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vvvvmvl + .{ .tag = @enumFromInt(2602), .properties = .{ .param_str = "V256dV256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfnmsbs_vvvvvl + .{ .tag = @enumFromInt(2603), .properties = .{ .param_str = "V256dV256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxdfst_vvl + .{ .tag = @enumFromInt(2604), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxdfst_vvvl + .{ .tag = @enumFromInt(2605), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxdlst_vvl + .{ .tag = @enumFromInt(2606), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxdlst_vvvl + .{ .tag = @enumFromInt(2607), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxsfst_vvl + .{ .tag = @enumFromInt(2608), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxsfst_vvvl + .{ .tag = @enumFromInt(2609), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxslst_vvl + .{ .tag = @enumFromInt(2610), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmaxslst_vvvl + .{ .tag = @enumFromInt(2611), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmindfst_vvl + .{ .tag = @enumFromInt(2612), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmindfst_vvvl + .{ .tag = @enumFromInt(2613), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmindlst_vvl + .{ .tag = @enumFromInt(2614), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrmindlst_vvvl + .{ .tag = @enumFromInt(2615), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrminsfst_vvl + .{ .tag = @enumFromInt(2616), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrminsfst_vvvl + .{ .tag = @enumFromInt(2617), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrminslst_vvl + .{ .tag = @enumFromInt(2618), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfrminslst_vvvl + .{ .tag = @enumFromInt(2619), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsqrtd_vvl + .{ .tag = @enumFromInt(2620), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsqrtd_vvvl + .{ .tag = @enumFromInt(2621), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsqrts_vvl + .{ .tag = @enumFromInt(2622), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsqrts_vvvl + .{ .tag = @enumFromInt(2623), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubd_vsvl + .{ .tag = @enumFromInt(2624), .properties = .{ .param_str = "V256ddV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubd_vsvmvl + .{ .tag = @enumFromInt(2625), .properties = .{ .param_str = "V256ddV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubd_vsvvl + .{ .tag = @enumFromInt(2626), .properties = .{ .param_str = "V256ddV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubd_vvvl + .{ .tag = @enumFromInt(2627), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubd_vvvmvl + .{ .tag = @enumFromInt(2628), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubd_vvvvl + .{ .tag = @enumFromInt(2629), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubs_vsvl + .{ .tag = @enumFromInt(2630), .properties = .{ .param_str = "V256dfV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubs_vsvmvl + .{ .tag = @enumFromInt(2631), .properties = .{ .param_str = "V256dfV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubs_vsvvl + .{ .tag = @enumFromInt(2632), .properties = .{ .param_str = "V256dfV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubs_vvvl + .{ .tag = @enumFromInt(2633), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubs_vvvmvl + .{ .tag = @enumFromInt(2634), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsubs_vvvvl + .{ .tag = @enumFromInt(2635), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsumd_vvl + .{ .tag = @enumFromInt(2636), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsumd_vvml + .{ .tag = @enumFromInt(2637), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsums_vvl + .{ .tag = @enumFromInt(2638), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vfsums_vvml + .{ .tag = @enumFromInt(2639), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgt_vvssl + .{ .tag = @enumFromInt(2640), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgt_vvssml + .{ .tag = @enumFromInt(2641), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgt_vvssmvl + .{ .tag = @enumFromInt(2642), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgt_vvssvl + .{ .tag = @enumFromInt(2643), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsx_vvssl + .{ .tag = @enumFromInt(2644), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsx_vvssml + .{ .tag = @enumFromInt(2645), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsx_vvssmvl + .{ .tag = @enumFromInt(2646), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsx_vvssvl + .{ .tag = @enumFromInt(2647), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsxnc_vvssl + .{ .tag = @enumFromInt(2648), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsxnc_vvssml + .{ .tag = @enumFromInt(2649), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsxnc_vvssmvl + .{ .tag = @enumFromInt(2650), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlsxnc_vvssvl + .{ .tag = @enumFromInt(2651), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzx_vvssl + .{ .tag = @enumFromInt(2652), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzx_vvssml + .{ .tag = @enumFromInt(2653), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzx_vvssmvl + .{ .tag = @enumFromInt(2654), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzx_vvssvl + .{ .tag = @enumFromInt(2655), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzxnc_vvssl + .{ .tag = @enumFromInt(2656), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzxnc_vvssml + .{ .tag = @enumFromInt(2657), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzxnc_vvssmvl + .{ .tag = @enumFromInt(2658), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtlzxnc_vvssvl + .{ .tag = @enumFromInt(2659), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtnc_vvssl + .{ .tag = @enumFromInt(2660), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtnc_vvssml + .{ .tag = @enumFromInt(2661), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtnc_vvssmvl + .{ .tag = @enumFromInt(2662), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtnc_vvssvl + .{ .tag = @enumFromInt(2663), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtu_vvssl + .{ .tag = @enumFromInt(2664), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtu_vvssml + .{ .tag = @enumFromInt(2665), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtu_vvssmvl + .{ .tag = @enumFromInt(2666), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtu_vvssvl + .{ .tag = @enumFromInt(2667), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtunc_vvssl + .{ .tag = @enumFromInt(2668), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtunc_vvssml + .{ .tag = @enumFromInt(2669), .properties = .{ .param_str = "V256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtunc_vvssmvl + .{ .tag = @enumFromInt(2670), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vgtunc_vvssvl + .{ .tag = @enumFromInt(2671), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vld2d_vssl + .{ .tag = @enumFromInt(2672), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vld2d_vssvl + .{ .tag = @enumFromInt(2673), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vld2dnc_vssl + .{ .tag = @enumFromInt(2674), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vld2dnc_vssvl + .{ .tag = @enumFromInt(2675), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vld_vssl + .{ .tag = @enumFromInt(2676), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vld_vssvl + .{ .tag = @enumFromInt(2677), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dsx_vssl + .{ .tag = @enumFromInt(2678), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dsx_vssvl + .{ .tag = @enumFromInt(2679), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dsxnc_vssl + .{ .tag = @enumFromInt(2680), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dsxnc_vssvl + .{ .tag = @enumFromInt(2681), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dzx_vssl + .{ .tag = @enumFromInt(2682), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dzx_vssvl + .{ .tag = @enumFromInt(2683), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dzxnc_vssl + .{ .tag = @enumFromInt(2684), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldl2dzxnc_vssvl + .{ .tag = @enumFromInt(2685), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlsx_vssl + .{ .tag = @enumFromInt(2686), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlsx_vssvl + .{ .tag = @enumFromInt(2687), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlsxnc_vssl + .{ .tag = @enumFromInt(2688), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlsxnc_vssvl + .{ .tag = @enumFromInt(2689), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlzx_vssl + .{ .tag = @enumFromInt(2690), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlzx_vssvl + .{ .tag = @enumFromInt(2691), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlzxnc_vssl + .{ .tag = @enumFromInt(2692), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldlzxnc_vssvl + .{ .tag = @enumFromInt(2693), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldnc_vssl + .{ .tag = @enumFromInt(2694), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldnc_vssvl + .{ .tag = @enumFromInt(2695), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldu2d_vssl + .{ .tag = @enumFromInt(2696), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldu2d_vssvl + .{ .tag = @enumFromInt(2697), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldu2dnc_vssl + .{ .tag = @enumFromInt(2698), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldu2dnc_vssvl + .{ .tag = @enumFromInt(2699), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldu_vssl + .{ .tag = @enumFromInt(2700), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldu_vssvl + .{ .tag = @enumFromInt(2701), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldunc_vssl + .{ .tag = @enumFromInt(2702), .properties = .{ .param_str = "V256dLUivC*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldunc_vssvl + .{ .tag = @enumFromInt(2703), .properties = .{ .param_str = "V256dLUivC*V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldz_vvl + .{ .tag = @enumFromInt(2704), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldz_vvmvl + .{ .tag = @enumFromInt(2705), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vldz_vvvl + .{ .tag = @enumFromInt(2706), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxsl_vsvl + .{ .tag = @enumFromInt(2707), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxsl_vsvmvl + .{ .tag = @enumFromInt(2708), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxsl_vsvvl + .{ .tag = @enumFromInt(2709), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxsl_vvvl + .{ .tag = @enumFromInt(2710), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxsl_vvvmvl + .{ .tag = @enumFromInt(2711), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxsl_vvvvl + .{ .tag = @enumFromInt(2712), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswsx_vsvl + .{ .tag = @enumFromInt(2713), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswsx_vsvmvl + .{ .tag = @enumFromInt(2714), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswsx_vsvvl + .{ .tag = @enumFromInt(2715), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswsx_vvvl + .{ .tag = @enumFromInt(2716), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswsx_vvvmvl + .{ .tag = @enumFromInt(2717), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswsx_vvvvl + .{ .tag = @enumFromInt(2718), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswzx_vsvl + .{ .tag = @enumFromInt(2719), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswzx_vsvmvl + .{ .tag = @enumFromInt(2720), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswzx_vsvvl + .{ .tag = @enumFromInt(2721), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswzx_vvvl + .{ .tag = @enumFromInt(2722), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswzx_vvvmvl + .{ .tag = @enumFromInt(2723), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmaxswzx_vvvvl + .{ .tag = @enumFromInt(2724), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminsl_vsvl + .{ .tag = @enumFromInt(2725), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminsl_vsvmvl + .{ .tag = @enumFromInt(2726), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminsl_vsvvl + .{ .tag = @enumFromInt(2727), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminsl_vvvl + .{ .tag = @enumFromInt(2728), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminsl_vvvmvl + .{ .tag = @enumFromInt(2729), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminsl_vvvvl + .{ .tag = @enumFromInt(2730), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswsx_vsvl + .{ .tag = @enumFromInt(2731), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswsx_vsvmvl + .{ .tag = @enumFromInt(2732), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswsx_vsvvl + .{ .tag = @enumFromInt(2733), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswsx_vvvl + .{ .tag = @enumFromInt(2734), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswsx_vvvmvl + .{ .tag = @enumFromInt(2735), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswsx_vvvvl + .{ .tag = @enumFromInt(2736), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswzx_vsvl + .{ .tag = @enumFromInt(2737), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswzx_vsvmvl + .{ .tag = @enumFromInt(2738), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswzx_vsvvl + .{ .tag = @enumFromInt(2739), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswzx_vvvl + .{ .tag = @enumFromInt(2740), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswzx_vvvmvl + .{ .tag = @enumFromInt(2741), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vminswzx_vvvvl + .{ .tag = @enumFromInt(2742), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrg_vsvml + .{ .tag = @enumFromInt(2743), .properties = .{ .param_str = "V256dLUiV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrg_vsvmvl + .{ .tag = @enumFromInt(2744), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrg_vvvml + .{ .tag = @enumFromInt(2745), .properties = .{ .param_str = "V256dV256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrg_vvvmvl + .{ .tag = @enumFromInt(2746), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrgw_vsvMl + .{ .tag = @enumFromInt(2747), .properties = .{ .param_str = "V256dUiV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrgw_vsvMvl + .{ .tag = @enumFromInt(2748), .properties = .{ .param_str = "V256dUiV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrgw_vvvMl + .{ .tag = @enumFromInt(2749), .properties = .{ .param_str = "V256dV256dV256dV512bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmrgw_vvvMvl + .{ .tag = @enumFromInt(2750), .properties = .{ .param_str = "V256dV256dV256dV512bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulsl_vsvl + .{ .tag = @enumFromInt(2751), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulsl_vsvmvl + .{ .tag = @enumFromInt(2752), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulsl_vsvvl + .{ .tag = @enumFromInt(2753), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulsl_vvvl + .{ .tag = @enumFromInt(2754), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulsl_vvvmvl + .{ .tag = @enumFromInt(2755), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulsl_vvvvl + .{ .tag = @enumFromInt(2756), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulslw_vsvl + .{ .tag = @enumFromInt(2757), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulslw_vsvvl + .{ .tag = @enumFromInt(2758), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulslw_vvvl + .{ .tag = @enumFromInt(2759), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulslw_vvvvl + .{ .tag = @enumFromInt(2760), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswsx_vsvl + .{ .tag = @enumFromInt(2761), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswsx_vsvmvl + .{ .tag = @enumFromInt(2762), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswsx_vsvvl + .{ .tag = @enumFromInt(2763), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswsx_vvvl + .{ .tag = @enumFromInt(2764), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswsx_vvvmvl + .{ .tag = @enumFromInt(2765), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswsx_vvvvl + .{ .tag = @enumFromInt(2766), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswzx_vsvl + .{ .tag = @enumFromInt(2767), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswzx_vsvmvl + .{ .tag = @enumFromInt(2768), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswzx_vsvvl + .{ .tag = @enumFromInt(2769), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswzx_vvvl + .{ .tag = @enumFromInt(2770), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswzx_vvvmvl + .{ .tag = @enumFromInt(2771), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulswzx_vvvvl + .{ .tag = @enumFromInt(2772), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulul_vsvl + .{ .tag = @enumFromInt(2773), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulul_vsvmvl + .{ .tag = @enumFromInt(2774), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulul_vsvvl + .{ .tag = @enumFromInt(2775), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulul_vvvl + .{ .tag = @enumFromInt(2776), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulul_vvvmvl + .{ .tag = @enumFromInt(2777), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmulul_vvvvl + .{ .tag = @enumFromInt(2778), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmuluw_vsvl + .{ .tag = @enumFromInt(2779), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmuluw_vsvmvl + .{ .tag = @enumFromInt(2780), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmuluw_vsvvl + .{ .tag = @enumFromInt(2781), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmuluw_vvvl + .{ .tag = @enumFromInt(2782), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmuluw_vvvmvl + .{ .tag = @enumFromInt(2783), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmuluw_vvvvl + .{ .tag = @enumFromInt(2784), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmv_vsvl + .{ .tag = @enumFromInt(2785), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmv_vsvmvl + .{ .tag = @enumFromInt(2786), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vmv_vsvvl + .{ .tag = @enumFromInt(2787), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vor_vsvl + .{ .tag = @enumFromInt(2788), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vor_vsvmvl + .{ .tag = @enumFromInt(2789), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vor_vsvvl + .{ .tag = @enumFromInt(2790), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vor_vvvl + .{ .tag = @enumFromInt(2791), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vor_vvvmvl + .{ .tag = @enumFromInt(2792), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vor_vvvvl + .{ .tag = @enumFromInt(2793), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vpcnt_vvl + .{ .tag = @enumFromInt(2794), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vpcnt_vvmvl + .{ .tag = @enumFromInt(2795), .properties = .{ .param_str = "V256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vpcnt_vvvl + .{ .tag = @enumFromInt(2796), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrand_vvl + .{ .tag = @enumFromInt(2797), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrand_vvml + .{ .tag = @enumFromInt(2798), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrcpd_vvl + .{ .tag = @enumFromInt(2799), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrcpd_vvvl + .{ .tag = @enumFromInt(2800), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrcps_vvl + .{ .tag = @enumFromInt(2801), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrcps_vvvl + .{ .tag = @enumFromInt(2802), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxslfst_vvl + .{ .tag = @enumFromInt(2803), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxslfst_vvvl + .{ .tag = @enumFromInt(2804), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxsllst_vvl + .{ .tag = @enumFromInt(2805), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxsllst_vvvl + .{ .tag = @enumFromInt(2806), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswfstsx_vvl + .{ .tag = @enumFromInt(2807), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswfstsx_vvvl + .{ .tag = @enumFromInt(2808), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswfstzx_vvl + .{ .tag = @enumFromInt(2809), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswfstzx_vvvl + .{ .tag = @enumFromInt(2810), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswlstsx_vvl + .{ .tag = @enumFromInt(2811), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswlstsx_vvvl + .{ .tag = @enumFromInt(2812), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswlstzx_vvl + .{ .tag = @enumFromInt(2813), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrmaxswlstzx_vvvl + .{ .tag = @enumFromInt(2814), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminslfst_vvl + .{ .tag = @enumFromInt(2815), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminslfst_vvvl + .{ .tag = @enumFromInt(2816), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminsllst_vvl + .{ .tag = @enumFromInt(2817), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminsllst_vvvl + .{ .tag = @enumFromInt(2818), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswfstsx_vvl + .{ .tag = @enumFromInt(2819), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswfstsx_vvvl + .{ .tag = @enumFromInt(2820), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswfstzx_vvl + .{ .tag = @enumFromInt(2821), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswfstzx_vvvl + .{ .tag = @enumFromInt(2822), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswlstsx_vvl + .{ .tag = @enumFromInt(2823), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswlstsx_vvvl + .{ .tag = @enumFromInt(2824), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswlstzx_vvl + .{ .tag = @enumFromInt(2825), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrminswlstzx_vvvl + .{ .tag = @enumFromInt(2826), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vror_vvl + .{ .tag = @enumFromInt(2827), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vror_vvml + .{ .tag = @enumFromInt(2828), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrtd_vvl + .{ .tag = @enumFromInt(2829), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrtd_vvvl + .{ .tag = @enumFromInt(2830), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrtdnex_vvl + .{ .tag = @enumFromInt(2831), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrtdnex_vvvl + .{ .tag = @enumFromInt(2832), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrts_vvl + .{ .tag = @enumFromInt(2833), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrts_vvvl + .{ .tag = @enumFromInt(2834), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrtsnex_vvl + .{ .tag = @enumFromInt(2835), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrsqrtsnex_vvvl + .{ .tag = @enumFromInt(2836), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrxor_vvl + .{ .tag = @enumFromInt(2837), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vrxor_vvml + .{ .tag = @enumFromInt(2838), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsc_vvssl + .{ .tag = @enumFromInt(2839), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsc_vvssml + .{ .tag = @enumFromInt(2840), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscl_vvssl + .{ .tag = @enumFromInt(2841), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscl_vvssml + .{ .tag = @enumFromInt(2842), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsclnc_vvssl + .{ .tag = @enumFromInt(2843), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsclnc_vvssml + .{ .tag = @enumFromInt(2844), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsclncot_vvssl + .{ .tag = @enumFromInt(2845), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsclncot_vvssml + .{ .tag = @enumFromInt(2846), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsclot_vvssl + .{ .tag = @enumFromInt(2847), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsclot_vvssml + .{ .tag = @enumFromInt(2848), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscnc_vvssl + .{ .tag = @enumFromInt(2849), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscnc_vvssml + .{ .tag = @enumFromInt(2850), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscncot_vvssl + .{ .tag = @enumFromInt(2851), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscncot_vvssml + .{ .tag = @enumFromInt(2852), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscot_vvssl + .{ .tag = @enumFromInt(2853), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscot_vvssml + .{ .tag = @enumFromInt(2854), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscu_vvssl + .{ .tag = @enumFromInt(2855), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscu_vvssml + .{ .tag = @enumFromInt(2856), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscunc_vvssl + .{ .tag = @enumFromInt(2857), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscunc_vvssml + .{ .tag = @enumFromInt(2858), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscuncot_vvssl + .{ .tag = @enumFromInt(2859), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscuncot_vvssml + .{ .tag = @enumFromInt(2860), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscuot_vvssl + .{ .tag = @enumFromInt(2861), .properties = .{ .param_str = "vV256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vscuot_vvssml + .{ .tag = @enumFromInt(2862), .properties = .{ .param_str = "vV256dV256dLUiLUiV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vseq_vl + .{ .tag = @enumFromInt(2863), .properties = .{ .param_str = "V256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vseq_vvl + .{ .tag = @enumFromInt(2864), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsfa_vvssl + .{ .tag = @enumFromInt(2865), .properties = .{ .param_str = "V256dV256dLUiLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsfa_vvssmvl + .{ .tag = @enumFromInt(2866), .properties = .{ .param_str = "V256dV256dLUiLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsfa_vvssvl + .{ .tag = @enumFromInt(2867), .properties = .{ .param_str = "V256dV256dLUiLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vshf_vvvsl + .{ .tag = @enumFromInt(2868), .properties = .{ .param_str = "V256dV256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vshf_vvvsvl + .{ .tag = @enumFromInt(2869), .properties = .{ .param_str = "V256dV256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslal_vvsl + .{ .tag = @enumFromInt(2870), .properties = .{ .param_str = "V256dV256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslal_vvsmvl + .{ .tag = @enumFromInt(2871), .properties = .{ .param_str = "V256dV256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslal_vvsvl + .{ .tag = @enumFromInt(2872), .properties = .{ .param_str = "V256dV256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslal_vvvl + .{ .tag = @enumFromInt(2873), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslal_vvvmvl + .{ .tag = @enumFromInt(2874), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslal_vvvvl + .{ .tag = @enumFromInt(2875), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawsx_vvsl + .{ .tag = @enumFromInt(2876), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawsx_vvsmvl + .{ .tag = @enumFromInt(2877), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawsx_vvsvl + .{ .tag = @enumFromInt(2878), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawsx_vvvl + .{ .tag = @enumFromInt(2879), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawsx_vvvmvl + .{ .tag = @enumFromInt(2880), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawsx_vvvvl + .{ .tag = @enumFromInt(2881), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawzx_vvsl + .{ .tag = @enumFromInt(2882), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawzx_vvsmvl + .{ .tag = @enumFromInt(2883), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawzx_vvsvl + .{ .tag = @enumFromInt(2884), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawzx_vvvl + .{ .tag = @enumFromInt(2885), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawzx_vvvmvl + .{ .tag = @enumFromInt(2886), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vslawzx_vvvvl + .{ .tag = @enumFromInt(2887), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsll_vvsl + .{ .tag = @enumFromInt(2888), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsll_vvsmvl + .{ .tag = @enumFromInt(2889), .properties = .{ .param_str = "V256dV256dLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsll_vvsvl + .{ .tag = @enumFromInt(2890), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsll_vvvl + .{ .tag = @enumFromInt(2891), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsll_vvvmvl + .{ .tag = @enumFromInt(2892), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsll_vvvvl + .{ .tag = @enumFromInt(2893), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsral_vvsl + .{ .tag = @enumFromInt(2894), .properties = .{ .param_str = "V256dV256dLiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsral_vvsmvl + .{ .tag = @enumFromInt(2895), .properties = .{ .param_str = "V256dV256dLiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsral_vvsvl + .{ .tag = @enumFromInt(2896), .properties = .{ .param_str = "V256dV256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsral_vvvl + .{ .tag = @enumFromInt(2897), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsral_vvvmvl + .{ .tag = @enumFromInt(2898), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsral_vvvvl + .{ .tag = @enumFromInt(2899), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawsx_vvsl + .{ .tag = @enumFromInt(2900), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawsx_vvsmvl + .{ .tag = @enumFromInt(2901), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawsx_vvsvl + .{ .tag = @enumFromInt(2902), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawsx_vvvl + .{ .tag = @enumFromInt(2903), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawsx_vvvmvl + .{ .tag = @enumFromInt(2904), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawsx_vvvvl + .{ .tag = @enumFromInt(2905), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawzx_vvsl + .{ .tag = @enumFromInt(2906), .properties = .{ .param_str = "V256dV256diUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawzx_vvsmvl + .{ .tag = @enumFromInt(2907), .properties = .{ .param_str = "V256dV256diV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawzx_vvsvl + .{ .tag = @enumFromInt(2908), .properties = .{ .param_str = "V256dV256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawzx_vvvl + .{ .tag = @enumFromInt(2909), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawzx_vvvmvl + .{ .tag = @enumFromInt(2910), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrawzx_vvvvl + .{ .tag = @enumFromInt(2911), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrl_vvsl + .{ .tag = @enumFromInt(2912), .properties = .{ .param_str = "V256dV256dLUiUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrl_vvsmvl + .{ .tag = @enumFromInt(2913), .properties = .{ .param_str = "V256dV256dLUiV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrl_vvsvl + .{ .tag = @enumFromInt(2914), .properties = .{ .param_str = "V256dV256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrl_vvvl + .{ .tag = @enumFromInt(2915), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrl_vvvmvl + .{ .tag = @enumFromInt(2916), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsrl_vvvvl + .{ .tag = @enumFromInt(2917), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2d_vssl + .{ .tag = @enumFromInt(2918), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2d_vssml + .{ .tag = @enumFromInt(2919), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2dnc_vssl + .{ .tag = @enumFromInt(2920), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2dnc_vssml + .{ .tag = @enumFromInt(2921), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2dncot_vssl + .{ .tag = @enumFromInt(2922), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2dncot_vssml + .{ .tag = @enumFromInt(2923), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2dot_vssl + .{ .tag = @enumFromInt(2924), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst2dot_vssml + .{ .tag = @enumFromInt(2925), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst_vssl + .{ .tag = @enumFromInt(2926), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vst_vssml + .{ .tag = @enumFromInt(2927), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2d_vssl + .{ .tag = @enumFromInt(2928), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2d_vssml + .{ .tag = @enumFromInt(2929), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2dnc_vssl + .{ .tag = @enumFromInt(2930), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2dnc_vssml + .{ .tag = @enumFromInt(2931), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2dncot_vssl + .{ .tag = @enumFromInt(2932), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2dncot_vssml + .{ .tag = @enumFromInt(2933), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2dot_vssl + .{ .tag = @enumFromInt(2934), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl2dot_vssml + .{ .tag = @enumFromInt(2935), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl_vssl + .{ .tag = @enumFromInt(2936), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstl_vssml + .{ .tag = @enumFromInt(2937), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstlnc_vssl + .{ .tag = @enumFromInt(2938), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstlnc_vssml + .{ .tag = @enumFromInt(2939), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstlncot_vssl + .{ .tag = @enumFromInt(2940), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstlncot_vssml + .{ .tag = @enumFromInt(2941), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstlot_vssl + .{ .tag = @enumFromInt(2942), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstlot_vssml + .{ .tag = @enumFromInt(2943), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstnc_vssl + .{ .tag = @enumFromInt(2944), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstnc_vssml + .{ .tag = @enumFromInt(2945), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstncot_vssl + .{ .tag = @enumFromInt(2946), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstncot_vssml + .{ .tag = @enumFromInt(2947), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstot_vssl + .{ .tag = @enumFromInt(2948), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstot_vssml + .{ .tag = @enumFromInt(2949), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2d_vssl + .{ .tag = @enumFromInt(2950), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2d_vssml + .{ .tag = @enumFromInt(2951), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2dnc_vssl + .{ .tag = @enumFromInt(2952), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2dnc_vssml + .{ .tag = @enumFromInt(2953), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2dncot_vssl + .{ .tag = @enumFromInt(2954), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2dncot_vssml + .{ .tag = @enumFromInt(2955), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2dot_vssl + .{ .tag = @enumFromInt(2956), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu2dot_vssml + .{ .tag = @enumFromInt(2957), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu_vssl + .{ .tag = @enumFromInt(2958), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstu_vssml + .{ .tag = @enumFromInt(2959), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstunc_vssl + .{ .tag = @enumFromInt(2960), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstunc_vssml + .{ .tag = @enumFromInt(2961), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstuncot_vssl + .{ .tag = @enumFromInt(2962), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstuncot_vssml + .{ .tag = @enumFromInt(2963), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstuot_vssl + .{ .tag = @enumFromInt(2964), .properties = .{ .param_str = "vV256dLUiv*Ui", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vstuot_vssml + .{ .tag = @enumFromInt(2965), .properties = .{ .param_str = "vV256dLUiv*V256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubsl_vsvl + .{ .tag = @enumFromInt(2966), .properties = .{ .param_str = "V256dLiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubsl_vsvmvl + .{ .tag = @enumFromInt(2967), .properties = .{ .param_str = "V256dLiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubsl_vsvvl + .{ .tag = @enumFromInt(2968), .properties = .{ .param_str = "V256dLiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubsl_vvvl + .{ .tag = @enumFromInt(2969), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubsl_vvvmvl + .{ .tag = @enumFromInt(2970), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubsl_vvvvl + .{ .tag = @enumFromInt(2971), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswsx_vsvl + .{ .tag = @enumFromInt(2972), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswsx_vsvmvl + .{ .tag = @enumFromInt(2973), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswsx_vsvvl + .{ .tag = @enumFromInt(2974), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswsx_vvvl + .{ .tag = @enumFromInt(2975), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswsx_vvvmvl + .{ .tag = @enumFromInt(2976), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswsx_vvvvl + .{ .tag = @enumFromInt(2977), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswzx_vsvl + .{ .tag = @enumFromInt(2978), .properties = .{ .param_str = "V256diV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswzx_vsvmvl + .{ .tag = @enumFromInt(2979), .properties = .{ .param_str = "V256diV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswzx_vsvvl + .{ .tag = @enumFromInt(2980), .properties = .{ .param_str = "V256diV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswzx_vvvl + .{ .tag = @enumFromInt(2981), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswzx_vvvmvl + .{ .tag = @enumFromInt(2982), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubswzx_vvvvl + .{ .tag = @enumFromInt(2983), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubul_vsvl + .{ .tag = @enumFromInt(2984), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubul_vsvmvl + .{ .tag = @enumFromInt(2985), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubul_vsvvl + .{ .tag = @enumFromInt(2986), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubul_vvvl + .{ .tag = @enumFromInt(2987), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubul_vvvmvl + .{ .tag = @enumFromInt(2988), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubul_vvvvl + .{ .tag = @enumFromInt(2989), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubuw_vsvl + .{ .tag = @enumFromInt(2990), .properties = .{ .param_str = "V256dUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubuw_vsvmvl + .{ .tag = @enumFromInt(2991), .properties = .{ .param_str = "V256dUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubuw_vsvvl + .{ .tag = @enumFromInt(2992), .properties = .{ .param_str = "V256dUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubuw_vvvl + .{ .tag = @enumFromInt(2993), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubuw_vvvmvl + .{ .tag = @enumFromInt(2994), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsubuw_vvvvl + .{ .tag = @enumFromInt(2995), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsuml_vvl + .{ .tag = @enumFromInt(2996), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsuml_vvml + .{ .tag = @enumFromInt(2997), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsumwsx_vvl + .{ .tag = @enumFromInt(2998), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsumwsx_vvml + .{ .tag = @enumFromInt(2999), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsumwzx_vvl + .{ .tag = @enumFromInt(3000), .properties = .{ .param_str = "V256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vsumwzx_vvml + .{ .tag = @enumFromInt(3001), .properties = .{ .param_str = "V256dV256dV256bUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vxor_vsvl + .{ .tag = @enumFromInt(3002), .properties = .{ .param_str = "V256dLUiV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vxor_vsvmvl + .{ .tag = @enumFromInt(3003), .properties = .{ .param_str = "V256dLUiV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vxor_vsvvl + .{ .tag = @enumFromInt(3004), .properties = .{ .param_str = "V256dLUiV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vxor_vvvl + .{ .tag = @enumFromInt(3005), .properties = .{ .param_str = "V256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vxor_vvvmvl + .{ .tag = @enumFromInt(3006), .properties = .{ .param_str = "V256dV256dV256dV256bV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_vxor_vvvvl + .{ .tag = @enumFromInt(3007), .properties = .{ .param_str = "V256dV256dV256dV256dUi", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_xorm_MMM + .{ .tag = @enumFromInt(3008), .properties = .{ .param_str = "V512bV512bV512b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_ve_vl_xorm_mmm + .{ .tag = @enumFromInt(3009), .properties = .{ .param_str = "V256bV256bV256b", .target_set = TargetSet.initOne(.vevl_gen) } }, + // __builtin_vfprintf + .{ .tag = @enumFromInt(3010), .properties = .{ .param_str = "iP*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } }, + // __builtin_vfscanf + .{ .tag = @enumFromInt(3011), .properties = .{ .param_str = "iP*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } }, + // __builtin_vprintf + .{ .tag = @enumFromInt(3012), .properties = .{ .param_str = "icC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf } } }, + // __builtin_vscanf + .{ .tag = @enumFromInt(3013), .properties = .{ .param_str = "icC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf } } }, + // __builtin_vsnprintf + .{ .tag = @enumFromInt(3014), .properties = .{ .param_str = "ic*RzcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 2 } } }, + // __builtin_vsprintf + .{ .tag = @enumFromInt(3015), .properties = .{ .param_str = "ic*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } }, + // __builtin_vsscanf + .{ .tag = @enumFromInt(3016), .properties = .{ .param_str = "icC*RcC*Ra", .attributes = .{ .lib_function_with_builtin_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } }, + // __builtin_wasm_max_f32 + .{ .tag = @enumFromInt(3017), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_max_f64 + .{ .tag = @enumFromInt(3018), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_memory_grow + .{ .tag = @enumFromInt(3019), .properties = .{ .param_str = "zIiz", .target_set = TargetSet.initOne(.webassembly) } }, + // __builtin_wasm_memory_size + .{ .tag = @enumFromInt(3020), .properties = .{ .param_str = "zIi", .target_set = TargetSet.initOne(.webassembly) } }, + // __builtin_wasm_min_f32 + .{ .tag = @enumFromInt(3021), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_min_f64 + .{ .tag = @enumFromInt(3022), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_s_i32_f32 + .{ .tag = @enumFromInt(3023), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_s_i32_f64 + .{ .tag = @enumFromInt(3024), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_s_i64_f32 + .{ .tag = @enumFromInt(3025), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_s_i64_f64 + .{ .tag = @enumFromInt(3026), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_u_i32_f32 + .{ .tag = @enumFromInt(3027), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_u_i32_f64 + .{ .tag = @enumFromInt(3028), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_u_i64_f32 + .{ .tag = @enumFromInt(3029), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wasm_trunc_u_i64_f64 + .{ .tag = @enumFromInt(3030), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.webassembly), .attributes = .{ .@"const" = true } } }, + // __builtin_wcschr + .{ .tag = @enumFromInt(3031), .properties = .{ .param_str = "w*wC*w", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_wcscmp + .{ .tag = @enumFromInt(3032), .properties = .{ .param_str = "iwC*wC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_wcslen + .{ .tag = @enumFromInt(3033), .properties = .{ .param_str = "zwC*", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_wcsncmp + .{ .tag = @enumFromInt(3034), .properties = .{ .param_str = "iwC*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_wmemchr + .{ .tag = @enumFromInt(3035), .properties = .{ .param_str = "w*wC*wz", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_wmemcmp + .{ .tag = @enumFromInt(3036), .properties = .{ .param_str = "iwC*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_wmemcpy + .{ .tag = @enumFromInt(3037), .properties = .{ .param_str = "w*w*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __builtin_wmemmove + .{ .tag = @enumFromInt(3038), .properties = .{ .param_str = "w*w*wC*z", .attributes = .{ .lib_function_with_builtin_prefix = true, .const_evaluable = true } } }, + // __c11_atomic_compare_exchange_strong + .{ .tag = @enumFromInt(3039), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_compare_exchange_weak + .{ .tag = @enumFromInt(3040), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_exchange + .{ .tag = @enumFromInt(3041), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_add + .{ .tag = @enumFromInt(3042), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_and + .{ .tag = @enumFromInt(3043), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_max + .{ .tag = @enumFromInt(3044), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_min + .{ .tag = @enumFromInt(3045), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_nand + .{ .tag = @enumFromInt(3046), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_or + .{ .tag = @enumFromInt(3047), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_sub + .{ .tag = @enumFromInt(3048), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_fetch_xor + .{ .tag = @enumFromInt(3049), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_init + .{ .tag = @enumFromInt(3050), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_is_lock_free + .{ .tag = @enumFromInt(3051), .properties = .{ .param_str = "bz", .attributes = .{ .const_evaluable = true } } }, + // __c11_atomic_load + .{ .tag = @enumFromInt(3052), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_signal_fence + .{ .tag = @enumFromInt(3053), .properties = .{ .param_str = "vi" } }, + // __c11_atomic_store + .{ .tag = @enumFromInt(3054), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __c11_atomic_thread_fence + .{ .tag = @enumFromInt(3055), .properties = .{ .param_str = "vi" } }, + // __clear_cache + .{ .tag = @enumFromInt(3056), .properties = .{ .param_str = "vv*v*", .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __cospi + .{ .tag = @enumFromInt(3057), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __cospif + .{ .tag = @enumFromInt(3058), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __debugbreak + .{ .tag = @enumFromInt(3059), .properties = .{ .param_str = "v", .language = .all_ms_languages } }, + // __dmb + .{ .tag = @enumFromInt(3060), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __dsb + .{ .tag = @enumFromInt(3061), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __emit + .{ .tag = @enumFromInt(3062), .properties = .{ .param_str = "vIUiC", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } }, + // __exception_code + .{ .tag = @enumFromInt(3063), .properties = .{ .param_str = "UNi", .language = .all_ms_languages } }, + // __exception_info + .{ .tag = @enumFromInt(3064), .properties = .{ .param_str = "v*", .language = .all_ms_languages } }, + // __exp10 + .{ .tag = @enumFromInt(3065), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __exp10f + .{ .tag = @enumFromInt(3066), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __fastfail + .{ .tag = @enumFromInt(3067), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .attributes = .{ .noreturn = true } } }, + // __finite + .{ .tag = @enumFromInt(3068), .properties = .{ .param_str = "id", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // __finitef + .{ .tag = @enumFromInt(3069), .properties = .{ .param_str = "if", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // __finitel + .{ .tag = @enumFromInt(3070), .properties = .{ .param_str = "iLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // __isb + .{ .tag = @enumFromInt(3071), .properties = .{ .param_str = "vUi", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }), .attributes = .{ .@"const" = true } } }, + // __iso_volatile_load16 + .{ .tag = @enumFromInt(3072), .properties = .{ .param_str = "ssCD*", .language = .all_ms_languages } }, + // __iso_volatile_load32 + .{ .tag = @enumFromInt(3073), .properties = .{ .param_str = "iiCD*", .language = .all_ms_languages } }, + // __iso_volatile_load64 + .{ .tag = @enumFromInt(3074), .properties = .{ .param_str = "LLiLLiCD*", .language = .all_ms_languages } }, + // __iso_volatile_load8 + .{ .tag = @enumFromInt(3075), .properties = .{ .param_str = "ccCD*", .language = .all_ms_languages } }, + // __iso_volatile_store16 + .{ .tag = @enumFromInt(3076), .properties = .{ .param_str = "vsD*s", .language = .all_ms_languages } }, + // __iso_volatile_store32 + .{ .tag = @enumFromInt(3077), .properties = .{ .param_str = "viD*i", .language = .all_ms_languages } }, + // __iso_volatile_store64 + .{ .tag = @enumFromInt(3078), .properties = .{ .param_str = "vLLiD*LLi", .language = .all_ms_languages } }, + // __iso_volatile_store8 + .{ .tag = @enumFromInt(3079), .properties = .{ .param_str = "vcD*c", .language = .all_ms_languages } }, + // __ldrexd + .{ .tag = @enumFromInt(3080), .properties = .{ .param_str = "WiWiCD*", .language = .all_ms_languages, .target_set = TargetSet.initOne(.arm) } }, + // __lzcnt + .{ .tag = @enumFromInt(3081), .properties = .{ .param_str = "UiUi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __lzcnt16 + .{ .tag = @enumFromInt(3082), .properties = .{ .param_str = "UsUs", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __lzcnt64 + .{ .tag = @enumFromInt(3083), .properties = .{ .param_str = "UWiUWi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __noop + .{ .tag = @enumFromInt(3084), .properties = .{ .param_str = "i.", .language = .all_ms_languages } }, + // __nvvm_add_rm_d + .{ .tag = @enumFromInt(3085), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rm_f + .{ .tag = @enumFromInt(3086), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rm_ftz_f + .{ .tag = @enumFromInt(3087), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rn_d + .{ .tag = @enumFromInt(3088), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rn_f + .{ .tag = @enumFromInt(3089), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rn_ftz_f + .{ .tag = @enumFromInt(3090), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rp_d + .{ .tag = @enumFromInt(3091), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rp_f + .{ .tag = @enumFromInt(3092), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rp_ftz_f + .{ .tag = @enumFromInt(3093), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rz_d + .{ .tag = @enumFromInt(3094), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rz_f + .{ .tag = @enumFromInt(3095), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_add_rz_ftz_f + .{ .tag = @enumFromInt(3096), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_add_gen_f + .{ .tag = @enumFromInt(3097), .properties = .{ .param_str = "ffD*f", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_add_gen_i + .{ .tag = @enumFromInt(3098), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_add_gen_l + .{ .tag = @enumFromInt(3099), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_add_gen_ll + .{ .tag = @enumFromInt(3100), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_and_gen_i + .{ .tag = @enumFromInt(3101), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_and_gen_l + .{ .tag = @enumFromInt(3102), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_and_gen_ll + .{ .tag = @enumFromInt(3103), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_cas_gen_i + .{ .tag = @enumFromInt(3104), .properties = .{ .param_str = "iiD*ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_cas_gen_l + .{ .tag = @enumFromInt(3105), .properties = .{ .param_str = "LiLiD*LiLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_cas_gen_ll + .{ .tag = @enumFromInt(3106), .properties = .{ .param_str = "LLiLLiD*LLiLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_dec_gen_ui + .{ .tag = @enumFromInt(3107), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_inc_gen_ui + .{ .tag = @enumFromInt(3108), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_max_gen_i + .{ .tag = @enumFromInt(3109), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_max_gen_l + .{ .tag = @enumFromInt(3110), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_max_gen_ll + .{ .tag = @enumFromInt(3111), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_max_gen_ui + .{ .tag = @enumFromInt(3112), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_max_gen_ul + .{ .tag = @enumFromInt(3113), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_max_gen_ull + .{ .tag = @enumFromInt(3114), .properties = .{ .param_str = "ULLiULLiD*ULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_min_gen_i + .{ .tag = @enumFromInt(3115), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_min_gen_l + .{ .tag = @enumFromInt(3116), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_min_gen_ll + .{ .tag = @enumFromInt(3117), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_min_gen_ui + .{ .tag = @enumFromInt(3118), .properties = .{ .param_str = "UiUiD*Ui", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_min_gen_ul + .{ .tag = @enumFromInt(3119), .properties = .{ .param_str = "ULiULiD*ULi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_min_gen_ull + .{ .tag = @enumFromInt(3120), .properties = .{ .param_str = "ULLiULLiD*ULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_or_gen_i + .{ .tag = @enumFromInt(3121), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_or_gen_l + .{ .tag = @enumFromInt(3122), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_or_gen_ll + .{ .tag = @enumFromInt(3123), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_sub_gen_i + .{ .tag = @enumFromInt(3124), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_sub_gen_l + .{ .tag = @enumFromInt(3125), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_sub_gen_ll + .{ .tag = @enumFromInt(3126), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_xchg_gen_i + .{ .tag = @enumFromInt(3127), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_xchg_gen_l + .{ .tag = @enumFromInt(3128), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_xchg_gen_ll + .{ .tag = @enumFromInt(3129), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_xor_gen_i + .{ .tag = @enumFromInt(3130), .properties = .{ .param_str = "iiD*i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_xor_gen_l + .{ .tag = @enumFromInt(3131), .properties = .{ .param_str = "LiLiD*Li", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_atom_xor_gen_ll + .{ .tag = @enumFromInt(3132), .properties = .{ .param_str = "LLiLLiD*LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bar0_and + .{ .tag = @enumFromInt(3133), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bar0_or + .{ .tag = @enumFromInt(3134), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bar0_popc + .{ .tag = @enumFromInt(3135), .properties = .{ .param_str = "ii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bar_sync + .{ .tag = @enumFromInt(3136), .properties = .{ .param_str = "vi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bitcast_d2ll + .{ .tag = @enumFromInt(3137), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bitcast_f2i + .{ .tag = @enumFromInt(3138), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bitcast_i2f + .{ .tag = @enumFromInt(3139), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_bitcast_ll2d + .{ .tag = @enumFromInt(3140), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ceil_d + .{ .tag = @enumFromInt(3141), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ceil_f + .{ .tag = @enumFromInt(3142), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ceil_ftz_f + .{ .tag = @enumFromInt(3143), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_compiler_error + .{ .tag = @enumFromInt(3144), .properties = .{ .param_str = "vcC*4", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_compiler_warn + .{ .tag = @enumFromInt(3145), .properties = .{ .param_str = "vcC*4", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_cos_approx_f + .{ .tag = @enumFromInt(3146), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_cos_approx_ftz_f + .{ .tag = @enumFromInt(3147), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rm + .{ .tag = @enumFromInt(3148), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rm_ftz + .{ .tag = @enumFromInt(3149), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rn + .{ .tag = @enumFromInt(3150), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rn_ftz + .{ .tag = @enumFromInt(3151), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rp + .{ .tag = @enumFromInt(3152), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rp_ftz + .{ .tag = @enumFromInt(3153), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rz + .{ .tag = @enumFromInt(3154), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2f_rz_ftz + .{ .tag = @enumFromInt(3155), .properties = .{ .param_str = "fd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2i_hi + .{ .tag = @enumFromInt(3156), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2i_lo + .{ .tag = @enumFromInt(3157), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2i_rm + .{ .tag = @enumFromInt(3158), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2i_rn + .{ .tag = @enumFromInt(3159), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2i_rp + .{ .tag = @enumFromInt(3160), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2i_rz + .{ .tag = @enumFromInt(3161), .properties = .{ .param_str = "id", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ll_rm + .{ .tag = @enumFromInt(3162), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ll_rn + .{ .tag = @enumFromInt(3163), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ll_rp + .{ .tag = @enumFromInt(3164), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ll_rz + .{ .tag = @enumFromInt(3165), .properties = .{ .param_str = "LLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ui_rm + .{ .tag = @enumFromInt(3166), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ui_rn + .{ .tag = @enumFromInt(3167), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ui_rp + .{ .tag = @enumFromInt(3168), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ui_rz + .{ .tag = @enumFromInt(3169), .properties = .{ .param_str = "Uid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ull_rm + .{ .tag = @enumFromInt(3170), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ull_rn + .{ .tag = @enumFromInt(3171), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ull_rp + .{ .tag = @enumFromInt(3172), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_d2ull_rz + .{ .tag = @enumFromInt(3173), .properties = .{ .param_str = "ULLid", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_approx_f + .{ .tag = @enumFromInt(3174), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_approx_ftz_f + .{ .tag = @enumFromInt(3175), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rm_d + .{ .tag = @enumFromInt(3176), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rm_f + .{ .tag = @enumFromInt(3177), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rm_ftz_f + .{ .tag = @enumFromInt(3178), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rn_d + .{ .tag = @enumFromInt(3179), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rn_f + .{ .tag = @enumFromInt(3180), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rn_ftz_f + .{ .tag = @enumFromInt(3181), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rp_d + .{ .tag = @enumFromInt(3182), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rp_f + .{ .tag = @enumFromInt(3183), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rp_ftz_f + .{ .tag = @enumFromInt(3184), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rz_d + .{ .tag = @enumFromInt(3185), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rz_f + .{ .tag = @enumFromInt(3186), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_div_rz_ftz_f + .{ .tag = @enumFromInt(3187), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ex2_approx_d + .{ .tag = @enumFromInt(3188), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ex2_approx_f + .{ .tag = @enumFromInt(3189), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ex2_approx_ftz_f + .{ .tag = @enumFromInt(3190), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2h_rn + .{ .tag = @enumFromInt(3191), .properties = .{ .param_str = "Usf", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2h_rn_ftz + .{ .tag = @enumFromInt(3192), .properties = .{ .param_str = "Usf", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rm + .{ .tag = @enumFromInt(3193), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rm_ftz + .{ .tag = @enumFromInt(3194), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rn + .{ .tag = @enumFromInt(3195), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rn_ftz + .{ .tag = @enumFromInt(3196), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rp + .{ .tag = @enumFromInt(3197), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rp_ftz + .{ .tag = @enumFromInt(3198), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rz + .{ .tag = @enumFromInt(3199), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2i_rz_ftz + .{ .tag = @enumFromInt(3200), .properties = .{ .param_str = "if", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rm + .{ .tag = @enumFromInt(3201), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rm_ftz + .{ .tag = @enumFromInt(3202), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rn + .{ .tag = @enumFromInt(3203), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rn_ftz + .{ .tag = @enumFromInt(3204), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rp + .{ .tag = @enumFromInt(3205), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rp_ftz + .{ .tag = @enumFromInt(3206), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rz + .{ .tag = @enumFromInt(3207), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ll_rz_ftz + .{ .tag = @enumFromInt(3208), .properties = .{ .param_str = "LLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rm + .{ .tag = @enumFromInt(3209), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rm_ftz + .{ .tag = @enumFromInt(3210), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rn + .{ .tag = @enumFromInt(3211), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rn_ftz + .{ .tag = @enumFromInt(3212), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rp + .{ .tag = @enumFromInt(3213), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rp_ftz + .{ .tag = @enumFromInt(3214), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rz + .{ .tag = @enumFromInt(3215), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ui_rz_ftz + .{ .tag = @enumFromInt(3216), .properties = .{ .param_str = "Uif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rm + .{ .tag = @enumFromInt(3217), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rm_ftz + .{ .tag = @enumFromInt(3218), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rn + .{ .tag = @enumFromInt(3219), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rn_ftz + .{ .tag = @enumFromInt(3220), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rp + .{ .tag = @enumFromInt(3221), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rp_ftz + .{ .tag = @enumFromInt(3222), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rz + .{ .tag = @enumFromInt(3223), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_f2ull_rz_ftz + .{ .tag = @enumFromInt(3224), .properties = .{ .param_str = "ULLif", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fabs_d + .{ .tag = @enumFromInt(3225), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fabs_f + .{ .tag = @enumFromInt(3226), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fabs_ftz_f + .{ .tag = @enumFromInt(3227), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_floor_d + .{ .tag = @enumFromInt(3228), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_floor_f + .{ .tag = @enumFromInt(3229), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_floor_ftz_f + .{ .tag = @enumFromInt(3230), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rm_d + .{ .tag = @enumFromInt(3231), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rm_f + .{ .tag = @enumFromInt(3232), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rm_ftz_f + .{ .tag = @enumFromInt(3233), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rn_d + .{ .tag = @enumFromInt(3234), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rn_f + .{ .tag = @enumFromInt(3235), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rn_ftz_f + .{ .tag = @enumFromInt(3236), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rp_d + .{ .tag = @enumFromInt(3237), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rp_f + .{ .tag = @enumFromInt(3238), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rp_ftz_f + .{ .tag = @enumFromInt(3239), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rz_d + .{ .tag = @enumFromInt(3240), .properties = .{ .param_str = "dddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rz_f + .{ .tag = @enumFromInt(3241), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fma_rz_ftz_f + .{ .tag = @enumFromInt(3242), .properties = .{ .param_str = "ffff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fmax_d + .{ .tag = @enumFromInt(3243), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fmax_f + .{ .tag = @enumFromInt(3244), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fmax_ftz_f + .{ .tag = @enumFromInt(3245), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fmin_d + .{ .tag = @enumFromInt(3246), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fmin_f + .{ .tag = @enumFromInt(3247), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_fmin_ftz_f + .{ .tag = @enumFromInt(3248), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2d_rm + .{ .tag = @enumFromInt(3249), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2d_rn + .{ .tag = @enumFromInt(3250), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2d_rp + .{ .tag = @enumFromInt(3251), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2d_rz + .{ .tag = @enumFromInt(3252), .properties = .{ .param_str = "di", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2f_rm + .{ .tag = @enumFromInt(3253), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2f_rn + .{ .tag = @enumFromInt(3254), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2f_rp + .{ .tag = @enumFromInt(3255), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_i2f_rz + .{ .tag = @enumFromInt(3256), .properties = .{ .param_str = "fi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_isspacep_const + .{ .tag = @enumFromInt(3257), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_isspacep_global + .{ .tag = @enumFromInt(3258), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_isspacep_local + .{ .tag = @enumFromInt(3259), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_isspacep_shared + .{ .tag = @enumFromInt(3260), .properties = .{ .param_str = "bvC*", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_ldg_c + .{ .tag = @enumFromInt(3261), .properties = .{ .param_str = "ccC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_c2 + .{ .tag = @enumFromInt(3262), .properties = .{ .param_str = "E2cE2cC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_c4 + .{ .tag = @enumFromInt(3263), .properties = .{ .param_str = "E4cE4cC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_d + .{ .tag = @enumFromInt(3264), .properties = .{ .param_str = "ddC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_d2 + .{ .tag = @enumFromInt(3265), .properties = .{ .param_str = "E2dE2dC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_f + .{ .tag = @enumFromInt(3266), .properties = .{ .param_str = "ffC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_f2 + .{ .tag = @enumFromInt(3267), .properties = .{ .param_str = "E2fE2fC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_f4 + .{ .tag = @enumFromInt(3268), .properties = .{ .param_str = "E4fE4fC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_h + .{ .tag = @enumFromInt(3269), .properties = .{ .param_str = "hhC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_h2 + .{ .tag = @enumFromInt(3270), .properties = .{ .param_str = "E2hE2hC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_i + .{ .tag = @enumFromInt(3271), .properties = .{ .param_str = "iiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_i2 + .{ .tag = @enumFromInt(3272), .properties = .{ .param_str = "E2iE2iC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_i4 + .{ .tag = @enumFromInt(3273), .properties = .{ .param_str = "E4iE4iC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_l + .{ .tag = @enumFromInt(3274), .properties = .{ .param_str = "LiLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_l2 + .{ .tag = @enumFromInt(3275), .properties = .{ .param_str = "E2LiE2LiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ll + .{ .tag = @enumFromInt(3276), .properties = .{ .param_str = "LLiLLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ll2 + .{ .tag = @enumFromInt(3277), .properties = .{ .param_str = "E2LLiE2LLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_s + .{ .tag = @enumFromInt(3278), .properties = .{ .param_str = "ssC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_s2 + .{ .tag = @enumFromInt(3279), .properties = .{ .param_str = "E2sE2sC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_s4 + .{ .tag = @enumFromInt(3280), .properties = .{ .param_str = "E4sE4sC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_sc + .{ .tag = @enumFromInt(3281), .properties = .{ .param_str = "ScScC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_sc2 + .{ .tag = @enumFromInt(3282), .properties = .{ .param_str = "E2ScE2ScC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_sc4 + .{ .tag = @enumFromInt(3283), .properties = .{ .param_str = "E4ScE4ScC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_uc + .{ .tag = @enumFromInt(3284), .properties = .{ .param_str = "UcUcC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_uc2 + .{ .tag = @enumFromInt(3285), .properties = .{ .param_str = "E2UcE2UcC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_uc4 + .{ .tag = @enumFromInt(3286), .properties = .{ .param_str = "E4UcE4UcC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ui + .{ .tag = @enumFromInt(3287), .properties = .{ .param_str = "UiUiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ui2 + .{ .tag = @enumFromInt(3288), .properties = .{ .param_str = "E2UiE2UiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ui4 + .{ .tag = @enumFromInt(3289), .properties = .{ .param_str = "E4UiE4UiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ul + .{ .tag = @enumFromInt(3290), .properties = .{ .param_str = "ULiULiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ul2 + .{ .tag = @enumFromInt(3291), .properties = .{ .param_str = "E2ULiE2ULiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ull + .{ .tag = @enumFromInt(3292), .properties = .{ .param_str = "ULLiULLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_ull2 + .{ .tag = @enumFromInt(3293), .properties = .{ .param_str = "E2ULLiE2ULLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_us + .{ .tag = @enumFromInt(3294), .properties = .{ .param_str = "UsUsC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_us2 + .{ .tag = @enumFromInt(3295), .properties = .{ .param_str = "E2UsE2UsC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldg_us4 + .{ .tag = @enumFromInt(3296), .properties = .{ .param_str = "E4UsE4UsC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_c + .{ .tag = @enumFromInt(3297), .properties = .{ .param_str = "ccC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_c2 + .{ .tag = @enumFromInt(3298), .properties = .{ .param_str = "E2cE2cC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_c4 + .{ .tag = @enumFromInt(3299), .properties = .{ .param_str = "E4cE4cC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_d + .{ .tag = @enumFromInt(3300), .properties = .{ .param_str = "ddC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_d2 + .{ .tag = @enumFromInt(3301), .properties = .{ .param_str = "E2dE2dC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_f + .{ .tag = @enumFromInt(3302), .properties = .{ .param_str = "ffC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_f2 + .{ .tag = @enumFromInt(3303), .properties = .{ .param_str = "E2fE2fC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_f4 + .{ .tag = @enumFromInt(3304), .properties = .{ .param_str = "E4fE4fC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_h + .{ .tag = @enumFromInt(3305), .properties = .{ .param_str = "hhC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_h2 + .{ .tag = @enumFromInt(3306), .properties = .{ .param_str = "E2hE2hC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_i + .{ .tag = @enumFromInt(3307), .properties = .{ .param_str = "iiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_i2 + .{ .tag = @enumFromInt(3308), .properties = .{ .param_str = "E2iE2iC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_i4 + .{ .tag = @enumFromInt(3309), .properties = .{ .param_str = "E4iE4iC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_l + .{ .tag = @enumFromInt(3310), .properties = .{ .param_str = "LiLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_l2 + .{ .tag = @enumFromInt(3311), .properties = .{ .param_str = "E2LiE2LiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ll + .{ .tag = @enumFromInt(3312), .properties = .{ .param_str = "LLiLLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ll2 + .{ .tag = @enumFromInt(3313), .properties = .{ .param_str = "E2LLiE2LLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_s + .{ .tag = @enumFromInt(3314), .properties = .{ .param_str = "ssC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_s2 + .{ .tag = @enumFromInt(3315), .properties = .{ .param_str = "E2sE2sC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_s4 + .{ .tag = @enumFromInt(3316), .properties = .{ .param_str = "E4sE4sC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_sc + .{ .tag = @enumFromInt(3317), .properties = .{ .param_str = "ScScC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_sc2 + .{ .tag = @enumFromInt(3318), .properties = .{ .param_str = "E2ScE2ScC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_sc4 + .{ .tag = @enumFromInt(3319), .properties = .{ .param_str = "E4ScE4ScC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_uc + .{ .tag = @enumFromInt(3320), .properties = .{ .param_str = "UcUcC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_uc2 + .{ .tag = @enumFromInt(3321), .properties = .{ .param_str = "E2UcE2UcC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_uc4 + .{ .tag = @enumFromInt(3322), .properties = .{ .param_str = "E4UcE4UcC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ui + .{ .tag = @enumFromInt(3323), .properties = .{ .param_str = "UiUiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ui2 + .{ .tag = @enumFromInt(3324), .properties = .{ .param_str = "E2UiE2UiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ui4 + .{ .tag = @enumFromInt(3325), .properties = .{ .param_str = "E4UiE4UiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ul + .{ .tag = @enumFromInt(3326), .properties = .{ .param_str = "ULiULiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ul2 + .{ .tag = @enumFromInt(3327), .properties = .{ .param_str = "E2ULiE2ULiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ull + .{ .tag = @enumFromInt(3328), .properties = .{ .param_str = "ULLiULLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_ull2 + .{ .tag = @enumFromInt(3329), .properties = .{ .param_str = "E2ULLiE2ULLiC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_us + .{ .tag = @enumFromInt(3330), .properties = .{ .param_str = "UsUsC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_us2 + .{ .tag = @enumFromInt(3331), .properties = .{ .param_str = "E2UsE2UsC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ldu_us4 + .{ .tag = @enumFromInt(3332), .properties = .{ .param_str = "E4UsE4UsC*", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_lg2_approx_d + .{ .tag = @enumFromInt(3333), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_lg2_approx_f + .{ .tag = @enumFromInt(3334), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_lg2_approx_ftz_f + .{ .tag = @enumFromInt(3335), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2d_rm + .{ .tag = @enumFromInt(3336), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2d_rn + .{ .tag = @enumFromInt(3337), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2d_rp + .{ .tag = @enumFromInt(3338), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2d_rz + .{ .tag = @enumFromInt(3339), .properties = .{ .param_str = "dLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2f_rm + .{ .tag = @enumFromInt(3340), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2f_rn + .{ .tag = @enumFromInt(3341), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2f_rp + .{ .tag = @enumFromInt(3342), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ll2f_rz + .{ .tag = @enumFromInt(3343), .properties = .{ .param_str = "fLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_lohi_i2d + .{ .tag = @enumFromInt(3344), .properties = .{ .param_str = "dii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_membar_cta + .{ .tag = @enumFromInt(3345), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_membar_gl + .{ .tag = @enumFromInt(3346), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_membar_sys + .{ .tag = @enumFromInt(3347), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_memcpy + .{ .tag = @enumFromInt(3348), .properties = .{ .param_str = "vUc*Uc*zi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_memset + .{ .tag = @enumFromInt(3349), .properties = .{ .param_str = "vUc*Uczi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul24_i + .{ .tag = @enumFromInt(3350), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul24_ui + .{ .tag = @enumFromInt(3351), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rm_d + .{ .tag = @enumFromInt(3352), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rm_f + .{ .tag = @enumFromInt(3353), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rm_ftz_f + .{ .tag = @enumFromInt(3354), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rn_d + .{ .tag = @enumFromInt(3355), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rn_f + .{ .tag = @enumFromInt(3356), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rn_ftz_f + .{ .tag = @enumFromInt(3357), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rp_d + .{ .tag = @enumFromInt(3358), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rp_f + .{ .tag = @enumFromInt(3359), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rp_ftz_f + .{ .tag = @enumFromInt(3360), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rz_d + .{ .tag = @enumFromInt(3361), .properties = .{ .param_str = "ddd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rz_f + .{ .tag = @enumFromInt(3362), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mul_rz_ftz_f + .{ .tag = @enumFromInt(3363), .properties = .{ .param_str = "fff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mulhi_i + .{ .tag = @enumFromInt(3364), .properties = .{ .param_str = "iii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mulhi_ll + .{ .tag = @enumFromInt(3365), .properties = .{ .param_str = "LLiLLiLLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mulhi_ui + .{ .tag = @enumFromInt(3366), .properties = .{ .param_str = "UiUiUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_mulhi_ull + .{ .tag = @enumFromInt(3367), .properties = .{ .param_str = "ULLiULLiULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_prmt + .{ .tag = @enumFromInt(3368), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_approx_ftz_d + .{ .tag = @enumFromInt(3369), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_approx_ftz_f + .{ .tag = @enumFromInt(3370), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rm_d + .{ .tag = @enumFromInt(3371), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rm_f + .{ .tag = @enumFromInt(3372), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rm_ftz_f + .{ .tag = @enumFromInt(3373), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rn_d + .{ .tag = @enumFromInt(3374), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rn_f + .{ .tag = @enumFromInt(3375), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rn_ftz_f + .{ .tag = @enumFromInt(3376), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rp_d + .{ .tag = @enumFromInt(3377), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rp_f + .{ .tag = @enumFromInt(3378), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rp_ftz_f + .{ .tag = @enumFromInt(3379), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rz_d + .{ .tag = @enumFromInt(3380), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rz_f + .{ .tag = @enumFromInt(3381), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rcp_rz_ftz_f + .{ .tag = @enumFromInt(3382), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_read_ptx_sreg_clock + .{ .tag = @enumFromInt(3383), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_read_ptx_sreg_clock64 + .{ .tag = @enumFromInt(3384), .properties = .{ .param_str = "LLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_read_ptx_sreg_ctaid_w + .{ .tag = @enumFromInt(3385), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_ctaid_x + .{ .tag = @enumFromInt(3386), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_ctaid_y + .{ .tag = @enumFromInt(3387), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_ctaid_z + .{ .tag = @enumFromInt(3388), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_gridid + .{ .tag = @enumFromInt(3389), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_laneid + .{ .tag = @enumFromInt(3390), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_lanemask_eq + .{ .tag = @enumFromInt(3391), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_lanemask_ge + .{ .tag = @enumFromInt(3392), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_lanemask_gt + .{ .tag = @enumFromInt(3393), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_lanemask_le + .{ .tag = @enumFromInt(3394), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_lanemask_lt + .{ .tag = @enumFromInt(3395), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_nctaid_w + .{ .tag = @enumFromInt(3396), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_nctaid_x + .{ .tag = @enumFromInt(3397), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_nctaid_y + .{ .tag = @enumFromInt(3398), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_nctaid_z + .{ .tag = @enumFromInt(3399), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_nsmid + .{ .tag = @enumFromInt(3400), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_ntid_w + .{ .tag = @enumFromInt(3401), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_ntid_x + .{ .tag = @enumFromInt(3402), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_ntid_y + .{ .tag = @enumFromInt(3403), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_ntid_z + .{ .tag = @enumFromInt(3404), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_nwarpid + .{ .tag = @enumFromInt(3405), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_pm0 + .{ .tag = @enumFromInt(3406), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_read_ptx_sreg_pm1 + .{ .tag = @enumFromInt(3407), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_read_ptx_sreg_pm2 + .{ .tag = @enumFromInt(3408), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_read_ptx_sreg_pm3 + .{ .tag = @enumFromInt(3409), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_read_ptx_sreg_smid + .{ .tag = @enumFromInt(3410), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_tid_w + .{ .tag = @enumFromInt(3411), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_tid_x + .{ .tag = @enumFromInt(3412), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_tid_y + .{ .tag = @enumFromInt(3413), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_tid_z + .{ .tag = @enumFromInt(3414), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_read_ptx_sreg_warpid + .{ .tag = @enumFromInt(3415), .properties = .{ .param_str = "i", .target_set = TargetSet.initOne(.nvptx), .attributes = .{ .@"const" = true } } }, + // __nvvm_round_d + .{ .tag = @enumFromInt(3416), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_round_f + .{ .tag = @enumFromInt(3417), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_round_ftz_f + .{ .tag = @enumFromInt(3418), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rsqrt_approx_d + .{ .tag = @enumFromInt(3419), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rsqrt_approx_f + .{ .tag = @enumFromInt(3420), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_rsqrt_approx_ftz_f + .{ .tag = @enumFromInt(3421), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sad_i + .{ .tag = @enumFromInt(3422), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sad_ui + .{ .tag = @enumFromInt(3423), .properties = .{ .param_str = "UiUiUiUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_saturate_d + .{ .tag = @enumFromInt(3424), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_saturate_f + .{ .tag = @enumFromInt(3425), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_saturate_ftz_f + .{ .tag = @enumFromInt(3426), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_bfly_f32 + .{ .tag = @enumFromInt(3427), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_bfly_i32 + .{ .tag = @enumFromInt(3428), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_down_f32 + .{ .tag = @enumFromInt(3429), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_down_i32 + .{ .tag = @enumFromInt(3430), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_idx_f32 + .{ .tag = @enumFromInt(3431), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_idx_i32 + .{ .tag = @enumFromInt(3432), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_up_f32 + .{ .tag = @enumFromInt(3433), .properties = .{ .param_str = "ffii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_shfl_up_i32 + .{ .tag = @enumFromInt(3434), .properties = .{ .param_str = "iiii", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sin_approx_f + .{ .tag = @enumFromInt(3435), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sin_approx_ftz_f + .{ .tag = @enumFromInt(3436), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_approx_f + .{ .tag = @enumFromInt(3437), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_approx_ftz_f + .{ .tag = @enumFromInt(3438), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rm_d + .{ .tag = @enumFromInt(3439), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rm_f + .{ .tag = @enumFromInt(3440), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rm_ftz_f + .{ .tag = @enumFromInt(3441), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rn_d + .{ .tag = @enumFromInt(3442), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rn_f + .{ .tag = @enumFromInt(3443), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rn_ftz_f + .{ .tag = @enumFromInt(3444), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rp_d + .{ .tag = @enumFromInt(3445), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rp_f + .{ .tag = @enumFromInt(3446), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rp_ftz_f + .{ .tag = @enumFromInt(3447), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rz_d + .{ .tag = @enumFromInt(3448), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rz_f + .{ .tag = @enumFromInt(3449), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_sqrt_rz_ftz_f + .{ .tag = @enumFromInt(3450), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_trunc_d + .{ .tag = @enumFromInt(3451), .properties = .{ .param_str = "dd", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_trunc_f + .{ .tag = @enumFromInt(3452), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_trunc_ftz_f + .{ .tag = @enumFromInt(3453), .properties = .{ .param_str = "ff", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2d_rm + .{ .tag = @enumFromInt(3454), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2d_rn + .{ .tag = @enumFromInt(3455), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2d_rp + .{ .tag = @enumFromInt(3456), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2d_rz + .{ .tag = @enumFromInt(3457), .properties = .{ .param_str = "dUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2f_rm + .{ .tag = @enumFromInt(3458), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2f_rn + .{ .tag = @enumFromInt(3459), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2f_rp + .{ .tag = @enumFromInt(3460), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ui2f_rz + .{ .tag = @enumFromInt(3461), .properties = .{ .param_str = "fUi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2d_rm + .{ .tag = @enumFromInt(3462), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2d_rn + .{ .tag = @enumFromInt(3463), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2d_rp + .{ .tag = @enumFromInt(3464), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2d_rz + .{ .tag = @enumFromInt(3465), .properties = .{ .param_str = "dULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2f_rm + .{ .tag = @enumFromInt(3466), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2f_rn + .{ .tag = @enumFromInt(3467), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2f_rp + .{ .tag = @enumFromInt(3468), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_ull2f_rz + .{ .tag = @enumFromInt(3469), .properties = .{ .param_str = "fULLi", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_vote_all + .{ .tag = @enumFromInt(3470), .properties = .{ .param_str = "bb", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_vote_any + .{ .tag = @enumFromInt(3471), .properties = .{ .param_str = "bb", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_vote_ballot + .{ .tag = @enumFromInt(3472), .properties = .{ .param_str = "Uib", .target_set = TargetSet.initOne(.nvptx) } }, + // __nvvm_vote_uni + .{ .tag = @enumFromInt(3473), .properties = .{ .param_str = "bb", .target_set = TargetSet.initOne(.nvptx) } }, + // __popcnt + .{ .tag = @enumFromInt(3474), .properties = .{ .param_str = "UiUi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __popcnt16 + .{ .tag = @enumFromInt(3475), .properties = .{ .param_str = "UsUs", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __popcnt64 + .{ .tag = @enumFromInt(3476), .properties = .{ .param_str = "UWiUWi", .language = .all_ms_languages, .attributes = .{ .@"const" = true, .const_evaluable = true } } }, + // __rdtsc + .{ .tag = @enumFromInt(3477), .properties = .{ .param_str = "UOi", .target_set = TargetSet.initOne(.x86) } }, + // __sev + .{ .tag = @enumFromInt(3478), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __sevl + .{ .tag = @enumFromInt(3479), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __sigsetjmp + .{ .tag = @enumFromInt(3480), .properties = .{ .param_str = "iSJi", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } }, + // __sinpi + .{ .tag = @enumFromInt(3481), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __sinpif + .{ .tag = @enumFromInt(3482), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __sync_add_and_fetch + .{ .tag = @enumFromInt(3483), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_add_and_fetch_1 + .{ .tag = @enumFromInt(3484), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_add_and_fetch_16 + .{ .tag = @enumFromInt(3485), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_add_and_fetch_2 + .{ .tag = @enumFromInt(3486), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_add_and_fetch_4 + .{ .tag = @enumFromInt(3487), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_add_and_fetch_8 + .{ .tag = @enumFromInt(3488), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_and_and_fetch + .{ .tag = @enumFromInt(3489), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_and_and_fetch_1 + .{ .tag = @enumFromInt(3490), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_and_and_fetch_16 + .{ .tag = @enumFromInt(3491), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_and_and_fetch_2 + .{ .tag = @enumFromInt(3492), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_and_and_fetch_4 + .{ .tag = @enumFromInt(3493), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_and_and_fetch_8 + .{ .tag = @enumFromInt(3494), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_bool_compare_and_swap + .{ .tag = @enumFromInt(3495), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_bool_compare_and_swap_1 + .{ .tag = @enumFromInt(3496), .properties = .{ .param_str = "bcD*cc.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_bool_compare_and_swap_16 + .{ .tag = @enumFromInt(3497), .properties = .{ .param_str = "bLLLiD*LLLiLLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_bool_compare_and_swap_2 + .{ .tag = @enumFromInt(3498), .properties = .{ .param_str = "bsD*ss.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_bool_compare_and_swap_4 + .{ .tag = @enumFromInt(3499), .properties = .{ .param_str = "biD*ii.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_bool_compare_and_swap_8 + .{ .tag = @enumFromInt(3500), .properties = .{ .param_str = "bLLiD*LLiLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_add + .{ .tag = @enumFromInt(3501), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_add_1 + .{ .tag = @enumFromInt(3502), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_add_16 + .{ .tag = @enumFromInt(3503), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_add_2 + .{ .tag = @enumFromInt(3504), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_add_4 + .{ .tag = @enumFromInt(3505), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_add_8 + .{ .tag = @enumFromInt(3506), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_and + .{ .tag = @enumFromInt(3507), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_and_1 + .{ .tag = @enumFromInt(3508), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_and_16 + .{ .tag = @enumFromInt(3509), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_and_2 + .{ .tag = @enumFromInt(3510), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_and_4 + .{ .tag = @enumFromInt(3511), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_and_8 + .{ .tag = @enumFromInt(3512), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_max + .{ .tag = @enumFromInt(3513), .properties = .{ .param_str = "iiD*i" } }, + // __sync_fetch_and_min + .{ .tag = @enumFromInt(3514), .properties = .{ .param_str = "iiD*i" } }, + // __sync_fetch_and_nand + .{ .tag = @enumFromInt(3515), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_nand_1 + .{ .tag = @enumFromInt(3516), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_nand_16 + .{ .tag = @enumFromInt(3517), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_nand_2 + .{ .tag = @enumFromInt(3518), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_nand_4 + .{ .tag = @enumFromInt(3519), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_nand_8 + .{ .tag = @enumFromInt(3520), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_or + .{ .tag = @enumFromInt(3521), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_or_1 + .{ .tag = @enumFromInt(3522), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_or_16 + .{ .tag = @enumFromInt(3523), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_or_2 + .{ .tag = @enumFromInt(3524), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_or_4 + .{ .tag = @enumFromInt(3525), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_or_8 + .{ .tag = @enumFromInt(3526), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_sub + .{ .tag = @enumFromInt(3527), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_sub_1 + .{ .tag = @enumFromInt(3528), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_sub_16 + .{ .tag = @enumFromInt(3529), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_sub_2 + .{ .tag = @enumFromInt(3530), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_sub_4 + .{ .tag = @enumFromInt(3531), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_sub_8 + .{ .tag = @enumFromInt(3532), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_umax + .{ .tag = @enumFromInt(3533), .properties = .{ .param_str = "UiUiD*Ui" } }, + // __sync_fetch_and_umin + .{ .tag = @enumFromInt(3534), .properties = .{ .param_str = "UiUiD*Ui" } }, + // __sync_fetch_and_xor + .{ .tag = @enumFromInt(3535), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_xor_1 + .{ .tag = @enumFromInt(3536), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_xor_16 + .{ .tag = @enumFromInt(3537), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_xor_2 + .{ .tag = @enumFromInt(3538), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_xor_4 + .{ .tag = @enumFromInt(3539), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_fetch_and_xor_8 + .{ .tag = @enumFromInt(3540), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_release + .{ .tag = @enumFromInt(3541), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_release_1 + .{ .tag = @enumFromInt(3542), .properties = .{ .param_str = "vcD*.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_release_16 + .{ .tag = @enumFromInt(3543), .properties = .{ .param_str = "vLLLiD*.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_release_2 + .{ .tag = @enumFromInt(3544), .properties = .{ .param_str = "vsD*.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_release_4 + .{ .tag = @enumFromInt(3545), .properties = .{ .param_str = "viD*.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_release_8 + .{ .tag = @enumFromInt(3546), .properties = .{ .param_str = "vLLiD*.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_test_and_set + .{ .tag = @enumFromInt(3547), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_test_and_set_1 + .{ .tag = @enumFromInt(3548), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_test_and_set_16 + .{ .tag = @enumFromInt(3549), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_test_and_set_2 + .{ .tag = @enumFromInt(3550), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_test_and_set_4 + .{ .tag = @enumFromInt(3551), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_lock_test_and_set_8 + .{ .tag = @enumFromInt(3552), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_nand_and_fetch + .{ .tag = @enumFromInt(3553), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_nand_and_fetch_1 + .{ .tag = @enumFromInt(3554), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_nand_and_fetch_16 + .{ .tag = @enumFromInt(3555), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_nand_and_fetch_2 + .{ .tag = @enumFromInt(3556), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_nand_and_fetch_4 + .{ .tag = @enumFromInt(3557), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_nand_and_fetch_8 + .{ .tag = @enumFromInt(3558), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_or_and_fetch + .{ .tag = @enumFromInt(3559), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_or_and_fetch_1 + .{ .tag = @enumFromInt(3560), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_or_and_fetch_16 + .{ .tag = @enumFromInt(3561), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_or_and_fetch_2 + .{ .tag = @enumFromInt(3562), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_or_and_fetch_4 + .{ .tag = @enumFromInt(3563), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_or_and_fetch_8 + .{ .tag = @enumFromInt(3564), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_sub_and_fetch + .{ .tag = @enumFromInt(3565), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_sub_and_fetch_1 + .{ .tag = @enumFromInt(3566), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_sub_and_fetch_16 + .{ .tag = @enumFromInt(3567), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_sub_and_fetch_2 + .{ .tag = @enumFromInt(3568), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_sub_and_fetch_4 + .{ .tag = @enumFromInt(3569), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_sub_and_fetch_8 + .{ .tag = @enumFromInt(3570), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_swap + .{ .tag = @enumFromInt(3571), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_swap_1 + .{ .tag = @enumFromInt(3572), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_swap_16 + .{ .tag = @enumFromInt(3573), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_swap_2 + .{ .tag = @enumFromInt(3574), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_swap_4 + .{ .tag = @enumFromInt(3575), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_swap_8 + .{ .tag = @enumFromInt(3576), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_synchronize + .{ .tag = @enumFromInt(3577), .properties = .{ .param_str = "v" } }, + // __sync_val_compare_and_swap + .{ .tag = @enumFromInt(3578), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_val_compare_and_swap_1 + .{ .tag = @enumFromInt(3579), .properties = .{ .param_str = "ccD*cc.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_val_compare_and_swap_16 + .{ .tag = @enumFromInt(3580), .properties = .{ .param_str = "LLLiLLLiD*LLLiLLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_val_compare_and_swap_2 + .{ .tag = @enumFromInt(3581), .properties = .{ .param_str = "ssD*ss.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_val_compare_and_swap_4 + .{ .tag = @enumFromInt(3582), .properties = .{ .param_str = "iiD*ii.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_val_compare_and_swap_8 + .{ .tag = @enumFromInt(3583), .properties = .{ .param_str = "LLiLLiD*LLiLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_xor_and_fetch + .{ .tag = @enumFromInt(3584), .properties = .{ .param_str = "v.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_xor_and_fetch_1 + .{ .tag = @enumFromInt(3585), .properties = .{ .param_str = "ccD*c.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_xor_and_fetch_16 + .{ .tag = @enumFromInt(3586), .properties = .{ .param_str = "LLLiLLLiD*LLLi.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_xor_and_fetch_2 + .{ .tag = @enumFromInt(3587), .properties = .{ .param_str = "ssD*s.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_xor_and_fetch_4 + .{ .tag = @enumFromInt(3588), .properties = .{ .param_str = "iiD*i.", .attributes = .{ .custom_typecheck = true } } }, + // __sync_xor_and_fetch_8 + .{ .tag = @enumFromInt(3589), .properties = .{ .param_str = "LLiLLiD*LLi.", .attributes = .{ .custom_typecheck = true } } }, + // __syncthreads + .{ .tag = @enumFromInt(3590), .properties = .{ .param_str = "v", .target_set = TargetSet.initOne(.nvptx) } }, + // __tanpi + .{ .tag = @enumFromInt(3591), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __tanpif + .{ .tag = @enumFromInt(3592), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // __va_start + .{ .tag = @enumFromInt(3593), .properties = .{ .param_str = "vc**.", .language = .all_ms_languages, .attributes = .{ .custom_typecheck = true } } }, + // __warn_memset_zero_len + .{ .tag = @enumFromInt(3594), .properties = .{ .param_str = "v", .attributes = .{ .pure = true } } }, + // __wfe + .{ .tag = @enumFromInt(3595), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __wfi + .{ .tag = @enumFromInt(3596), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // __xray_customevent + .{ .tag = @enumFromInt(3597), .properties = .{ .param_str = "vcC*z" } }, + // __xray_typedevent + .{ .tag = @enumFromInt(3598), .properties = .{ .param_str = "vzcC*z" } }, + // __yield + .{ .tag = @enumFromInt(3599), .properties = .{ .param_str = "v", .language = .all_ms_languages, .target_set = TargetSet.initMany(&.{ .aarch64, .arm }) } }, + // _abnormal_termination + .{ .tag = @enumFromInt(3600), .properties = .{ .param_str = "i", .language = .all_ms_languages } }, + // _alloca + .{ .tag = @enumFromInt(3601), .properties = .{ .param_str = "v*z", .language = .all_ms_languages } }, + // _bittest + .{ .tag = @enumFromInt(3602), .properties = .{ .param_str = "UcNiC*Ni", .language = .all_ms_languages } }, + // _bittest64 + .{ .tag = @enumFromInt(3603), .properties = .{ .param_str = "UcWiC*Wi", .language = .all_ms_languages } }, + // _bittestandcomplement + .{ .tag = @enumFromInt(3604), .properties = .{ .param_str = "UcNi*Ni", .language = .all_ms_languages } }, + // _bittestandcomplement64 + .{ .tag = @enumFromInt(3605), .properties = .{ .param_str = "UcWi*Wi", .language = .all_ms_languages } }, + // _bittestandreset + .{ .tag = @enumFromInt(3606), .properties = .{ .param_str = "UcNi*Ni", .language = .all_ms_languages } }, + // _bittestandreset64 + .{ .tag = @enumFromInt(3607), .properties = .{ .param_str = "UcWi*Wi", .language = .all_ms_languages } }, + // _bittestandset + .{ .tag = @enumFromInt(3608), .properties = .{ .param_str = "UcNi*Ni", .language = .all_ms_languages } }, + // _bittestandset64 + .{ .tag = @enumFromInt(3609), .properties = .{ .param_str = "UcWi*Wi", .language = .all_ms_languages } }, + // _byteswap_uint64 + .{ .tag = @enumFromInt(3610), .properties = .{ .param_str = "ULLiULLi", .header = .stdlib, .language = .all_ms_languages, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // _byteswap_ulong + .{ .tag = @enumFromInt(3611), .properties = .{ .param_str = "UNiUNi", .header = .stdlib, .language = .all_ms_languages, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // _byteswap_ushort + .{ .tag = @enumFromInt(3612), .properties = .{ .param_str = "UsUs", .header = .stdlib, .language = .all_ms_languages, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // _exception_code + .{ .tag = @enumFromInt(3613), .properties = .{ .param_str = "UNi", .language = .all_ms_languages } }, + // _exception_info + .{ .tag = @enumFromInt(3614), .properties = .{ .param_str = "v*", .language = .all_ms_languages } }, + // _exit + .{ .tag = @enumFromInt(3615), .properties = .{ .param_str = "vi", .header = .unistd, .language = .all_gnu_languages, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } }, + // _interlockedbittestandreset + .{ .tag = @enumFromInt(3616), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _interlockedbittestandreset64 + .{ .tag = @enumFromInt(3617), .properties = .{ .param_str = "UcWiD*Wi", .language = .all_ms_languages } }, + // _interlockedbittestandreset_acq + .{ .tag = @enumFromInt(3618), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _interlockedbittestandreset_nf + .{ .tag = @enumFromInt(3619), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _interlockedbittestandreset_rel + .{ .tag = @enumFromInt(3620), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _interlockedbittestandset + .{ .tag = @enumFromInt(3621), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _interlockedbittestandset64 + .{ .tag = @enumFromInt(3622), .properties = .{ .param_str = "UcWiD*Wi", .language = .all_ms_languages } }, + // _interlockedbittestandset_acq + .{ .tag = @enumFromInt(3623), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _interlockedbittestandset_nf + .{ .tag = @enumFromInt(3624), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _interlockedbittestandset_rel + .{ .tag = @enumFromInt(3625), .properties = .{ .param_str = "UcNiD*Ni", .language = .all_ms_languages } }, + // _longjmp + .{ .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 } } }, + // _lrotl + .{ .tag = @enumFromInt(3627), .properties = .{ .param_str = "ULiULii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _lrotr + .{ .tag = @enumFromInt(3628), .properties = .{ .param_str = "ULiULii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotl + .{ .tag = @enumFromInt(3629), .properties = .{ .param_str = "UiUii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotl16 + .{ .tag = @enumFromInt(3630), .properties = .{ .param_str = "UsUsUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotl64 + .{ .tag = @enumFromInt(3631), .properties = .{ .param_str = "UWiUWii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotl8 + .{ .tag = @enumFromInt(3632), .properties = .{ .param_str = "UcUcUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotr + .{ .tag = @enumFromInt(3633), .properties = .{ .param_str = "UiUii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotr16 + .{ .tag = @enumFromInt(3634), .properties = .{ .param_str = "UsUsUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotr64 + .{ .tag = @enumFromInt(3635), .properties = .{ .param_str = "UWiUWii", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _rotr8 + .{ .tag = @enumFromInt(3636), .properties = .{ .param_str = "UcUcUc", .language = .all_ms_languages, .attributes = .{ .const_evaluable = true } } }, + // _setjmp + .{ .tag = @enumFromInt(3637), .properties = .{ .param_str = "iJ", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } }, + // _setjmpex + .{ .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 } } }, + // abort + .{ .tag = @enumFromInt(3639), .properties = .{ .param_str = "v", .header = .stdlib, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } }, + // abs + .{ .tag = @enumFromInt(3640), .properties = .{ .param_str = "ii", .header = .stdlib, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // acos + .{ .tag = @enumFromInt(3641), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // acosf + .{ .tag = @enumFromInt(3642), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // acosh + .{ .tag = @enumFromInt(3643), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // acoshf + .{ .tag = @enumFromInt(3644), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // acoshl + .{ .tag = @enumFromInt(3645), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // acosl + .{ .tag = @enumFromInt(3646), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // aligned_alloc + .{ .tag = @enumFromInt(3647), .properties = .{ .param_str = "v*zz", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // alloca + .{ .tag = @enumFromInt(3648), .properties = .{ .param_str = "v*z", .header = .stdlib, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // asin + .{ .tag = @enumFromInt(3649), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // asinf + .{ .tag = @enumFromInt(3650), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // asinh + .{ .tag = @enumFromInt(3651), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // asinhf + .{ .tag = @enumFromInt(3652), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // asinhl + .{ .tag = @enumFromInt(3653), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // asinl + .{ .tag = @enumFromInt(3654), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atan + .{ .tag = @enumFromInt(3655), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atan2 + .{ .tag = @enumFromInt(3656), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atan2f + .{ .tag = @enumFromInt(3657), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atan2l + .{ .tag = @enumFromInt(3658), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atanf + .{ .tag = @enumFromInt(3659), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atanh + .{ .tag = @enumFromInt(3660), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atanhf + .{ .tag = @enumFromInt(3661), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atanhl + .{ .tag = @enumFromInt(3662), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // atanl + .{ .tag = @enumFromInt(3663), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // bcmp + .{ .tag = @enumFromInt(3664), .properties = .{ .param_str = "ivC*vC*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // bcopy + .{ .tag = @enumFromInt(3665), .properties = .{ .param_str = "vvC*v*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // bzero + .{ .tag = @enumFromInt(3666), .properties = .{ .param_str = "vv*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // cabs + .{ .tag = @enumFromInt(3667), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cabsf + .{ .tag = @enumFromInt(3668), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cabsl + .{ .tag = @enumFromInt(3669), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cacos + .{ .tag = @enumFromInt(3670), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cacosf + .{ .tag = @enumFromInt(3671), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cacosh + .{ .tag = @enumFromInt(3672), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cacoshf + .{ .tag = @enumFromInt(3673), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cacoshl + .{ .tag = @enumFromInt(3674), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cacosl + .{ .tag = @enumFromInt(3675), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // calloc + .{ .tag = @enumFromInt(3676), .properties = .{ .param_str = "v*zz", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // carg + .{ .tag = @enumFromInt(3677), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cargf + .{ .tag = @enumFromInt(3678), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cargl + .{ .tag = @enumFromInt(3679), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // casin + .{ .tag = @enumFromInt(3680), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // casinf + .{ .tag = @enumFromInt(3681), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // casinh + .{ .tag = @enumFromInt(3682), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // casinhf + .{ .tag = @enumFromInt(3683), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // casinhl + .{ .tag = @enumFromInt(3684), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // casinl + .{ .tag = @enumFromInt(3685), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // catan + .{ .tag = @enumFromInt(3686), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // catanf + .{ .tag = @enumFromInt(3687), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // catanh + .{ .tag = @enumFromInt(3688), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // catanhf + .{ .tag = @enumFromInt(3689), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // catanhl + .{ .tag = @enumFromInt(3690), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // catanl + .{ .tag = @enumFromInt(3691), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cbrt + .{ .tag = @enumFromInt(3692), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cbrtf + .{ .tag = @enumFromInt(3693), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cbrtl + .{ .tag = @enumFromInt(3694), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // ccos + .{ .tag = @enumFromInt(3695), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ccosf + .{ .tag = @enumFromInt(3696), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ccosh + .{ .tag = @enumFromInt(3697), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ccoshf + .{ .tag = @enumFromInt(3698), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ccoshl + .{ .tag = @enumFromInt(3699), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ccosl + .{ .tag = @enumFromInt(3700), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ceil + .{ .tag = @enumFromInt(3701), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // ceilf + .{ .tag = @enumFromInt(3702), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // ceill + .{ .tag = @enumFromInt(3703), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cexp + .{ .tag = @enumFromInt(3704), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cexpf + .{ .tag = @enumFromInt(3705), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cexpl + .{ .tag = @enumFromInt(3706), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cimag + .{ .tag = @enumFromInt(3707), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cimagf + .{ .tag = @enumFromInt(3708), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cimagl + .{ .tag = @enumFromInt(3709), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // clog + .{ .tag = @enumFromInt(3710), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // clogf + .{ .tag = @enumFromInt(3711), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // clogl + .{ .tag = @enumFromInt(3712), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // conj + .{ .tag = @enumFromInt(3713), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // conjf + .{ .tag = @enumFromInt(3714), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // conjl + .{ .tag = @enumFromInt(3715), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // copysign + .{ .tag = @enumFromInt(3716), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // copysignf + .{ .tag = @enumFromInt(3717), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // copysignl + .{ .tag = @enumFromInt(3718), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cos + .{ .tag = @enumFromInt(3719), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cosf + .{ .tag = @enumFromInt(3720), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cosh + .{ .tag = @enumFromInt(3721), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // coshf + .{ .tag = @enumFromInt(3722), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // coshl + .{ .tag = @enumFromInt(3723), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cosl + .{ .tag = @enumFromInt(3724), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cpow + .{ .tag = @enumFromInt(3725), .properties = .{ .param_str = "XdXdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cpowf + .{ .tag = @enumFromInt(3726), .properties = .{ .param_str = "XfXfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cpowl + .{ .tag = @enumFromInt(3727), .properties = .{ .param_str = "XLdXLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // cproj + .{ .tag = @enumFromInt(3728), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cprojf + .{ .tag = @enumFromInt(3729), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // cprojl + .{ .tag = @enumFromInt(3730), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // creal + .{ .tag = @enumFromInt(3731), .properties = .{ .param_str = "dXd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // crealf + .{ .tag = @enumFromInt(3732), .properties = .{ .param_str = "fXf", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // creall + .{ .tag = @enumFromInt(3733), .properties = .{ .param_str = "LdXLd", .header = .complex, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // csin + .{ .tag = @enumFromInt(3734), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csinf + .{ .tag = @enumFromInt(3735), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csinh + .{ .tag = @enumFromInt(3736), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csinhf + .{ .tag = @enumFromInt(3737), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csinhl + .{ .tag = @enumFromInt(3738), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csinl + .{ .tag = @enumFromInt(3739), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csqrt + .{ .tag = @enumFromInt(3740), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csqrtf + .{ .tag = @enumFromInt(3741), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // csqrtl + .{ .tag = @enumFromInt(3742), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ctan + .{ .tag = @enumFromInt(3743), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ctanf + .{ .tag = @enumFromInt(3744), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ctanh + .{ .tag = @enumFromInt(3745), .properties = .{ .param_str = "XdXd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ctanhf + .{ .tag = @enumFromInt(3746), .properties = .{ .param_str = "XfXf", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ctanhl + .{ .tag = @enumFromInt(3747), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ctanl + .{ .tag = @enumFromInt(3748), .properties = .{ .param_str = "XLdXLd", .header = .complex, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // erf + .{ .tag = @enumFromInt(3749), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // erfc + .{ .tag = @enumFromInt(3750), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // erfcf + .{ .tag = @enumFromInt(3751), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // erfcl + .{ .tag = @enumFromInt(3752), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // erff + .{ .tag = @enumFromInt(3753), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // erfl + .{ .tag = @enumFromInt(3754), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // exit + .{ .tag = @enumFromInt(3755), .properties = .{ .param_str = "vi", .header = .stdlib, .attributes = .{ .noreturn = true, .lib_function_without_prefix = true } } }, + // exp + .{ .tag = @enumFromInt(3756), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // exp2 + .{ .tag = @enumFromInt(3757), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // exp2f + .{ .tag = @enumFromInt(3758), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // exp2l + .{ .tag = @enumFromInt(3759), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // expf + .{ .tag = @enumFromInt(3760), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // expl + .{ .tag = @enumFromInt(3761), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // expm1 + .{ .tag = @enumFromInt(3762), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // expm1f + .{ .tag = @enumFromInt(3763), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // expm1l + .{ .tag = @enumFromInt(3764), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fabs + .{ .tag = @enumFromInt(3765), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fabsf + .{ .tag = @enumFromInt(3766), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fabsl + .{ .tag = @enumFromInt(3767), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fdim + .{ .tag = @enumFromInt(3768), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fdimf + .{ .tag = @enumFromInt(3769), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fdiml + .{ .tag = @enumFromInt(3770), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // finite + .{ .tag = @enumFromInt(3771), .properties = .{ .param_str = "id", .header = .math, .language = .gnu_lang, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // finitef + .{ .tag = @enumFromInt(3772), .properties = .{ .param_str = "if", .header = .math, .language = .gnu_lang, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // finitel + .{ .tag = @enumFromInt(3773), .properties = .{ .param_str = "iLd", .header = .math, .language = .gnu_lang, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // floor + .{ .tag = @enumFromInt(3774), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // floorf + .{ .tag = @enumFromInt(3775), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // floorl + .{ .tag = @enumFromInt(3776), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fma + .{ .tag = @enumFromInt(3777), .properties = .{ .param_str = "dddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fmaf + .{ .tag = @enumFromInt(3778), .properties = .{ .param_str = "ffff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fmal + .{ .tag = @enumFromInt(3779), .properties = .{ .param_str = "LdLdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fmax + .{ .tag = @enumFromInt(3780), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fmaxf + .{ .tag = @enumFromInt(3781), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fmaxl + .{ .tag = @enumFromInt(3782), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fmin + .{ .tag = @enumFromInt(3783), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fminf + .{ .tag = @enumFromInt(3784), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fminl + .{ .tag = @enumFromInt(3785), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // fmod + .{ .tag = @enumFromInt(3786), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fmodf + .{ .tag = @enumFromInt(3787), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fmodl + .{ .tag = @enumFromInt(3788), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // fopen + .{ .tag = @enumFromInt(3789), .properties = .{ .param_str = "P*cC*cC*", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true } } }, + // fprintf + .{ .tag = @enumFromInt(3790), .properties = .{ .param_str = "iP*cC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 1 } } }, + // fread + .{ .tag = @enumFromInt(3791), .properties = .{ .param_str = "zv*zzP*", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true } } }, + // free + .{ .tag = @enumFromInt(3792), .properties = .{ .param_str = "vv*", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // frexp + .{ .tag = @enumFromInt(3793), .properties = .{ .param_str = "ddi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // frexpf + .{ .tag = @enumFromInt(3794), .properties = .{ .param_str = "ffi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // frexpl + .{ .tag = @enumFromInt(3795), .properties = .{ .param_str = "LdLdi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // fscanf + .{ .tag = @enumFromInt(3796), .properties = .{ .param_str = "iP*RcC*R.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } }, + // fwrite + .{ .tag = @enumFromInt(3797), .properties = .{ .param_str = "zvC*zzP*", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true } } }, + // getcontext + .{ .tag = @enumFromInt(3798), .properties = .{ .param_str = "iK*", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } }, + // hypot + .{ .tag = @enumFromInt(3799), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // hypotf + .{ .tag = @enumFromInt(3800), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // hypotl + .{ .tag = @enumFromInt(3801), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ilogb + .{ .tag = @enumFromInt(3802), .properties = .{ .param_str = "id", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ilogbf + .{ .tag = @enumFromInt(3803), .properties = .{ .param_str = "if", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ilogbl + .{ .tag = @enumFromInt(3804), .properties = .{ .param_str = "iLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // index + .{ .tag = @enumFromInt(3805), .properties = .{ .param_str = "c*cC*i", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // isalnum + .{ .tag = @enumFromInt(3806), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isalpha + .{ .tag = @enumFromInt(3807), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isblank + .{ .tag = @enumFromInt(3808), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // iscntrl + .{ .tag = @enumFromInt(3809), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isdigit + .{ .tag = @enumFromInt(3810), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isgraph + .{ .tag = @enumFromInt(3811), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // islower + .{ .tag = @enumFromInt(3812), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isprint + .{ .tag = @enumFromInt(3813), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // ispunct + .{ .tag = @enumFromInt(3814), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isspace + .{ .tag = @enumFromInt(3815), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isupper + .{ .tag = @enumFromInt(3816), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // isxdigit + .{ .tag = @enumFromInt(3817), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // labs + .{ .tag = @enumFromInt(3818), .properties = .{ .param_str = "LiLi", .header = .stdlib, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // ldexp + .{ .tag = @enumFromInt(3819), .properties = .{ .param_str = "ddi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ldexpf + .{ .tag = @enumFromInt(3820), .properties = .{ .param_str = "ffi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // ldexpl + .{ .tag = @enumFromInt(3821), .properties = .{ .param_str = "LdLdi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // lgamma + .{ .tag = @enumFromInt(3822), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // lgammaf + .{ .tag = @enumFromInt(3823), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // lgammal + .{ .tag = @enumFromInt(3824), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // llabs + .{ .tag = @enumFromInt(3825), .properties = .{ .param_str = "LLiLLi", .header = .stdlib, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // llrint + .{ .tag = @enumFromInt(3826), .properties = .{ .param_str = "LLid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // llrintf + .{ .tag = @enumFromInt(3827), .properties = .{ .param_str = "LLif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // llrintl + .{ .tag = @enumFromInt(3828), .properties = .{ .param_str = "LLiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // llround + .{ .tag = @enumFromInt(3829), .properties = .{ .param_str = "LLid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // llroundf + .{ .tag = @enumFromInt(3830), .properties = .{ .param_str = "LLif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // llroundl + .{ .tag = @enumFromInt(3831), .properties = .{ .param_str = "LLiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log + .{ .tag = @enumFromInt(3832), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log10 + .{ .tag = @enumFromInt(3833), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log10f + .{ .tag = @enumFromInt(3834), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log10l + .{ .tag = @enumFromInt(3835), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log1p + .{ .tag = @enumFromInt(3836), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log1pf + .{ .tag = @enumFromInt(3837), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log1pl + .{ .tag = @enumFromInt(3838), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log2 + .{ .tag = @enumFromInt(3839), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log2f + .{ .tag = @enumFromInt(3840), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // log2l + .{ .tag = @enumFromInt(3841), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // logb + .{ .tag = @enumFromInt(3842), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // logbf + .{ .tag = @enumFromInt(3843), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // logbl + .{ .tag = @enumFromInt(3844), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // logf + .{ .tag = @enumFromInt(3845), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // logl + .{ .tag = @enumFromInt(3846), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // longjmp + .{ .tag = @enumFromInt(3847), .properties = .{ .param_str = "vJi", .header = .setjmp, .attributes = .{ .noreturn = true, .allow_type_mismatch = true, .lib_function_without_prefix = true } } }, + // lrint + .{ .tag = @enumFromInt(3848), .properties = .{ .param_str = "Lid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // lrintf + .{ .tag = @enumFromInt(3849), .properties = .{ .param_str = "Lif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // lrintl + .{ .tag = @enumFromInt(3850), .properties = .{ .param_str = "LiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // lround + .{ .tag = @enumFromInt(3851), .properties = .{ .param_str = "Lid", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // lroundf + .{ .tag = @enumFromInt(3852), .properties = .{ .param_str = "Lif", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // lroundl + .{ .tag = @enumFromInt(3853), .properties = .{ .param_str = "LiLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // malloc + .{ .tag = @enumFromInt(3854), .properties = .{ .param_str = "v*z", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // memalign + .{ .tag = @enumFromInt(3855), .properties = .{ .param_str = "v*zz", .header = .malloc, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // memccpy + .{ .tag = @enumFromInt(3856), .properties = .{ .param_str = "v*v*vC*iz", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // memchr + .{ .tag = @enumFromInt(3857), .properties = .{ .param_str = "v*vC*iz", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // memcmp + .{ .tag = @enumFromInt(3858), .properties = .{ .param_str = "ivC*vC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // memcpy + .{ .tag = @enumFromInt(3859), .properties = .{ .param_str = "v*v*vC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // memmove + .{ .tag = @enumFromInt(3860), .properties = .{ .param_str = "v*v*vC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // mempcpy + .{ .tag = @enumFromInt(3861), .properties = .{ .param_str = "v*v*vC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // memset + .{ .tag = @enumFromInt(3862), .properties = .{ .param_str = "v*v*iz", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // modf + .{ .tag = @enumFromInt(3863), .properties = .{ .param_str = "ddd*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // modff + .{ .tag = @enumFromInt(3864), .properties = .{ .param_str = "fff*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // modfl + .{ .tag = @enumFromInt(3865), .properties = .{ .param_str = "LdLdLd*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // nan + .{ .tag = @enumFromInt(3866), .properties = .{ .param_str = "dcC*", .header = .math, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // nanf + .{ .tag = @enumFromInt(3867), .properties = .{ .param_str = "fcC*", .header = .math, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // nanl + .{ .tag = @enumFromInt(3868), .properties = .{ .param_str = "LdcC*", .header = .math, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // nearbyint + .{ .tag = @enumFromInt(3869), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // nearbyintf + .{ .tag = @enumFromInt(3870), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // nearbyintl + .{ .tag = @enumFromInt(3871), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // nextafter + .{ .tag = @enumFromInt(3872), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // nextafterf + .{ .tag = @enumFromInt(3873), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // nextafterl + .{ .tag = @enumFromInt(3874), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // nexttoward + .{ .tag = @enumFromInt(3875), .properties = .{ .param_str = "ddLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // nexttowardf + .{ .tag = @enumFromInt(3876), .properties = .{ .param_str = "ffLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // nexttowardl + .{ .tag = @enumFromInt(3877), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // pow + .{ .tag = @enumFromInt(3878), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // powf + .{ .tag = @enumFromInt(3879), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // powl + .{ .tag = @enumFromInt(3880), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // printf + .{ .tag = @enumFromInt(3881), .properties = .{ .param_str = "icC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf } } }, + // realloc + .{ .tag = @enumFromInt(3882), .properties = .{ .param_str = "v*v*z", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // remainder + .{ .tag = @enumFromInt(3883), .properties = .{ .param_str = "ddd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // remainderf + .{ .tag = @enumFromInt(3884), .properties = .{ .param_str = "fff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // remainderl + .{ .tag = @enumFromInt(3885), .properties = .{ .param_str = "LdLdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // remquo + .{ .tag = @enumFromInt(3886), .properties = .{ .param_str = "dddi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // remquof + .{ .tag = @enumFromInt(3887), .properties = .{ .param_str = "fffi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // remquol + .{ .tag = @enumFromInt(3888), .properties = .{ .param_str = "LdLdLdi*", .header = .math, .attributes = .{ .lib_function_without_prefix = true } } }, + // rindex + .{ .tag = @enumFromInt(3889), .properties = .{ .param_str = "c*cC*i", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // rint + .{ .tag = @enumFromInt(3890), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true } } }, + // rintf + .{ .tag = @enumFromInt(3891), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true } } }, + // rintl + .{ .tag = @enumFromInt(3892), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_fp_exceptions = true } } }, + // round + .{ .tag = @enumFromInt(3893), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // roundeven + .{ .tag = @enumFromInt(3894), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // roundevenf + .{ .tag = @enumFromInt(3895), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // roundevenl + .{ .tag = @enumFromInt(3896), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // roundf + .{ .tag = @enumFromInt(3897), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // roundl + .{ .tag = @enumFromInt(3898), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // savectx + .{ .tag = @enumFromInt(3899), .properties = .{ .param_str = "iJ", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } }, + // scalbln + .{ .tag = @enumFromInt(3900), .properties = .{ .param_str = "ddLi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // scalblnf + .{ .tag = @enumFromInt(3901), .properties = .{ .param_str = "ffLi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // scalblnl + .{ .tag = @enumFromInt(3902), .properties = .{ .param_str = "LdLdLi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // scalbn + .{ .tag = @enumFromInt(3903), .properties = .{ .param_str = "ddi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // scalbnf + .{ .tag = @enumFromInt(3904), .properties = .{ .param_str = "ffi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // scalbnl + .{ .tag = @enumFromInt(3905), .properties = .{ .param_str = "LdLdi", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // scanf + .{ .tag = @enumFromInt(3906), .properties = .{ .param_str = "icC*R.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf } } }, + // setjmp + .{ .tag = @enumFromInt(3907), .properties = .{ .param_str = "iJ", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } }, + // siglongjmp + .{ .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 } } }, + // sigsetjmp + .{ .tag = @enumFromInt(3909), .properties = .{ .param_str = "iSJi", .header = .setjmp, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } }, + // sin + .{ .tag = @enumFromInt(3910), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sinf + .{ .tag = @enumFromInt(3911), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sinh + .{ .tag = @enumFromInt(3912), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sinhf + .{ .tag = @enumFromInt(3913), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sinhl + .{ .tag = @enumFromInt(3914), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sinl + .{ .tag = @enumFromInt(3915), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // snprintf + .{ .tag = @enumFromInt(3916), .properties = .{ .param_str = "ic*zcC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 2 } } }, + // sprintf + .{ .tag = @enumFromInt(3917), .properties = .{ .param_str = "ic*cC*.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .printf, .format_string_position = 1 } } }, + // sqrt + .{ .tag = @enumFromInt(3918), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sqrtf + .{ .tag = @enumFromInt(3919), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sqrtl + .{ .tag = @enumFromInt(3920), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // sscanf + .{ .tag = @enumFromInt(3921), .properties = .{ .param_str = "icC*RcC*R.", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .scanf, .format_string_position = 1 } } }, + // stpcpy + .{ .tag = @enumFromInt(3922), .properties = .{ .param_str = "c*c*cC*", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // stpncpy + .{ .tag = @enumFromInt(3923), .properties = .{ .param_str = "c*c*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // strcasecmp + .{ .tag = @enumFromInt(3924), .properties = .{ .param_str = "icC*cC*", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // strcat + .{ .tag = @enumFromInt(3925), .properties = .{ .param_str = "c*c*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strchr + .{ .tag = @enumFromInt(3926), .properties = .{ .param_str = "c*cC*i", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // strcmp + .{ .tag = @enumFromInt(3927), .properties = .{ .param_str = "icC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // strcpy + .{ .tag = @enumFromInt(3928), .properties = .{ .param_str = "c*c*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strcspn + .{ .tag = @enumFromInt(3929), .properties = .{ .param_str = "zcC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strdup + .{ .tag = @enumFromInt(3930), .properties = .{ .param_str = "c*cC*", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // strerror + .{ .tag = @enumFromInt(3931), .properties = .{ .param_str = "c*i", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strlcat + .{ .tag = @enumFromInt(3932), .properties = .{ .param_str = "zc*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // strlcpy + .{ .tag = @enumFromInt(3933), .properties = .{ .param_str = "zc*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // strlen + .{ .tag = @enumFromInt(3934), .properties = .{ .param_str = "zcC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // strncasecmp + .{ .tag = @enumFromInt(3935), .properties = .{ .param_str = "icC*cC*z", .header = .strings, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // strncat + .{ .tag = @enumFromInt(3936), .properties = .{ .param_str = "c*c*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strncmp + .{ .tag = @enumFromInt(3937), .properties = .{ .param_str = "icC*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // strncpy + .{ .tag = @enumFromInt(3938), .properties = .{ .param_str = "c*c*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strndup + .{ .tag = @enumFromInt(3939), .properties = .{ .param_str = "c*cC*z", .header = .string, .language = .all_gnu_languages, .attributes = .{ .lib_function_without_prefix = true } } }, + // strpbrk + .{ .tag = @enumFromInt(3940), .properties = .{ .param_str = "c*cC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strrchr + .{ .tag = @enumFromInt(3941), .properties = .{ .param_str = "c*cC*i", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strspn + .{ .tag = @enumFromInt(3942), .properties = .{ .param_str = "zcC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strstr + .{ .tag = @enumFromInt(3943), .properties = .{ .param_str = "c*cC*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtod + .{ .tag = @enumFromInt(3944), .properties = .{ .param_str = "dcC*c**", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtof + .{ .tag = @enumFromInt(3945), .properties = .{ .param_str = "fcC*c**", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtok + .{ .tag = @enumFromInt(3946), .properties = .{ .param_str = "c*c*cC*", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtol + .{ .tag = @enumFromInt(3947), .properties = .{ .param_str = "LicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtold + .{ .tag = @enumFromInt(3948), .properties = .{ .param_str = "LdcC*c**", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtoll + .{ .tag = @enumFromInt(3949), .properties = .{ .param_str = "LLicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtoul + .{ .tag = @enumFromInt(3950), .properties = .{ .param_str = "ULicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // strtoull + .{ .tag = @enumFromInt(3951), .properties = .{ .param_str = "ULLicC*c**i", .header = .stdlib, .attributes = .{ .lib_function_without_prefix = true } } }, + // strxfrm + .{ .tag = @enumFromInt(3952), .properties = .{ .param_str = "zc*cC*z", .header = .string, .attributes = .{ .lib_function_without_prefix = true } } }, + // tan + .{ .tag = @enumFromInt(3953), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tanf + .{ .tag = @enumFromInt(3954), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tanh + .{ .tag = @enumFromInt(3955), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tanhf + .{ .tag = @enumFromInt(3956), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tanhl + .{ .tag = @enumFromInt(3957), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tanl + .{ .tag = @enumFromInt(3958), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tgamma + .{ .tag = @enumFromInt(3959), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tgammaf + .{ .tag = @enumFromInt(3960), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tgammal + .{ .tag = @enumFromInt(3961), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .lib_function_without_prefix = true, .const_without_errno_and_fp_exceptions = true } } }, + // tolower + .{ .tag = @enumFromInt(3962), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // toupper + .{ .tag = @enumFromInt(3963), .properties = .{ .param_str = "ii", .header = .ctype, .attributes = .{ .pure = true, .lib_function_without_prefix = true } } }, + // trunc + .{ .tag = @enumFromInt(3964), .properties = .{ .param_str = "dd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // truncf + .{ .tag = @enumFromInt(3965), .properties = .{ .param_str = "ff", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // truncl + .{ .tag = @enumFromInt(3966), .properties = .{ .param_str = "LdLd", .header = .math, .attributes = .{ .@"const" = true, .lib_function_without_prefix = true } } }, + // va_copy + .{ .tag = @enumFromInt(3967), .properties = .{ .param_str = "vAA", .header = .stdarg, .attributes = .{ .lib_function_without_prefix = true } } }, + // va_end + .{ .tag = @enumFromInt(3968), .properties = .{ .param_str = "vA", .header = .stdarg, .attributes = .{ .lib_function_without_prefix = true } } }, + // va_start + .{ .tag = @enumFromInt(3969), .properties = .{ .param_str = "vA.", .header = .stdarg, .attributes = .{ .lib_function_without_prefix = true } } }, + // vfork + .{ .tag = @enumFromInt(3970), .properties = .{ .param_str = "p", .header = .unistd, .attributes = .{ .allow_type_mismatch = true, .lib_function_without_prefix = true, .returns_twice = true } } }, + // vfprintf + .{ .tag = @enumFromInt(3971), .properties = .{ .param_str = "iP*cC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } }, + // vfscanf + .{ .tag = @enumFromInt(3972), .properties = .{ .param_str = "iP*RcC*Ra", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } }, + // vprintf + .{ .tag = @enumFromInt(3973), .properties = .{ .param_str = "icC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf } } }, + // vscanf + .{ .tag = @enumFromInt(3974), .properties = .{ .param_str = "icC*Ra", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf } } }, + // vsnprintf + .{ .tag = @enumFromInt(3975), .properties = .{ .param_str = "ic*zcC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 2 } } }, + // vsprintf + .{ .tag = @enumFromInt(3976), .properties = .{ .param_str = "ic*cC*a", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vprintf, .format_string_position = 1 } } }, + // vsscanf + .{ .tag = @enumFromInt(3977), .properties = .{ .param_str = "icC*RcC*Ra", .header = .stdio, .attributes = .{ .lib_function_without_prefix = true, .format_kind = .vscanf, .format_string_position = 1 } } }, + // wcschr + .{ .tag = @enumFromInt(3978), .properties = .{ .param_str = "w*wC*w", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // wcscmp + .{ .tag = @enumFromInt(3979), .properties = .{ .param_str = "iwC*wC*", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // wcslen + .{ .tag = @enumFromInt(3980), .properties = .{ .param_str = "zwC*", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // wcsncmp + .{ .tag = @enumFromInt(3981), .properties = .{ .param_str = "iwC*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // wmemchr + .{ .tag = @enumFromInt(3982), .properties = .{ .param_str = "w*wC*wz", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // wmemcmp + .{ .tag = @enumFromInt(3983), .properties = .{ .param_str = "iwC*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // wmemcpy + .{ .tag = @enumFromInt(3984), .properties = .{ .param_str = "w*w*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + // wmemmove + .{ .tag = @enumFromInt(3985), .properties = .{ .param_str = "w*w*wC*z", .header = .wchar, .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } } }, + }; +}; +}; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/Properties.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/Properties.zig new file mode 100644 index 00000000..72e74759 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/Properties.zig @@ -0,0 +1,143 @@ +const std = @import("std"); + +const Properties = @This(); + +param_str: []const u8, +language: Language = .all_languages, +attributes: Attributes = Attributes{}, +header: Header = .none, +target_set: TargetSet = TargetSet.initOne(.basic), + +/// Header which must be included for a builtin to be available +pub const Header = enum { + none, + /// stdio.h + stdio, + /// stdlib.h + stdlib, + /// setjmpex.h + setjmpex, + /// stdarg.h + stdarg, + /// string.h + string, + /// ctype.h + ctype, + /// wchar.h + wchar, + /// setjmp.h + setjmp, + /// malloc.h + malloc, + /// strings.h + strings, + /// unistd.h + unistd, + /// pthread.h + pthread, + /// math.h + math, + /// complex.h + complex, + /// Blocks.h + blocks, +}; + +/// Languages in which a builtin is available +pub const Language = enum { + all_languages, + all_ms_languages, + all_gnu_languages, + gnu_lang, +}; + +pub const Attributes = packed struct { + /// Function does not return + noreturn: bool = false, + + /// Function has no side effects + pure: bool = false, + + /// Function has no side effects and does not read memory + @"const": bool = false, + + /// Signature is meaningless; use custom typecheck + custom_typecheck: bool = false, + + /// A declaration of this builtin should be recognized even if the type doesn't match the specified signature. + allow_type_mismatch: bool = false, + + /// this is a libc/libm function with a '__builtin_' prefix added. + lib_function_with_builtin_prefix: bool = false, + + /// this is a libc/libm function without a '__builtin_' prefix. This builtin is disableable by '-fno-builtin-foo' + lib_function_without_prefix: bool = false, + + /// Function returns twice (e.g. setjmp) + returns_twice: bool = false, + + /// Nature of the format string passed to this function + format_kind: enum(u3) { + /// Does not take a format string + none, + /// this is a printf-like function whose Nth argument is the format string + printf, + /// function is like vprintf in that it accepts its arguments as a va_list rather than through an ellipsis + vprintf, + /// this is a scanf-like function whose Nth argument is the format string + scanf, + /// the function is like vscanf in that it accepts its arguments as a va_list rather than through an ellipsis + vscanf, + } = .none, + + /// Position of format string argument. Only meaningful if format_kind is not .none + format_string_position: u5 = 0, + + /// if false, arguments are not evaluated + eval_args: bool = true, + + /// no side effects and does not read memory, but only when -fno-math-errno and FP exceptions are ignored + const_without_errno_and_fp_exceptions: bool = false, + + /// no side effects and does not read memory, but only when FP exceptions are ignored + const_without_fp_exceptions: bool = false, + + /// this function can be constant evaluated by the frontend + const_evaluable: bool = false, +}; + +pub const Target = enum { + /// Supported on all targets + basic, + aarch64, + aarch64_neon_sve_bridge, + aarch64_neon_sve_bridge_cg, + amdgpu, + arm, + bpf, + hexagon, + hexagon_dep, + hexagon_map_custom_dep, + loong_arch, + mips, + neon, + nvptx, + ppc, + riscv, + riscv_vector, + sve, + systemz, + ve, + vevl_gen, + webassembly, + x86, + x86_64, + xcore, +}; + +/// Targets for which a builtin is enabled +pub const TargetSet = std.enums.EnumSet(Target); + +pub fn isVarArgs(properties: Properties) bool { + return properties.param_str[properties.param_str.len - 1] == '.'; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/TypeDescription.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/TypeDescription.zig new file mode 100644 index 00000000..aca66e7f --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/TypeDescription.zig @@ -0,0 +1,286 @@ +const std = @import("std"); + +const TypeDescription = @This(); + +prefix: []const Prefix, +spec: Spec, +suffix: []const Suffix, + +pub const Component = union(enum) { + prefix: Prefix, + spec: Spec, + suffix: Suffix, +}; + +pub const ComponentIterator = struct { + str: []const u8, + idx: usize, + + pub fn init(str: []const u8) ComponentIterator { + return .{ + .str = str, + .idx = 0, + }; + } + + pub fn peek(self: *ComponentIterator) ?Component { + const idx = self.idx; + defer self.idx = idx; + return self.next(); + } + + pub fn next(self: *ComponentIterator) ?Component { + if (self.idx == self.str.len) return null; + const c = self.str[self.idx]; + self.idx += 1; + switch (c) { + 'L' => { + if (self.str[self.idx] != 'L') return .{ .prefix = .L }; + self.idx += 1; + if (self.str[self.idx] != 'L') return .{ .prefix = .LL }; + self.idx += 1; + return .{ .prefix = .LLL }; + }, + 'Z' => return .{ .prefix = .Z }, + 'W' => return .{ .prefix = .W }, + 'N' => return .{ .prefix = .N }, + 'O' => return .{ .prefix = .O }, + 'S' => { + if (self.str[self.idx] == 'J') { + self.idx += 1; + return .{ .spec = .SJ }; + } + return .{ .prefix = .S }; + }, + 'U' => return .{ .prefix = .U }, + 'I' => return .{ .prefix = .I }, + + 'v' => return .{ .spec = .v }, + 'b' => return .{ .spec = .b }, + 'c' => return .{ .spec = .c }, + 's' => return .{ .spec = .s }, + 'i' => return .{ .spec = .i }, + 'h' => return .{ .spec = .h }, + 'x' => return .{ .spec = .x }, + 'y' => return .{ .spec = .y }, + 'f' => return .{ .spec = .f }, + 'd' => return .{ .spec = .d }, + 'z' => return .{ .spec = .z }, + 'w' => return .{ .spec = .w }, + 'F' => return .{ .spec = .F }, + 'G' => return .{ .spec = .G }, + 'H' => return .{ .spec = .H }, + 'M' => return .{ .spec = .M }, + 'a' => return .{ .spec = .a }, + 'A' => return .{ .spec = .A }, + 'V', 'q', 'E' => { + const start = self.idx; + while (std.ascii.isDigit(self.str[self.idx])) : (self.idx += 1) {} + const count = std.fmt.parseUnsigned(u32, self.str[start..self.idx], 10) catch unreachable; + return switch (c) { + 'V' => .{ .spec = .{ .V = count } }, + 'q' => .{ .spec = .{ .q = count } }, + 'E' => .{ .spec = .{ .E = count } }, + else => unreachable, + }; + }, + 'X' => { + defer self.idx += 1; + switch (self.str[self.idx]) { + 'f' => return .{ .spec = .{ .X = .float } }, + 'd' => return .{ .spec = .{ .X = .double } }, + 'L' => { + self.idx += 1; + return .{ .spec = .{ .X = .longdouble } }; + }, + else => unreachable, + } + }, + 'Y' => return .{ .spec = .Y }, + 'P' => return .{ .spec = .P }, + 'J' => return .{ .spec = .J }, + 'K' => return .{ .spec = .K }, + 'p' => return .{ .spec = .p }, + '.' => { + // can only appear at end of param string; indicates varargs function + std.debug.assert(self.idx == self.str.len); + return null; + }, + '!' => { + std.debug.assert(self.str.len == 1); + return .{ .spec = .@"!" }; + }, + + '*' => { + if (self.idx < self.str.len and std.ascii.isDigit(self.str[self.idx])) { + defer self.idx += 1; + const addr_space = self.str[self.idx] - '0'; + return .{ .suffix = .{ .@"*" = addr_space } }; + } else { + return .{ .suffix = .{ .@"*" = null } }; + } + }, + 'C' => return .{ .suffix = .C }, + 'D' => return .{ .suffix = .D }, + 'R' => return .{ .suffix = .R }, + else => unreachable, + } + return null; + } +}; + +pub const TypeIterator = struct { + param_str: []const u8, + prefix: [4]Prefix, + spec: Spec, + suffix: [4]Suffix, + idx: usize, + + pub fn init(param_str: []const u8) TypeIterator { + return .{ + .param_str = param_str, + .prefix = undefined, + .spec = undefined, + .suffix = undefined, + .idx = 0, + }; + } + + /// Returned `TypeDescription` contains fields which are slices into the underlying `TypeIterator` + /// The returned value is invalidated when `.next()` is called again or the TypeIterator goes out + // of scope. + pub fn next(self: *TypeIterator) ?TypeDescription { + var it = ComponentIterator.init(self.param_str[self.idx..]); + defer self.idx += it.idx; + + var prefix_count: usize = 0; + var maybe_spec: ?Spec = null; + var suffix_count: usize = 0; + while (it.peek()) |component| { + switch (component) { + .prefix => |prefix| { + if (maybe_spec != null) break; + self.prefix[prefix_count] = prefix; + prefix_count += 1; + }, + .spec => |spec| { + if (maybe_spec != null) break; + maybe_spec = spec; + }, + .suffix => |suffix| { + std.debug.assert(maybe_spec != null); + self.suffix[suffix_count] = suffix; + suffix_count += 1; + }, + } + _ = it.next(); + } + if (maybe_spec) |spec| { + return TypeDescription{ + .prefix = self.prefix[0..prefix_count], + .spec = spec, + .suffix = self.suffix[0..suffix_count], + }; + } + return null; + } +}; + +const Prefix = enum { + /// long (e.g. Li for 'long int', Ld for 'long double') + L, + /// long long (e.g. LLi for 'long long int', LLd for __float128) + LL, + /// __int128_t (e.g. LLLi) + LLL, + /// int32_t (require a native 32-bit integer type on the target) + Z, + /// int64_t (require a native 64-bit integer type on the target) + W, + /// 'int' size if target is LP64, 'L' otherwise. + N, + /// long for OpenCL targets, long long otherwise. + O, + /// signed + S, + /// unsigned + U, + /// Required to constant fold to an integer constant expression. + I, +}; + +const Spec = union(enum) { + /// void + v, + /// boolean + b, + /// char + c, + /// short + s, + /// int + i, + /// half (__fp16, OpenCL) + h, + /// half (_Float16) + x, + /// half (__bf16) + y, + /// float + f, + /// double + d, + /// size_t + z, + /// wchar_t + w, + /// constant CFString + F, + /// id + G, + /// SEL + H, + /// struct objc_super + M, + /// __builtin_va_list + a, + /// "reference" to __builtin_va_list + A, + /// Vector, followed by the number of elements and the base type. + V: u32, + /// Scalable vector, followed by the number of elements and the base type. + q: u32, + /// ext_vector, followed by the number of elements and the base type. + E: u32, + /// _Complex, followed by the base type. + X: enum { + float, + double, + longdouble, + }, + /// ptrdiff_t + Y, + /// FILE + P, + /// jmp_buf + J, + /// sigjmp_buf + SJ, + /// ucontext_t + K, + /// pid_t + p, + /// Used to indicate a builtin with target-dependent param types. Must appear by itself + @"!", +}; + +const Suffix = union(enum) { + /// pointer (optionally followed by an address space number,if no address space is specified than any address space will be accepted) + @"*": ?u8, + /// const + C, + /// volatile + D, + /// restrict + R, +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/eval.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/eval.zig new file mode 100644 index 00000000..008da152 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Builtins/eval.zig @@ -0,0 +1,86 @@ +const std = @import("std"); +const backend = @import("../../backend.zig"); +const Interner = backend.Interner; +const Builtins = @import("../Builtins.zig"); +const Builtin = Builtins.Builtin; +const Parser = @import("../Parser.zig"); +const Tree = @import("../Tree.zig"); +const NodeIndex = Tree.NodeIndex; +const Type = @import("../Type.zig"); +const Value = @import("../Value.zig"); + +fn makeNan(comptime T: type, str: []const u8) T { + const UnsignedSameSize = std.meta.Int(.unsigned, @bitSizeOf(T)); + const parsed = std.fmt.parseUnsigned(UnsignedSameSize, str[0 .. str.len - 1], 0) catch 0; + const bits: switch (T) { + f32 => u23, + f64 => u52, + f80 => u63, + f128 => u112, + else => @compileError("Invalid type for makeNan"), + } = @truncate(parsed); + return @bitCast(@as(UnsignedSameSize, bits) | @as(UnsignedSameSize, @bitCast(std.math.nan(T)))); +} + +pub fn eval(tag: Builtin.Tag, p: *Parser, args: []const NodeIndex) !Value { + const builtin = Builtin.fromTag(tag); + if (!builtin.properties.attributes.const_evaluable) return .{}; + + switch (tag) { + Builtin.tagFromName("__builtin_inff").?, + Builtin.tagFromName("__builtin_inf").?, + Builtin.tagFromName("__builtin_infl").?, + => { + const ty: Type = switch (tag) { + Builtin.tagFromName("__builtin_inff").? => .{ .specifier = .float }, + Builtin.tagFromName("__builtin_inf").? => .{ .specifier = .double }, + Builtin.tagFromName("__builtin_infl").? => .{ .specifier = .long_double }, + else => unreachable, + }; + const f: Interner.Key.Float = switch (ty.bitSizeof(p.comp).?) { + 32 => .{ .f32 = std.math.inf(f32) }, + 64 => .{ .f64 = std.math.inf(f64) }, + 80 => .{ .f80 = std.math.inf(f80) }, + 128 => .{ .f128 = std.math.inf(f128) }, + else => unreachable, + }; + return Value.intern(p.comp, .{ .float = f }); + }, + Builtin.tagFromName("__builtin_isinf").? => blk: { + if (args.len == 0) break :blk; + const val = p.value_map.get(args[0]) orelse break :blk; + return Value.fromBool(val.isInf(p.comp)); + }, + Builtin.tagFromName("__builtin_isinf_sign").? => blk: { + if (args.len == 0) break :blk; + const val = p.value_map.get(args[0]) orelse break :blk; + switch (val.isInfSign(p.comp)) { + .unknown => {}, + .finite => return Value.zero, + .positive => return Value.one, + .negative => return Value.int(@as(i64, -1), p.comp), + } + }, + Builtin.tagFromName("__builtin_isnan").? => blk: { + if (args.len == 0) break :blk; + const val = p.value_map.get(args[0]) orelse break :blk; + return Value.fromBool(val.isNan(p.comp)); + }, + Builtin.tagFromName("__builtin_nan").? => blk: { + if (args.len == 0) break :blk; + const val = p.getDecayedStringLiteral(args[0]) orelse break :blk; + const bytes = p.comp.interner.get(val.ref()).bytes; + + const f: Interner.Key.Float = switch ((Type{ .specifier = .double }).bitSizeof(p.comp).?) { + 32 => .{ .f32 = makeNan(f32, bytes) }, + 64 => .{ .f64 = makeNan(f64, bytes) }, + 80 => .{ .f80 = makeNan(f80, bytes) }, + 128 => .{ .f128 = makeNan(f128, bytes) }, + else => unreachable, + }; + return Value.intern(p.comp, .{ .float = f }); + }, + else => {}, + } + return .{}; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/CodeGen.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/CodeGen.zig new file mode 100644 index 00000000..bfffb411 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/CodeGen.zig @@ -0,0 +1,1295 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const backend = @import("../backend.zig"); +const Interner = backend.Interner; +const Ir = backend.Ir; +const Builtins = @import("Builtins.zig"); +const Builtin = Builtins.Builtin; +const Compilation = @import("Compilation.zig"); +const Builder = Ir.Builder; +const StrInt = @import("StringInterner.zig"); +const StringId = StrInt.StringId; +const Tree = @import("Tree.zig"); +const NodeIndex = Tree.NodeIndex; +const Type = @import("Type.zig"); +const Value = @import("Value.zig"); + +const WipSwitch = struct { + cases: Cases = .{}, + default: ?Ir.Ref = null, + size: u64, + + const Cases = std.MultiArrayList(struct { + val: Interner.Ref, + label: Ir.Ref, + }); +}; + +const Symbol = struct { + name: StringId, + val: Ir.Ref, +}; + +const Error = Compilation.Error; + +const CodeGen = @This(); + +tree: Tree, +comp: *Compilation, +builder: Builder, +node_tag: []const Tree.Tag, +node_data: []const Tree.Node.Data, +node_ty: []const Type, +wip_switch: *WipSwitch = undefined, +symbols: std.ArrayListUnmanaged(Symbol) = .empty, +ret_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .empty, +phi_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .empty, +record_elem_buf: std.ArrayListUnmanaged(Interner.Ref) = .empty, +record_cache: std.AutoHashMapUnmanaged(*Type.Record, Interner.Ref) = .empty, +cond_dummy_ty: ?Interner.Ref = null, +bool_invert: bool = false, +bool_end_label: Ir.Ref = .none, +cond_dummy_ref: Ir.Ref = undefined, +continue_label: Ir.Ref = undefined, +break_label: Ir.Ref = undefined, +return_label: Ir.Ref = undefined, + +fn fail(c: *CodeGen, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } { + try c.comp.diagnostics.list.append(c.comp.gpa, .{ + .tag = .cli_error, + .kind = .@"fatal error", + .extra = .{ .str = try std.fmt.allocPrint(c.comp.diagnostics.arena.allocator(), fmt, args) }, + }); + return error.FatalError; +} + +pub fn genIr(tree: Tree) Compilation.Error!Ir { + const gpa = tree.comp.gpa; + var c = CodeGen{ + .builder = .{ + .gpa = tree.comp.gpa, + .interner = &tree.comp.interner, + .arena = std.heap.ArenaAllocator.init(gpa), + }, + .tree = tree, + .comp = tree.comp, + .node_tag = tree.nodes.items(.tag), + .node_data = tree.nodes.items(.data), + .node_ty = tree.nodes.items(.ty), + }; + defer c.symbols.deinit(gpa); + defer c.ret_nodes.deinit(gpa); + defer c.phi_nodes.deinit(gpa); + defer c.record_elem_buf.deinit(gpa); + defer c.record_cache.deinit(gpa); + defer c.builder.deinit(); + + const node_tags = tree.nodes.items(.tag); + for (tree.root_decls) |decl| { + c.builder.arena.deinit(); + c.builder.arena = std.heap.ArenaAllocator.init(gpa); + + switch (node_tags[@intFromEnum(decl)]) { + .static_assert, + .typedef, + .struct_decl_two, + .union_decl_two, + .enum_decl_two, + .struct_decl, + .union_decl, + .enum_decl, + => {}, + + .fn_proto, + .static_fn_proto, + .inline_fn_proto, + .inline_static_fn_proto, + .extern_var, + .threadlocal_extern_var, + => {}, + + .fn_def, + .static_fn_def, + .inline_fn_def, + .inline_static_fn_def, + => c.genFn(decl) catch |err| switch (err) { + error.FatalError => return error.FatalError, + error.OutOfMemory => return error.OutOfMemory, + }, + + .@"var", + .static_var, + .threadlocal_var, + .threadlocal_static_var, + => c.genVar(decl) catch |err| switch (err) { + error.FatalError => return error.FatalError, + error.OutOfMemory => return error.OutOfMemory, + }, + else => unreachable, + } + } + return c.builder.finish(); +} + +fn genType(c: *CodeGen, base_ty: Type) !Interner.Ref { + var key: Interner.Key = undefined; + const ty = base_ty.canonicalize(.standard); + switch (ty.specifier) { + .void => return .void, + .bool => return .i1, + .@"struct" => { + if (c.record_cache.get(ty.data.record)) |some| return some; + + const elem_buf_top = c.record_elem_buf.items.len; + defer c.record_elem_buf.items.len = elem_buf_top; + + for (ty.data.record.fields) |field| { + if (!field.isRegularField()) { + return c.fail("TODO lower struct bitfields", .{}); + } + // TODO handle padding bits + const field_ref = try c.genType(field.ty); + try c.record_elem_buf.append(c.builder.gpa, field_ref); + } + + return c.builder.interner.put(c.builder.gpa, .{ + .record_ty = c.record_elem_buf.items[elem_buf_top..], + }); + }, + .@"union" => { + return c.fail("TODO lower union types", .{}); + }, + else => {}, + } + if (ty.isPtr()) return .ptr; + if (ty.isFunc()) return .func; + if (!ty.isReal()) return c.fail("TODO lower complex types", .{}); + if (ty.isInt()) { + const bits = ty.bitSizeof(c.comp).?; + key = .{ .int_ty = @intCast(bits) }; + } else if (ty.isFloat()) { + const bits = ty.bitSizeof(c.comp).?; + key = .{ .float_ty = @intCast(bits) }; + } else if (ty.isArray()) { + const elem = try c.genType(ty.elemType()); + key = .{ .array_ty = .{ .child = elem, .len = ty.arrayLen().? } }; + } else if (ty.specifier == .vector) { + const elem = try c.genType(ty.elemType()); + key = .{ .vector_ty = .{ .child = elem, .len = @intCast(ty.data.array.len) } }; + } else if (ty.is(.nullptr_t)) { + return c.fail("TODO lower nullptr_t", .{}); + } + return c.builder.interner.put(c.builder.gpa, key); +} + +fn genFn(c: *CodeGen, decl: NodeIndex) Error!void { + const name = c.tree.tokSlice(c.node_data[@intFromEnum(decl)].decl.name); + const func_ty = c.node_ty[@intFromEnum(decl)].canonicalize(.standard); + c.ret_nodes.items.len = 0; + + try c.builder.startFn(); + + for (func_ty.data.func.params) |param| { + // TODO handle calling convention here + const arg = try c.builder.addArg(try c.genType(param.ty)); + + const size: u32 = @intCast(param.ty.sizeof(c.comp).?); // TODO add error in parser + const @"align" = param.ty.alignof(c.comp); + const alloc = try c.builder.addAlloc(size, @"align"); + try c.builder.addStore(alloc, arg); + try c.symbols.append(c.comp.gpa, .{ .name = param.name, .val = alloc }); + } + + // Generate body + c.return_label = try c.builder.makeLabel("return"); + try c.genStmt(c.node_data[@intFromEnum(decl)].decl.node); + + // Relocate returns + if (c.ret_nodes.items.len == 0) { + _ = try c.builder.addInst(.ret, .{ .un = .none }, .noreturn); + } else if (c.ret_nodes.items.len == 1) { + c.builder.body.items.len -= 1; + _ = try c.builder.addInst(.ret, .{ .un = c.ret_nodes.items[0].value }, .noreturn); + } else { + try c.builder.startBlock(c.return_label); + const phi = try c.builder.addPhi(c.ret_nodes.items, try c.genType(func_ty.returnType())); + _ = try c.builder.addInst(.ret, .{ .un = phi }, .noreturn); + } + + try c.builder.finishFn(name); +} + +fn addUn(c: *CodeGen, tag: Ir.Inst.Tag, operand: Ir.Ref, ty: Type) !Ir.Ref { + return c.builder.addInst(tag, .{ .un = operand }, try c.genType(ty)); +} + +fn addBin(c: *CodeGen, tag: Ir.Inst.Tag, lhs: Ir.Ref, rhs: Ir.Ref, ty: Type) !Ir.Ref { + return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, try c.genType(ty)); +} + +fn addBranch(c: *CodeGen, cond: Ir.Ref, true_label: Ir.Ref, false_label: Ir.Ref) !void { + if (true_label == c.bool_end_label) { + if (false_label == c.bool_end_label) { + try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = cond }); + return; + } + try c.addBoolPhi(!c.bool_invert); + } + if (false_label == c.bool_end_label) { + try c.addBoolPhi(c.bool_invert); + } + return c.builder.addBranch(cond, true_label, false_label); +} + +fn addBoolPhi(c: *CodeGen, value: bool) !void { + const val = try c.builder.addConstant((try Value.int(@intFromBool(value), c.comp)).ref(), .i1); + try c.phi_nodes.append(c.comp.gpa, .{ .label = c.builder.current_label, .value = val }); +} + +fn genStmt(c: *CodeGen, node: NodeIndex) Error!void { + _ = try c.genExpr(node); +} + +fn genExpr(c: *CodeGen, node: NodeIndex) Error!Ir.Ref { + std.debug.assert(node != .none); + const ty = c.node_ty[@intFromEnum(node)]; + if (c.tree.value_map.get(node)) |val| { + return c.builder.addConstant(val.ref(), try c.genType(ty)); + } + const data = c.node_data[@intFromEnum(node)]; + switch (c.node_tag[@intFromEnum(node)]) { + .enumeration_ref, + .bool_literal, + .int_literal, + .char_literal, + .float_literal, + .imaginary_literal, + .string_literal_expr, + .alignof_expr, + => unreachable, // These should have an entry in value_map. + .fn_def, + .static_fn_def, + .inline_fn_def, + .inline_static_fn_def, + .invalid, + .threadlocal_var, + => unreachable, + .static_assert, + .fn_proto, + .static_fn_proto, + .inline_fn_proto, + .inline_static_fn_proto, + .extern_var, + .threadlocal_extern_var, + .typedef, + .struct_decl_two, + .union_decl_two, + .enum_decl_two, + .struct_decl, + .union_decl, + .enum_decl, + .enum_field_decl, + .record_field_decl, + .indirect_record_field_decl, + .struct_forward_decl, + .union_forward_decl, + .enum_forward_decl, + .null_stmt, + => {}, + .static_var, + .implicit_static_var, + .threadlocal_static_var, + => try c.genVar(node), // TODO + .@"var" => { + const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser + const @"align" = ty.alignof(c.comp); + const alloc = try c.builder.addAlloc(size, @"align"); + const name = try StrInt.intern(c.comp, c.tree.tokSlice(data.decl.name)); + try c.symbols.append(c.comp.gpa, .{ .name = name, .val = alloc }); + if (data.decl.node != .none) { + try c.genInitializer(alloc, ty, data.decl.node); + } + }, + .labeled_stmt => { + const label = try c.builder.makeLabel("label"); + try c.builder.startBlock(label); + try c.genStmt(data.decl.node); + }, + .compound_stmt_two => { + const old_sym_len = c.symbols.items.len; + c.symbols.items.len = old_sym_len; + + if (data.bin.lhs != .none) try c.genStmt(data.bin.lhs); + if (data.bin.rhs != .none) try c.genStmt(data.bin.rhs); + }, + .compound_stmt => { + const old_sym_len = c.symbols.items.len; + c.symbols.items.len = old_sym_len; + + for (c.tree.data[data.range.start..data.range.end]) |stmt| try c.genStmt(stmt); + }, + .if_then_else_stmt => { + const then_label = try c.builder.makeLabel("if.then"); + const else_label = try c.builder.makeLabel("if.else"); + const end_label = try c.builder.makeLabel("if.end"); + + try c.genBoolExpr(data.if3.cond, then_label, else_label); + + try c.builder.startBlock(then_label); + try c.genStmt(c.tree.data[data.if3.body]); // then + try c.builder.addJump(end_label); + + try c.builder.startBlock(else_label); + try c.genStmt(c.tree.data[data.if3.body + 1]); // else + + try c.builder.startBlock(end_label); + }, + .if_then_stmt => { + const then_label = try c.builder.makeLabel("if.then"); + const end_label = try c.builder.makeLabel("if.end"); + + try c.genBoolExpr(data.bin.lhs, then_label, end_label); + + try c.builder.startBlock(then_label); + try c.genStmt(data.bin.rhs); // then + try c.builder.startBlock(end_label); + }, + .switch_stmt => { + var wip_switch = WipSwitch{ + .size = c.node_ty[@intFromEnum(data.bin.lhs)].sizeof(c.comp).?, + }; + defer wip_switch.cases.deinit(c.builder.gpa); + + const old_wip_switch = c.wip_switch; + defer c.wip_switch = old_wip_switch; + c.wip_switch = &wip_switch; + + const old_break_label = c.break_label; + defer c.break_label = old_break_label; + const end_ref = try c.builder.makeLabel("switch.end"); + c.break_label = end_ref; + + const cond = try c.genExpr(data.bin.lhs); + const switch_index = c.builder.instructions.len; + _ = try c.builder.addInst(.@"switch", undefined, .noreturn); + + try c.genStmt(data.bin.rhs); // body + + const default_ref = wip_switch.default orelse end_ref; + try c.builder.startBlock(end_ref); + + const a = c.builder.arena.allocator(); + const switch_data = try a.create(Ir.Inst.Switch); + switch_data.* = .{ + .target = cond, + .cases_len = @intCast(wip_switch.cases.len), + .case_vals = (try a.dupe(Interner.Ref, wip_switch.cases.items(.val))).ptr, + .case_labels = (try a.dupe(Ir.Ref, wip_switch.cases.items(.label))).ptr, + .default = default_ref, + }; + c.builder.instructions.items(.data)[switch_index] = .{ .@"switch" = switch_data }; + }, + .case_stmt => { + const val = c.tree.value_map.get(data.bin.lhs).?; + const label = try c.builder.makeLabel("case"); + try c.builder.startBlock(label); + try c.wip_switch.cases.append(c.builder.gpa, .{ + .val = val.ref(), + .label = label, + }); + try c.genStmt(data.bin.rhs); + }, + .default_stmt => { + const default = try c.builder.makeLabel("default"); + try c.builder.startBlock(default); + c.wip_switch.default = default; + try c.genStmt(data.un); + }, + .while_stmt => { + const old_break_label = c.break_label; + defer c.break_label = old_break_label; + + const old_continue_label = c.continue_label; + defer c.continue_label = old_continue_label; + + const cond_label = try c.builder.makeLabel("while.cond"); + const then_label = try c.builder.makeLabel("while.then"); + const end_label = try c.builder.makeLabel("while.end"); + + c.continue_label = cond_label; + c.break_label = end_label; + + try c.builder.startBlock(cond_label); + try c.genBoolExpr(data.bin.lhs, then_label, end_label); + + try c.builder.startBlock(then_label); + try c.genStmt(data.bin.rhs); + try c.builder.addJump(cond_label); + try c.builder.startBlock(end_label); + }, + .do_while_stmt => { + const old_break_label = c.break_label; + defer c.break_label = old_break_label; + + const old_continue_label = c.continue_label; + defer c.continue_label = old_continue_label; + + const then_label = try c.builder.makeLabel("do.then"); + const cond_label = try c.builder.makeLabel("do.cond"); + const end_label = try c.builder.makeLabel("do.end"); + + c.continue_label = cond_label; + c.break_label = end_label; + + try c.builder.startBlock(then_label); + try c.genStmt(data.bin.rhs); + + try c.builder.startBlock(cond_label); + try c.genBoolExpr(data.bin.lhs, then_label, end_label); + + try c.builder.startBlock(end_label); + }, + .for_decl_stmt => { + const old_break_label = c.break_label; + defer c.break_label = old_break_label; + + const old_continue_label = c.continue_label; + defer c.continue_label = old_continue_label; + + const for_decl = data.forDecl(&c.tree); + for (for_decl.decls) |decl| try c.genStmt(decl); + + const then_label = try c.builder.makeLabel("for.then"); + var cond_label = then_label; + const cont_label = try c.builder.makeLabel("for.cont"); + const end_label = try c.builder.makeLabel("for.end"); + + c.continue_label = cont_label; + c.break_label = end_label; + + if (for_decl.cond != .none) { + cond_label = try c.builder.makeLabel("for.cond"); + try c.builder.startBlock(cond_label); + try c.genBoolExpr(for_decl.cond, then_label, end_label); + } + try c.builder.startBlock(then_label); + try c.genStmt(for_decl.body); + if (for_decl.incr != .none) { + _ = try c.genExpr(for_decl.incr); + } + try c.builder.addJump(cond_label); + try c.builder.startBlock(end_label); + }, + .forever_stmt => { + const old_break_label = c.break_label; + defer c.break_label = old_break_label; + + const old_continue_label = c.continue_label; + defer c.continue_label = old_continue_label; + + const then_label = try c.builder.makeLabel("for.then"); + const end_label = try c.builder.makeLabel("for.end"); + + c.continue_label = then_label; + c.break_label = end_label; + + try c.builder.startBlock(then_label); + try c.genStmt(data.un); + try c.builder.startBlock(end_label); + }, + .for_stmt => { + const old_break_label = c.break_label; + defer c.break_label = old_break_label; + + const old_continue_label = c.continue_label; + defer c.continue_label = old_continue_label; + + const for_stmt = data.forStmt(&c.tree); + if (for_stmt.init != .none) _ = try c.genExpr(for_stmt.init); + + const then_label = try c.builder.makeLabel("for.then"); + var cond_label = then_label; + const cont_label = try c.builder.makeLabel("for.cont"); + const end_label = try c.builder.makeLabel("for.end"); + + c.continue_label = cont_label; + c.break_label = end_label; + + if (for_stmt.cond != .none) { + cond_label = try c.builder.makeLabel("for.cond"); + try c.builder.startBlock(cond_label); + try c.genBoolExpr(for_stmt.cond, then_label, end_label); + } + try c.builder.startBlock(then_label); + try c.genStmt(for_stmt.body); + if (for_stmt.incr != .none) { + _ = try c.genExpr(for_stmt.incr); + } + try c.builder.addJump(cond_label); + try c.builder.startBlock(end_label); + }, + .continue_stmt => try c.builder.addJump(c.continue_label), + .break_stmt => try c.builder.addJump(c.break_label), + .return_stmt => { + if (data.un != .none) { + const operand = try c.genExpr(data.un); + try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label }); + } + try c.builder.addJump(c.return_label); + }, + .implicit_return => { + if (data.return_zero) { + const operand = try c.builder.addConstant(.zero, try c.genType(ty)); + try c.ret_nodes.append(c.comp.gpa, .{ .value = operand, .label = c.builder.current_label }); + } + // No need to emit a jump since implicit_return is always the last instruction. + }, + .case_range_stmt, + .goto_stmt, + .computed_goto_stmt, + .nullptr_literal, + => return c.fail("TODO CodeGen.genStmt {}\n", .{c.node_tag[@intFromEnum(node)]}), + .comma_expr => { + _ = try c.genExpr(data.bin.lhs); + return c.genExpr(data.bin.rhs); + }, + .assign_expr => { + const rhs = try c.genExpr(data.bin.rhs); + const lhs = try c.genLval(data.bin.lhs); + try c.builder.addStore(lhs, rhs); + return rhs; + }, + .mul_assign_expr => return c.genCompoundAssign(node, .mul), + .div_assign_expr => return c.genCompoundAssign(node, .div), + .mod_assign_expr => return c.genCompoundAssign(node, .mod), + .add_assign_expr => return c.genCompoundAssign(node, .add), + .sub_assign_expr => return c.genCompoundAssign(node, .sub), + .shl_assign_expr => return c.genCompoundAssign(node, .bit_shl), + .shr_assign_expr => return c.genCompoundAssign(node, .bit_shr), + .bit_and_assign_expr => return c.genCompoundAssign(node, .bit_and), + .bit_xor_assign_expr => return c.genCompoundAssign(node, .bit_xor), + .bit_or_assign_expr => return c.genCompoundAssign(node, .bit_or), + .bit_or_expr => return c.genBinOp(node, .bit_or), + .bit_xor_expr => return c.genBinOp(node, .bit_xor), + .bit_and_expr => return c.genBinOp(node, .bit_and), + .equal_expr => { + const cmp = try c.genComparison(node, .cmp_eq); + return c.addUn(.zext, cmp, ty); + }, + .not_equal_expr => { + const cmp = try c.genComparison(node, .cmp_ne); + return c.addUn(.zext, cmp, ty); + }, + .less_than_expr => { + const cmp = try c.genComparison(node, .cmp_lt); + return c.addUn(.zext, cmp, ty); + }, + .less_than_equal_expr => { + const cmp = try c.genComparison(node, .cmp_lte); + return c.addUn(.zext, cmp, ty); + }, + .greater_than_expr => { + const cmp = try c.genComparison(node, .cmp_gt); + return c.addUn(.zext, cmp, ty); + }, + .greater_than_equal_expr => { + const cmp = try c.genComparison(node, .cmp_gte); + return c.addUn(.zext, cmp, ty); + }, + .shl_expr => return c.genBinOp(node, .bit_shl), + .shr_expr => return c.genBinOp(node, .bit_shr), + .add_expr => { + if (ty.isPtr()) { + const lhs_ty = c.node_ty[@intFromEnum(data.bin.lhs)]; + if (lhs_ty.isPtr()) { + const ptr = try c.genExpr(data.bin.lhs); + const offset = try c.genExpr(data.bin.rhs); + const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)]; + return c.genPtrArithmetic(ptr, offset, offset_ty, ty); + } else { + const offset = try c.genExpr(data.bin.lhs); + const ptr = try c.genExpr(data.bin.rhs); + const offset_ty = lhs_ty; + return c.genPtrArithmetic(ptr, offset, offset_ty, ty); + } + } + return c.genBinOp(node, .add); + }, + .sub_expr => { + if (ty.isPtr()) { + const ptr = try c.genExpr(data.bin.lhs); + const offset = try c.genExpr(data.bin.rhs); + const offset_ty = c.node_ty[@intFromEnum(data.bin.rhs)]; + return c.genPtrArithmetic(ptr, offset, offset_ty, ty); + } + return c.genBinOp(node, .sub); + }, + .mul_expr => return c.genBinOp(node, .mul), + .div_expr => return c.genBinOp(node, .div), + .mod_expr => return c.genBinOp(node, .mod), + .addr_of_expr => return try c.genLval(data.un), + .deref_expr => { + const un_data = c.node_data[@intFromEnum(data.un)]; + if (c.node_tag[@intFromEnum(data.un)] == .implicit_cast and un_data.cast.kind == .function_to_pointer) { + return c.genExpr(data.un); + } + const operand = try c.genLval(data.un); + return c.addUn(.load, operand, ty); + }, + .plus_expr => return c.genExpr(data.un), + .negate_expr => { + const zero = try c.builder.addConstant(.zero, try c.genType(ty)); + const operand = try c.genExpr(data.un); + return c.addBin(.sub, zero, operand, ty); + }, + .bit_not_expr => { + const operand = try c.genExpr(data.un); + return c.addUn(.bit_not, operand, ty); + }, + .bool_not_expr => { + const zero = try c.builder.addConstant(.zero, try c.genType(ty)); + const operand = try c.genExpr(data.un); + return c.addBin(.cmp_ne, zero, operand, ty); + }, + .pre_inc_expr => { + const operand = try c.genLval(data.un); + const val = try c.addUn(.load, operand, ty); + const one = try c.builder.addConstant(.one, try c.genType(ty)); + const plus_one = try c.addBin(.add, val, one, ty); + try c.builder.addStore(operand, plus_one); + return plus_one; + }, + .pre_dec_expr => { + const operand = try c.genLval(data.un); + const val = try c.addUn(.load, operand, ty); + const one = try c.builder.addConstant(.one, try c.genType(ty)); + const plus_one = try c.addBin(.sub, val, one, ty); + try c.builder.addStore(operand, plus_one); + return plus_one; + }, + .post_inc_expr => { + const operand = try c.genLval(data.un); + const val = try c.addUn(.load, operand, ty); + const one = try c.builder.addConstant(.one, try c.genType(ty)); + const plus_one = try c.addBin(.add, val, one, ty); + try c.builder.addStore(operand, plus_one); + return val; + }, + .post_dec_expr => { + const operand = try c.genLval(data.un); + const val = try c.addUn(.load, operand, ty); + const one = try c.builder.addConstant(.one, try c.genType(ty)); + const plus_one = try c.addBin(.sub, val, one, ty); + try c.builder.addStore(operand, plus_one); + return val; + }, + .paren_expr => return c.genExpr(data.un), + .decl_ref_expr => unreachable, // Lval expression. + .explicit_cast, .implicit_cast => switch (data.cast.kind) { + .no_op => return c.genExpr(data.cast.operand), + .to_void => { + _ = try c.genExpr(data.cast.operand); + return .none; + }, + .lval_to_rval => { + const operand = try c.genLval(data.cast.operand); + return c.addUn(.load, operand, ty); + }, + .function_to_pointer, .array_to_pointer => { + return c.genLval(data.cast.operand); + }, + .int_cast => { + const operand = try c.genExpr(data.cast.operand); + const src_ty = c.node_ty[@intFromEnum(data.cast.operand)]; + const src_bits = src_ty.bitSizeof(c.comp).?; + const dest_bits = ty.bitSizeof(c.comp).?; + if (src_bits == dest_bits) { + return operand; + } else if (src_bits < dest_bits) { + if (src_ty.isUnsignedInt(c.comp)) + return c.addUn(.zext, operand, ty) + else + return c.addUn(.sext, operand, ty); + } else { + return c.addUn(.trunc, operand, ty); + } + }, + .bool_to_int => { + const operand = try c.genExpr(data.cast.operand); + return c.addUn(.zext, operand, ty); + }, + .pointer_to_bool, .int_to_bool, .float_to_bool => { + const lhs = try c.genExpr(data.cast.operand); + const rhs = try c.builder.addConstant(.zero, try c.genType(c.node_ty[@intFromEnum(node)])); + return c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1); + }, + .bitcast, + .pointer_to_int, + .bool_to_float, + .bool_to_pointer, + .int_to_float, + .complex_int_to_complex_float, + .int_to_pointer, + .float_to_int, + .complex_float_to_complex_int, + .complex_int_cast, + .complex_int_to_real, + .real_to_complex_int, + .float_cast, + .complex_float_cast, + .complex_float_to_real, + .real_to_complex_float, + .null_to_pointer, + .union_cast, + .vector_splat, + => return c.fail("TODO CodeGen gen CastKind {}\n", .{data.cast.kind}), + }, + .binary_cond_expr => { + if (c.tree.value_map.get(data.if3.cond)) |cond| { + if (cond.toBool(c.comp)) { + c.cond_dummy_ref = try c.genExpr(data.if3.cond); + return c.genExpr(c.tree.data[data.if3.body]); // then + } else { + return c.genExpr(c.tree.data[data.if3.body + 1]); // else + } + } + + const then_label = try c.builder.makeLabel("ternary.then"); + const else_label = try c.builder.makeLabel("ternary.else"); + const end_label = try c.builder.makeLabel("ternary.end"); + const cond_ty = c.node_ty[@intFromEnum(data.if3.cond)]; + { + const old_cond_dummy_ty = c.cond_dummy_ty; + defer c.cond_dummy_ty = old_cond_dummy_ty; + c.cond_dummy_ty = try c.genType(cond_ty); + + try c.genBoolExpr(data.if3.cond, then_label, else_label); + } + + try c.builder.startBlock(then_label); + if (c.builder.instructions.items(.ty)[@intFromEnum(c.cond_dummy_ref)] == .i1) { + c.cond_dummy_ref = try c.addUn(.zext, c.cond_dummy_ref, cond_ty); + } + const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then + try c.builder.addJump(end_label); + const then_exit = c.builder.current_label; + + try c.builder.startBlock(else_label); + const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else + const else_exit = c.builder.current_label; + + try c.builder.startBlock(end_label); + + var phi_buf: [2]Ir.Inst.Phi.Input = .{ + .{ .value = then_val, .label = then_exit }, + .{ .value = else_val, .label = else_exit }, + }; + return c.builder.addPhi(&phi_buf, try c.genType(ty)); + }, + .cond_dummy_expr => return c.cond_dummy_ref, + .cond_expr => { + if (c.tree.value_map.get(data.if3.cond)) |cond| { + if (cond.toBool(c.comp)) { + return c.genExpr(c.tree.data[data.if3.body]); // then + } else { + return c.genExpr(c.tree.data[data.if3.body + 1]); // else + } + } + + const then_label = try c.builder.makeLabel("ternary.then"); + const else_label = try c.builder.makeLabel("ternary.else"); + const end_label = try c.builder.makeLabel("ternary.end"); + + try c.genBoolExpr(data.if3.cond, then_label, else_label); + + try c.builder.startBlock(then_label); + const then_val = try c.genExpr(c.tree.data[data.if3.body]); // then + try c.builder.addJump(end_label); + const then_exit = c.builder.current_label; + + try c.builder.startBlock(else_label); + const else_val = try c.genExpr(c.tree.data[data.if3.body + 1]); // else + const else_exit = c.builder.current_label; + + try c.builder.startBlock(end_label); + + var phi_buf: [2]Ir.Inst.Phi.Input = .{ + .{ .value = then_val, .label = then_exit }, + .{ .value = else_val, .label = else_exit }, + }; + return c.builder.addPhi(&phi_buf, try c.genType(ty)); + }, + .call_expr_one => if (data.bin.rhs == .none) { + return c.genCall(data.bin.lhs, &.{}, ty); + } else { + return c.genCall(data.bin.lhs, &.{data.bin.rhs}, ty); + }, + .call_expr => { + return c.genCall(c.tree.data[data.range.start], c.tree.data[data.range.start + 1 .. data.range.end], ty); + }, + .bool_or_expr => { + if (c.tree.value_map.get(data.bin.lhs)) |lhs| { + if (!lhs.toBool(c.comp)) { + return c.builder.addConstant(.one, try c.genType(ty)); + } + return c.genExpr(data.bin.rhs); + } + + const false_label = try c.builder.makeLabel("bool_false"); + const exit_label = try c.builder.makeLabel("bool_exit"); + + const old_bool_end_label = c.bool_end_label; + defer c.bool_end_label = old_bool_end_label; + c.bool_end_label = exit_label; + + const phi_nodes_top = c.phi_nodes.items.len; + defer c.phi_nodes.items.len = phi_nodes_top; + + try c.genBoolExpr(data.bin.lhs, exit_label, false_label); + + try c.builder.startBlock(false_label); + try c.genBoolExpr(data.bin.rhs, exit_label, exit_label); + + try c.builder.startBlock(exit_label); + + const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1); + return c.addUn(.zext, phi, ty); + }, + .bool_and_expr => { + if (c.tree.value_map.get(data.bin.lhs)) |lhs| { + if (!lhs.toBool(c.comp)) { + return c.builder.addConstant(.zero, try c.genType(ty)); + } + return c.genExpr(data.bin.rhs); + } + + const true_label = try c.builder.makeLabel("bool_true"); + const exit_label = try c.builder.makeLabel("bool_exit"); + + const old_bool_end_label = c.bool_end_label; + defer c.bool_end_label = old_bool_end_label; + c.bool_end_label = exit_label; + + const phi_nodes_top = c.phi_nodes.items.len; + defer c.phi_nodes.items.len = phi_nodes_top; + + try c.genBoolExpr(data.bin.lhs, true_label, exit_label); + + try c.builder.startBlock(true_label); + try c.genBoolExpr(data.bin.rhs, exit_label, exit_label); + + try c.builder.startBlock(exit_label); + + const phi = try c.builder.addPhi(c.phi_nodes.items[phi_nodes_top..], .i1); + return c.addUn(.zext, phi, ty); + }, + .builtin_choose_expr => { + const cond = c.tree.value_map.get(data.if3.cond).?; + if (cond.toBool(c.comp)) { + return c.genExpr(c.tree.data[data.if3.body]); + } else { + return c.genExpr(c.tree.data[data.if3.body + 1]); + } + }, + .generic_expr_one => { + const index = @intFromEnum(data.bin.rhs); + switch (c.node_tag[index]) { + .generic_association_expr, .generic_default_expr => { + return c.genExpr(c.node_data[index].un); + }, + else => unreachable, + } + }, + .generic_expr => { + const index = @intFromEnum(c.tree.data[data.range.start + 1]); + switch (c.node_tag[index]) { + .generic_association_expr, .generic_default_expr => { + return c.genExpr(c.node_data[index].un); + }, + else => unreachable, + } + }, + .generic_association_expr, .generic_default_expr => unreachable, + .stmt_expr => switch (c.node_tag[@intFromEnum(data.un)]) { + .compound_stmt_two => { + const old_sym_len = c.symbols.items.len; + c.symbols.items.len = old_sym_len; + + const stmt_data = c.node_data[@intFromEnum(data.un)]; + if (stmt_data.bin.rhs == .none) return c.genExpr(stmt_data.bin.lhs); + try c.genStmt(stmt_data.bin.lhs); + return c.genExpr(stmt_data.bin.rhs); + }, + .compound_stmt => { + const old_sym_len = c.symbols.items.len; + c.symbols.items.len = old_sym_len; + + const stmt_data = c.node_data[@intFromEnum(data.un)]; + for (c.tree.data[stmt_data.range.start .. stmt_data.range.end - 1]) |stmt| try c.genStmt(stmt); + return c.genExpr(c.tree.data[stmt_data.range.end]); + }, + else => unreachable, + }, + .builtin_call_expr_one => { + const name = c.tree.tokSlice(data.decl.name); + const builtin = c.comp.builtins.lookup(name).builtin; + if (data.decl.node == .none) { + return c.genBuiltinCall(builtin, &.{}, ty); + } else { + return c.genBuiltinCall(builtin, &.{data.decl.node}, ty); + } + }, + .builtin_call_expr => { + const name_node_idx = c.tree.data[data.range.start]; + const name = c.tree.tokSlice(@intFromEnum(name_node_idx)); + const builtin = c.comp.builtins.lookup(name).builtin; + return c.genBuiltinCall(builtin, c.tree.data[data.range.start + 1 .. data.range.end], ty); + }, + .addr_of_label, + .imag_expr, + .real_expr, + .sizeof_expr, + .special_builtin_call_one, + => return c.fail("TODO CodeGen.genExpr {}\n", .{c.node_tag[@intFromEnum(node)]}), + else => unreachable, // Not an expression. + } + return .none; +} + +fn genLval(c: *CodeGen, node: NodeIndex) Error!Ir.Ref { + std.debug.assert(node != .none); + assert(c.tree.isLval(node)); + const data = c.node_data[@intFromEnum(node)]; + switch (c.node_tag[@intFromEnum(node)]) { + .string_literal_expr => { + const val = c.tree.value_map.get(node).?; + return c.builder.addConstant(val.ref(), .ptr); + }, + .paren_expr => return c.genLval(data.un), + .decl_ref_expr => { + const slice = c.tree.tokSlice(data.decl_ref); + const name = try StrInt.intern(c.comp, slice); + var i = c.symbols.items.len; + while (i > 0) { + i -= 1; + if (c.symbols.items[i].name == name) { + return c.symbols.items[i].val; + } + } + + const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice); + const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len); + try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr }); + return ref; + }, + .deref_expr => return c.genExpr(data.un), + .compound_literal_expr => { + const ty = c.node_ty[@intFromEnum(node)]; + const size: u32 = @intCast(ty.sizeof(c.comp).?); // TODO add error in parser + const @"align" = ty.alignof(c.comp); + const alloc = try c.builder.addAlloc(size, @"align"); + try c.genInitializer(alloc, ty, data.un); + return alloc; + }, + .builtin_choose_expr => { + const cond = c.tree.value_map.get(data.if3.cond).?; + if (cond.toBool(c.comp)) { + return c.genLval(c.tree.data[data.if3.body]); + } else { + return c.genLval(c.tree.data[data.if3.body + 1]); + } + }, + .member_access_expr, + .member_access_ptr_expr, + .array_access_expr, + .static_compound_literal_expr, + .thread_local_compound_literal_expr, + .static_thread_local_compound_literal_expr, + => return c.fail("TODO CodeGen.genLval {}\n", .{c.node_tag[@intFromEnum(node)]}), + else => unreachable, // Not an lval expression. + } +} + +fn genBoolExpr(c: *CodeGen, base: NodeIndex, true_label: Ir.Ref, false_label: Ir.Ref) Error!void { + var node = base; + while (true) switch (c.node_tag[@intFromEnum(node)]) { + .paren_expr => { + node = c.node_data[@intFromEnum(node)].un; + }, + else => break, + }; + + const data = c.node_data[@intFromEnum(node)]; + switch (c.node_tag[@intFromEnum(node)]) { + .bool_or_expr => { + if (c.tree.value_map.get(data.bin.lhs)) |lhs| { + if (lhs.toBool(c.comp)) { + if (true_label == c.bool_end_label) { + return c.addBoolPhi(!c.bool_invert); + } + return c.builder.addJump(true_label); + } + return c.genBoolExpr(data.bin.rhs, true_label, false_label); + } + + const new_false_label = try c.builder.makeLabel("bool_false"); + try c.genBoolExpr(data.bin.lhs, true_label, new_false_label); + try c.builder.startBlock(new_false_label); + + if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty); + return c.genBoolExpr(data.bin.rhs, true_label, false_label); + }, + .bool_and_expr => { + if (c.tree.value_map.get(data.bin.lhs)) |lhs| { + if (!lhs.toBool(c.comp)) { + if (false_label == c.bool_end_label) { + return c.addBoolPhi(c.bool_invert); + } + return c.builder.addJump(false_label); + } + return c.genBoolExpr(data.bin.rhs, true_label, false_label); + } + + const new_true_label = try c.builder.makeLabel("bool_true"); + try c.genBoolExpr(data.bin.lhs, new_true_label, false_label); + try c.builder.startBlock(new_true_label); + + if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty); + return c.genBoolExpr(data.bin.rhs, true_label, false_label); + }, + .bool_not_expr => { + c.bool_invert = !c.bool_invert; + defer c.bool_invert = !c.bool_invert; + + if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.zero, ty); + return c.genBoolExpr(data.un, false_label, true_label); + }, + .equal_expr => { + const cmp = try c.genComparison(node, .cmp_eq); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp; + return c.addBranch(cmp, true_label, false_label); + }, + .not_equal_expr => { + const cmp = try c.genComparison(node, .cmp_ne); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp; + return c.addBranch(cmp, true_label, false_label); + }, + .less_than_expr => { + const cmp = try c.genComparison(node, .cmp_lt); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp; + return c.addBranch(cmp, true_label, false_label); + }, + .less_than_equal_expr => { + const cmp = try c.genComparison(node, .cmp_lte); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp; + return c.addBranch(cmp, true_label, false_label); + }, + .greater_than_expr => { + const cmp = try c.genComparison(node, .cmp_gt); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp; + return c.addBranch(cmp, true_label, false_label); + }, + .greater_than_equal_expr => { + const cmp = try c.genComparison(node, .cmp_gte); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp; + return c.addBranch(cmp, true_label, false_label); + }, + .explicit_cast, .implicit_cast => switch (data.cast.kind) { + .bool_to_int => { + const operand = try c.genExpr(data.cast.operand); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = operand; + return c.addBranch(operand, true_label, false_label); + }, + else => {}, + }, + .binary_cond_expr => { + if (c.tree.value_map.get(data.if3.cond)) |cond| { + if (cond.toBool(c.comp)) { + return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then + } else { + return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else + } + } + + const new_false_label = try c.builder.makeLabel("ternary.else"); + try c.genBoolExpr(data.if3.cond, true_label, new_false_label); + + try c.builder.startBlock(new_false_label); + if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty); + return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else + }, + .cond_expr => { + if (c.tree.value_map.get(data.if3.cond)) |cond| { + if (cond.toBool(c.comp)) { + return c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then + } else { + return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else + } + } + + const new_true_label = try c.builder.makeLabel("ternary.then"); + const new_false_label = try c.builder.makeLabel("ternary.else"); + try c.genBoolExpr(data.if3.cond, new_true_label, new_false_label); + + try c.builder.startBlock(new_true_label); + try c.genBoolExpr(c.tree.data[data.if3.body], true_label, false_label); // then + try c.builder.startBlock(new_false_label); + if (c.cond_dummy_ty) |ty| c.cond_dummy_ref = try c.builder.addConstant(.one, ty); + return c.genBoolExpr(c.tree.data[data.if3.body + 1], true_label, false_label); // else + }, + else => {}, + } + + if (c.tree.value_map.get(node)) |value| { + if (value.toBool(c.comp)) { + if (true_label == c.bool_end_label) { + return c.addBoolPhi(!c.bool_invert); + } + return c.builder.addJump(true_label); + } else { + if (false_label == c.bool_end_label) { + return c.addBoolPhi(c.bool_invert); + } + return c.builder.addJump(false_label); + } + } + + // Assume int operand. + const lhs = try c.genExpr(node); + const rhs = try c.builder.addConstant(.zero, try c.genType(c.node_ty[@intFromEnum(node)])); + const cmp = try c.builder.addInst(.cmp_ne, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1); + if (c.cond_dummy_ty != null) c.cond_dummy_ref = cmp; + try c.addBranch(cmp, true_label, false_label); +} + +fn genBuiltinCall(c: *CodeGen, builtin: Builtin, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref { + _ = arg_nodes; + _ = ty; + return c.fail("TODO CodeGen.genBuiltinCall {s}\n", .{Builtin.nameFromTag(builtin.tag).span()}); +} + +fn genCall(c: *CodeGen, fn_node: NodeIndex, arg_nodes: []const NodeIndex, ty: Type) Error!Ir.Ref { + // Detect direct calls. + const fn_ref = blk: { + const data = c.node_data[@intFromEnum(fn_node)]; + if (c.node_tag[@intFromEnum(fn_node)] != .implicit_cast or data.cast.kind != .function_to_pointer) { + break :blk try c.genExpr(fn_node); + } + + var cur = @intFromEnum(data.cast.operand); + while (true) switch (c.node_tag[cur]) { + .paren_expr, .addr_of_expr, .deref_expr => { + cur = @intFromEnum(c.node_data[cur].un); + }, + .implicit_cast => { + const cast = c.node_data[cur].cast; + if (cast.kind != .function_to_pointer) { + break :blk try c.genExpr(fn_node); + } + cur = @intFromEnum(cast.operand); + }, + .decl_ref_expr => { + const slice = c.tree.tokSlice(c.node_data[cur].decl_ref); + const name = try StrInt.intern(c.comp, slice); + var i = c.symbols.items.len; + while (i > 0) { + i -= 1; + if (c.symbols.items[i].name == name) { + break :blk try c.genExpr(fn_node); + } + } + + const duped_name = try c.builder.arena.allocator().dupeZ(u8, slice); + const ref: Ir.Ref = @enumFromInt(c.builder.instructions.len); + try c.builder.instructions.append(c.builder.gpa, .{ .tag = .symbol, .data = .{ .label = duped_name }, .ty = .ptr }); + break :blk ref; + }, + else => break :blk try c.genExpr(fn_node), + }; + }; + + const args = try c.builder.arena.allocator().alloc(Ir.Ref, arg_nodes.len); + for (arg_nodes, args) |node, *arg| { + // TODO handle calling convention here + arg.* = try c.genExpr(node); + } + // TODO handle variadic call + const call = try c.builder.arena.allocator().create(Ir.Inst.Call); + call.* = .{ + .func = fn_ref, + .args_len = @intCast(args.len), + .args_ptr = args.ptr, + }; + return c.builder.addInst(.call, .{ .call = call }, try c.genType(ty)); +} + +fn genCompoundAssign(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref { + const bin = c.node_data[@intFromEnum(node)].bin; + const ty = c.node_ty[@intFromEnum(node)]; + const rhs = try c.genExpr(bin.rhs); + const lhs = try c.genLval(bin.lhs); + const res = try c.addBin(tag, lhs, rhs, ty); + try c.builder.addStore(lhs, res); + return res; +} + +fn genBinOp(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref { + const bin = c.node_data[@intFromEnum(node)].bin; + const ty = c.node_ty[@intFromEnum(node)]; + const lhs = try c.genExpr(bin.lhs); + const rhs = try c.genExpr(bin.rhs); + return c.addBin(tag, lhs, rhs, ty); +} + +fn genComparison(c: *CodeGen, node: NodeIndex, tag: Ir.Inst.Tag) Error!Ir.Ref { + const bin = c.node_data[@intFromEnum(node)].bin; + const lhs = try c.genExpr(bin.lhs); + const rhs = try c.genExpr(bin.rhs); + + return c.builder.addInst(tag, .{ .bin = .{ .lhs = lhs, .rhs = rhs } }, .i1); +} + +fn genPtrArithmetic(c: *CodeGen, ptr: Ir.Ref, offset: Ir.Ref, offset_ty: Type, ty: Type) Error!Ir.Ref { + // TODO consider adding a getelemptr instruction + const size = ty.elemType().sizeof(c.comp).?; + if (size == 1) { + return c.builder.addInst(.add, .{ .bin = .{ .lhs = ptr, .rhs = offset } }, try c.genType(ty)); + } + + const size_inst = try c.builder.addConstant((try Value.int(size, c.comp)).ref(), try c.genType(offset_ty)); + const offset_inst = try c.addBin(.mul, offset, size_inst, offset_ty); + return c.addBin(.add, ptr, offset_inst, offset_ty); +} + +fn genInitializer(c: *CodeGen, ptr: Ir.Ref, dest_ty: Type, initializer: NodeIndex) Error!void { + std.debug.assert(initializer != .none); + switch (c.node_tag[@intFromEnum(initializer)]) { + .array_init_expr_two, + .array_init_expr, + .struct_init_expr_two, + .struct_init_expr, + .union_init_expr, + .array_filler_expr, + .default_init_expr, + => return c.fail("TODO CodeGen.genInitializer {}\n", .{c.node_tag[@intFromEnum(initializer)]}), + .string_literal_expr => { + const val = c.tree.value_map.get(initializer).?; + const str_ptr = try c.builder.addConstant(val.ref(), .ptr); + if (dest_ty.isArray()) { + return c.fail("TODO memcpy\n", .{}); + } else { + try c.builder.addStore(ptr, str_ptr); + } + }, + else => { + const res = try c.genExpr(initializer); + try c.builder.addStore(ptr, res); + }, + } +} + +fn genVar(c: *CodeGen, decl: NodeIndex) Error!void { + _ = decl; + return c.fail("TODO CodeGen.genVar\n", .{}); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Compilation.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Compilation.zig new file mode 100644 index 00000000..68bad1a5 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Compilation.zig @@ -0,0 +1,1740 @@ +const std = @import("std"); +const Allocator = mem.Allocator; +const assert = std.debug.assert; +const EpochSeconds = std.time.epoch.EpochSeconds; +const mem = std.mem; +const Interner = @import("../backend.zig").Interner; +const Builtins = @import("Builtins.zig"); +const Builtin = Builtins.Builtin; +const Diagnostics = @import("Diagnostics.zig"); +const LangOpts = @import("LangOpts.zig"); +const Source = @import("Source.zig"); +const Tokenizer = @import("Tokenizer.zig"); +const Token = Tokenizer.Token; +const Type = @import("Type.zig"); +const Pragma = @import("Pragma.zig"); +const StrInt = @import("StringInterner.zig"); +const record_layout = @import("record_layout.zig"); +const target_util = @import("target.zig"); + +pub const Error = error{ + /// A fatal error has ocurred and compilation has stopped. + FatalError, +} || Allocator.Error; + +pub const bit_int_max_bits = std.math.maxInt(u16); +const path_buf_stack_limit = 1024; + +/// Environment variables used during compilation / linking. +pub const Environment = struct { + /// Directory to use for temporary files + /// TODO: not implemented yet + tmpdir: ?[]const u8 = null, + + /// PATH environment variable used to search for programs + path: ?[]const u8 = null, + + /// Directories to try when searching for subprograms. + /// TODO: not implemented yet + compiler_path: ?[]const u8 = null, + + /// Directories to try when searching for special linker files, if compiling for the native target + /// TODO: not implemented yet + library_path: ?[]const u8 = null, + + /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line + /// Used regardless of the language being compiled + /// TODO: not implemented yet + cpath: ?[]const u8 = null, + + /// List of directories to be searched as if specified with -I, but after any paths given with -I options on the command line + /// Used if the language being compiled is C + /// TODO: not implemented yet + c_include_path: ?[]const u8 = null, + + /// UNIX timestamp to be used instead of the current date and time in the __DATE__ and __TIME__ macros + source_date_epoch: ?[]const u8 = null, + + /// Load all of the environment variables using the std.process API. Do not use if using Aro as a shared library on Linux without libc + /// See https://github.com/ziglang/zig/issues/4524 + pub fn loadAll(allocator: std.mem.Allocator) !Environment { + var env: Environment = .{}; + errdefer env.deinit(allocator); + + inline for (@typeInfo(@TypeOf(env)).@"struct".fields) |field| { + std.debug.assert(@field(env, field.name) == null); + + var env_var_buf: [field.name.len]u8 = undefined; + const env_var_name = std.ascii.upperString(&env_var_buf, field.name); + const val: ?[]const u8 = std.process.getEnvVarOwned(allocator, env_var_name) catch |err| switch (err) { + error.OutOfMemory => |e| return e, + error.EnvironmentVariableNotFound => null, + error.InvalidWtf8 => null, + }; + @field(env, field.name) = val; + } + return env; + } + + /// Use this only if environment slices were allocated with `allocator` (such as via `loadAll`) + pub fn deinit(self: *Environment, allocator: std.mem.Allocator) void { + inline for (@typeInfo(@TypeOf(self.*)).@"struct".fields) |field| { + if (@field(self, field.name)) |slice| { + allocator.free(slice); + } + } + self.* = undefined; + } +}; + +const Compilation = @This(); + +gpa: Allocator, +diagnostics: Diagnostics, + +environment: Environment = .{}, +sources: std.StringArrayHashMapUnmanaged(Source) = .empty, +include_dirs: std.ArrayListUnmanaged([]const u8) = .empty, +system_include_dirs: std.ArrayListUnmanaged([]const u8) = .empty, +target: std.Target = @import("builtin").target, +pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .empty, +langopts: LangOpts = .{}, +generated_buf: std.ArrayListUnmanaged(u8) = .empty, +builtins: Builtins = .{}, +types: struct { + wchar: Type = undefined, + uint_least16_t: Type = undefined, + uint_least32_t: Type = undefined, + ptrdiff: Type = undefined, + size: Type = undefined, + va_list: Type = undefined, + pid_t: Type = undefined, + ns_constant_string: struct { + ty: Type = undefined, + record: Type.Record = undefined, + fields: [4]Type.Record.Field = undefined, + int_ty: Type = .{ .specifier = .int, .qual = .{ .@"const" = true } }, + char_ty: Type = .{ .specifier = .char, .qual = .{ .@"const" = true } }, + } = .{}, + file: Type = .{ .specifier = .invalid }, + jmp_buf: Type = .{ .specifier = .invalid }, + sigjmp_buf: Type = .{ .specifier = .invalid }, + ucontext_t: Type = .{ .specifier = .invalid }, + intmax: Type = .{ .specifier = .invalid }, + intptr: Type = .{ .specifier = .invalid }, + int16: Type = .{ .specifier = .invalid }, + int64: Type = .{ .specifier = .invalid }, +} = .{}, +string_interner: StrInt = .{}, +interner: Interner = .{}, +/// If this is not null, the directory containing the specified Source will be searched for includes +/// Used by MS extensions which allow searching for includes relative to the directory of the main source file. +ms_cwd_source_id: ?Source.Id = null, +cwd: std.fs.Dir, + +pub fn init(gpa: Allocator, cwd: std.fs.Dir) Compilation { + return .{ + .gpa = gpa, + .diagnostics = Diagnostics.init(gpa), + .cwd = cwd, + }; +} + +/// Initialize Compilation with default environment, +/// pragma handlers and emulation mode set to target. +pub fn initDefault(gpa: Allocator, cwd: std.fs.Dir) !Compilation { + var comp: Compilation = .{ + .gpa = gpa, + .environment = try Environment.loadAll(gpa), + .diagnostics = Diagnostics.init(gpa), + .cwd = cwd, + }; + errdefer comp.deinit(); + try comp.addDefaultPragmaHandlers(); + comp.langopts.setEmulatedCompiler(target_util.systemCompiler(comp.target)); + return comp; +} + +pub fn deinit(comp: *Compilation) void { + for (comp.pragma_handlers.values()) |pragma| { + pragma.deinit(pragma, comp); + } + for (comp.sources.values()) |source| { + comp.gpa.free(source.path); + comp.gpa.free(source.buf); + comp.gpa.free(source.splice_locs); + } + comp.sources.deinit(comp.gpa); + comp.diagnostics.deinit(); + comp.include_dirs.deinit(comp.gpa); + for (comp.system_include_dirs.items) |path| comp.gpa.free(path); + comp.system_include_dirs.deinit(comp.gpa); + comp.pragma_handlers.deinit(comp.gpa); + comp.generated_buf.deinit(comp.gpa); + comp.builtins.deinit(comp.gpa); + comp.string_interner.deinit(comp.gpa); + comp.interner.deinit(comp.gpa); + comp.environment.deinit(comp.gpa); +} + +pub fn getSourceEpoch(self: *const Compilation, max: i64) !?i64 { + const provided = self.environment.source_date_epoch orelse return null; + const parsed = std.fmt.parseInt(i64, provided, 10) catch return error.InvalidEpoch; + if (parsed < 0 or parsed > max) return error.InvalidEpoch; + return parsed; +} + +/// Dec 31 9999 23:59:59 +const max_timestamp = 253402300799; + +fn getTimestamp(comp: *Compilation) !u47 { + const provided: ?i64 = comp.getSourceEpoch(max_timestamp) catch blk: { + try comp.addDiagnostic(.{ + .tag = .invalid_source_epoch, + .loc = .{ .id = .unused, .byte_offset = 0, .line = 0 }, + }, &.{}); + break :blk null; + }; + const timestamp = provided orelse std.time.timestamp(); + return @intCast(std.math.clamp(timestamp, 0, max_timestamp)); +} + +fn generateDateAndTime(w: anytype, timestamp: u47) !void { + const epoch_seconds = EpochSeconds{ .secs = timestamp }; + const epoch_day = epoch_seconds.getEpochDay(); + const day_seconds = epoch_seconds.getDaySeconds(); + const year_day = epoch_day.calculateYearDay(); + const month_day = year_day.calculateMonthDay(); + + const month_names = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + std.debug.assert(std.time.epoch.Month.jan.numeric() == 1); + + const month_name = month_names[month_day.month.numeric() - 1]; + try w.print("#define __DATE__ \"{s} {d: >2} {d}\"\n", .{ + month_name, + month_day.day_index + 1, + year_day.year, + }); + try w.print("#define __TIME__ \"{d:0>2}:{d:0>2}:{d:0>2}\"\n", .{ + day_seconds.getHoursIntoDay(), + day_seconds.getMinutesIntoHour(), + day_seconds.getSecondsIntoMinute(), + }); + + const day_names = [_][]const u8{ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; + const day_name = day_names[@intCast((epoch_day.day + 3) % 7)]; + try w.print("#define __TIMESTAMP__ \"{s} {s} {d: >2} {d:0>2}:{d:0>2}:{d:0>2} {d}\"\n", .{ + day_name, + month_name, + month_day.day_index + 1, + day_seconds.getHoursIntoDay(), + day_seconds.getMinutesIntoHour(), + day_seconds.getSecondsIntoMinute(), + year_day.year, + }); +} + +/// Which set of system defines to generate via generateBuiltinMacros +pub const SystemDefinesMode = enum { + /// Only define macros required by the C standard (date/time macros and those beginning with `__STDC`) + no_system_defines, + /// Define the standard set of system macros + include_system_defines, +}; + +fn generateSystemDefines(comp: *Compilation, w: anytype) !void { + const ptr_width = comp.target.ptrBitWidth(); + + if (comp.langopts.gnuc_version > 0) { + try w.print("#define __GNUC__ {d}\n", .{comp.langopts.gnuc_version / 10_000}); + try w.print("#define __GNUC_MINOR__ {d}\n", .{comp.langopts.gnuc_version / 100 % 100}); + try w.print("#define __GNUC_PATCHLEVEL__ {d}\n", .{comp.langopts.gnuc_version % 100}); + } + + // os macros + switch (comp.target.os.tag) { + .linux => try w.writeAll( + \\#define linux 1 + \\#define __linux 1 + \\#define __linux__ 1 + \\ + ), + .windows => if (ptr_width == 32) try w.writeAll( + \\#define WIN32 1 + \\#define _WIN32 1 + \\#define __WIN32 1 + \\#define __WIN32__ 1 + \\ + ) else try w.writeAll( + \\#define WIN32 1 + \\#define WIN64 1 + \\#define _WIN32 1 + \\#define _WIN64 1 + \\#define __WIN32 1 + \\#define __WIN64 1 + \\#define __WIN32__ 1 + \\#define __WIN64__ 1 + \\ + ), + .freebsd => try w.print("#define __FreeBSD__ {d}\n", .{comp.target.os.version_range.semver.min.major}), + .netbsd => try w.writeAll("#define __NetBSD__ 1\n"), + .openbsd => try w.writeAll("#define __OpenBSD__ 1\n"), + .dragonfly => try w.writeAll("#define __DragonFly__ 1\n"), + .solaris => try w.writeAll( + \\#define sun 1 + \\#define __sun 1 + \\ + ), + .macos => try w.writeAll( + \\#define __APPLE__ 1 + \\#define __MACH__ 1 + \\ + ), + else => {}, + } + + // unix and other additional os macros + switch (comp.target.os.tag) { + .freebsd, + .netbsd, + .openbsd, + .dragonfly, + .linux, + => try w.writeAll( + \\#define unix 1 + \\#define __unix 1 + \\#define __unix__ 1 + \\ + ), + else => {}, + } + if (comp.target.abi.isAndroid()) { + try w.writeAll("#define __ANDROID__ 1\n"); + } + + // architecture macros + switch (comp.target.cpu.arch) { + .x86_64 => try w.writeAll( + \\#define __amd64__ 1 + \\#define __amd64 1 + \\#define __x86_64 1 + \\#define __x86_64__ 1 + \\ + ), + .x86 => try w.writeAll( + \\#define i386 1 + \\#define __i386 1 + \\#define __i386__ 1 + \\ + ), + .mips, + .mipsel, + .mips64, + .mips64el, + => try w.writeAll( + \\#define __mips__ 1 + \\#define mips 1 + \\ + ), + .powerpc, + .powerpcle, + => try w.writeAll( + \\#define __powerpc__ 1 + \\#define __POWERPC__ 1 + \\#define __ppc__ 1 + \\#define __PPC__ 1 + \\#define _ARCH_PPC 1 + \\ + ), + .powerpc64, + .powerpc64le, + => try w.writeAll( + \\#define __powerpc 1 + \\#define __powerpc__ 1 + \\#define __powerpc64__ 1 + \\#define __POWERPC__ 1 + \\#define __ppc__ 1 + \\#define __ppc64__ 1 + \\#define __PPC__ 1 + \\#define __PPC64__ 1 + \\#define _ARCH_PPC 1 + \\#define _ARCH_PPC64 1 + \\ + ), + .sparc64 => try w.writeAll( + \\#define __sparc__ 1 + \\#define __sparc 1 + \\#define __sparc_v9__ 1 + \\ + ), + .sparc => try w.writeAll( + \\#define __sparc__ 1 + \\#define __sparc 1 + \\ + ), + .arm, .armeb => try w.writeAll( + \\#define __arm__ 1 + \\#define __arm 1 + \\ + ), + .thumb, .thumbeb => try w.writeAll( + \\#define __arm__ 1 + \\#define __arm 1 + \\#define __thumb__ 1 + \\ + ), + .aarch64, .aarch64_be => try w.writeAll("#define __aarch64__ 1\n"), + .msp430 => try w.writeAll( + \\#define MSP430 1 + \\#define __MSP430__ 1 + \\ + ), + else => {}, + } + + if (comp.target.os.tag != .windows) switch (ptr_width) { + 64 => try w.writeAll( + \\#define _LP64 1 + \\#define __LP64__ 1 + \\ + ), + 32 => try w.writeAll("#define _ILP32 1\n"), + else => {}, + }; + + try w.writeAll( + \\#define __ORDER_LITTLE_ENDIAN__ 1234 + \\#define __ORDER_BIG_ENDIAN__ 4321 + \\#define __ORDER_PDP_ENDIAN__ 3412 + \\ + ); + if (comp.target.cpu.arch.endian() == .little) try w.writeAll( + \\#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ + \\#define __LITTLE_ENDIAN__ 1 + \\ + ) else try w.writeAll( + \\#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ + \\#define __BIG_ENDIAN__ 1 + \\ + ); + + // atomics + try w.writeAll( + \\#define __ATOMIC_RELAXED 0 + \\#define __ATOMIC_CONSUME 1 + \\#define __ATOMIC_ACQUIRE 2 + \\#define __ATOMIC_RELEASE 3 + \\#define __ATOMIC_ACQ_REL 4 + \\#define __ATOMIC_SEQ_CST 5 + \\ + ); + + // TODO: Set these to target-specific constants depending on backend capabilities + // For now they are just set to the "may be lock-free" value + try w.writeAll( + \\#define __ATOMIC_BOOL_LOCK_FREE 1 + \\#define __ATOMIC_CHAR_LOCK_FREE 1 + \\#define __ATOMIC_CHAR16_T_LOCK_FREE 1 + \\#define __ATOMIC_CHAR32_T_LOCK_FREE 1 + \\#define __ATOMIC_WCHAR_T_LOCK_FREE 1 + \\#define __ATOMIC_SHORT_LOCK_FREE 1 + \\#define __ATOMIC_INT_LOCK_FREE 1 + \\#define __ATOMIC_LONG_LOCK_FREE 1 + \\#define __ATOMIC_LLONG_LOCK_FREE 1 + \\#define __ATOMIC_POINTER_LOCK_FREE 1 + \\ + ); + if (comp.langopts.hasChar8_T()) { + try w.writeAll("#define __ATOMIC_CHAR8_T_LOCK_FREE 1\n"); + } + + // types + if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n"); + try w.writeAll("#define __CHAR_BIT__ 8\n"); + + // int maxs + try comp.generateIntWidth(w, "BOOL", .{ .specifier = .bool }); + try comp.generateIntMaxAndWidth(w, "SCHAR", .{ .specifier = .schar }); + try comp.generateIntMaxAndWidth(w, "SHRT", .{ .specifier = .short }); + try comp.generateIntMaxAndWidth(w, "INT", .{ .specifier = .int }); + try comp.generateIntMaxAndWidth(w, "LONG", .{ .specifier = .long }); + try comp.generateIntMaxAndWidth(w, "LONG_LONG", .{ .specifier = .long_long }); + try comp.generateIntMaxAndWidth(w, "WCHAR", comp.types.wchar); + // try comp.generateIntMax(w, "WINT", comp.types.wchar); + try comp.generateIntMaxAndWidth(w, "INTMAX", comp.types.intmax); + try comp.generateIntMaxAndWidth(w, "SIZE", comp.types.size); + try comp.generateIntMaxAndWidth(w, "UINTMAX", comp.types.intmax.makeIntegerUnsigned()); + try comp.generateIntMaxAndWidth(w, "PTRDIFF", comp.types.ptrdiff); + try comp.generateIntMaxAndWidth(w, "INTPTR", comp.types.intptr); + try comp.generateIntMaxAndWidth(w, "UINTPTR", comp.types.intptr.makeIntegerUnsigned()); + try comp.generateIntMaxAndWidth(w, "SIG_ATOMIC", target_util.sigAtomicType(comp.target)); + + // int widths + try w.print("#define __BITINT_MAXWIDTH__ {d}\n", .{bit_int_max_bits}); + + // sizeof types + try comp.generateSizeofType(w, "__SIZEOF_FLOAT__", .{ .specifier = .float }); + try comp.generateSizeofType(w, "__SIZEOF_DOUBLE__", .{ .specifier = .double }); + try comp.generateSizeofType(w, "__SIZEOF_LONG_DOUBLE__", .{ .specifier = .long_double }); + try comp.generateSizeofType(w, "__SIZEOF_SHORT__", .{ .specifier = .short }); + try comp.generateSizeofType(w, "__SIZEOF_INT__", .{ .specifier = .int }); + try comp.generateSizeofType(w, "__SIZEOF_LONG__", .{ .specifier = .long }); + try comp.generateSizeofType(w, "__SIZEOF_LONG_LONG__", .{ .specifier = .long_long }); + try comp.generateSizeofType(w, "__SIZEOF_POINTER__", .{ .specifier = .pointer }); + try comp.generateSizeofType(w, "__SIZEOF_PTRDIFF_T__", comp.types.ptrdiff); + try comp.generateSizeofType(w, "__SIZEOF_SIZE_T__", comp.types.size); + try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar); + // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer }); + + if (target_util.hasInt128(comp.target)) { + try comp.generateSizeofType(w, "__SIZEOF_INT128__", .{ .specifier = .int128 }); + } + + // various int types + const mapper = comp.string_interner.getSlowTypeMapper(); + try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts); + try generateTypeMacro(w, mapper, "__UINTPTR_TYPE__", comp.types.intptr.makeIntegerUnsigned(), comp.langopts); + + try generateTypeMacro(w, mapper, "__INTMAX_TYPE__", comp.types.intmax, comp.langopts); + try comp.generateSuffixMacro("__INTMAX", w, comp.types.intptr); + + try generateTypeMacro(w, mapper, "__UINTMAX_TYPE__", comp.types.intmax.makeIntegerUnsigned(), comp.langopts); + try comp.generateSuffixMacro("__UINTMAX", w, comp.types.intptr.makeIntegerUnsigned()); + + try generateTypeMacro(w, mapper, "__PTRDIFF_TYPE__", comp.types.ptrdiff, comp.langopts); + try generateTypeMacro(w, mapper, "__SIZE_TYPE__", comp.types.size, comp.langopts); + try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts); + try generateTypeMacro(w, mapper, "__CHAR16_TYPE__", comp.types.uint_least16_t, comp.langopts); + try generateTypeMacro(w, mapper, "__CHAR32_TYPE__", comp.types.uint_least32_t, comp.langopts); + + try comp.generateExactWidthTypes(w, mapper); + try comp.generateFastAndLeastWidthTypes(w, mapper); + + if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| { + try generateFloatMacros(w, "FLT16", half, "F16"); + } + try generateFloatMacros(w, "FLT", target_util.FPSemantics.forType(.float, comp.target), "F"); + try generateFloatMacros(w, "DBL", target_util.FPSemantics.forType(.double, comp.target), ""); + try generateFloatMacros(w, "LDBL", target_util.FPSemantics.forType(.longdouble, comp.target), "L"); + + // TODO: clang treats __FLT_EVAL_METHOD__ as a special-cased macro because evaluating it within a scope + // where `#pragma clang fp eval_method(X)` has been called produces an error diagnostic. + const flt_eval_method = comp.langopts.fp_eval_method orelse target_util.defaultFpEvalMethod(comp.target); + try w.print("#define __FLT_EVAL_METHOD__ {d}\n", .{@intFromEnum(flt_eval_method)}); + + try w.writeAll( + \\#define __FLT_RADIX__ 2 + \\#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ + \\ + ); +} + +/// Generate builtin macros that will be available to each source file. +pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) !Source { + try comp.generateBuiltinTypes(); + + var buf = std.ArrayList(u8).init(comp.gpa); + defer buf.deinit(); + + if (system_defines_mode == .include_system_defines) { + try buf.appendSlice( + \\#define __VERSION__ "Aro + ++ " " ++ @import("../backend.zig").version_str ++ "\"\n" ++ + \\#define __Aro__ + \\ + ); + } + + try buf.appendSlice("#define __STDC__ 1\n"); + try buf.writer().print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)}); + + // standard macros + try buf.appendSlice( + \\#define __STDC_NO_COMPLEX__ 1 + \\#define __STDC_NO_THREADS__ 1 + \\#define __STDC_NO_VLA__ 1 + \\#define __STDC_UTF_16__ 1 + \\#define __STDC_UTF_32__ 1 + \\#define __STDC_EMBED_NOT_FOUND__ 0 + \\#define __STDC_EMBED_FOUND__ 1 + \\#define __STDC_EMBED_EMPTY__ 2 + \\ + ); + if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| { + try buf.appendSlice("#define __STDC_VERSION__ "); + try buf.appendSlice(stdc_version); + try buf.append('\n'); + } + + // timestamps + const timestamp = try comp.getTimestamp(); + try generateDateAndTime(buf.writer(), timestamp); + + if (system_defines_mode == .include_system_defines) { + try comp.generateSystemDefines(buf.writer()); + } + + return comp.addSourceFromBuffer("", buf.items); +} + +fn generateFloatMacros(w: anytype, prefix: []const u8, semantics: target_util.FPSemantics, ext: []const u8) !void { + const denormMin = semantics.chooseValue( + []const u8, + .{ + "5.9604644775390625e-8", + "1.40129846e-45", + "4.9406564584124654e-324", + "3.64519953188247460253e-4951", + "4.94065645841246544176568792868221e-324", + "6.47517511943802511092443895822764655e-4966", + }, + ); + const digits = semantics.chooseValue(i32, .{ 3, 6, 15, 18, 31, 33 }); + const decimalDigits = semantics.chooseValue(i32, .{ 5, 9, 17, 21, 33, 36 }); + const epsilon = semantics.chooseValue( + []const u8, + .{ + "9.765625e-4", + "1.19209290e-7", + "2.2204460492503131e-16", + "1.08420217248550443401e-19", + "4.94065645841246544176568792868221e-324", + "1.92592994438723585305597794258492732e-34", + }, + ); + const mantissaDigits = semantics.chooseValue(i32, .{ 11, 24, 53, 64, 106, 113 }); + + const min10Exp = semantics.chooseValue(i32, .{ -4, -37, -307, -4931, -291, -4931 }); + const max10Exp = semantics.chooseValue(i32, .{ 4, 38, 308, 4932, 308, 4932 }); + + const minExp = semantics.chooseValue(i32, .{ -13, -125, -1021, -16381, -968, -16381 }); + const maxExp = semantics.chooseValue(i32, .{ 16, 128, 1024, 16384, 1024, 16384 }); + + const min = semantics.chooseValue( + []const u8, + .{ + "6.103515625e-5", + "1.17549435e-38", + "2.2250738585072014e-308", + "3.36210314311209350626e-4932", + "2.00416836000897277799610805135016e-292", + "3.36210314311209350626267781732175260e-4932", + }, + ); + const max = semantics.chooseValue( + []const u8, + .{ + "6.5504e+4", + "3.40282347e+38", + "1.7976931348623157e+308", + "1.18973149535723176502e+4932", + "1.79769313486231580793728971405301e+308", + "1.18973149535723176508575932662800702e+4932", + }, + ); + + var def_prefix_buf: [32]u8 = undefined; + const prefix_slice = std.fmt.bufPrint(&def_prefix_buf, "__{s}_", .{prefix}) catch + return error.OutOfMemory; + + try w.print("#define {s}DENORM_MIN__ {s}{s}\n", .{ prefix_slice, denormMin, ext }); + try w.print("#define {s}HAS_DENORM__\n", .{prefix_slice}); + try w.print("#define {s}DIG__ {d}\n", .{ prefix_slice, digits }); + try w.print("#define {s}DECIMAL_DIG__ {d}\n", .{ prefix_slice, decimalDigits }); + + try w.print("#define {s}EPSILON__ {s}{s}\n", .{ prefix_slice, epsilon, ext }); + try w.print("#define {s}HAS_INFINITY__\n", .{prefix_slice}); + try w.print("#define {s}HAS_QUIET_NAN__\n", .{prefix_slice}); + try w.print("#define {s}MANT_DIG__ {d}\n", .{ prefix_slice, mantissaDigits }); + + try w.print("#define {s}MAX_10_EXP__ {d}\n", .{ prefix_slice, max10Exp }); + try w.print("#define {s}MAX_EXP__ {d}\n", .{ prefix_slice, maxExp }); + try w.print("#define {s}MAX__ {s}{s}\n", .{ prefix_slice, max, ext }); + + try w.print("#define {s}MIN_10_EXP__ ({d})\n", .{ prefix_slice, min10Exp }); + try w.print("#define {s}MIN_EXP__ ({d})\n", .{ prefix_slice, minExp }); + try w.print("#define {s}MIN__ {s}{s}\n", .{ prefix_slice, min, ext }); +} + +fn generateTypeMacro(w: anytype, mapper: StrInt.TypeMapper, name: []const u8, ty: Type, langopts: LangOpts) !void { + try w.print("#define {s} ", .{name}); + try ty.print(mapper, langopts, w); + try w.writeByte('\n'); +} + +fn generateBuiltinTypes(comp: *Compilation) !void { + const os = comp.target.os.tag; + const wchar: Type = switch (comp.target.cpu.arch) { + .xcore => .{ .specifier = .uchar }, + .ve, .msp430 => .{ .specifier = .uint }, + .arm, .armeb, .thumb, .thumbeb => .{ + .specifier = if (os != .windows and os != .netbsd and os != .openbsd) .uint else .int, + }, + .aarch64, .aarch64_be => .{ + .specifier = if (!os.isDarwin() and os != .netbsd) .uint else .int, + }, + .x86_64, .x86 => .{ .specifier = if (os == .windows) .ushort else .int }, + else => .{ .specifier = .int }, + }; + + const ptr_width = comp.target.ptrBitWidth(); + const ptrdiff = if (os == .windows and ptr_width == 64) + Type{ .specifier = .long_long } + else switch (ptr_width) { + 16 => Type{ .specifier = .int }, + 32 => Type{ .specifier = .int }, + 64 => Type{ .specifier = .long }, + else => unreachable, + }; + + const size = if (os == .windows and ptr_width == 64) + Type{ .specifier = .ulong_long } + else switch (ptr_width) { + 16 => Type{ .specifier = .uint }, + 32 => Type{ .specifier = .uint }, + 64 => Type{ .specifier = .ulong }, + else => unreachable, + }; + + const va_list = try comp.generateVaListType(); + + const pid_t: Type = switch (os) { + .haiku => .{ .specifier = .long }, + // Todo: pid_t is required to "a signed integer type"; are there any systems + // on which it is `short int`? + else => .{ .specifier = .int }, + }; + + const intmax = target_util.intMaxType(comp.target); + const intptr = target_util.intPtrType(comp.target); + const int16 = target_util.int16Type(comp.target); + const int64 = target_util.int64Type(comp.target); + + comp.types = .{ + .wchar = wchar, + .ptrdiff = ptrdiff, + .size = size, + .va_list = va_list, + .pid_t = pid_t, + .intmax = intmax, + .intptr = intptr, + .int16 = int16, + .int64 = int64, + .uint_least16_t = comp.intLeastN(16, .unsigned), + .uint_least32_t = comp.intLeastN(32, .unsigned), + }; + + try comp.generateNsConstantStringType(); +} + +pub fn float80Type(comp: *const Compilation) ?Type { + if (comp.langopts.emulate != .gcc) return null; + return target_util.float80Type(comp.target); +} + +/// Smallest integer type with at least N bits +pub fn intLeastN(comp: *const Compilation, bits: usize, signedness: std.builtin.Signedness) Type { + if (bits == 64 and (comp.target.os.tag.isDarwin() or comp.target.cpu.arch.isWasm())) { + // WebAssembly and Darwin use `long long` for `int_least64_t` and `int_fast64_t`. + return .{ .specifier = if (signedness == .signed) .long_long else .ulong_long }; + } + if (bits == 16 and comp.target.cpu.arch == .avr) { + // AVR uses int for int_least16_t and int_fast16_t. + return .{ .specifier = if (signedness == .signed) .int else .uint }; + } + const candidates = switch (signedness) { + .signed => &[_]Type.Specifier{ .schar, .short, .int, .long, .long_long }, + .unsigned => &[_]Type.Specifier{ .uchar, .ushort, .uint, .ulong, .ulong_long }, + }; + for (candidates) |specifier| { + const ty: Type = .{ .specifier = specifier }; + if (ty.sizeof(comp).? * 8 >= bits) return ty; + } else unreachable; +} + +fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 { + const ty = Type{ .specifier = specifier }; + return ty.sizeof(comp).?; +} + +fn generateFastOrLeastType( + comp: *Compilation, + bits: usize, + kind: enum { least, fast }, + signedness: std.builtin.Signedness, + w: anytype, + mapper: StrInt.TypeMapper, +) !void { + const ty = comp.intLeastN(bits, signedness); // defining the fast types as the least types is permitted + + var buf: [32]u8 = undefined; + const suffix = "_TYPE__"; + const base_name = switch (signedness) { + .signed => "__INT_", + .unsigned => "__UINT_", + }; + const kind_str = switch (kind) { + .fast => "FAST", + .least => "LEAST", + }; + + const full = std.fmt.bufPrint(&buf, "{s}{s}{d}{s}", .{ + base_name, kind_str, bits, suffix, + }) catch return error.OutOfMemory; + + try generateTypeMacro(w, mapper, full, ty, comp.langopts); + + const prefix = full[2 .. full.len - suffix.len]; // remove "__" and "_TYPE__" + + switch (signedness) { + .signed => try comp.generateIntMaxAndWidth(w, prefix, ty), + .unsigned => try comp.generateIntMax(w, prefix, ty), + } + try comp.generateFmt(prefix, w, ty); +} + +fn generateFastAndLeastWidthTypes(comp: *Compilation, w: anytype, mapper: StrInt.TypeMapper) !void { + const sizes = [_]usize{ 8, 16, 32, 64 }; + for (sizes) |size| { + try comp.generateFastOrLeastType(size, .least, .signed, w, mapper); + try comp.generateFastOrLeastType(size, .least, .unsigned, w, mapper); + try comp.generateFastOrLeastType(size, .fast, .signed, w, mapper); + try comp.generateFastOrLeastType(size, .fast, .unsigned, w, mapper); + } +} + +fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper) !void { + try comp.generateExactWidthType(w, mapper, .schar); + + if (comp.intSize(.short) > comp.intSize(.char)) { + try comp.generateExactWidthType(w, mapper, .short); + } + + if (comp.intSize(.int) > comp.intSize(.short)) { + try comp.generateExactWidthType(w, mapper, .int); + } + + if (comp.intSize(.long) > comp.intSize(.int)) { + try comp.generateExactWidthType(w, mapper, .long); + } + + if (comp.intSize(.long_long) > comp.intSize(.long)) { + try comp.generateExactWidthType(w, mapper, .long_long); + } + + try comp.generateExactWidthType(w, mapper, .uchar); + try comp.generateExactWidthIntMax(w, .uchar); + try comp.generateExactWidthIntMax(w, .schar); + + if (comp.intSize(.short) > comp.intSize(.char)) { + try comp.generateExactWidthType(w, mapper, .ushort); + try comp.generateExactWidthIntMax(w, .ushort); + try comp.generateExactWidthIntMax(w, .short); + } + + if (comp.intSize(.int) > comp.intSize(.short)) { + try comp.generateExactWidthType(w, mapper, .uint); + try comp.generateExactWidthIntMax(w, .uint); + try comp.generateExactWidthIntMax(w, .int); + } + + if (comp.intSize(.long) > comp.intSize(.int)) { + try comp.generateExactWidthType(w, mapper, .ulong); + try comp.generateExactWidthIntMax(w, .ulong); + try comp.generateExactWidthIntMax(w, .long); + } + + if (comp.intSize(.long_long) > comp.intSize(.long)) { + try comp.generateExactWidthType(w, mapper, .ulong_long); + try comp.generateExactWidthIntMax(w, .ulong_long); + try comp.generateExactWidthIntMax(w, .long_long); + } +} + +fn generateFmt(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void { + const unsigned = ty.isUnsignedInt(comp); + const modifier = ty.formatModifier(); + const formats = if (unsigned) "ouxX" else "di"; + for (formats) |c| { + try w.print("#define {s}_FMT{c}__ \"{s}{c}\"\n", .{ prefix, c, modifier, c }); + } +} + +fn generateSuffixMacro(comp: *const Compilation, prefix: []const u8, w: anytype, ty: Type) !void { + return w.print("#define {s}_C_SUFFIX__ {s}\n", .{ prefix, ty.intValueSuffix(comp) }); +} + +/// Generate the following for ty: +/// Name macro (e.g. #define __UINT32_TYPE__ unsigned int) +/// Format strings (e.g. #define __UINT32_FMTu__ "u") +/// Suffix macro (e.g. #define __UINT32_C_SUFFIX__ U) +fn generateExactWidthType(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper, specifier: Type.Specifier) !void { + var ty = Type{ .specifier = specifier }; + const width = 8 * ty.sizeof(comp).?; + const unsigned = ty.isUnsignedInt(comp); + + if (width == 16) { + ty = if (unsigned) comp.types.int16.makeIntegerUnsigned() else comp.types.int16; + } else if (width == 64) { + ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64; + } + + var buffer: [16]u8 = undefined; + const suffix = "_TYPE__"; + const full = std.fmt.bufPrint(&buffer, "{s}{d}{s}", .{ + if (unsigned) "__UINT" else "__INT", width, suffix, + }) catch return error.OutOfMemory; + + try generateTypeMacro(w, mapper, full, ty, comp.langopts); + + const prefix = full[0 .. full.len - suffix.len]; // remove "_TYPE__" + + try comp.generateFmt(prefix, w, ty); + try comp.generateSuffixMacro(prefix, w, ty); +} + +pub fn hasFloat128(comp: *const Compilation) bool { + return target_util.hasFloat128(comp.target); +} + +pub fn hasHalfPrecisionFloatABI(comp: *const Compilation) bool { + return comp.langopts.allow_half_args_and_returns or target_util.hasHalfPrecisionFloatABI(comp.target); +} + +fn generateNsConstantStringType(comp: *Compilation) !void { + comp.types.ns_constant_string.record = .{ + .name = try StrInt.intern(comp, "__NSConstantString_tag"), + .fields = &comp.types.ns_constant_string.fields, + .field_attributes = null, + .type_layout = undefined, + }; + const const_int_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.int_ty } }; + const const_char_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = &comp.types.ns_constant_string.char_ty } }; + + comp.types.ns_constant_string.fields[0] = .{ .name = try StrInt.intern(comp, "isa"), .ty = const_int_ptr }; + comp.types.ns_constant_string.fields[1] = .{ .name = try StrInt.intern(comp, "flags"), .ty = .{ .specifier = .int } }; + comp.types.ns_constant_string.fields[2] = .{ .name = try StrInt.intern(comp, "str"), .ty = const_char_ptr }; + comp.types.ns_constant_string.fields[3] = .{ .name = try StrInt.intern(comp, "length"), .ty = .{ .specifier = .long } }; + comp.types.ns_constant_string.ty = .{ .specifier = .@"struct", .data = .{ .record = &comp.types.ns_constant_string.record } }; + record_layout.compute(&comp.types.ns_constant_string.record, comp.types.ns_constant_string.ty, comp, null) catch unreachable; +} + +fn generateVaListType(comp: *Compilation) !Type { + const Kind = enum { char_ptr, void_ptr, aarch64_va_list, x86_64_va_list }; + const kind: Kind = switch (comp.target.cpu.arch) { + .aarch64 => switch (comp.target.os.tag) { + .windows => @as(Kind, .char_ptr), + .ios, .macos, .tvos, .watchos => .char_ptr, + else => .aarch64_va_list, + }, + .sparc, .wasm32, .wasm64, .bpfel, .bpfeb, .riscv32, .riscv64, .avr, .spirv32, .spirv64 => .void_ptr, + .powerpc => switch (comp.target.os.tag) { + .ios, .macos, .tvos, .watchos, .aix => @as(Kind, .char_ptr), + else => return Type{ .specifier = .void }, // unknown + }, + .x86, .msp430 => .char_ptr, + .x86_64 => switch (comp.target.os.tag) { + .windows => @as(Kind, .char_ptr), + else => .x86_64_va_list, + }, + else => return Type{ .specifier = .void }, // unknown + }; + + // TODO this might be bad? + const arena = comp.diagnostics.arena.allocator(); + + var ty: Type = undefined; + switch (kind) { + .char_ptr => ty = .{ .specifier = .char }, + .void_ptr => ty = .{ .specifier = .void }, + .aarch64_va_list => { + const record_ty = try arena.create(Type.Record); + record_ty.* = .{ + .name = try StrInt.intern(comp, "__va_list_tag"), + .fields = try arena.alloc(Type.Record.Field, 5), + .field_attributes = null, + .type_layout = undefined, // computed below + }; + const void_ty = try arena.create(Type); + void_ty.* = .{ .specifier = .void }; + const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } }; + record_ty.fields[0] = .{ .name = try StrInt.intern(comp, "__stack"), .ty = void_ptr }; + record_ty.fields[1] = .{ .name = try StrInt.intern(comp, "__gr_top"), .ty = void_ptr }; + record_ty.fields[2] = .{ .name = try StrInt.intern(comp, "__vr_top"), .ty = void_ptr }; + record_ty.fields[3] = .{ .name = try StrInt.intern(comp, "__gr_offs"), .ty = .{ .specifier = .int } }; + record_ty.fields[4] = .{ .name = try StrInt.intern(comp, "__vr_offs"), .ty = .{ .specifier = .int } }; + ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } }; + record_layout.compute(record_ty, ty, comp, null) catch unreachable; + }, + .x86_64_va_list => { + const record_ty = try arena.create(Type.Record); + record_ty.* = .{ + .name = try StrInt.intern(comp, "__va_list_tag"), + .fields = try arena.alloc(Type.Record.Field, 4), + .field_attributes = null, + .type_layout = undefined, // computed below + }; + const void_ty = try arena.create(Type); + void_ty.* = .{ .specifier = .void }; + const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } }; + record_ty.fields[0] = .{ .name = try StrInt.intern(comp, "gp_offset"), .ty = .{ .specifier = .uint } }; + record_ty.fields[1] = .{ .name = try StrInt.intern(comp, "fp_offset"), .ty = .{ .specifier = .uint } }; + record_ty.fields[2] = .{ .name = try StrInt.intern(comp, "overflow_arg_area"), .ty = void_ptr }; + record_ty.fields[3] = .{ .name = try StrInt.intern(comp, "reg_save_area"), .ty = void_ptr }; + ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } }; + record_layout.compute(record_ty, ty, comp, null) catch unreachable; + }, + } + if (kind == .char_ptr or kind == .void_ptr) { + const elem_ty = try arena.create(Type); + elem_ty.* = ty; + ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } }; + } else { + const arr_ty = try arena.create(Type.Array); + arr_ty.* = .{ .len = 1, .elem = ty }; + ty = Type{ .specifier = .array, .data = .{ .array = arr_ty } }; + } + + return ty; +} + +fn generateIntMax(comp: *const Compilation, w: anytype, name: []const u8, ty: Type) !void { + const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8); + const unsigned = ty.isUnsignedInt(comp); + const max: u128 = switch (bit_count) { + 8 => if (unsigned) std.math.maxInt(u8) else std.math.maxInt(i8), + 16 => if (unsigned) std.math.maxInt(u16) else std.math.maxInt(i16), + 32 => if (unsigned) std.math.maxInt(u32) else std.math.maxInt(i32), + 64 => if (unsigned) std.math.maxInt(u64) else std.math.maxInt(i64), + 128 => if (unsigned) std.math.maxInt(u128) else std.math.maxInt(i128), + else => unreachable, + }; + try w.print("#define __{s}_MAX__ {d}{s}\n", .{ name, max, ty.intValueSuffix(comp) }); +} + +/// Largest value that can be stored in wchar_t +pub fn wcharMax(comp: *const Compilation) u32 { + const unsigned = comp.types.wchar.isUnsignedInt(comp); + return switch (comp.types.wchar.bitSizeof(comp).?) { + 8 => if (unsigned) std.math.maxInt(u8) else std.math.maxInt(i8), + 16 => if (unsigned) std.math.maxInt(u16) else std.math.maxInt(i16), + 32 => if (unsigned) std.math.maxInt(u32) else std.math.maxInt(i32), + else => unreachable, + }; +} + +fn generateExactWidthIntMax(comp: *const Compilation, w: anytype, specifier: Type.Specifier) !void { + var ty = Type{ .specifier = specifier }; + const bit_count: u8 = @intCast(ty.sizeof(comp).? * 8); + const unsigned = ty.isUnsignedInt(comp); + + if (bit_count == 64) { + ty = if (unsigned) comp.types.int64.makeIntegerUnsigned() else comp.types.int64; + } + + var name_buffer: [6]u8 = undefined; + const name = std.fmt.bufPrint(&name_buffer, "{s}{d}", .{ + if (unsigned) "UINT" else "INT", bit_count, + }) catch return error.OutOfMemory; + + return comp.generateIntMax(w, name, ty); +} + +fn generateIntWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void { + try w.print("#define __{s}_WIDTH__ {d}\n", .{ name, 8 * ty.sizeof(comp).? }); +} + +fn generateIntMaxAndWidth(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void { + try comp.generateIntMax(w, name, ty); + try comp.generateIntWidth(w, name, ty); +} + +fn generateSizeofType(comp: *Compilation, w: anytype, name: []const u8, ty: Type) !void { + try w.print("#define {s} {d}\n", .{ name, ty.sizeof(comp).? }); +} + +pub fn nextLargestIntSameSign(comp: *const Compilation, ty: Type) ?Type { + assert(ty.isInt()); + const specifiers = if (ty.isUnsignedInt(comp)) + [_]Type.Specifier{ .short, .int, .long, .long_long } + else + [_]Type.Specifier{ .ushort, .uint, .ulong, .ulong_long }; + const size = ty.sizeof(comp).?; + for (specifiers) |specifier| { + const candidate = Type{ .specifier = specifier }; + if (candidate.sizeof(comp).? > size) return candidate; + } + return null; +} + +/// Maximum size of an array, in bytes +pub fn maxArrayBytes(comp: *const Compilation) u64 { + const max_bits = @min(61, comp.target.ptrBitWidth()); + return (@as(u64, 1) << @truncate(max_bits)) - 1; +} + +/// If `enum E { ... }` syntax has a fixed underlying integer type regardless of the presence of +/// __attribute__((packed)) or the range of values of the corresponding enumerator constants, +/// specify it here. +/// TODO: likely incomplete +pub fn fixedEnumTagSpecifier(comp: *const Compilation) ?Type.Specifier { + switch (comp.langopts.emulate) { + .msvc => return .int, + .clang => if (comp.target.os.tag == .windows) return .int, + .gcc => {}, + } + return null; +} + +pub fn getCharSignedness(comp: *const Compilation) std.builtin.Signedness { + return comp.langopts.char_signedness_override orelse comp.target.charSignedness(); +} + +/// Add built-in aro headers directory to system include paths +pub fn addBuiltinIncludeDir(comp: *Compilation, aro_dir: []const u8) !void { + var search_path = aro_dir; + while (std.fs.path.dirname(search_path)) |dirname| : (search_path = dirname) { + var base_dir = comp.cwd.openDir(dirname, .{}) catch continue; + defer base_dir.close(); + + base_dir.access("include/stddef.h", .{}) catch continue; + const path = try std.fs.path.join(comp.gpa, &.{ dirname, "include" }); + errdefer comp.gpa.free(path); + try comp.system_include_dirs.append(comp.gpa, path); + break; + } else return error.AroIncludeNotFound; +} + +pub fn addSystemIncludeDir(comp: *Compilation, path: []const u8) !void { + const duped = try comp.gpa.dupe(u8, path); + errdefer comp.gpa.free(duped); + try comp.system_include_dirs.append(comp.gpa, duped); +} + +pub fn getSource(comp: *const Compilation, id: Source.Id) Source { + if (id == .generated) return .{ + .path = "", + .buf = comp.generated_buf.items, + .id = .generated, + .splice_locs = &.{}, + .kind = .user, + }; + return comp.sources.values()[@intFromEnum(id) - 2]; +} + +/// Creates a Source from the contents of `reader` and adds it to the Compilation +pub fn addSourceFromReader(comp: *Compilation, reader: anytype, path: []const u8, kind: Source.Kind) !Source { + const contents = try reader.readAllAlloc(comp.gpa, std.math.maxInt(u32)); + errdefer comp.gpa.free(contents); + return comp.addSourceFromOwnedBuffer(contents, path, kind); +} + +/// Creates a Source from `buf` and adds it to the Compilation +/// Performs newline splicing and line-ending normalization to '\n' +/// `buf` will be modified and the allocation will be resized if newline splicing +/// or line-ending changes happen. +/// caller retains ownership of `path` +/// To add the contents of an arbitrary reader as a Source, see addSourceFromReader +/// To add a file's contents given its path, see addSourceFromPath +pub fn addSourceFromOwnedBuffer(comp: *Compilation, buf: []u8, path: []const u8, kind: Source.Kind) !Source { + try comp.sources.ensureUnusedCapacity(comp.gpa, 1); + + var contents = buf; + const duped_path = try comp.gpa.dupe(u8, path); + errdefer comp.gpa.free(duped_path); + + var splice_list = std.ArrayList(u32).init(comp.gpa); + defer splice_list.deinit(); + + const source_id: Source.Id = @enumFromInt(comp.sources.count() + 2); + + var i: u32 = 0; + var backslash_loc: u32 = undefined; + var state: enum { + beginning_of_file, + bom1, + bom2, + start, + back_slash, + cr, + back_slash_cr, + trailing_ws, + } = .beginning_of_file; + var line: u32 = 1; + + for (contents) |byte| { + contents[i] = byte; + + switch (byte) { + '\r' => { + switch (state) { + .start, .cr, .beginning_of_file => { + state = .start; + line += 1; + state = .cr; + contents[i] = '\n'; + i += 1; + }, + .back_slash, .trailing_ws, .back_slash_cr => { + i = backslash_loc; + try splice_list.append(i); + if (state == .trailing_ws) { + try comp.addDiagnostic(.{ + .tag = .backslash_newline_escape, + .loc = .{ .id = source_id, .byte_offset = i, .line = line }, + }, &.{}); + } + state = if (state == .back_slash_cr) .cr else .back_slash_cr; + }, + .bom1, .bom2 => break, // invalid utf-8 + } + }, + '\n' => { + switch (state) { + .start, .beginning_of_file => { + state = .start; + line += 1; + i += 1; + }, + .cr, .back_slash_cr => {}, + .back_slash, .trailing_ws => { + i = backslash_loc; + if (state == .back_slash or state == .trailing_ws) { + try splice_list.append(i); + } + if (state == .trailing_ws) { + try comp.addDiagnostic(.{ + .tag = .backslash_newline_escape, + .loc = .{ .id = source_id, .byte_offset = i, .line = line }, + }, &.{}); + } + }, + .bom1, .bom2 => break, + } + state = .start; + }, + '\\' => { + backslash_loc = i; + state = .back_slash; + i += 1; + }, + '\t', '\x0B', '\x0C', ' ' => { + switch (state) { + .start, .trailing_ws => {}, + .beginning_of_file => state = .start, + .cr, .back_slash_cr => state = .start, + .back_slash => state = .trailing_ws, + .bom1, .bom2 => break, + } + i += 1; + }, + '\xEF' => { + i += 1; + state = switch (state) { + .beginning_of_file => .bom1, + else => .start, + }; + }, + '\xBB' => { + i += 1; + state = switch (state) { + .bom1 => .bom2, + else => .start, + }; + }, + '\xBF' => { + switch (state) { + .bom2 => i = 0, // rewind and overwrite the BOM + else => i += 1, + } + state = .start; + }, + else => { + i += 1; + state = .start; + }, + } + } + + const splice_locs = try splice_list.toOwnedSlice(); + errdefer comp.gpa.free(splice_locs); + + if (i != contents.len) contents = try comp.gpa.realloc(contents, i); + errdefer @compileError("errdefers in callers would possibly free the realloced slice using the original len"); + + const source = Source{ + .id = source_id, + .path = duped_path, + .buf = contents, + .splice_locs = splice_locs, + .kind = kind, + }; + + comp.sources.putAssumeCapacityNoClobber(duped_path, source); + return source; +} + +/// Caller retains ownership of `path` and `buf`. +/// Dupes the source buffer; if it is acceptable to modify the source buffer and possibly resize +/// the allocation, please use `addSourceFromOwnedBuffer` +pub fn addSourceFromBuffer(comp: *Compilation, path: []const u8, buf: []const u8) !Source { + if (comp.sources.get(path)) |some| return some; + if (@as(u64, buf.len) > std.math.maxInt(u32)) return error.StreamTooLong; + + const contents = try comp.gpa.dupe(u8, buf); + errdefer comp.gpa.free(contents); + + return comp.addSourceFromOwnedBuffer(contents, path, .user); +} + +/// Caller retains ownership of `path`. +pub fn addSourceFromPath(comp: *Compilation, path: []const u8) !Source { + return comp.addSourceFromPathExtra(path, .user); +} + +/// Caller retains ownership of `path`. +fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kind) !Source { + if (comp.sources.get(path)) |some| return some; + + if (mem.indexOfScalar(u8, path, 0) != null) { + return error.FileNotFound; + } + + const file = try comp.cwd.openFile(path, .{}); + defer file.close(); + + const contents = file.readToEndAlloc(comp.gpa, std.math.maxInt(u32)) catch |err| switch (err) { + error.FileTooBig => return error.StreamTooLong, + else => |e| return e, + }; + errdefer comp.gpa.free(contents); + + return comp.addSourceFromOwnedBuffer(contents, path, kind); +} + +pub const IncludeDirIterator = struct { + comp: *const Compilation, + cwd_source_id: ?Source.Id, + include_dirs_idx: usize = 0, + sys_include_dirs_idx: usize = 0, + tried_ms_cwd: bool = false, + + const FoundSource = struct { + path: []const u8, + kind: Source.Kind, + }; + + fn next(self: *IncludeDirIterator) ?FoundSource { + if (self.cwd_source_id) |source_id| { + self.cwd_source_id = null; + const path = self.comp.getSource(source_id).path; + return .{ .path = std.fs.path.dirname(path) orelse ".", .kind = .user }; + } + if (self.include_dirs_idx < self.comp.include_dirs.items.len) { + defer self.include_dirs_idx += 1; + return .{ .path = self.comp.include_dirs.items[self.include_dirs_idx], .kind = .user }; + } + if (self.sys_include_dirs_idx < self.comp.system_include_dirs.items.len) { + defer self.sys_include_dirs_idx += 1; + return .{ .path = self.comp.system_include_dirs.items[self.sys_include_dirs_idx], .kind = .system }; + } + if (self.comp.ms_cwd_source_id) |source_id| { + if (self.tried_ms_cwd) return null; + self.tried_ms_cwd = true; + const path = self.comp.getSource(source_id).path; + return .{ .path = std.fs.path.dirname(path) orelse ".", .kind = .user }; + } + return null; + } + + /// Returned value's path field must be freed by allocator + fn nextWithFile(self: *IncludeDirIterator, filename: []const u8, allocator: Allocator) !?FoundSource { + while (self.next()) |found| { + const path = try std.fs.path.join(allocator, &.{ found.path, filename }); + if (self.comp.langopts.ms_extensions) { + std.mem.replaceScalar(u8, path, '\\', '/'); + } + return .{ .path = path, .kind = found.kind }; + } + return null; + } + + /// Advance the iterator until it finds an include directory that matches + /// the directory which contains `source`. + fn skipUntilDirMatch(self: *IncludeDirIterator, source: Source.Id) void { + const path = self.comp.getSource(source).path; + const includer_path = std.fs.path.dirname(path) orelse "."; + while (self.next()) |found| { + if (mem.eql(u8, includer_path, found.path)) break; + } + } +}; + +pub fn hasInclude( + comp: *const Compilation, + filename: []const u8, + includer_token_source: Source.Id, + /// angle bracket vs quotes + include_type: IncludeType, + /// __has_include vs __has_include_next + which: WhichInclude, +) !bool { + if (mem.indexOfScalar(u8, filename, 0) != null) { + return false; + } + + if (std.fs.path.isAbsolute(filename)) { + if (which == .next) return false; + return !std.meta.isError(comp.cwd.access(filename, .{})); + } + + const cwd_source_id = switch (include_type) { + .quotes => switch (which) { + .first => includer_token_source, + .next => null, + }, + .angle_brackets => null, + }; + var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id }; + if (which == .next) { + it.skipUntilDirMatch(includer_token_source); + } + + var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa); + const sf_allocator = stack_fallback.get(); + + while (try it.nextWithFile(filename, sf_allocator)) |found| { + defer sf_allocator.free(found.path); + if (!std.meta.isError(comp.cwd.access(found.path, .{}))) return true; + } + return false; +} + +pub const WhichInclude = enum { + first, + next, +}; + +pub const IncludeType = enum { + quotes, + angle_brackets, +}; + +fn getFileContents(comp: *Compilation, path: []const u8, limit: ?u32) ![]const u8 { + if (mem.indexOfScalar(u8, path, 0) != null) { + return error.FileNotFound; + } + + const file = try comp.cwd.openFile(path, .{}); + defer file.close(); + + var buf = std.ArrayList(u8).init(comp.gpa); + defer buf.deinit(); + + const max = limit orelse std.math.maxInt(u32); + file.reader().readAllArrayList(&buf, max) catch |e| switch (e) { + error.StreamTooLong => if (limit == null) return e, + else => return e, + }; + + return buf.toOwnedSlice(); +} + +pub fn findEmbed( + comp: *Compilation, + filename: []const u8, + includer_token_source: Source.Id, + /// angle bracket vs quotes + include_type: IncludeType, + limit: ?u32, +) !?[]const u8 { + if (std.fs.path.isAbsolute(filename)) { + return if (comp.getFileContents(filename, limit)) |some| + some + else |err| switch (err) { + error.OutOfMemory => |e| return e, + else => null, + }; + } + + const cwd_source_id = switch (include_type) { + .quotes => includer_token_source, + .angle_brackets => null, + }; + var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id }; + var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa); + const sf_allocator = stack_fallback.get(); + + while (try it.nextWithFile(filename, sf_allocator)) |found| { + defer sf_allocator.free(found.path); + if (comp.getFileContents(found.path, limit)) |some| + return some + else |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => {}, + } + } + return null; +} + +pub fn findInclude( + comp: *Compilation, + filename: []const u8, + includer_token: Token, + /// angle bracket vs quotes + include_type: IncludeType, + /// include vs include_next + which: WhichInclude, +) !?Source { + if (std.fs.path.isAbsolute(filename)) { + if (which == .next) return null; + // TODO: classify absolute file as belonging to system includes or not? + return if (comp.addSourceFromPath(filename)) |some| + some + else |err| switch (err) { + error.OutOfMemory => |e| return e, + else => null, + }; + } + const cwd_source_id = switch (include_type) { + .quotes => switch (which) { + .first => includer_token.source, + .next => null, + }, + .angle_brackets => null, + }; + var it = IncludeDirIterator{ .comp = comp, .cwd_source_id = cwd_source_id }; + + if (which == .next) { + it.skipUntilDirMatch(includer_token.source); + } + + var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa); + const sf_allocator = stack_fallback.get(); + + while (try it.nextWithFile(filename, sf_allocator)) |found| { + defer sf_allocator.free(found.path); + if (comp.addSourceFromPathExtra(found.path, found.kind)) |some| { + if (it.tried_ms_cwd) { + try comp.addDiagnostic(.{ + .tag = .ms_search_rule, + .extra = .{ .str = some.path }, + .loc = .{ + .id = includer_token.source, + .byte_offset = includer_token.start, + .line = includer_token.line, + }, + }, &.{}); + } + return some; + } else |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => {}, + } + } + return null; +} + +pub fn addPragmaHandler(comp: *Compilation, name: []const u8, handler: *Pragma) Allocator.Error!void { + try comp.pragma_handlers.putNoClobber(comp.gpa, name, handler); +} + +pub fn addDefaultPragmaHandlers(comp: *Compilation) Allocator.Error!void { + const GCC = @import("pragmas/gcc.zig"); + var gcc = try GCC.init(comp.gpa); + errdefer gcc.deinit(gcc, comp); + + const Once = @import("pragmas/once.zig"); + var once = try Once.init(comp.gpa); + errdefer once.deinit(once, comp); + + const Message = @import("pragmas/message.zig"); + var message = try Message.init(comp.gpa); + errdefer message.deinit(message, comp); + + const Pack = @import("pragmas/pack.zig"); + var pack = try Pack.init(comp.gpa); + errdefer pack.deinit(pack, comp); + + try comp.addPragmaHandler("GCC", gcc); + try comp.addPragmaHandler("once", once); + try comp.addPragmaHandler("message", message); + try comp.addPragmaHandler("pack", pack); +} + +pub fn getPragma(comp: *Compilation, name: []const u8) ?*Pragma { + return comp.pragma_handlers.get(name); +} + +const PragmaEvent = enum { + before_preprocess, + before_parse, + after_parse, +}; + +pub fn pragmaEvent(comp: *Compilation, event: PragmaEvent) void { + for (comp.pragma_handlers.values()) |pragma| { + const maybe_func = switch (event) { + .before_preprocess => pragma.beforePreprocess, + .before_parse => pragma.beforeParse, + .after_parse => pragma.afterParse, + }; + if (maybe_func) |func| func(pragma, comp); + } +} + +pub fn hasBuiltin(comp: *const Compilation, name: []const u8) bool { + if (std.mem.eql(u8, name, "__builtin_va_arg") or + std.mem.eql(u8, name, "__builtin_choose_expr") or + std.mem.eql(u8, name, "__builtin_bitoffsetof") or + std.mem.eql(u8, name, "__builtin_offsetof") or + std.mem.eql(u8, name, "__builtin_types_compatible_p")) return true; + + const builtin = Builtin.fromName(name) orelse return false; + return comp.hasBuiltinFunction(builtin); +} + +pub fn hasBuiltinFunction(comp: *const Compilation, builtin: Builtin) bool { + if (!target_util.builtinEnabled(comp.target, builtin.properties.target_set)) return false; + + switch (builtin.properties.language) { + .all_languages => return true, + .all_ms_languages => return comp.langopts.emulate == .msvc, + .gnu_lang, .all_gnu_languages => return comp.langopts.standard.isGNU(), + } +} + +pub fn locSlice(comp: *const Compilation, loc: Source.Location) []const u8 { + var tmp_tokenizer = Tokenizer{ + .buf = comp.getSource(loc.id).buf, + .langopts = comp.langopts, + .index = loc.byte_offset, + .source = .generated, + }; + const tok = tmp_tokenizer.next(); + return tmp_tokenizer.buf[tok.start..tok.end]; +} + +pub const CharUnitSize = enum(u32) { + @"1" = 1, + @"2" = 2, + @"4" = 4, + + pub fn Type(comptime self: CharUnitSize) type { + return switch (self) { + .@"1" => u8, + .@"2" => u16, + .@"4" => u32, + }; + } +}; + +pub const addDiagnostic = Diagnostics.add; + +test "addSourceFromReader" { + const Test = struct { + fn addSourceFromReader(str: []const u8, expected: []const u8, warning_count: u32, splices: []const u32) !void { + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + + var buf_reader = std.io.fixedBufferStream(str); + const source = try comp.addSourceFromReader(buf_reader.reader(), "path", .user); + + try std.testing.expectEqualStrings(expected, source.buf); + try std.testing.expectEqual(warning_count, @as(u32, @intCast(comp.diagnostics.list.items.len))); + try std.testing.expectEqualSlices(u32, splices, source.splice_locs); + } + + fn withAllocationFailures(allocator: std.mem.Allocator) !void { + var comp = Compilation.init(allocator, std.fs.cwd()); + defer comp.deinit(); + + _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n"); + _ = try comp.addSourceFromBuffer("path", "non-spliced buffer\n"); + } + }; + try Test.addSourceFromReader("ab\\\nc", "abc", 0, &.{2}); + try Test.addSourceFromReader("ab\\\rc", "abc", 0, &.{2}); + try Test.addSourceFromReader("ab\\\r\nc", "abc", 0, &.{2}); + try Test.addSourceFromReader("ab\\ \nc", "abc", 1, &.{2}); + try Test.addSourceFromReader("ab\\\t\nc", "abc", 1, &.{2}); + try Test.addSourceFromReader("ab\\ \t\nc", "abc", 1, &.{2}); + try Test.addSourceFromReader("ab\\\r \nc", "ab \nc", 0, &.{2}); + try Test.addSourceFromReader("ab\\\\\nc", "ab\\c", 0, &.{3}); + try Test.addSourceFromReader("ab\\ \r\nc", "abc", 1, &.{2}); + try Test.addSourceFromReader("ab\\ \\\nc", "ab\\ c", 0, &.{4}); + try Test.addSourceFromReader("ab\\\r\\\nc", "abc", 0, &.{ 2, 2 }); + try Test.addSourceFromReader("ab\\ \rc", "abc", 1, &.{2}); + try Test.addSourceFromReader("ab\\", "ab\\", 0, &.{}); + try Test.addSourceFromReader("ab\\\\", "ab\\\\", 0, &.{}); + try Test.addSourceFromReader("ab\\ ", "ab\\ ", 0, &.{}); + try Test.addSourceFromReader("ab\\\n", "ab", 0, &.{2}); + try Test.addSourceFromReader("ab\\\r\n", "ab", 0, &.{2}); + try Test.addSourceFromReader("ab\\\r", "ab", 0, &.{2}); + + // carriage return normalization + try Test.addSourceFromReader("ab\r", "ab\n", 0, &.{}); + try Test.addSourceFromReader("ab\r\r", "ab\n\n", 0, &.{}); + try Test.addSourceFromReader("ab\r\r\n", "ab\n\n", 0, &.{}); + try Test.addSourceFromReader("ab\r\r\n\r", "ab\n\n\n", 0, &.{}); + try Test.addSourceFromReader("\r\\", "\n\\", 0, &.{}); + try Test.addSourceFromReader("\\\r\\", "\\", 0, &.{0}); + + try std.testing.checkAllAllocationFailures(std.testing.allocator, Test.withAllocationFailures, .{}); +} + +test "addSourceFromReader - exhaustive check for carriage return elimination" { + const alphabet = [_]u8{ '\r', '\n', ' ', '\\', 'a' }; + const alen = alphabet.len; + var buf: [alphabet.len]u8 = [1]u8{alphabet[0]} ** alen; + + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + + var source_count: u32 = 0; + + while (true) { + const source = try comp.addSourceFromBuffer(&buf, &buf); + source_count += 1; + try std.testing.expect(std.mem.indexOfScalar(u8, source.buf, '\r') == null); + + if (std.mem.allEqual(u8, &buf, alphabet[alen - 1])) break; + + var idx = std.mem.indexOfScalar(u8, &alphabet, buf[buf.len - 1]).?; + buf[buf.len - 1] = alphabet[(idx + 1) % alen]; + var j = buf.len - 1; + while (j > 0) : (j -= 1) { + idx = std.mem.indexOfScalar(u8, &alphabet, buf[j - 1]).?; + if (buf[j] == alphabet[0]) buf[j - 1] = alphabet[(idx + 1) % alen] else break; + } + } + try std.testing.expect(source_count == std.math.powi(usize, alen, alen) catch unreachable); +} + +test "ignore BOM at beginning of file" { + const BOM = "\xEF\xBB\xBF"; + + const Test = struct { + fn run(buf: []const u8) !void { + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + + var buf_reader = std.io.fixedBufferStream(buf); + const source = try comp.addSourceFromReader(buf_reader.reader(), "file.c", .user); + const expected_output = if (mem.startsWith(u8, buf, BOM)) buf[BOM.len..] else buf; + try std.testing.expectEqualStrings(expected_output, source.buf); + } + }; + + try Test.run(BOM); + try Test.run(BOM ++ "x"); + try Test.run("x" ++ BOM); + try Test.run(BOM ++ " "); + try Test.run(BOM ++ "\n"); + try Test.run(BOM ++ "\\"); + + try Test.run(BOM[0..1] ++ "x"); + try Test.run(BOM[0..2] ++ "x"); + try Test.run(BOM[1..] ++ "x"); + try Test.run(BOM[2..] ++ "x"); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Diagnostics.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Diagnostics.zig new file mode 100644 index 00000000..eb3bb31e --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Diagnostics.zig @@ -0,0 +1,602 @@ +const std = @import("std"); +const Allocator = mem.Allocator; +const mem = std.mem; +const Source = @import("Source.zig"); +const Compilation = @import("Compilation.zig"); +const Attribute = @import("Attribute.zig"); +const Builtins = @import("Builtins.zig"); +const Builtin = Builtins.Builtin; +const Header = @import("Builtins/Properties.zig").Header; +const Tree = @import("Tree.zig"); +const is_windows = @import("builtin").os.tag == .windows; +const LangOpts = @import("LangOpts.zig"); + +pub const Message = struct { + tag: Tag, + kind: Kind = undefined, + loc: Source.Location = .{}, + extra: Extra = .{ .none = {} }, + + pub const Extra = union { + str: []const u8, + tok_id: struct { + expected: Tree.Token.Id, + actual: Tree.Token.Id, + }, + tok_id_expected: Tree.Token.Id, + arguments: struct { + expected: u32, + actual: u32, + }, + codepoints: struct { + actual: u21, + resembles: u21, + }, + attr_arg_count: struct { + attribute: Attribute.Tag, + expected: u32, + }, + attr_arg_type: struct { + expected: Attribute.ArgumentType, + actual: Attribute.ArgumentType, + }, + attr_enum: struct { + tag: Attribute.Tag, + }, + ignored_record_attr: struct { + tag: Attribute.Tag, + specifier: enum { @"struct", @"union", @"enum" }, + }, + attribute_todo: struct { + tag: Attribute.Tag, + kind: enum { variables, fields, types, functions }, + }, + builtin_with_header: struct { + builtin: Builtin.Tag, + header: Header, + }, + invalid_escape: struct { + offset: u32, + char: u8, + }, + actual_codepoint: u21, + ascii: u7, + unsigned: u64, + offset: u64, + pow_2_as_string: u8, + signed: i64, + normalized: []const u8, + none: void, + }; +}; + +const Properties = struct { + msg: []const u8, + kind: Kind, + extra: std.meta.FieldEnum(Message.Extra) = .none, + opt: ?u8 = null, + all: bool = false, + w_extra: bool = false, + pedantic: bool = false, + suppress_version: ?LangOpts.Standard = null, + suppress_unless_version: ?LangOpts.Standard = null, + suppress_gnu: bool = false, + suppress_gcc: bool = false, + suppress_clang: bool = false, + suppress_msvc: bool = false, + + pub fn makeOpt(comptime str: []const u8) u16 { + return @offsetOf(Options, str); + } + pub fn getKind(prop: Properties, options: *Options) Kind { + const opt = @as([*]Kind, @ptrCast(options))[prop.opt orelse return prop.kind]; + if (opt == .default) return prop.kind; + return opt; + } + pub const max_bits = Compilation.bit_int_max_bits; +}; + +pub const Tag = @import("Diagnostics/messages.zig").with(Properties).Tag; + +pub const Kind = enum { @"fatal error", @"error", note, warning, off, default }; + +pub const Options = struct { + // do not directly use these, instead add `const NAME = true;` + all: Kind = .default, + extra: Kind = .default, + pedantic: Kind = .default, + + @"unsupported-pragma": Kind = .default, + @"c99-extensions": Kind = .default, + @"implicit-int": Kind = .default, + @"duplicate-decl-specifier": Kind = .default, + @"missing-declaration": Kind = .default, + @"extern-initializer": Kind = .default, + @"implicit-function-declaration": Kind = .default, + @"unused-value": Kind = .default, + @"unreachable-code": Kind = .default, + @"unknown-warning-option": Kind = .default, + @"gnu-empty-struct": Kind = .default, + @"gnu-alignof-expression": Kind = .default, + @"macro-redefined": Kind = .default, + @"generic-qual-type": Kind = .default, + multichar: Kind = .default, + @"pointer-integer-compare": Kind = .default, + @"compare-distinct-pointer-types": Kind = .default, + @"literal-conversion": Kind = .default, + @"cast-qualifiers": Kind = .default, + @"array-bounds": Kind = .default, + @"int-conversion": Kind = .default, + @"pointer-type-mismatch": Kind = .default, + @"c23-extensions": Kind = .default, + @"incompatible-pointer-types": Kind = .default, + @"excess-initializers": Kind = .default, + @"division-by-zero": Kind = .default, + @"initializer-overrides": Kind = .default, + @"incompatible-pointer-types-discards-qualifiers": Kind = .default, + @"unknown-attributes": Kind = .default, + @"ignored-attributes": Kind = .default, + @"builtin-macro-redefined": Kind = .default, + @"gnu-label-as-value": Kind = .default, + @"malformed-warning-check": Kind = .default, + @"#pragma-messages": Kind = .default, + @"newline-eof": Kind = .default, + @"empty-translation-unit": Kind = .default, + @"implicitly-unsigned-literal": Kind = .default, + @"c99-compat": Kind = .default, + @"unicode-zero-width": Kind = .default, + @"unicode-homoglyph": Kind = .default, + unicode: Kind = .default, + @"return-type": Kind = .default, + @"dollar-in-identifier-extension": Kind = .default, + @"unknown-pragmas": Kind = .default, + @"predefined-identifier-outside-function": Kind = .default, + @"many-braces-around-scalar-init": Kind = .default, + uninitialized: Kind = .default, + @"gnu-statement-expression": Kind = .default, + @"gnu-imaginary-constant": Kind = .default, + @"gnu-complex-integer": Kind = .default, + @"ignored-qualifiers": Kind = .default, + @"integer-overflow": Kind = .default, + @"extra-semi": Kind = .default, + @"gnu-binary-literal": Kind = .default, + @"variadic-macros": Kind = .default, + varargs: Kind = .default, + @"#warnings": Kind = .default, + @"deprecated-declarations": Kind = .default, + @"backslash-newline-escape": Kind = .default, + @"pointer-to-int-cast": Kind = .default, + @"gnu-case-range": Kind = .default, + @"c++-compat": Kind = .default, + vla: Kind = .default, + @"float-overflow-conversion": Kind = .default, + @"float-zero-conversion": Kind = .default, + @"float-conversion": Kind = .default, + @"gnu-folding-constant": Kind = .default, + undef: Kind = .default, + @"ignored-pragmas": Kind = .default, + @"gnu-include-next": Kind = .default, + @"include-next-outside-header": Kind = .default, + @"include-next-absolute-path": Kind = .default, + @"enum-too-large": Kind = .default, + @"fixed-enum-extension": Kind = .default, + @"designated-init": Kind = .default, + @"attribute-warning": Kind = .default, + @"invalid-noreturn": Kind = .default, + @"zero-length-array": Kind = .default, + @"old-style-flexible-struct": Kind = .default, + @"gnu-zero-variadic-macro-arguments": Kind = .default, + @"main-return-type": Kind = .default, + @"expansion-to-defined": Kind = .default, + @"bit-int-extension": Kind = .default, + @"keyword-macro": Kind = .default, + @"pointer-arith": Kind = .default, + @"sizeof-array-argument": Kind = .default, + @"pre-c23-compat": Kind = .default, + @"pointer-bool-conversion": Kind = .default, + @"string-conversion": Kind = .default, + @"gnu-auto-type": Kind = .default, + @"gnu-union-cast": Kind = .default, + @"pointer-sign": Kind = .default, + @"fuse-ld-path": Kind = .default, + @"language-extension-token": Kind = .default, + @"complex-component-init": Kind = .default, + @"microsoft-include": Kind = .default, + @"microsoft-end-of-file": Kind = .default, + @"invalid-source-encoding": Kind = .default, + @"four-char-constants": Kind = .default, + @"unknown-escape-sequence": Kind = .default, + @"invalid-pp-token": Kind = .default, + @"deprecated-non-prototype": Kind = .default, + @"duplicate-embed-param": Kind = .default, + @"unsupported-embed-param": Kind = .default, + @"unused-result": Kind = .default, + normalized: Kind = .default, + @"shift-count-negative": Kind = .default, + @"shift-count-overflow": Kind = .default, + @"constant-conversion": Kind = .default, + @"sign-conversion": Kind = .default, + nonnull: Kind = .default, +}; + +const Diagnostics = @This(); + +list: std.ArrayListUnmanaged(Message) = .empty, +arena: std.heap.ArenaAllocator, +fatal_errors: bool = false, +options: Options = .{}, +errors: u32 = 0, +macro_backtrace_limit: u32 = 6, + +pub fn warningExists(name: []const u8) bool { + inline for (@typeInfo(Options).@"struct".fields) |f| { + if (mem.eql(u8, f.name, name)) return true; + } + return false; +} + +pub fn set(d: *Diagnostics, name: []const u8, to: Kind) !void { + inline for (@typeInfo(Options).@"struct".fields) |f| { + if (mem.eql(u8, f.name, name)) { + @field(d.options, f.name) = to; + return; + } + } + try d.addExtra(.{}, .{ + .tag = .unknown_warning, + .extra = .{ .str = name }, + }, &.{}, true); +} + +pub fn init(gpa: Allocator) Diagnostics { + return .{ + .arena = std.heap.ArenaAllocator.init(gpa), + }; +} + +pub fn deinit(d: *Diagnostics) void { + d.list.deinit(d.arena.child_allocator); + d.arena.deinit(); +} + +pub fn add(comp: *Compilation, msg: Message, expansion_locs: []const Source.Location) Compilation.Error!void { + return comp.diagnostics.addExtra(comp.langopts, msg, expansion_locs, true); +} + +pub fn addExtra( + d: *Diagnostics, + langopts: LangOpts, + msg: Message, + expansion_locs: []const Source.Location, + note_msg_loc: bool, +) Compilation.Error!void { + const kind = d.tagKind(msg.tag, langopts); + if (kind == .off) return; + var copy = msg; + copy.kind = kind; + + if (expansion_locs.len != 0) copy.loc = expansion_locs[expansion_locs.len - 1]; + try d.list.append(d.arena.child_allocator, copy); + if (expansion_locs.len != 0) { + // Add macro backtrace notes in reverse order omitting from the middle if needed. + var i = expansion_locs.len - 1; + const half = d.macro_backtrace_limit / 2; + const limit = if (i < d.macro_backtrace_limit) 0 else i - half; + try d.list.ensureUnusedCapacity( + d.arena.child_allocator, + if (limit == 0) expansion_locs.len else d.macro_backtrace_limit + 1, + ); + while (i > limit) { + i -= 1; + d.list.appendAssumeCapacity(.{ + .tag = .expanded_from_here, + .kind = .note, + .loc = expansion_locs[i], + }); + } + if (limit != 0) { + d.list.appendAssumeCapacity(.{ + .tag = .skipping_macro_backtrace, + .kind = .note, + .extra = .{ .unsigned = expansion_locs.len - d.macro_backtrace_limit }, + }); + i = half -| 1; + while (i > 0) { + i -= 1; + d.list.appendAssumeCapacity(.{ + .tag = .expanded_from_here, + .kind = .note, + .loc = expansion_locs[i], + }); + } + } + + if (note_msg_loc) d.list.appendAssumeCapacity(.{ + .tag = .expanded_from_here, + .kind = .note, + .loc = msg.loc, + }); + } + if (kind == .@"fatal error" or (kind == .@"error" and d.fatal_errors)) + return error.FatalError; +} + +pub fn render(comp: *Compilation, config: std.io.tty.Config) void { + if (comp.diagnostics.list.items.len == 0) return; + var m = defaultMsgWriter(config); + defer m.deinit(); + renderMessages(comp, &m); +} +pub fn defaultMsgWriter(config: std.io.tty.Config) MsgWriter { + return MsgWriter.init(config); +} + +pub fn renderMessages(comp: *Compilation, m: anytype) void { + var errors: u32 = 0; + var warnings: u32 = 0; + for (comp.diagnostics.list.items) |msg| { + switch (msg.kind) { + .@"fatal error", .@"error" => errors += 1, + .warning => warnings += 1, + .note => {}, + .off => continue, // happens if an error is added before it is disabled + .default => unreachable, + } + renderMessage(comp, m, msg); + } + const w_s: []const u8 = if (warnings == 1) "" else "s"; + const e_s: []const u8 = if (errors == 1) "" else "s"; + if (errors != 0 and warnings != 0) { + m.print("{d} warning{s} and {d} error{s} generated.\n", .{ warnings, w_s, errors, e_s }); + } else if (warnings != 0) { + m.print("{d} warning{s} generated.\n", .{ warnings, w_s }); + } else if (errors != 0) { + m.print("{d} error{s} generated.\n", .{ errors, e_s }); + } + + comp.diagnostics.list.items.len = 0; + comp.diagnostics.errors += errors; +} + +pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void { + var line: ?[]const u8 = null; + var end_with_splice = false; + const width = if (msg.loc.id != .unused) blk: { + var loc = msg.loc; + switch (msg.tag) { + .escape_sequence_overflow, + .invalid_universal_character, + => loc.byte_offset += @truncate(msg.extra.offset), + .non_standard_escape_char, + .unknown_escape_sequence, + => loc.byte_offset += msg.extra.invalid_escape.offset, + else => {}, + } + const source = comp.getSource(loc.id); + var line_col = source.lineCol(loc); + line = line_col.line; + end_with_splice = line_col.end_with_splice; + if (msg.tag == .backslash_newline_escape) { + line = line_col.line[0 .. line_col.col - 1]; + line_col.col += 1; + line_col.width += 1; + } + m.location(source.path, line_col.line_no, line_col.col); + break :blk line_col.width; + } else 0; + + m.start(msg.kind); + const prop = msg.tag.property(); + switch (prop.extra) { + .str => printRt(m, prop.msg, .{"{s}"}, .{msg.extra.str}), + .tok_id => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{ + msg.extra.tok_id.expected.symbol(), + msg.extra.tok_id.actual.symbol(), + }), + .tok_id_expected => printRt(m, prop.msg, .{"{s}"}, .{msg.extra.tok_id_expected.symbol()}), + .arguments => printRt(m, prop.msg, .{ "{d}", "{d}" }, .{ + msg.extra.arguments.expected, + msg.extra.arguments.actual, + }), + .codepoints => printRt(m, prop.msg, .{ "{X:0>4}", "{u}" }, .{ + msg.extra.codepoints.actual, + msg.extra.codepoints.resembles, + }), + .attr_arg_count => printRt(m, prop.msg, .{ "{s}", "{d}" }, .{ + @tagName(msg.extra.attr_arg_count.attribute), + msg.extra.attr_arg_count.expected, + }), + .attr_arg_type => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{ + msg.extra.attr_arg_type.expected.toString(), + msg.extra.attr_arg_type.actual.toString(), + }), + .actual_codepoint => printRt(m, prop.msg, .{"{X:0>4}"}, .{msg.extra.actual_codepoint}), + .ascii => printRt(m, prop.msg, .{"{c}"}, .{msg.extra.ascii}), + .unsigned => printRt(m, prop.msg, .{"{d}"}, .{msg.extra.unsigned}), + .pow_2_as_string => printRt(m, prop.msg, .{"{s}"}, .{switch (msg.extra.pow_2_as_string) { + 63 => "9223372036854775808", + 64 => "18446744073709551616", + 127 => "170141183460469231731687303715884105728", + 128 => "340282366920938463463374607431768211456", + else => unreachable, + }}), + .signed => printRt(m, prop.msg, .{"{d}"}, .{msg.extra.signed}), + .attr_enum => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{ + @tagName(msg.extra.attr_enum.tag), + Attribute.Formatting.choices(msg.extra.attr_enum.tag), + }), + .ignored_record_attr => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{ + @tagName(msg.extra.ignored_record_attr.tag), + @tagName(msg.extra.ignored_record_attr.specifier), + }), + .attribute_todo => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{ + @tagName(msg.extra.attribute_todo.tag), + @tagName(msg.extra.attribute_todo.kind), + }), + .builtin_with_header => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{ + @tagName(msg.extra.builtin_with_header.header), + Builtin.nameFromTag(msg.extra.builtin_with_header.builtin).span(), + }), + .invalid_escape => { + if (std.ascii.isPrint(msg.extra.invalid_escape.char)) { + const str: [1]u8 = .{msg.extra.invalid_escape.char}; + printRt(m, prop.msg, .{"{s}"}, .{&str}); + } else { + var buf: [3]u8 = undefined; + const str = std.fmt.bufPrint(&buf, "x{x}", .{std.fmt.fmtSliceHexLower(&.{msg.extra.invalid_escape.char})}) catch unreachable; + printRt(m, prop.msg, .{"{s}"}, .{str}); + } + }, + .normalized => { + const f = struct { + pub fn f( + bytes: []const u8, + comptime _: []const u8, + _: std.fmt.FormatOptions, + writer: anytype, + ) !void { + var it: std.unicode.Utf8Iterator = .{ + .bytes = bytes, + .i = 0, + }; + while (it.nextCodepoint()) |codepoint| { + if (codepoint < 0x7F) { + try writer.writeByte(@intCast(codepoint)); + } else if (codepoint < 0xFFFF) { + try writer.writeAll("\\u"); + try std.fmt.formatInt(codepoint, 16, .upper, .{ + .fill = '0', + .width = 4, + }, writer); + } else { + try writer.writeAll("\\U"); + try std.fmt.formatInt(codepoint, 16, .upper, .{ + .fill = '0', + .width = 8, + }, writer); + } + } + } + }.f; + printRt(m, prop.msg, .{"{s}"}, .{ + std.fmt.Formatter(f){ .data = msg.extra.normalized }, + }); + }, + .none, .offset => m.write(prop.msg), + } + + if (prop.opt) |some| { + if (msg.kind == .@"error" and prop.kind != .@"error") { + m.print(" [-Werror,-W{s}]", .{optName(some)}); + } else if (msg.kind != .note) { + m.print(" [-W{s}]", .{optName(some)}); + } + } + + m.end(line, width, end_with_splice); +} + +fn printRt(m: anytype, str: []const u8, comptime fmts: anytype, args: anytype) void { + var i: usize = 0; + inline for (fmts, args) |fmt, arg| { + const new = std.mem.indexOfPos(u8, str, i, fmt).?; + m.write(str[i..new]); + i = new + fmt.len; + m.print(fmt, .{arg}); + } + m.write(str[i..]); +} + +fn optName(offset: u16) []const u8 { + return std.meta.fieldNames(Options)[offset / @sizeOf(Kind)]; +} + +fn tagKind(d: *Diagnostics, tag: Tag, langopts: LangOpts) Kind { + const prop = tag.property(); + var kind = prop.getKind(&d.options); + + if (prop.all) { + if (d.options.all != .default) kind = d.options.all; + } + if (prop.w_extra) { + if (d.options.extra != .default) kind = d.options.extra; + } + if (prop.pedantic) { + if (d.options.pedantic != .default) kind = d.options.pedantic; + } + if (prop.suppress_version) |some| if (langopts.standard.atLeast(some)) return .off; + if (prop.suppress_unless_version) |some| if (!langopts.standard.atLeast(some)) return .off; + if (prop.suppress_gnu and langopts.standard.isExplicitGNU()) return .off; + if (prop.suppress_gcc and langopts.emulate == .gcc) return .off; + if (prop.suppress_clang and langopts.emulate == .clang) return .off; + if (prop.suppress_msvc and langopts.emulate == .msvc) return .off; + if (kind == .@"error" and d.fatal_errors) kind = .@"fatal error"; + return kind; +} + +const MsgWriter = struct { + w: std.io.BufferedWriter(4096, std.fs.File.Writer), + config: std.io.tty.Config, + + fn init(config: std.io.tty.Config) MsgWriter { + std.debug.lockStdErr(); + return .{ + .w = std.io.bufferedWriter(std.io.getStdErr().writer()), + .config = config, + }; + } + + pub fn deinit(m: *MsgWriter) void { + m.w.flush() catch {}; + std.debug.unlockStdErr(); + } + + pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void { + m.w.writer().print(fmt, args) catch {}; + } + + fn write(m: *MsgWriter, msg: []const u8) void { + m.w.writer().writeAll(msg) catch {}; + } + + fn setColor(m: *MsgWriter, color: std.io.tty.Color) void { + m.config.setColor(m.w.writer(), color) catch {}; + } + + fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void { + m.setColor(.bold); + m.print("{s}:{d}:{d}: ", .{ path, line, col }); + } + + fn start(m: *MsgWriter, kind: Kind) void { + switch (kind) { + .@"fatal error", .@"error" => m.setColor(.bright_red), + .note => m.setColor(.bright_cyan), + .warning => m.setColor(.bright_magenta), + .off, .default => unreachable, + } + m.write(switch (kind) { + .@"fatal error" => "fatal error: ", + .@"error" => "error: ", + .note => "note: ", + .warning => "warning: ", + .off, .default => unreachable, + }); + m.setColor(.white); + } + + fn end(m: *MsgWriter, maybe_line: ?[]const u8, col: u32, end_with_splice: bool) void { + const line = maybe_line orelse { + m.write("\n"); + m.setColor(.reset); + return; + }; + const trailer = if (end_with_splice) "\\ " else ""; + m.setColor(.reset); + m.print("\n{s}{s}\n{s: >[3]}", .{ line, trailer, "", col }); + m.setColor(.bold); + m.setColor(.bright_green); + m.write("^\n"); + m.setColor(.reset); + } +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Diagnostics/messages.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Diagnostics/messages.zig new file mode 100644 index 00000000..c56641a4 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Diagnostics/messages.zig @@ -0,0 +1,1041 @@ +//! Autogenerated by GenerateDef from src/aro/Diagnostics/messages.def, do not edit +// zig fmt: off + +const std = @import("std"); + +pub fn with(comptime Properties: type) type { +return struct { +const W = Properties.makeOpt; +const pointer_sign_message = " converts between pointers to integer types with different sign"; +const expected_arguments = "expected {d} argument(s) got {d}"; +pub const Tag = enum { + todo, + error_directive, + warning_directive, + elif_without_if, + elif_after_else, + elifdef_without_if, + elifdef_after_else, + elifndef_without_if, + elifndef_after_else, + else_without_if, + else_after_else, + endif_without_if, + unknown_pragma, + line_simple_digit, + line_invalid_filename, + unterminated_conditional_directive, + invalid_preprocessing_directive, + macro_name_missing, + extra_tokens_directive_end, + expected_value_in_expr, + closing_paren, + to_match_paren, + to_match_brace, + to_match_bracket, + header_str_closing, + header_str_match, + string_literal_in_pp_expr, + float_literal_in_pp_expr, + defined_as_macro_name, + macro_name_must_be_identifier, + whitespace_after_macro_name, + hash_hash_at_start, + hash_hash_at_end, + pasting_formed_invalid, + missing_paren_param_list, + unterminated_macro_param_list, + invalid_token_param_list, + expected_comma_param_list, + hash_not_followed_param, + expected_filename, + empty_filename, + expected_invalid, + expected_eof, + expected_token, + expected_expr, + expected_integer_constant_expr, + missing_type_specifier, + missing_type_specifier_c23, + multiple_storage_class, + static_assert_failure, + static_assert_failure_message, + expected_type, + cannot_combine_spec, + duplicate_decl_spec, + restrict_non_pointer, + expected_external_decl, + expected_ident_or_l_paren, + missing_declaration, + func_not_in_root, + illegal_initializer, + extern_initializer, + spec_from_typedef, + param_before_var_args, + void_only_param, + void_param_qualified, + void_must_be_first_param, + invalid_storage_on_param, + threadlocal_non_var, + func_spec_non_func, + illegal_storage_on_func, + illegal_storage_on_global, + expected_stmt, + func_cannot_return_func, + func_cannot_return_array, + undeclared_identifier, + not_callable, + unsupported_str_cat, + static_func_not_global, + implicit_func_decl, + unknown_builtin, + implicit_builtin, + implicit_builtin_header_note, + expected_param_decl, + invalid_old_style_params, + expected_fn_body, + invalid_void_param, + unused_value, + continue_not_in_loop, + break_not_in_loop_or_switch, + unreachable_code, + duplicate_label, + previous_label, + undeclared_label, + case_not_in_switch, + duplicate_switch_case, + multiple_default, + previous_case, + expected_arguments, + callee_with_static_array, + array_argument_too_small, + non_null_argument, + expected_arguments_old, + expected_at_least_arguments, + invalid_static_star, + static_non_param, + array_qualifiers, + star_non_param, + variable_len_array_file_scope, + useless_static, + negative_array_size, + array_incomplete_elem, + array_func_elem, + static_non_outermost_array, + qualifier_non_outermost_array, + unterminated_macro_arg_list, + unknown_warning, + overflow, + int_literal_too_big, + indirection_ptr, + addr_of_rvalue, + addr_of_bitfield, + not_assignable, + ident_or_l_brace, + empty_enum, + redefinition, + previous_definition, + expected_identifier, + expected_str_literal, + expected_str_literal_in, + parameter_missing, + empty_record, + empty_record_size, + wrong_tag, + expected_parens_around_typename, + alignof_expr, + invalid_alignof, + invalid_sizeof, + macro_redefined, + generic_qual_type, + generic_array_type, + generic_func_type, + generic_duplicate, + generic_duplicate_here, + generic_duplicate_default, + generic_no_match, + escape_sequence_overflow, + invalid_universal_character, + incomplete_universal_character, + multichar_literal_warning, + invalid_multichar_literal, + wide_multichar_literal, + char_lit_too_wide, + char_too_large, + must_use_struct, + must_use_union, + must_use_enum, + redefinition_different_sym, + redefinition_incompatible, + redefinition_of_parameter, + invalid_bin_types, + comparison_ptr_int, + comparison_distinct_ptr, + incompatible_pointers, + invalid_argument_un, + incompatible_assign, + implicit_ptr_to_int, + invalid_cast_to_float, + invalid_cast_to_pointer, + invalid_cast_type, + qual_cast, + invalid_index, + invalid_subscript, + array_after, + array_before, + statement_int, + statement_scalar, + func_should_return, + incompatible_return, + incompatible_return_sign, + implicit_int_to_ptr, + func_does_not_return, + void_func_returns_value, + incompatible_arg, + incompatible_ptr_arg, + incompatible_ptr_arg_sign, + parameter_here, + atomic_array, + atomic_func, + atomic_incomplete, + addr_of_register, + variable_incomplete_ty, + parameter_incomplete_ty, + tentative_array, + deref_incomplete_ty_ptr, + alignas_on_func, + alignas_on_param, + minimum_alignment, + maximum_alignment, + negative_alignment, + align_ignored, + zero_align_ignored, + non_pow2_align, + pointer_mismatch, + static_assert_not_constant, + static_assert_missing_message, + pre_c23_compat, + unbound_vla, + array_too_large, + record_too_large, + incompatible_ptr_init, + incompatible_ptr_init_sign, + incompatible_ptr_assign, + incompatible_ptr_assign_sign, + vla_init, + func_init, + incompatible_init, + empty_scalar_init, + excess_scalar_init, + excess_str_init, + excess_struct_init, + excess_array_init, + str_init_too_long, + arr_init_too_long, + invalid_typeof, + division_by_zero, + division_by_zero_macro, + builtin_choose_cond, + alignas_unavailable, + case_val_unavailable, + enum_val_unavailable, + incompatible_array_init, + array_init_str, + initializer_overrides, + previous_initializer, + invalid_array_designator, + negative_array_designator, + oob_array_designator, + invalid_field_designator, + no_such_field_designator, + empty_aggregate_init_braces, + ptr_init_discards_quals, + ptr_assign_discards_quals, + ptr_ret_discards_quals, + ptr_arg_discards_quals, + unknown_attribute, + ignored_attribute, + invalid_fallthrough, + cannot_apply_attribute_to_statement, + builtin_macro_redefined, + feature_check_requires_identifier, + missing_tok_builtin, + gnu_label_as_value, + expected_record_ty, + member_expr_not_ptr, + member_expr_ptr, + no_such_member, + malformed_warning_check, + invalid_computed_goto, + pragma_warning_message, + pragma_error_message, + pragma_message, + pragma_requires_string_literal, + poisoned_identifier, + pragma_poison_identifier, + pragma_poison_macro, + newline_eof, + empty_translation_unit, + omitting_parameter_name, + non_int_bitfield, + negative_bitwidth, + zero_width_named_field, + bitfield_too_big, + invalid_utf8, + implicitly_unsigned_literal, + invalid_preproc_operator, + invalid_preproc_expr_start, + c99_compat, + unexpected_character, + invalid_identifier_start_char, + unicode_zero_width, + unicode_homoglyph, + meaningless_asm_qual, + duplicate_asm_qual, + invalid_asm_str, + dollar_in_identifier_extension, + dollars_in_identifiers, + expanded_from_here, + skipping_macro_backtrace, + pragma_operator_string_literal, + unknown_gcc_pragma, + unknown_gcc_pragma_directive, + predefined_top_level, + incompatible_va_arg, + too_many_scalar_init_braces, + uninitialized_in_own_init, + gnu_statement_expression, + stmt_expr_not_allowed_file_scope, + gnu_imaginary_constant, + plain_complex, + complex_int, + qual_on_ret_type, + cli_invalid_standard, + cli_invalid_target, + cli_invalid_emulate, + cli_unknown_arg, + cli_error, + cli_unused_link_object, + cli_unknown_linker, + extra_semi, + func_field, + vla_field, + field_incomplete_ty, + flexible_in_union, + flexible_non_final, + flexible_in_empty, + duplicate_member, + binary_integer_literal, + gnu_va_macro, + builtin_must_be_called, + va_start_not_in_func, + va_start_fixed_args, + va_start_not_last_param, + attribute_not_enough_args, + attribute_too_many_args, + attribute_arg_invalid, + unknown_attr_enum, + attribute_requires_identifier, + declspec_not_enabled, + declspec_attr_not_supported, + deprecated_declarations, + deprecated_note, + unavailable, + unavailable_note, + warning_attribute, + error_attribute, + ignored_record_attr, + backslash_newline_escape, + array_size_non_int, + cast_to_smaller_int, + gnu_switch_range, + empty_case_range, + non_standard_escape_char, + invalid_pp_stringify_escape, + vla, + int_value_changed, + sign_conversion, + float_overflow_conversion, + float_out_of_range, + float_zero_conversion, + float_value_changed, + float_to_int, + const_decl_folded, + const_decl_folded_vla, + redefinition_of_typedef, + undefined_macro, + fn_macro_undefined, + preprocessing_directive_only, + missing_lparen_after_builtin, + offsetof_ty, + offsetof_incomplete, + offsetof_array, + pragma_pack_lparen, + pragma_pack_rparen, + pragma_pack_unknown_action, + pragma_pack_show, + pragma_pack_int, + pragma_pack_int_ident, + pragma_pack_undefined_pop, + pragma_pack_empty_stack, + cond_expr_type, + too_many_includes, + enumerator_too_small, + enumerator_too_large, + include_next, + include_next_outside_header, + enumerator_overflow, + enum_not_representable, + enum_too_large, + enum_fixed, + enum_prev_nonfixed, + enum_prev_fixed, + enum_different_explicit_ty, + enum_not_representable_fixed, + transparent_union_wrong_type, + transparent_union_one_field, + transparent_union_size, + transparent_union_size_note, + designated_init_invalid, + designated_init_needed, + ignore_common, + ignore_nocommon, + non_string_ignored, + local_variable_attribute, + ignore_cold, + ignore_hot, + ignore_noinline, + ignore_always_inline, + invalid_noreturn, + nodiscard_unused, + warn_unused_result, + invalid_vec_elem_ty, + vec_size_not_multiple, + invalid_imag, + invalid_real, + zero_length_array, + old_style_flexible_struct, + comma_deletion_va_args, + main_return_type, + expansion_to_defined, + invalid_int_suffix, + invalid_float_suffix, + invalid_octal_digit, + invalid_binary_digit, + exponent_has_no_digits, + hex_floating_constant_requires_exponent, + sizeof_returns_zero, + declspec_not_allowed_after_declarator, + declarator_name_tok, + type_not_supported_on_target, + bit_int, + unsigned_bit_int_too_small, + signed_bit_int_too_small, + unsigned_bit_int_too_big, + signed_bit_int_too_big, + keyword_macro, + ptr_arithmetic_incomplete, + callconv_not_supported, + pointer_arith_void, + sizeof_array_arg, + array_address_to_bool, + string_literal_to_bool, + constant_expression_conversion_not_allowed, + invalid_object_cast, + cli_invalid_fp_eval_method, + suggest_pointer_for_invalid_fp16, + bitint_suffix, + auto_type_extension, + auto_type_not_allowed, + auto_type_requires_initializer, + auto_type_requires_single_declarator, + auto_type_requires_plain_declarator, + invalid_cast_to_auto_type, + auto_type_from_bitfield, + array_of_auto_type, + auto_type_with_init_list, + missing_semicolon, + tentative_definition_incomplete, + forward_declaration_here, + gnu_union_cast, + invalid_union_cast, + cast_to_incomplete_type, + invalid_source_epoch, + fuse_ld_path, + invalid_rtlib, + unsupported_rtlib_gcc, + invalid_unwindlib, + incompatible_unwindlib, + gnu_asm_disabled, + extension_token_used, + complex_component_init, + complex_prefix_postfix_op, + not_floating_type, + argument_types_differ, + ms_search_rule, + ctrl_z_eof, + illegal_char_encoding_warning, + illegal_char_encoding_error, + ucn_basic_char_error, + ucn_basic_char_warning, + ucn_control_char_error, + ucn_control_char_warning, + c89_ucn_in_literal, + four_char_char_literal, + multi_char_char_literal, + missing_hex_escape, + unknown_escape_sequence, + attribute_requires_string, + unterminated_string_literal_warning, + unterminated_string_literal_error, + empty_char_literal_warning, + empty_char_literal_error, + unterminated_char_literal_warning, + unterminated_char_literal_error, + unterminated_comment, + def_no_proto_deprecated, + passing_args_to_kr, + unknown_type_name, + label_compound_end, + u8_char_lit, + malformed_embed_param, + malformed_embed_limit, + duplicate_embed_param, + unsupported_embed_param, + invalid_compound_literal_storage_class, + va_opt_lparen, + va_opt_rparen, + attribute_int_out_of_range, + identifier_not_normalized, + c23_auto_plain_declarator, + c23_auto_single_declarator, + c32_auto_requires_initializer, + c23_auto_scalar_init, + negative_shift_count, + too_big_shift_count, + complex_conj, + overflow_builtin_requires_int, + overflow_result_requires_ptr, + attribute_todo, + invalid_type_underlying_enum, + auto_type_self_initialized, + + pub fn property(tag: Tag) Properties { + return named_data[@intFromEnum(tag)]; + } + + const named_data = [_]Properties{ + .{ .msg = "TODO: {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s}", .opt = W("#warnings"), .extra = .str, .kind = .warning }, + .{ .msg = "#elif without #if", .kind = .@"error" }, + .{ .msg = "#elif after #else", .kind = .@"error" }, + .{ .msg = "#elifdef without #if", .kind = .@"error" }, + .{ .msg = "#elifdef after #else", .kind = .@"error" }, + .{ .msg = "#elifndef without #if", .kind = .@"error" }, + .{ .msg = "#elifndef after #else", .kind = .@"error" }, + .{ .msg = "#else without #if", .kind = .@"error" }, + .{ .msg = "#else after #else", .kind = .@"error" }, + .{ .msg = "#endif without #if", .kind = .@"error" }, + .{ .msg = "unknown pragma ignored", .opt = W("unknown-pragmas"), .kind = .off, .all = true }, + .{ .msg = "#line directive requires a simple digit sequence", .kind = .@"error" }, + .{ .msg = "invalid filename for #line directive", .kind = .@"error" }, + .{ .msg = "unterminated conditional directive", .kind = .@"error" }, + .{ .msg = "invalid preprocessing directive", .kind = .@"error" }, + .{ .msg = "macro name missing", .kind = .@"error" }, + .{ .msg = "extra tokens at end of macro directive", .kind = .@"error" }, + .{ .msg = "expected value in expression", .kind = .@"error" }, + .{ .msg = "expected closing ')'", .kind = .@"error" }, + .{ .msg = "to match this '('", .kind = .note }, + .{ .msg = "to match this '{'", .kind = .note }, + .{ .msg = "to match this '['", .kind = .note }, + .{ .msg = "expected closing '>'", .kind = .@"error" }, + .{ .msg = "to match this '<'", .kind = .note }, + .{ .msg = "string literal in preprocessor expression", .kind = .@"error" }, + .{ .msg = "floating point literal in preprocessor expression", .kind = .@"error" }, + .{ .msg = "'defined' cannot be used as a macro name", .kind = .@"error" }, + .{ .msg = "macro name must be an identifier", .kind = .@"error" }, + .{ .msg = "ISO C99 requires whitespace after the macro name", .opt = W("c99-extensions"), .kind = .warning }, + .{ .msg = "'##' cannot appear at the start of a macro expansion", .kind = .@"error" }, + .{ .msg = "'##' cannot appear at the end of a macro expansion", .kind = .@"error" }, + .{ .msg = "pasting formed '{s}', an invalid preprocessing token", .extra = .str, .kind = .@"error" }, + .{ .msg = "missing ')' in macro parameter list", .kind = .@"error" }, + .{ .msg = "unterminated macro param list", .kind = .@"error" }, + .{ .msg = "invalid token in macro parameter list", .kind = .@"error" }, + .{ .msg = "expected comma in macro parameter list", .kind = .@"error" }, + .{ .msg = "'#' is not followed by a macro parameter", .kind = .@"error" }, + .{ .msg = "expected \"FILENAME\" or ", .kind = .@"error" }, + .{ .msg = "empty filename", .kind = .@"error" }, + .{ .msg = "expected '{s}', found invalid bytes", .extra = .tok_id_expected, .kind = .@"error" }, + .{ .msg = "expected '{s}' before end of file", .extra = .tok_id_expected, .kind = .@"error" }, + .{ .msg = "expected '{s}', found '{s}'", .extra = .tok_id, .kind = .@"error" }, + .{ .msg = "expected expression", .kind = .@"error" }, + .{ .msg = "expression is not an integer constant expression", .kind = .@"error" }, + .{ .msg = "type specifier missing, defaults to 'int'", .opt = W("implicit-int"), .kind = .warning, .all = true }, + .{ .msg = "a type specifier is required for all declarations", .kind = .@"error" }, + .{ .msg = "cannot combine with previous '{s}' declaration specifier", .extra = .str, .kind = .@"error" }, + .{ .msg = "static assertion failed", .kind = .@"error" }, + .{ .msg = "static assertion failed {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "expected a type", .kind = .@"error" }, + .{ .msg = "cannot combine with previous '{s}' specifier", .extra = .str, .kind = .@"error" }, + .{ .msg = "duplicate '{s}' declaration specifier", .extra = .str, .opt = W("duplicate-decl-specifier"), .kind = .warning, .all = true }, + .{ .msg = "restrict requires a pointer or reference ('{s}' is invalid)", .extra = .str, .kind = .@"error" }, + .{ .msg = "expected external declaration", .kind = .@"error" }, + .{ .msg = "expected identifier or '('", .kind = .@"error" }, + .{ .msg = "declaration does not declare anything", .opt = W("missing-declaration"), .kind = .warning }, + .{ .msg = "function definition is not allowed here", .kind = .@"error" }, + .{ .msg = "illegal initializer (only variables can be initialized)", .kind = .@"error" }, + .{ .msg = "extern variable has initializer", .opt = W("extern-initializer"), .kind = .warning }, + .{ .msg = "'{s}' came from typedef", .extra = .str, .kind = .note }, + .{ .msg = "ISO C requires a named parameter before '...'", .kind = .@"error", .suppress_version = .c23 }, + .{ .msg = "'void' must be the only parameter if specified", .kind = .@"error" }, + .{ .msg = "'void' parameter cannot be qualified", .kind = .@"error" }, + .{ .msg = "'void' must be the first parameter if specified", .kind = .@"error" }, + .{ .msg = "invalid storage class on function parameter", .kind = .@"error" }, + .{ .msg = "_Thread_local only allowed on variables", .kind = .@"error" }, + .{ .msg = "'{s}' can only appear on functions", .extra = .str, .kind = .@"error" }, + .{ .msg = "illegal storage class on function", .kind = .@"error" }, + .{ .msg = "illegal storage class on global variable", .kind = .@"error" }, + .{ .msg = "expected statement", .kind = .@"error" }, + .{ .msg = "function cannot return a function", .kind = .@"error" }, + .{ .msg = "function cannot return an array", .kind = .@"error" }, + .{ .msg = "use of undeclared identifier '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "cannot call non function type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "unsupported string literal concatenation", .kind = .@"error" }, + .{ .msg = "static functions must be global", .kind = .@"error" }, + .{ .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 }, + .{ .msg = "use of unknown builtin '{s}'", .extra = .str, .opt = W("implicit-function-declaration"), .kind = .@"error", .all = true }, + .{ .msg = "implicitly declaring library function '{s}'", .extra = .str, .opt = W("implicit-function-declaration"), .kind = .@"error", .all = true }, + .{ .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 }, + .{ .msg = "expected parameter declaration", .kind = .@"error" }, + .{ .msg = "identifier parameter lists are only allowed in function definitions", .kind = .@"error" }, + .{ .msg = "expected function body after function declaration", .kind = .@"error" }, + .{ .msg = "parameter cannot have void type", .kind = .@"error" }, + .{ .msg = "expression result unused", .opt = W("unused-value"), .kind = .warning, .all = true }, + .{ .msg = "'continue' statement not in a loop", .kind = .@"error" }, + .{ .msg = "'break' statement not in a loop or a switch", .kind = .@"error" }, + .{ .msg = "unreachable code", .opt = W("unreachable-code"), .kind = .warning, .all = true }, + .{ .msg = "duplicate label '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "previous definition of label '{s}' was here", .extra = .str, .kind = .note }, + .{ .msg = "use of undeclared label '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "'{s}' statement not in a switch statement", .extra = .str, .kind = .@"error" }, + .{ .msg = "duplicate case value '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "multiple default cases in the same switch", .kind = .@"error" }, + .{ .msg = "previous case defined here", .kind = .note }, + .{ .msg = expected_arguments, .extra = .arguments, .kind = .@"error" }, + .{ .msg = "callee declares array parameter as static here", .kind = .note }, + .{ .msg = "array argument is too small; contains {d} elements, callee requires at least {d}", .extra = .arguments, .kind = .warning, .opt = W("array-bounds") }, + .{ .msg = "null passed to a callee that requires a non-null argument", .kind = .warning, .opt = W("nonnull") }, + .{ .msg = expected_arguments, .extra = .arguments, .kind = .warning }, + .{ .msg = "expected at least {d} argument(s) got {d}", .extra = .arguments, .kind = .warning }, + .{ .msg = "'static' may not be used with an unspecified variable length array size", .kind = .@"error" }, + .{ .msg = "'static' used outside of function parameters", .kind = .@"error" }, + .{ .msg = "type qualifier in non parameter array type", .kind = .@"error" }, + .{ .msg = "star modifier used outside of function parameters", .kind = .@"error" }, + .{ .msg = "variable length arrays not allowed at file scope", .kind = .@"error" }, + .{ .msg = "'static' useless without a constant size", .kind = .warning, .w_extra = true }, + .{ .msg = "array size must be 0 or greater", .kind = .@"error" }, + .{ .msg = "array has incomplete element type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "arrays cannot have functions as their element type", .kind = .@"error" }, + .{ .msg = "'static' used in non-outermost array type", .kind = .@"error" }, + .{ .msg = "type qualifier used in non-outermost array type", .kind = .@"error" }, + .{ .msg = "unterminated function macro argument list", .kind = .@"error" }, + .{ .msg = "unknown warning '{s}'", .extra = .str, .opt = W("unknown-warning-option"), .kind = .warning }, + .{ .msg = "overflow in expression; result is '{s}'", .extra = .str, .opt = W("integer-overflow"), .kind = .warning }, + .{ .msg = "integer literal is too large to be represented in any integer type", .kind = .@"error" }, + .{ .msg = "indirection requires pointer operand", .kind = .@"error" }, + .{ .msg = "cannot take the address of an rvalue", .kind = .@"error" }, + .{ .msg = "address of bit-field requested", .kind = .@"error" }, + .{ .msg = "expression is not assignable", .kind = .@"error" }, + .{ .msg = "expected identifier or '{'", .kind = .@"error" }, + .{ .msg = "empty enum is invalid", .kind = .@"error" }, + .{ .msg = "redefinition of '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "previous definition is here", .kind = .note }, + .{ .msg = "expected identifier", .kind = .@"error" }, + .{ .msg = "expected string literal for diagnostic message in static_assert", .kind = .@"error" }, + .{ .msg = "expected string literal in '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "parameter named '{s}' is missing", .extra = .str, .kind = .@"error" }, + .{ .msg = "empty {s} is a GNU extension", .extra = .str, .opt = W("gnu-empty-struct"), .kind = .off, .pedantic = true }, + .{ .msg = "empty {s} has size 0 in C, size 1 in C++", .extra = .str, .opt = W("c++-compat"), .kind = .off }, + .{ .msg = "use of '{s}' with tag type that does not match previous definition", .extra = .str, .kind = .@"error" }, + .{ .msg = "expected parentheses around type name", .kind = .@"error" }, + .{ .msg = "'_Alignof' applied to an expression is a GNU extension", .opt = W("gnu-alignof-expression"), .kind = .warning, .suppress_gnu = true }, + .{ .msg = "invalid application of 'alignof' to an incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid application of 'sizeof' to an incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "'{s}' macro redefined", .extra = .str, .opt = W("macro-redefined"), .kind = .warning }, + .{ .msg = "generic association with qualifiers cannot be matched with", .opt = W("generic-qual-type"), .kind = .warning }, + .{ .msg = "generic association array type cannot be matched with", .opt = W("generic-qual-type"), .kind = .warning }, + .{ .msg = "generic association function type cannot be matched with", .opt = W("generic-qual-type"), .kind = .warning }, + .{ .msg = "type '{s}' in generic association compatible with previously specified type", .extra = .str, .kind = .@"error" }, + .{ .msg = "compatible type '{s}' specified here", .extra = .str, .kind = .note }, + .{ .msg = "duplicate default generic association", .kind = .@"error" }, + .{ .msg = "controlling expression type '{s}' not compatible with any generic association type", .extra = .str, .kind = .@"error" }, + .{ .msg = "escape sequence out of range", .kind = .@"error" }, + .{ .msg = "invalid universal character", .kind = .@"error" }, + .{ .msg = "incomplete universal character name", .kind = .@"error" }, + .{ .msg = "multi-character character constant", .opt = W("multichar"), .kind = .warning, .all = true }, + .{ .msg = "{s} character literals may not contain multiple characters", .kind = .@"error", .extra = .str }, + .{ .msg = "extraneous characters in character constant ignored", .kind = .warning }, + .{ .msg = "character constant too long for its type", .kind = .warning, .all = true }, + .{ .msg = "character too large for enclosing character literal type", .kind = .@"error" }, + .{ .msg = "must use 'struct' tag to refer to type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "must use 'union' tag to refer to type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "must use 'enum' tag to refer to type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "redefinition of '{s}' as different kind of symbol", .extra = .str, .kind = .@"error" }, + .{ .msg = "redefinition of '{s}' with a different type", .extra = .str, .kind = .@"error" }, + .{ .msg = "redefinition of parameter '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid operands to binary expression ({s})", .extra = .str, .kind = .@"error" }, + .{ .msg = "comparison between pointer and integer ({s})", .extra = .str, .opt = W("pointer-integer-compare"), .kind = .warning }, + .{ .msg = "comparison of distinct pointer types ({s})", .extra = .str, .opt = W("compare-distinct-pointer-types"), .kind = .warning }, + .{ .msg = "incompatible pointer types ({s})", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid argument type '{s}' to unary expression", .extra = .str, .kind = .@"error" }, + .{ .msg = "assignment to {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "implicit pointer to integer conversion from {s}", .extra = .str, .opt = W("int-conversion"), .kind = .warning }, + .{ .msg = "pointer cannot be cast to type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "operand of type '{s}' cannot be cast to a pointer type", .extra = .str, .kind = .@"error" }, + .{ .msg = "cannot cast to non arithmetic or pointer type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "cast to type '{s}' will not preserve qualifiers", .extra = .str, .opt = W("cast-qualifiers"), .kind = .warning }, + .{ .msg = "array subscript is not an integer", .kind = .@"error" }, + .{ .msg = "subscripted value is not an array or pointer", .kind = .@"error" }, + .{ .msg = "array index {s} is past the end of the array", .extra = .str, .opt = W("array-bounds"), .kind = .warning }, + .{ .msg = "array index {s} is before the beginning of the array", .extra = .str, .opt = W("array-bounds"), .kind = .warning }, + .{ .msg = "statement requires expression with integer type ('{s}' invalid)", .extra = .str, .kind = .@"error" }, + .{ .msg = "statement requires expression with scalar type ('{s}' invalid)", .extra = .str, .kind = .@"error" }, + .{ .msg = "non-void function '{s}' should return a value", .extra = .str, .opt = W("return-type"), .kind = .@"error", .all = true }, + .{ .msg = "returning {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "returning {s}" ++ pointer_sign_message, .extra = .str, .kind = .warning, .opt = W("pointer-sign") }, + .{ .msg = "implicit integer to pointer conversion from {s}", .extra = .str, .opt = W("int-conversion"), .kind = .warning }, + .{ .msg = "non-void function '{s}' does not return a value", .extra = .str, .opt = W("return-type"), .kind = .warning, .all = true }, + .{ .msg = "void function '{s}' should not return a value", .extra = .str, .opt = W("return-type"), .kind = .@"error", .all = true }, + .{ .msg = "passing {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "passing {s}", .extra = .str, .kind = .warning, .opt = W("incompatible-pointer-types") }, + .{ .msg = "passing {s}" ++ pointer_sign_message, .extra = .str, .kind = .warning, .opt = W("pointer-sign") }, + .{ .msg = "passing argument to parameter here", .kind = .note }, + .{ .msg = "atomic cannot be applied to array type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "atomic cannot be applied to function type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "atomic cannot be applied to incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "address of register variable requested", .kind = .@"error" }, + .{ .msg = "variable has incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "parameter has incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "tentative array definition assumed to have one element", .kind = .warning }, + .{ .msg = "dereferencing pointer to incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "'_Alignas' attribute only applies to variables and fields", .kind = .@"error" }, + .{ .msg = "'_Alignas' attribute cannot be applied to a function parameter", .kind = .@"error" }, + .{ .msg = "requested alignment is less than minimum alignment of {d}", .extra = .unsigned, .kind = .@"error" }, + .{ .msg = "requested alignment of {s} is too large", .extra = .str, .kind = .@"error" }, + .{ .msg = "requested negative alignment of {s} is invalid", .extra = .str, .kind = .@"error" }, + .{ .msg = "'_Alignas' attribute is ignored here", .kind = .warning }, + .{ .msg = "requested alignment of zero is ignored", .kind = .warning }, + .{ .msg = "requested alignment is not a power of 2", .kind = .@"error" }, + .{ .msg = "pointer type mismatch ({s})", .extra = .str, .opt = W("pointer-type-mismatch"), .kind = .warning }, + .{ .msg = "static_assert expression is not an integral constant expression", .kind = .@"error" }, + .{ .msg = "static_assert with no message is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 }, + .{ .msg = "{s} is incompatible with C standards before C23", .extra = .str, .kind = .off, .suppress_unless_version = .c23, .opt = W("pre-c23-compat") }, + .{ .msg = "variable length array must be bound in function definition", .kind = .@"error" }, + .{ .msg = "array is too large", .kind = .@"error" }, + .{ .msg = "type '{s}' is too large", .kind = .@"error", .extra = .str }, + .{ .msg = "incompatible pointer types initializing {s}", .extra = .str, .opt = W("incompatible-pointer-types"), .kind = .warning }, + .{ .msg = "incompatible pointer types initializing {s}" ++ pointer_sign_message, .extra = .str, .opt = W("pointer-sign"), .kind = .warning }, + .{ .msg = "incompatible pointer types assigning to {s}", .extra = .str, .opt = W("incompatible-pointer-types"), .kind = .warning }, + .{ .msg = "incompatible pointer types assigning to {s} " ++ pointer_sign_message, .extra = .str, .opt = W("pointer-sign"), .kind = .warning }, + .{ .msg = "variable-sized object may not be initialized", .kind = .@"error" }, + .{ .msg = "illegal initializer type", .kind = .@"error" }, + .{ .msg = "initializing {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "scalar initializer cannot be empty", .kind = .@"error" }, + .{ .msg = "excess elements in scalar initializer", .opt = W("excess-initializers"), .kind = .warning }, + .{ .msg = "excess elements in string initializer", .opt = W("excess-initializers"), .kind = .warning }, + .{ .msg = "excess elements in struct initializer", .opt = W("excess-initializers"), .kind = .warning }, + .{ .msg = "excess elements in array initializer", .opt = W("excess-initializers"), .kind = .warning }, + .{ .msg = "initializer-string for char array is too long", .opt = W("excess-initializers"), .kind = .warning }, + .{ .msg = "cannot initialize type ({s})", .extra = .str, .kind = .@"error" }, + .{ .msg = "'{s} typeof' is invalid", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s} by zero is undefined", .extra = .str, .opt = W("division-by-zero"), .kind = .warning }, + .{ .msg = "{s} by zero in preprocessor expression", .extra = .str, .kind = .@"error" }, + .{ .msg = "'__builtin_choose_expr' requires a constant expression", .kind = .@"error" }, + .{ .msg = "'_Alignas' attribute requires integer constant expression", .kind = .@"error" }, + .{ .msg = "case value must be an integer constant expression", .kind = .@"error" }, + .{ .msg = "enum value must be an integer constant expression", .kind = .@"error" }, + .{ .msg = "cannot initialize array of type {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "array initializer must be an initializer list or wide string literal", .kind = .@"error" }, + .{ .msg = "initializer overrides previous initialization", .opt = W("initializer-overrides"), .kind = .warning, .w_extra = true }, + .{ .msg = "previous initialization", .kind = .note }, + .{ .msg = "array designator used for non-array type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "array designator value {s} is negative", .extra = .str, .kind = .@"error" }, + .{ .msg = "array designator index {s} exceeds array bounds", .extra = .str, .kind = .@"error" }, + .{ .msg = "field designator used for non-record type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "record type has no field named '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "initializer for aggregate with no elements requires explicit braces", .kind = .@"error" }, + .{ .msg = "initializing {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning }, + .{ .msg = "assigning to {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning }, + .{ .msg = "returning {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning }, + .{ .msg = "passing {s} discards qualifiers", .extra = .str, .opt = W("incompatible-pointer-types-discards-qualifiers"), .kind = .warning }, + .{ .msg = "unknown attribute '{s}' ignored", .extra = .str, .opt = W("unknown-attributes"), .kind = .warning }, + .{ .msg = "{s}", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "fallthrough annotation does not directly precede switch label", .kind = .@"error" }, + .{ .msg = "'{s}' attribute cannot be applied to a statement", .extra = .str, .kind = .@"error" }, + .{ .msg = "redefining builtin macro", .opt = W("builtin-macro-redefined"), .kind = .warning }, + .{ .msg = "builtin feature check macro requires a parenthesized identifier", .kind = .@"error" }, + .{ .msg = "missing '{s}', after builtin feature-check macro", .extra = .tok_id_expected, .kind = .@"error" }, + .{ .msg = "use of GNU address-of-label extension", .opt = W("gnu-label-as-value"), .kind = .off, .pedantic = true }, + .{ .msg = "member reference base type '{s}' is not a structure or union", .extra = .str, .kind = .@"error" }, + .{ .msg = "member reference type '{s}' is not a pointer; did you mean to use '.'?", .extra = .str, .kind = .@"error" }, + .{ .msg = "member reference type '{s}' is a pointer; did you mean to use '->'?", .extra = .str, .kind = .@"error" }, + .{ .msg = "no member named {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s} expected option name (e.g. \"-Wundef\")", .extra = .str, .opt = W("malformed-warning-check"), .kind = .warning, .all = true }, + .{ .msg = "computed goto in function with no address-of-label expressions", .kind = .@"error" }, + .{ .msg = "{s}", .extra = .str, .opt = W("#pragma-messages"), .kind = .warning }, + .{ .msg = "{s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "#pragma message: {s}", .extra = .str, .kind = .note }, + .{ .msg = "pragma {s} requires string literal", .extra = .str, .kind = .@"error" }, + .{ .msg = "attempt to use a poisoned identifier", .kind = .@"error" }, + .{ .msg = "can only poison identifier tokens", .kind = .@"error" }, + .{ .msg = "poisoning existing macro", .kind = .warning }, + .{ .msg = "no newline at end of file", .opt = W("newline-eof"), .kind = .off, .pedantic = true }, + .{ .msg = "ISO C requires a translation unit to contain at least one declaration", .opt = W("empty-translation-unit"), .kind = .off, .pedantic = true }, + .{ .msg = "omitting the parameter name in a function definition is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 }, + .{ .msg = "bit-field has non-integer type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "bit-field has negative width ({s})", .extra = .str, .kind = .@"error" }, + .{ .msg = "named bit-field has zero width", .kind = .@"error" }, + .{ .msg = "width of bit-field exceeds width of its type", .kind = .@"error" }, + .{ .msg = "source file is not valid UTF-8", .kind = .@"error" }, + .{ .msg = "integer literal is too large to be represented in a signed integer type, interpreting as unsigned", .opt = W("implicitly-unsigned-literal"), .kind = .warning }, + .{ .msg = "token is not a valid binary operator in a preprocessor subexpression", .kind = .@"error" }, + .{ .msg = "invalid token at start of a preprocessor expression", .kind = .@"error" }, + .{ .msg = "using this character in an identifier is incompatible with C99", .opt = W("c99-compat"), .kind = .off }, + .{ .msg = "unexpected character 4}>", .extra = .actual_codepoint, .kind = .@"error" }, + .{ .msg = "character 4}> not allowed at the start of an identifier", .extra = .actual_codepoint, .kind = .@"error" }, + .{ .msg = "identifier contains Unicode character 4}> that is invisible in some environments", .opt = W("unicode-homoglyph"), .extra = .actual_codepoint, .kind = .warning }, + .{ .msg = "treating Unicode character 4}> as identifier character rather than as '{u}' symbol", .extra = .codepoints, .opt = W("unicode-homoglyph"), .kind = .warning }, + .{ .msg = "meaningless '{s}' on assembly outside function", .extra = .str, .kind = .@"error" }, + .{ .msg = "duplicate asm qualifier '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "cannot use {s} string literal in assembly", .extra = .str, .kind = .@"error" }, + .{ .msg = "'$' in identifier", .opt = W("dollar-in-identifier-extension"), .kind = .off, .pedantic = true }, + .{ .msg = "illegal character '$' in identifier", .kind = .@"error" }, + .{ .msg = "expanded from here", .kind = .note }, + .{ .msg = "(skipping {d} expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)", .extra = .unsigned, .kind = .note }, + .{ .msg = "_Pragma requires exactly one string literal token", .kind = .@"error" }, + .{ .msg = "pragma GCC expected 'error', 'warning', 'diagnostic', 'poison'", .opt = W("unknown-pragmas"), .kind = .off, .all = true }, + .{ .msg = "pragma GCC diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'", .opt = W("unknown-pragmas"), .kind = .warning, .all = true }, + .{ .msg = "predefined identifier is only valid inside function", .opt = W("predefined-identifier-outside-function"), .kind = .warning }, + .{ .msg = "first argument to va_arg, is of type '{s}' and not 'va_list'", .extra = .str, .kind = .@"error" }, + .{ .msg = "too many braces around scalar initializer", .opt = W("many-braces-around-scalar-init"), .kind = .warning }, + .{ .msg = "variable '{s}' is uninitialized when used within its own initialization", .extra = .str, .opt = W("uninitialized"), .kind = .off, .all = true }, + .{ .msg = "use of GNU statement expression extension", .opt = W("gnu-statement-expression"), .kind = .off, .suppress_gnu = true, .pedantic = true }, + .{ .msg = "statement expression not allowed at file scope", .kind = .@"error" }, + .{ .msg = "imaginary constants are a GNU extension", .opt = W("gnu-imaginary-constant"), .kind = .off, .suppress_gnu = true, .pedantic = true }, + .{ .msg = "plain '_Complex' requires a type specifier; assuming '_Complex double'", .kind = .warning }, + .{ .msg = "complex integer types are a GNU extension", .opt = W("gnu-complex-integer"), .suppress_gnu = true, .kind = .off }, + .{ .msg = "'{s}' type qualifier on return type has no effect", .opt = W("ignored-qualifiers"), .extra = .str, .kind = .off, .all = true }, + .{ .msg = "invalid standard '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid target '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid compiler '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "unknown argument '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s}: linker input file unused because linking not done", .extra = .str, .kind = .warning }, + .{ .msg = "unrecognized linker '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "extra ';' outside of a function", .opt = W("extra-semi"), .kind = .off, .pedantic = true }, + .{ .msg = "field declared as a function", .kind = .@"error" }, + .{ .msg = "variable length array fields extension is not supported", .kind = .@"error" }, + .{ .msg = "field has incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "flexible array member in union is not allowed", .kind = .@"error", .suppress_msvc = true }, + .{ .msg = "flexible array member is not at the end of struct", .kind = .@"error" }, + .{ .msg = "flexible array member in otherwise empty struct", .kind = .@"error", .suppress_msvc = true }, + .{ .msg = "duplicate member '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "binary integer literals are a GNU extension", .kind = .off, .opt = W("gnu-binary-literal"), .pedantic = true }, + .{ .msg = "named variadic macros are a GNU extension", .opt = W("variadic-macros"), .kind = .off, .pedantic = true }, + .{ .msg = "builtin function must be directly called", .kind = .@"error" }, + .{ .msg = "'va_start' cannot be used outside a function", .kind = .@"error" }, + .{ .msg = "'va_start' used in a function with fixed args", .kind = .@"error" }, + .{ .msg = "second argument to 'va_start' is not the last named parameter", .opt = W("varargs"), .kind = .warning }, + .{ .msg = "'{s}' attribute takes at least {d} argument(s)", .kind = .@"error", .extra = .attr_arg_count }, + .{ .msg = "'{s}' attribute takes at most {d} argument(s)", .kind = .@"error", .extra = .attr_arg_count }, + .{ .msg = "Attribute argument is invalid, expected {s} but got {s}", .kind = .@"error", .extra = .attr_arg_type }, + .{ .msg = "Unknown `{s}` argument. Possible values are: {s}", .kind = .@"error", .extra = .attr_enum }, + .{ .msg = "'{s}' attribute requires an identifier", .kind = .@"error", .extra = .str }, + .{ .msg = "'__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes", .kind = .@"error" }, + .{ .msg = "__declspec attribute '{s}' is not supported", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "{s}", .extra = .str, .opt = W("deprecated-declarations"), .kind = .warning }, + .{ .msg = "'{s}' has been explicitly marked deprecated here", .extra = .str, .opt = W("deprecated-declarations"), .kind = .note }, + .{ .msg = "{s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "'{s}' has been explicitly marked unavailable here", .extra = .str, .kind = .note }, + .{ .msg = "{s}", .extra = .str, .kind = .warning, .opt = W("attribute-warning") }, + .{ .msg = "{s}", .extra = .str, .kind = .@"error" }, + .{ .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") }, + .{ .msg = "backslash and newline separated by space", .kind = .warning, .opt = W("backslash-newline-escape") }, + .{ .msg = "size of array has non-integer type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "cast to smaller integer type {s}", .extra = .str, .kind = .warning, .opt = W("pointer-to-int-cast") }, + .{ .msg = "use of GNU case range extension", .opt = W("gnu-case-range"), .kind = .off, .pedantic = true }, + .{ .msg = "empty case range specified", .kind = .warning }, + .{ .msg = "use of non-standard escape character '\\{s}'", .kind = .off, .opt = W("pedantic"), .extra = .invalid_escape }, + .{ .msg = "invalid string literal, ignoring final '\\'", .kind = .warning }, + .{ .msg = "variable length array used", .kind = .off, .opt = W("vla") }, + .{ .msg = "implicit conversion from {s}", .extra = .str, .kind = .warning, .opt = W("constant-conversion") }, + .{ .msg = "implicit conversion changes signedness: {s}", .extra = .str, .kind = .off, .opt = W("sign-conversion") }, + .{ .msg = "implicit conversion of non-finite value from {s} is undefined", .extra = .str, .kind = .off, .opt = W("float-overflow-conversion") }, + .{ .msg = "implicit conversion of out of range value from {s} is undefined", .extra = .str, .kind = .warning, .opt = W("literal-conversion") }, + .{ .msg = "implicit conversion from {s}", .extra = .str, .kind = .off, .opt = W("float-zero-conversion") }, + .{ .msg = "implicit conversion from {s}", .extra = .str, .kind = .warning, .opt = W("float-conversion") }, + .{ .msg = "implicit conversion turns floating-point number into integer: {s}", .extra = .str, .kind = .off, .opt = W("literal-conversion") }, + .{ .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 }, + .{ .msg = "variable length array folded to constant array as an extension", .kind = .off, .opt = W("gnu-folding-constant"), .pedantic = true }, + .{ .msg = "typedef redefinition with different types ({s})", .extra = .str, .kind = .@"error" }, + .{ .msg = "'{s}' is not defined, evaluates to 0", .extra = .str, .kind = .off, .opt = W("undef") }, + .{ .msg = "function-like macro '{s}' is not defined", .extra = .str, .kind = .@"error" }, + .{ .msg = "'{s}' must be used within a preprocessing directive", .extra = .tok_id_expected, .kind = .@"error" }, + .{ .msg = "Missing '(' after built-in macro '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "offsetof requires struct or union type, '{s}' invalid", .extra = .str, .kind = .@"error" }, + .{ .msg = "offsetof of incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "offsetof requires array type, '{s}' invalid", .extra = .str, .kind = .@"error" }, + .{ .msg = "missing '(' after '#pragma pack' - ignoring", .kind = .warning, .opt = W("ignored-pragmas") }, + .{ .msg = "missing ')' after '#pragma pack' - ignoring", .kind = .warning, .opt = W("ignored-pragmas") }, + .{ .msg = "unknown action for '#pragma pack' - ignoring", .opt = W("ignored-pragmas"), .kind = .warning }, + .{ .msg = "value of #pragma pack(show) == {d}", .extra = .unsigned, .kind = .warning }, + .{ .msg = "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'", .opt = W("ignored-pragmas"), .kind = .warning }, + .{ .msg = "expected integer or identifier in '#pragma pack' - ignored", .opt = W("ignored-pragmas"), .kind = .warning }, + .{ .msg = "specifying both a name and alignment to 'pop' is undefined", .kind = .warning }, + .{ .msg = "#pragma pack(pop, ...) failed: stack empty", .opt = W("ignored-pragmas"), .kind = .warning }, + .{ .msg = "used type '{s}' where arithmetic or pointer type is required", .extra = .str, .kind = .@"error" }, + .{ .msg = "#include nested too deeply", .kind = .@"error" }, + .{ .msg = "ISO C restricts enumerator values to range of 'int' ({s} is too small)", .extra = .str, .kind = .off, .opt = W("pedantic") }, + .{ .msg = "ISO C restricts enumerator values to range of 'int' ({s} is too large)", .extra = .str, .kind = .off, .opt = W("pedantic") }, + .{ .msg = "#include_next is a language extension", .kind = .off, .pedantic = true, .opt = W("gnu-include-next") }, + .{ .msg = "#include_next in primary source file; will search from start of include path", .kind = .warning, .opt = W("include-next-outside-header") }, + .{ .msg = "overflow in enumeration value", .kind = .warning }, + .{ .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 }, + .{ .msg = "enumeration values exceed range of largest integer", .kind = .warning, .opt = W("enum-too-large") }, + .{ .msg = "enumeration types with a fixed underlying type are a Clang extension", .kind = .off, .pedantic = true, .opt = W("fixed-enum-extension") }, + .{ .msg = "enumeration previously declared with nonfixed underlying type", .kind = .@"error" }, + .{ .msg = "enumeration previously declared with fixed underlying type", .kind = .@"error" }, + .{ .msg = "enumeration redeclared with different underlying type {s})", .extra = .str, .kind = .@"error" }, + .{ .msg = "enumerator value is not representable in the underlying type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "'transparent_union' attribute only applies to unions", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "transparent union definition must contain at least one field; transparent_union attribute ignored", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .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 }, + .{ .msg = "size of first field is {d}", .extra = .unsigned, .kind = .note }, + .{ .msg = "'designated_init' attribute is only valid on 'struct' type'", .kind = .@"error" }, + .{ .msg = "positional initialization of field in 'struct' declared with 'designated_init' attribute", .opt = W("designated-init"), .kind = .warning }, + .{ .msg = "ignoring attribute 'common' because it conflicts with attribute 'nocommon'", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "ignoring attribute 'nocommon' because it conflicts with attribute 'common'", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "'nonstring' attribute ignored on objects of type '{s}'", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "'{s}' attribute only applies to local variables", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "ignoring attribute 'cold' because it conflicts with attribute 'hot'", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "ignoring attribute 'hot' because it conflicts with attribute 'cold'", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "ignoring attribute 'noinline' because it conflicts with attribute 'always_inline'", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "ignoring attribute 'always_inline' because it conflicts with attribute 'noinline'", .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "function '{s}' declared 'noreturn' should not return", .extra = .str, .kind = .warning, .opt = W("invalid-noreturn") }, + .{ .msg = "ignoring return value of '{s}', declared with 'nodiscard' attribute", .extra = .str, .kind = .warning, .opt = W("unused-result") }, + .{ .msg = "ignoring return value of '{s}', declared with 'warn_unused_result' attribute", .extra = .str, .kind = .warning, .opt = W("unused-result") }, + .{ .msg = "invalid vector element type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "vector size not an integral multiple of component size", .kind = .@"error" }, + .{ .msg = "invalid type '{s}' to __imag operator", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid type '{s}' to __real operator", .extra = .str, .kind = .@"error" }, + .{ .msg = "zero size arrays are an extension", .kind = .off, .pedantic = true, .opt = W("zero-length-array") }, + .{ .msg = "array index {s} is past the end of the array", .extra = .str, .kind = .off, .pedantic = true, .opt = W("old-style-flexible-struct") }, + .{ .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 }, + .{ .msg = "return type of 'main' is not 'int'", .kind = .warning, .opt = W("main-return-type") }, + .{ .msg = "macro expansion producing 'defined' has undefined behavior", .kind = .off, .pedantic = true, .opt = W("expansion-to-defined") }, + .{ .msg = "invalid suffix '{s}' on integer constant", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid suffix '{s}' on floating constant", .extra = .str, .kind = .@"error" }, + .{ .msg = "invalid digit '{c}' in octal constant", .extra = .ascii, .kind = .@"error" }, + .{ .msg = "invalid digit '{c}' in binary constant", .extra = .ascii, .kind = .@"error" }, + .{ .msg = "exponent has no digits", .kind = .@"error" }, + .{ .msg = "hexadecimal floating constant requires an exponent", .kind = .@"error" }, + .{ .msg = "sizeof returns 0", .kind = .warning, .suppress_gcc = true, .suppress_clang = true }, + .{ .msg = "'declspec' attribute not allowed after declarator", .kind = .@"error" }, + .{ .msg = "this declarator", .kind = .note }, + .{ .msg = "{s} is not supported on this target", .extra = .str, .kind = .@"error" }, + .{ .msg = "'_BitInt' in C17 and earlier is a Clang extension'", .kind = .off, .pedantic = true, .opt = W("bit-int-extension"), .suppress_version = .c23 }, + .{ .msg = "{s}unsigned _BitInt must have a bit size of at least 1", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s}signed _BitInt must have a bit size of at least 2", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s}unsigned _BitInt of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Properties.max_bits}) ++ " not supported", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s}signed _BitInt of bit sizes greater than " ++ std.fmt.comptimePrint("{d}", .{Properties.max_bits}) ++ " not supported", .extra = .str, .kind = .@"error" }, + .{ .msg = "keyword is hidden by macro definition", .kind = .off, .pedantic = true, .opt = W("keyword-macro") }, + .{ .msg = "arithmetic on a pointer to an incomplete type '{s}'", .extra = .str, .kind = .@"error" }, + .{ .msg = "'{s}' calling convention is not supported for this target", .extra = .str, .opt = W("ignored-attributes"), .kind = .warning }, + .{ .msg = "invalid application of '{s}' to a void type", .extra = .str, .kind = .off, .pedantic = true, .opt = W("pointer-arith") }, + .{ .msg = "sizeof on array function parameter will return size of {s}", .extra = .str, .kind = .warning, .opt = W("sizeof-array-argument") }, + .{ .msg = "address of array '{s}' will always evaluate to 'true'", .extra = .str, .kind = .warning, .opt = W("pointer-bool-conversion") }, + .{ .msg = "implicit conversion turns string literal into bool: {s}", .extra = .str, .kind = .off, .opt = W("string-conversion") }, + .{ .msg = "this conversion is not allowed in a constant expression", .kind = .note }, + .{ .msg = "cannot cast an object of type {s}", .extra = .str, .kind = .@"error" }, + .{ .msg = "unsupported argument '{s}' to option '-ffp-eval-method='; expected 'source', 'double', or 'extended'", .extra = .str, .kind = .@"error" }, + .{ .msg = "{s} cannot have __fp16 type; did you forget * ?", .extra = .str, .kind = .@"error" }, + .{ .msg = "'_BitInt' suffix for literals is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 }, + .{ .msg = "'__auto_type' is a GNU extension", .opt = W("gnu-auto-type"), .kind = .off, .pedantic = true }, + .{ .msg = "'__auto_type' not allowed in {s}", .kind = .@"error", .extra = .str }, + .{ .msg = "declaration of variable '{s}' with deduced type requires an initializer", .kind = .@"error", .extra = .str }, + .{ .msg = "'__auto_type' may only be used with a single declarator", .kind = .@"error" }, + .{ .msg = "'__auto_type' requires a plain identifier as declarator", .kind = .@"error" }, + .{ .msg = "invalid cast to '__auto_type'", .kind = .@"error" }, + .{ .msg = "cannot use bit-field as '__auto_type' initializer", .kind = .@"error" }, + .{ .msg = "'{s}' declared as array of '__auto_type'", .kind = .@"error", .extra = .str }, + .{ .msg = "cannot use '__auto_type' with initializer list", .kind = .@"error" }, + .{ .msg = "expected ';' at end of declaration list", .kind = .warning }, + .{ .msg = "tentative definition has type '{s}' that is never completed", .kind = .@"error", .extra = .str }, + .{ .msg = "forward declaration of '{s}'", .kind = .note, .extra = .str }, + .{ .msg = "cast to union type is a GNU extension", .opt = W("gnu-union-cast"), .kind = .off, .pedantic = true }, + .{ .msg = "cast to union type from type '{s}' not present in union", .kind = .@"error", .extra = .str }, + .{ .msg = "cast to incomplete type '{s}'", .kind = .@"error", .extra = .str }, + .{ .msg = "environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799", .kind = .@"error" }, + .{ .msg = "'-fuse-ld=' taking a path is deprecated; use '--ld-path=' instead", .kind = .off, .opt = W("fuse-ld-path") }, + .{ .msg = "invalid runtime library name '{s}'", .kind = .@"error", .extra = .str }, + .{ .msg = "unsupported runtime library 'libgcc' for platform '{s}'", .kind = .@"error", .extra = .str }, + .{ .msg = "invalid unwind library name '{s}'", .kind = .@"error", .extra = .str }, + .{ .msg = "--rtlib=libgcc requires --unwindlib=libgcc", .kind = .@"error" }, + .{ .msg = "GNU-style inline assembly is disabled", .kind = .@"error" }, + .{ .msg = "extension used", .kind = .off, .pedantic = true, .opt = W("language-extension-token") }, + .{ .msg = "complex initialization specifying real and imaginary components is an extension", .opt = W("complex-component-init"), .kind = .off, .pedantic = true }, + .{ .msg = "ISO C does not support '++'/'--' on complex type '{s}'", .opt = W("pedantic"), .extra = .str, .kind = .off }, + .{ .msg = "argument type '{s}' is not a real floating point type", .extra = .str, .kind = .@"error" }, + .{ .msg = "arguments are of different types ({s})", .extra = .str, .kind = .@"error" }, + .{ .msg = "#include resolved using non-portable Microsoft search rules as: {s}", .extra = .str, .opt = W("microsoft-include"), .kind = .warning }, + .{ .msg = "treating Ctrl-Z as end-of-file is a Microsoft extension", .opt = W("microsoft-end-of-file"), .kind = .off, .pedantic = true }, + .{ .msg = "illegal character encoding in character literal", .opt = W("invalid-source-encoding"), .kind = .warning }, + .{ .msg = "illegal character encoding in character literal", .kind = .@"error" }, + .{ .msg = "character '{c}' cannot be specified by a universal character name", .kind = .@"error", .extra = .ascii }, + .{ .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") }, + .{ .msg = "universal character name refers to a control character", .kind = .@"error" }, + .{ .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") }, + .{ .msg = "universal character names are only valid in C99 or later", .suppress_version = .c99, .kind = .warning, .opt = W("unicode") }, + .{ .msg = "multi-character character constant", .opt = W("four-char-constants"), .kind = .off }, + .{ .msg = "multi-character character constant", .kind = .off }, + .{ .msg = "\\{c} used with no following hex digits", .kind = .@"error", .extra = .ascii }, + .{ .msg = "unknown escape sequence '\\{s}'", .kind = .warning, .opt = W("unknown-escape-sequence"), .extra = .invalid_escape }, + .{ .msg = "attribute '{s}' requires an ordinary string", .kind = .@"error", .extra = .str }, + .{ .msg = "missing terminating '\"' character", .kind = .warning, .opt = W("invalid-pp-token") }, + .{ .msg = "missing terminating '\"' character", .kind = .@"error" }, + .{ .msg = "empty character constant", .kind = .warning, .opt = W("invalid-pp-token") }, + .{ .msg = "empty character constant", .kind = .@"error" }, + .{ .msg = "missing terminating ' character", .kind = .warning, .opt = W("invalid-pp-token") }, + .{ .msg = "missing terminating ' character", .kind = .@"error" }, + .{ .msg = "unterminated comment", .kind = .@"error" }, + .{ .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") }, + .{ .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") }, + .{ .msg = "unknown type name '{s}'", .kind = .@"error", .extra = .str }, + .{ .msg = "label at end of compound statement is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 }, + .{ .msg = "UTF-8 character literal is a C23 extension", .opt = W("c23-extensions"), .kind = .warning, .suppress_version = .c23 }, + .{ .msg = "unexpected token in embed parameter", .kind = .@"error" }, + .{ .msg = "the limit parameter expects one non-negative integer as a parameter", .kind = .@"error" }, + .{ .msg = "duplicate embed parameter '{s}'", .kind = .warning, .extra = .str, .opt = W("duplicate-embed-param") }, + .{ .msg = "unsupported embed parameter '{s}' embed parameter", .kind = .warning, .extra = .str, .opt = W("unsupported-embed-param") }, + .{ .msg = "compound literal cannot have {s} storage class", .kind = .@"error", .extra = .str }, + .{ .msg = "missing '(' following __VA_OPT__", .kind = .@"error" }, + .{ .msg = "unterminated __VA_OPT__ argument list", .kind = .@"error" }, + .{ .msg = "attribute value '{s}' out of range", .kind = .@"error", .extra = .str }, + .{ .msg = "'{s}' is not in NFC", .kind = .warning, .extra = .normalized, .opt = W("normalized") }, + .{ .msg = "'auto' requires a plain identifier declarator", .kind = .@"error" }, + .{ .msg = "'auto' can only be used with a single declarator", .kind = .@"error" }, + .{ .msg = "'auto' requires an initializer", .kind = .@"error" }, + .{ .msg = "'auto' requires a scalar initializer", .kind = .@"error" }, + .{ .msg = "shift count is negative", .opt = W("shift-count-negative"), .kind = .warning, .all = true }, + .{ .msg = "shift count >= width of type", .opt = W("shift-count-overflow"), .kind = .warning, .all = true }, + .{ .msg = "ISO C does not support '~' for complex conjugation of '{s}'", .opt = W("pedantic"), .extra = .str, .kind = .off }, + .{ .msg = "operand argument to overflow builtin must be an integer ('{s}' invalid)", .extra = .str, .kind = .@"error" }, + .{ .msg = "result argument to overflow builtin must be a pointer to a non-const integer ('{s}' invalid)", .extra = .str, .kind = .@"error" }, + .{ .msg = "TODO: implement '{s}' attribute for {s}", .extra = .attribute_todo, .kind = .@"error" }, + .{ .msg = "non-integral type '{s}' is an invalid underlying type", .extra = .str, .kind = .@"error" }, + .{ .msg = "variable '{s}' declared with deduced type '__auto_type' cannot appear in its own initializer", .extra = .str, .kind = .@"error" }, + }; +}; +}; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver.zig new file mode 100644 index 00000000..c89dafe0 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver.zig @@ -0,0 +1,863 @@ +const std = @import("std"); +const mem = std.mem; +const Allocator = mem.Allocator; +const process = std.process; +const backend = @import("../backend.zig"); +const Ir = backend.Ir; +const Object = backend.Object; +const Compilation = @import("Compilation.zig"); +const Diagnostics = @import("Diagnostics.zig"); +const LangOpts = @import("LangOpts.zig"); +const Preprocessor = @import("Preprocessor.zig"); +const Source = @import("Source.zig"); +const Toolchain = @import("Toolchain.zig"); +const target_util = @import("target.zig"); +const GCCVersion = @import("Driver/GCCVersion.zig"); + +pub const Linker = enum { + ld, + bfd, + gold, + lld, + mold, +}; + +const Driver = @This(); + +comp: *Compilation, +inputs: std.ArrayListUnmanaged(Source) = .empty, +link_objects: std.ArrayListUnmanaged([]const u8) = .empty, +output_name: ?[]const u8 = null, +sysroot: ?[]const u8 = null, +system_defines: Compilation.SystemDefinesMode = .include_system_defines, +temp_file_count: u32 = 0, +/// If false, do not emit line directives in -E mode +line_commands: bool = true, +/// If true, use `#line ` instead of `# ` for line directives +use_line_directives: bool = false, +only_preprocess: bool = false, +only_syntax: bool = false, +only_compile: bool = false, +only_preprocess_and_compile: bool = false, +verbose_ast: bool = false, +verbose_pp: bool = false, +verbose_ir: bool = false, +verbose_linker_args: bool = false, +color: ?bool = null, +nobuiltininc: bool = false, +nostdinc: bool = false, +nostdlibinc: bool = false, +debug_dump_letters: packed struct(u3) { + d: bool = false, + m: bool = false, + n: bool = false, + + /// According to GCC, specifying letters whose behavior conflicts is undefined. + /// We follow clang in that `-dM` always takes precedence over `-dD` + pub fn getPreprocessorDumpMode(self: @This()) Preprocessor.DumpMode { + if (self.m) return .macros_only; + if (self.d) return .macros_and_result; + if (self.n) return .macro_names_and_result; + return .result_only; + } +} = .{}, + +/// Full path to the aro executable +aro_name: []const u8 = "", + +/// Value of --triple= passed via CLI +raw_target_triple: ?[]const u8 = null, + +// linker options +use_linker: ?[]const u8 = null, +linker_path: ?[]const u8 = null, +nodefaultlibs: bool = false, +nolibc: bool = false, +nostartfiles: bool = false, +nostdlib: bool = false, +pie: ?bool = null, +rdynamic: bool = false, +relocatable: bool = false, +rtlib: ?[]const u8 = null, +shared: bool = false, +shared_libgcc: bool = false, +static: bool = false, +static_libgcc: bool = false, +static_pie: bool = false, +strip: bool = false, +unwindlib: ?[]const u8 = null, + +pub fn deinit(d: *Driver) void { + for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| { + std.fs.deleteFileAbsolute(obj) catch {}; + d.comp.gpa.free(obj); + } + d.inputs.deinit(d.comp.gpa); + d.link_objects.deinit(d.comp.gpa); + d.* = undefined; +} + +pub const usage = + \\Usage {s}: [options] file.. + \\ + \\General options: + \\ -h, --help Print this message. + \\ -v, --version Print aro version. + \\ + \\Compile options: + \\ -c, --compile Only run preprocess, compile, and assemble steps + \\ -dM Output #define directives for all the macros defined during the execution of the preprocessor + \\ -dD Like -dM except that it outputs both the #define directives and the result of preprocessing + \\ -dN Like -dD, but emit only the macro names, not their expansions. + \\ -D = Define to (defaults to 1) + \\ -E Only run the preprocessor + \\ -fchar8_t Enable char8_t (enabled by default in C23 and later) + \\ -fno-char8_t Disable char8_t (disabled by default for pre-C23) + \\ -fcolor-diagnostics Enable colors in diagnostics + \\ -fno-color-diagnostics Disable colors in diagnostics + \\ -fdeclspec Enable support for __declspec attributes + \\ -fgnuc-version= Controls value of __GNUC__ and related macros. Set to 0 or empty to disable them. + \\ -fno-declspec Disable support for __declspec attributes + \\ -ffp-eval-method=[source|double|extended] + \\ Evaluation method to use for floating-point arithmetic + \\ -ffreestanding Compilation in a freestanding environment + \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled) + \\ -fno-gnu-inline-asm Disable GNU style inline asm + \\ -fhosted Compilation in a hosted environment + \\ -fms-extensions Enable support for Microsoft extensions + \\ -fno-ms-extensions Disable support for Microsoft extensions + \\ -fdollars-in-identifiers + \\ Allow '$' in identifiers + \\ -fno-dollars-in-identifiers + \\ Disallow '$' in identifiers + \\ -fmacro-backtrace-limit= + \\ Set limit on how many macro expansion traces are shown in errors (default 6) + \\ -fnative-half-type Use the native half type for __fp16 instead of promoting to float + \\ -fnative-half-arguments-and-returns + \\ Allow half-precision function arguments and return values + \\ -fshort-enums Use the narrowest possible integer type for enums + \\ -fno-short-enums Use "int" as the tag type for enums + \\ -fsigned-char "char" is signed + \\ -fno-signed-char "char" is unsigned + \\ -fsyntax-only Only run the preprocessor, parser, and semantic analysis stages + \\ -funsigned-char "char" is unsigned + \\ -fno-unsigned-char "char" is signed + \\ -fuse-line-directives Use `#line ` linemarkers in preprocessed output + \\ -fno-use-line-directives + \\ Use `# ` linemarkers in preprocessed output + \\ -I Add directory to include search path + \\ -isystem Add directory to SYSTEM include search path + \\ --emulate=[clang|gcc|msvc] + \\ Select which C compiler to emulate (default clang) + \\ -nobuiltininc Do not search the compiler's builtin directory for include files + \\ -nostdinc, --no-standard-includes + \\ Do not search the standard system directories or compiler builtin directories for include files. + \\ -nostdlibinc Do not search the standard system directories for include files, but do search compiler builtin include directories + \\ -o Write output to + \\ -P, --no-line-commands Disable linemarker output in -E mode + \\ -pedantic Warn on language extensions + \\ --rtlib= Compiler runtime library to use (libgcc or compiler-rt) + \\ -std= Specify language standard + \\ -S, --assemble Only run preprocess and compilation steps + \\ --sysroot= Use dir as the logical root directory for headers and libraries (not fully implemented) + \\ --target= Generate code for the given target + \\ -U Undefine + \\ -undef Do not predefine any system-specific macros. Standard predefined macros remain defined. + \\ -Werror Treat all warnings as errors + \\ -Werror= Treat warning as error + \\ -W Enable the specified warning + \\ -Wno- Disable the specified warning + \\ + \\Link options: + \\ -fuse-ld=[bfd|gold|lld|mold] + \\ Use specific linker + \\ -nodefaultlibs Do not use the standard system libraries when linking. + \\ -nolibc Do not use the C library or system libraries tightly coupled with it when linking. + \\ -nostdlib Do not use the standard system startup files or libraries when linking + \\ -nostartfiles Do not use the standard system startup files when linking. + \\ -pie Produce a dynamically linked position independent executable on targets that support it. + \\ --ld-path= Use linker specified by + \\ -r Produce a relocatable object as output. + \\ -rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it. + \\ -s Remove all symbol table and relocation information from the executable. + \\ -shared Produce a shared object which can then be linked with other objects to form an executable. + \\ -shared-libgcc On systems that provide libgcc as a shared library, force the use of the shared version + \\ -static On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries. + \\ -static-libgcc On systems that provide libgcc as a shared library, force the use of the static version + \\ -static-pie Produce a static position independent executable on targets that support it. + \\ --unwindlib= Unwind library to use ("none", "libgcc", or "libunwind") If not specified, will match runtime library + \\ + \\Debug options: + \\ --verbose-ast Dump produced AST to stdout + \\ --verbose-pp Dump preprocessor state + \\ --verbose-ir Dump ir to stdout + \\ --verbose-linker-args Dump linker args to stdout + \\ + \\ +; + +/// Process command line arguments, returns true if something was written to std_out. +pub fn parseArgs( + d: *Driver, + std_out: anytype, + macro_buf: anytype, + args: []const []const u8, +) !bool { + var i: usize = 1; + var comment_arg: []const u8 = ""; + var hosted: ?bool = null; + var gnuc_version: []const u8 = "4.2.1"; // default value set by clang + while (i < args.len) : (i += 1) { + const arg = args[i]; + if (mem.startsWith(u8, arg, "-") and arg.len > 1) { + if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { + std_out.print(usage, .{args[0]}) catch |er| { + return d.fatal("unable to print usage: {s}", .{errorDescription(er)}); + }; + return true; + } else if (mem.eql(u8, arg, "-v") or mem.eql(u8, arg, "--version")) { + std_out.writeAll(@import("../backend.zig").version_str ++ "\n") catch |er| { + return d.fatal("unable to print version: {s}", .{errorDescription(er)}); + }; + return true; + } else if (mem.startsWith(u8, arg, "-D")) { + var macro = arg["-D".len..]; + if (macro.len == 0) { + i += 1; + if (i >= args.len) { + try d.err("expected argument after -I"); + continue; + } + macro = args[i]; + } + var value: []const u8 = "1"; + if (mem.indexOfScalar(u8, macro, '=')) |some| { + value = macro[some + 1 ..]; + macro = macro[0..some]; + } + try macro_buf.print("#define {s} {s}\n", .{ macro, value }); + } else if (mem.startsWith(u8, arg, "-U")) { + var macro = arg["-U".len..]; + if (macro.len == 0) { + i += 1; + if (i >= args.len) { + try d.err("expected argument after -I"); + continue; + } + macro = args[i]; + } + try macro_buf.print("#undef {s}\n", .{macro}); + } else if (mem.eql(u8, arg, "-undef")) { + d.system_defines = .no_system_defines; + } else if (mem.eql(u8, arg, "-c") or mem.eql(u8, arg, "--compile")) { + d.only_compile = true; + } else if (mem.eql(u8, arg, "-dD")) { + d.debug_dump_letters.d = true; + } else if (mem.eql(u8, arg, "-dM")) { + d.debug_dump_letters.m = true; + } else if (mem.eql(u8, arg, "-dN")) { + d.debug_dump_letters.n = true; + } else if (mem.eql(u8, arg, "-E")) { + d.only_preprocess = true; + } else if (mem.eql(u8, arg, "-P") or mem.eql(u8, arg, "--no-line-commands")) { + d.line_commands = false; + } else if (mem.eql(u8, arg, "-fuse-line-directives")) { + d.use_line_directives = true; + } else if (mem.eql(u8, arg, "-fno-use-line-directives")) { + d.use_line_directives = false; + } else if (mem.eql(u8, arg, "-fchar8_t")) { + d.comp.langopts.has_char8_t_override = true; + } else if (mem.eql(u8, arg, "-fno-char8_t")) { + d.comp.langopts.has_char8_t_override = false; + } else if (mem.eql(u8, arg, "-fcolor-diagnostics")) { + d.color = true; + } else if (mem.eql(u8, arg, "-fno-color-diagnostics")) { + d.color = false; + } else if (mem.eql(u8, arg, "-fdollars-in-identifiers")) { + d.comp.langopts.dollars_in_identifiers = true; + } else if (mem.eql(u8, arg, "-fno-dollars-in-identifiers")) { + d.comp.langopts.dollars_in_identifiers = false; + } else if (mem.eql(u8, arg, "-fdigraphs")) { + d.comp.langopts.digraphs = true; + } else if (mem.eql(u8, arg, "-fgnu-inline-asm")) { + d.comp.langopts.gnu_asm = true; + } else if (mem.eql(u8, arg, "-fno-gnu-inline-asm")) { + d.comp.langopts.gnu_asm = false; + } else if (mem.eql(u8, arg, "-fno-digraphs")) { + d.comp.langopts.digraphs = false; + } else if (option(arg, "-fmacro-backtrace-limit=")) |limit_str| { + var limit = std.fmt.parseInt(u32, limit_str, 10) catch { + try d.err("-fmacro-backtrace-limit takes a number argument"); + continue; + }; + + if (limit == 0) limit = std.math.maxInt(u32); + d.comp.diagnostics.macro_backtrace_limit = limit; + } else if (mem.eql(u8, arg, "-fnative-half-type")) { + d.comp.langopts.use_native_half_type = true; + } else if (mem.eql(u8, arg, "-fnative-half-arguments-and-returns")) { + d.comp.langopts.allow_half_args_and_returns = true; + } else if (mem.eql(u8, arg, "-fshort-enums")) { + d.comp.langopts.short_enums = true; + } else if (mem.eql(u8, arg, "-fno-short-enums")) { + d.comp.langopts.short_enums = false; + } else if (mem.eql(u8, arg, "-fsigned-char")) { + d.comp.langopts.setCharSignedness(.signed); + } else if (mem.eql(u8, arg, "-fno-signed-char")) { + d.comp.langopts.setCharSignedness(.unsigned); + } else if (mem.eql(u8, arg, "-funsigned-char")) { + d.comp.langopts.setCharSignedness(.unsigned); + } else if (mem.eql(u8, arg, "-fno-unsigned-char")) { + d.comp.langopts.setCharSignedness(.signed); + } else if (mem.eql(u8, arg, "-fdeclspec")) { + d.comp.langopts.declspec_attrs = true; + } else if (mem.eql(u8, arg, "-fno-declspec")) { + d.comp.langopts.declspec_attrs = false; + } else if (mem.eql(u8, arg, "-ffreestanding")) { + hosted = false; + } else if (mem.eql(u8, arg, "-fhosted")) { + hosted = true; + } else if (mem.eql(u8, arg, "-fms-extensions")) { + d.comp.langopts.enableMSExtensions(); + } else if (mem.eql(u8, arg, "-fno-ms-extensions")) { + d.comp.langopts.disableMSExtensions(); + } else if (mem.startsWith(u8, arg, "-I")) { + var path = arg["-I".len..]; + if (path.len == 0) { + i += 1; + if (i >= args.len) { + try d.err("expected argument after -I"); + continue; + } + path = args[i]; + } + try d.comp.include_dirs.append(d.comp.gpa, path); + } else if (mem.startsWith(u8, arg, "-fsyntax-only")) { + d.only_syntax = true; + } else if (mem.startsWith(u8, arg, "-fno-syntax-only")) { + d.only_syntax = false; + } else if (mem.eql(u8, arg, "-fgnuc-version=")) { + gnuc_version = "0"; + } else if (option(arg, "-fgnuc-version=")) |version| { + gnuc_version = version; + } else if (mem.startsWith(u8, arg, "-isystem")) { + var path = arg["-isystem".len..]; + if (path.len == 0) { + i += 1; + if (i >= args.len) { + try d.err("expected argument after -isystem"); + continue; + } + path = args[i]; + } + const duped = try d.comp.gpa.dupe(u8, path); + errdefer d.comp.gpa.free(duped); + try d.comp.system_include_dirs.append(d.comp.gpa, duped); + } else if (option(arg, "--emulate=")) |compiler_str| { + const compiler = std.meta.stringToEnum(LangOpts.Compiler, compiler_str) orelse { + try d.comp.addDiagnostic(.{ .tag = .cli_invalid_emulate, .extra = .{ .str = arg } }, &.{}); + continue; + }; + d.comp.langopts.setEmulatedCompiler(compiler); + } else if (option(arg, "-ffp-eval-method=")) |fp_method_str| { + const fp_eval_method = std.meta.stringToEnum(LangOpts.FPEvalMethod, fp_method_str) orelse .indeterminate; + if (fp_eval_method == .indeterminate) { + try d.comp.addDiagnostic(.{ .tag = .cli_invalid_fp_eval_method, .extra = .{ .str = fp_method_str } }, &.{}); + continue; + } + d.comp.langopts.setFpEvalMethod(fp_eval_method); + } else if (mem.startsWith(u8, arg, "-o")) { + var file = arg["-o".len..]; + if (file.len == 0) { + i += 1; + if (i >= args.len) { + try d.err("expected argument after -o"); + continue; + } + file = args[i]; + } + d.output_name = file; + } else if (option(arg, "--sysroot=")) |sysroot| { + d.sysroot = sysroot; + } else if (mem.eql(u8, arg, "-pedantic")) { + d.comp.diagnostics.options.pedantic = .warning; + } else if (option(arg, "--rtlib=")) |rtlib| { + if (mem.eql(u8, rtlib, "compiler-rt") or mem.eql(u8, rtlib, "libgcc") or mem.eql(u8, rtlib, "platform")) { + d.rtlib = rtlib; + } else { + try d.comp.addDiagnostic(.{ .tag = .invalid_rtlib, .extra = .{ .str = rtlib } }, &.{}); + } + } else if (option(arg, "-Werror=")) |err_name| { + try d.comp.diagnostics.set(err_name, .@"error"); + } else if (mem.eql(u8, arg, "-Wno-fatal-errors")) { + d.comp.diagnostics.fatal_errors = false; + } else if (option(arg, "-Wno-")) |err_name| { + try d.comp.diagnostics.set(err_name, .off); + } else if (mem.eql(u8, arg, "-Wfatal-errors")) { + d.comp.diagnostics.fatal_errors = true; + } else if (option(arg, "-W")) |err_name| { + try d.comp.diagnostics.set(err_name, .warning); + } else if (option(arg, "-std=")) |standard| { + d.comp.langopts.setStandard(standard) catch + try d.comp.addDiagnostic(.{ .tag = .cli_invalid_standard, .extra = .{ .str = arg } }, &.{}); + } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) { + d.only_preprocess_and_compile = true; + } else if (option(arg, "--target=")) |triple| { + const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch { + try d.comp.addDiagnostic(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{}); + continue; + }; + const target = std.zig.system.resolveTargetQuery(query) catch |e| { + return d.fatal("unable to resolve target: {s}", .{errorDescription(e)}); + }; + d.comp.target = target; + d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(target)); + d.raw_target_triple = triple; + } else if (mem.eql(u8, arg, "--verbose-ast")) { + d.verbose_ast = true; + } else if (mem.eql(u8, arg, "--verbose-pp")) { + d.verbose_pp = true; + } else if (mem.eql(u8, arg, "--verbose-ir")) { + d.verbose_ir = true; + } else if (mem.eql(u8, arg, "--verbose-linker-args")) { + d.verbose_linker_args = true; + } else if (mem.eql(u8, arg, "-C") or mem.eql(u8, arg, "--comments")) { + d.comp.langopts.preserve_comments = true; + comment_arg = arg; + } else if (mem.eql(u8, arg, "-CC") or mem.eql(u8, arg, "--comments-in-macros")) { + d.comp.langopts.preserve_comments = true; + d.comp.langopts.preserve_comments_in_macros = true; + comment_arg = arg; + } else if (option(arg, "-fuse-ld=")) |linker_name| { + d.use_linker = linker_name; + } else if (mem.eql(u8, arg, "-fuse-ld=")) { + d.use_linker = null; + } else if (option(arg, "--ld-path=")) |linker_path| { + d.linker_path = linker_path; + } else if (mem.eql(u8, arg, "-r")) { + d.relocatable = true; + } else if (mem.eql(u8, arg, "-shared")) { + d.shared = true; + } else if (mem.eql(u8, arg, "-shared-libgcc")) { + d.shared_libgcc = true; + } else if (mem.eql(u8, arg, "-static")) { + d.static = true; + } else if (mem.eql(u8, arg, "-static-libgcc")) { + d.static_libgcc = true; + } else if (mem.eql(u8, arg, "-static-pie")) { + d.static_pie = true; + } else if (mem.eql(u8, arg, "-pie")) { + d.pie = true; + } else if (mem.eql(u8, arg, "-no-pie") or mem.eql(u8, arg, "-nopie")) { + d.pie = false; + } else if (mem.eql(u8, arg, "-rdynamic")) { + d.rdynamic = true; + } else if (mem.eql(u8, arg, "-s")) { + d.strip = true; + } else if (mem.eql(u8, arg, "-nodefaultlibs")) { + d.nodefaultlibs = true; + } else if (mem.eql(u8, arg, "-nolibc")) { + d.nolibc = true; + } else if (mem.eql(u8, arg, "-nobuiltininc")) { + d.nobuiltininc = true; + } else if (mem.eql(u8, arg, "-nostdinc") or mem.eql(u8, arg, "--no-standard-includes")) { + d.nostdinc = true; + } else if (mem.eql(u8, arg, "-nostdlibinc")) { + d.nostdlibinc = true; + } else if (mem.eql(u8, arg, "-nostdlib")) { + d.nostdlib = true; + } else if (mem.eql(u8, arg, "-nostartfiles")) { + d.nostartfiles = true; + } else if (option(arg, "--unwindlib=")) |unwindlib| { + const valid_unwindlibs: [5][]const u8 = .{ "", "none", "platform", "libunwind", "libgcc" }; + for (valid_unwindlibs) |name| { + if (mem.eql(u8, name, unwindlib)) { + d.unwindlib = unwindlib; + break; + } + } else { + try d.comp.addDiagnostic(.{ .tag = .invalid_unwindlib, .extra = .{ .str = unwindlib } }, &.{}); + } + } else { + try d.comp.addDiagnostic(.{ .tag = .cli_unknown_arg, .extra = .{ .str = arg } }, &.{}); + } + } else if (std.mem.endsWith(u8, arg, ".o") or std.mem.endsWith(u8, arg, ".obj")) { + try d.link_objects.append(d.comp.gpa, arg); + } else { + const source = d.addSource(arg) catch |er| { + return d.fatal("unable to add source file '{s}': {s}", .{ arg, errorDescription(er) }); + }; + try d.inputs.append(d.comp.gpa, source); + } + } + if (d.comp.langopts.preserve_comments and !d.only_preprocess) { + return d.fatal("invalid argument '{s}' only allowed with '-E'", .{comment_arg}); + } + if (hosted) |is_hosted| { + if (is_hosted) { + if (d.comp.target.os.tag == .freestanding) { + return d.fatal("Cannot use freestanding target with `-fhosted`", .{}); + } + } else { + d.comp.target.os.tag = .freestanding; + } + } + const version = GCCVersion.parse(gnuc_version); + if (version.major == -1) { + return d.fatal("invalid value '{0s}' in '-fgnuc-version={0s}'", .{gnuc_version}); + } + d.comp.langopts.gnuc_version = version.toUnsigned(); + return false; +} + +fn option(arg: []const u8, name: []const u8) ?[]const u8 { + if (std.mem.startsWith(u8, arg, name) and arg.len > name.len) { + return arg[name.len..]; + } + return null; +} + +fn addSource(d: *Driver, path: []const u8) !Source { + if (mem.eql(u8, "-", path)) { + const stdin = std.io.getStdIn().reader(); + const input = try stdin.readAllAlloc(d.comp.gpa, std.math.maxInt(u32)); + defer d.comp.gpa.free(input); + return d.comp.addSourceFromBuffer("", input); + } + return d.comp.addSourceFromPath(path); +} + +pub fn err(d: *Driver, msg: []const u8) !void { + try d.comp.addDiagnostic(.{ .tag = .cli_error, .extra = .{ .str = msg } }, &.{}); +} + +pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } { + try d.comp.diagnostics.list.append(d.comp.gpa, .{ + .tag = .cli_error, + .kind = .@"fatal error", + .extra = .{ .str = try std.fmt.allocPrint(d.comp.diagnostics.arena.allocator(), fmt, args) }, + }); + return error.FatalError; +} + +pub fn renderErrors(d: *Driver) void { + Diagnostics.render(d.comp, d.detectConfig(std.io.getStdErr())); +} + +pub fn detectConfig(d: *Driver, file: std.fs.File) std.io.tty.Config { + if (d.color == true) return .escape_codes; + if (d.color == false) return .no_color; + + if (file.supportsAnsiEscapeCodes()) return .escape_codes; + if (@import("builtin").os.tag == .windows and file.isTty()) { + var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; + if (std.os.windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != std.os.windows.TRUE) { + return .no_color; + } + return .{ .windows_api = .{ + .handle = file.handle, + .reset_attributes = info.wAttributes, + } }; + } + + return .no_color; +} + +pub fn errorDescription(e: anyerror) []const u8 { + return switch (e) { + error.OutOfMemory => "ran out of memory", + error.FileNotFound => "file not found", + error.IsDir => "is a directory", + error.NotDir => "is not a directory", + error.NotOpenForReading => "file is not open for reading", + error.NotOpenForWriting => "file is not open for writing", + error.InvalidUtf8 => "path is not valid UTF-8", + error.InvalidWtf8 => "path is not valid WTF-8", + error.FileBusy => "file is busy", + error.NameTooLong => "file name is too long", + error.AccessDenied => "access denied", + error.FileTooBig => "file is too big", + error.ProcessFdQuotaExceeded, error.SystemFdQuotaExceeded => "ran out of file descriptors", + error.SystemResources => "ran out of system resources", + error.FatalError => "a fatal error occurred", + error.Unexpected => "an unexpected error occurred", + else => @errorName(e), + }; +} + +/// The entry point of the Aro compiler. +/// **MAY call `exit` if `fast_exit` is set.** +pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_exit: bool) !void { + var macro_buf = std.ArrayList(u8).init(d.comp.gpa); + defer macro_buf.deinit(); + + const std_out = std.io.getStdOut().writer(); + if (try parseArgs(d, std_out, macro_buf.writer(), args)) return; + + const linking = !(d.only_preprocess or d.only_syntax or d.only_compile or d.only_preprocess_and_compile); + + if (d.inputs.items.len == 0) { + return d.fatal("no input files", .{}); + } else if (d.inputs.items.len != 1 and d.output_name != null and !linking) { + return d.fatal("cannot specify -o when generating multiple output files", .{}); + } + + if (!linking) for (d.link_objects.items) |obj| { + try d.comp.addDiagnostic(.{ .tag = .cli_unused_link_object, .extra = .{ .str = obj } }, &.{}); + }; + + try tc.discover(); + tc.defineSystemIncludes() catch |er| switch (er) { + error.OutOfMemory => return error.OutOfMemory, + error.AroIncludeNotFound => return d.fatal("unable to find Aro builtin headers", .{}), + }; + + const builtin = try d.comp.generateBuiltinMacros(d.system_defines); + const user_macros = try d.comp.addSourceFromBuffer("", macro_buf.items); + + if (fast_exit and d.inputs.items.len == 1) { + d.processSource(tc, d.inputs.items[0], builtin, user_macros, fast_exit) catch |e| switch (e) { + error.FatalError => { + d.renderErrors(); + d.exitWithCleanup(1); + }, + else => |er| return er, + }; + unreachable; + } + + for (d.inputs.items) |source| { + d.processSource(tc, source, builtin, user_macros, fast_exit) catch |e| switch (e) { + error.FatalError => { + d.renderErrors(); + }, + else => |er| return er, + }; + } + if (d.comp.diagnostics.errors != 0) { + if (fast_exit) d.exitWithCleanup(1); + return; + } + if (linking) { + try d.invokeLinker(tc, fast_exit); + } + if (fast_exit) std.process.exit(0); +} + +fn processSource( + d: *Driver, + tc: *Toolchain, + source: Source, + builtin: Source, + user_macros: Source, + comptime fast_exit: bool, +) !void { + d.comp.generated_buf.items.len = 0; + var pp = try Preprocessor.initDefault(d.comp); + defer pp.deinit(); + + if (d.comp.langopts.ms_extensions) { + d.comp.ms_cwd_source_id = source.id; + } + const dump_mode = d.debug_dump_letters.getPreprocessorDumpMode(); + if (d.verbose_pp) pp.verbose = true; + if (d.only_preprocess) { + pp.preserve_whitespace = true; + if (d.line_commands) { + pp.linemarkers = if (d.use_line_directives) .line_directives else .numeric_directives; + } + switch (dump_mode) { + .macros_and_result, .macro_names_and_result => pp.store_macro_tokens = true, + .result_only, .macros_only => {}, + } + } + + try pp.preprocessSources(&.{ source, builtin, user_macros }); + + if (d.only_preprocess) { + d.renderErrors(); + + if (d.comp.diagnostics.errors != 0) { + if (fast_exit) std.process.exit(1); // Not linking, no need for cleanup. + return; + } + + const file = if (d.output_name) |some| + std.fs.cwd().createFile(some, .{}) catch |er| + return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) }) + else + std.io.getStdOut(); + defer if (d.output_name != null) file.close(); + + var buf_w = std.io.bufferedWriter(file.writer()); + + pp.prettyPrintTokens(buf_w.writer(), dump_mode) catch |er| + return d.fatal("unable to write result: {s}", .{errorDescription(er)}); + + buf_w.flush() catch |er| + return d.fatal("unable to write result: {s}", .{errorDescription(er)}); + if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup. + return; + } + + var tree = try pp.parse(); + defer tree.deinit(); + + if (d.verbose_ast) { + const stdout = std.io.getStdOut(); + var buf_writer = std.io.bufferedWriter(stdout.writer()); + tree.dump(d.detectConfig(stdout), buf_writer.writer()) catch {}; + buf_writer.flush() catch {}; + } + + const prev_errors = d.comp.diagnostics.errors; + d.renderErrors(); + + if (d.comp.diagnostics.errors != prev_errors) { + if (fast_exit) d.exitWithCleanup(1); + return; // do not compile if there were errors + } + + if (d.only_syntax) { + if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup. + return; + } + + if (d.comp.target.ofmt != .elf or d.comp.target.cpu.arch != .x86_64) { + return d.fatal( + "unsupported target {s}-{s}-{s}, currently only x86-64 elf is supported", + .{ @tagName(d.comp.target.cpu.arch), @tagName(d.comp.target.os.tag), @tagName(d.comp.target.abi) }, + ); + } + + var ir = try tree.genIr(); + defer ir.deinit(d.comp.gpa); + + if (d.verbose_ir) { + const stdout = std.io.getStdOut(); + var buf_writer = std.io.bufferedWriter(stdout.writer()); + ir.dump(d.comp.gpa, d.detectConfig(stdout), buf_writer.writer()) catch {}; + buf_writer.flush() catch {}; + } + + var render_errors: Ir.Renderer.ErrorList = .{}; + defer { + for (render_errors.values()) |msg| d.comp.gpa.free(msg); + render_errors.deinit(d.comp.gpa); + } + + var obj = ir.render(d.comp.gpa, d.comp.target, &render_errors) catch |e| switch (e) { + error.OutOfMemory => return error.OutOfMemory, + error.LowerFail => { + return d.fatal( + "unable to render Ir to machine code: {s}", + .{render_errors.values()[0]}, + ); + }, + }; + defer obj.deinit(); + + // If it's used, name_buf will either hold a filename or `/tmp/<12 random bytes with base-64 encoding>.` + // both of which should fit into max_name_bytes for all systems + var name_buf: [std.fs.max_name_bytes]u8 = undefined; + + const out_file_name = if (d.only_compile) blk: { + const fmt_template = "{s}{s}"; + const fmt_args = .{ + std.fs.path.stem(source.path), + d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch), + }; + break :blk d.output_name orelse + std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args); + } else blk: { + const random_bytes_count = 12; + const sub_path_len = comptime std.fs.base64_encoder.calcSize(random_bytes_count); + + var random_bytes: [random_bytes_count]u8 = undefined; + std.crypto.random.bytes(&random_bytes); + var random_name: [sub_path_len]u8 = undefined; + _ = std.fs.base64_encoder.encode(&random_name, &random_bytes); + + const fmt_template = "/tmp/{s}{s}"; + const fmt_args = .{ + random_name, + d.comp.target.ofmt.fileExt(d.comp.target.cpu.arch), + }; + break :blk std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args); + }; + + const out_file = std.fs.cwd().createFile(out_file_name, .{}) catch |er| + return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); + defer out_file.close(); + + obj.finish(out_file) catch |er| + return d.fatal("could not output to object file '{s}': {s}", .{ out_file_name, errorDescription(er) }); + + if (d.only_compile) { + if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup. + return; + } + try d.link_objects.ensureUnusedCapacity(d.comp.gpa, 1); + d.link_objects.appendAssumeCapacity(try d.comp.gpa.dupe(u8, out_file_name)); + d.temp_file_count += 1; + if (fast_exit) { + try d.invokeLinker(tc, fast_exit); + } +} + +fn dumpLinkerArgs(items: []const []const u8) !void { + const stdout = std.io.getStdOut().writer(); + for (items, 0..) |item, i| { + if (i > 0) try stdout.writeByte(' '); + try stdout.print("\"{}\"", .{std.zig.fmtEscapes(item)}); + } + try stdout.writeByte('\n'); +} + +/// The entry point of the Aro compiler. +/// **MAY call `exit` if `fast_exit` is set.** +pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) !void { + var argv = std.ArrayList([]const u8).init(d.comp.gpa); + defer argv.deinit(); + + var linker_path_buf: [std.fs.max_path_bytes]u8 = undefined; + const linker_path = try tc.getLinkerPath(&linker_path_buf); + try argv.append(linker_path); + + try tc.buildLinkerArgs(&argv); + + if (d.verbose_linker_args) { + dumpLinkerArgs(argv.items) catch |er| { + return d.fatal("unable to dump linker args: {s}", .{errorDescription(er)}); + }; + } + var child = std.process.Child.init(argv.items, d.comp.gpa); + // TODO handle better + child.stdin_behavior = .Inherit; + child.stdout_behavior = .Inherit; + child.stderr_behavior = .Inherit; + + const term = child.spawnAndWait() catch |er| { + return d.fatal("unable to spawn linker: {s}", .{errorDescription(er)}); + }; + switch (term) { + .Exited => |code| if (code != 0) { + const e = d.fatal("linker exited with an error code", .{}); + if (fast_exit) d.exitWithCleanup(code); + return e; + }, + else => { + const e = d.fatal("linker crashed", .{}); + if (fast_exit) d.exitWithCleanup(1); + return e; + }, + } + if (fast_exit) d.exitWithCleanup(0); +} + +fn exitWithCleanup(d: *Driver, code: u8) noreturn { + for (d.link_objects.items[d.link_objects.items.len - d.temp_file_count ..]) |obj| { + std.fs.deleteFileAbsolute(obj) catch {}; + } + std.process.exit(code); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Distro.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Distro.zig new file mode 100644 index 00000000..10f15f04 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Distro.zig @@ -0,0 +1,328 @@ +//! Tools for figuring out what Linux distro we're running on + +const std = @import("std"); +const mem = std.mem; +const Filesystem = @import("Filesystem.zig").Filesystem; + +const MAX_BYTES = 1024; // TODO: Can we assume 1024 bytes enough for the info we need? + +/// Value for linker `--hash-style=` argument +pub const HashStyle = enum { + both, + gnu, +}; + +pub const Tag = enum { + alpine, + arch, + debian_lenny, + debian_squeeze, + debian_wheezy, + debian_jessie, + debian_stretch, + debian_buster, + debian_bullseye, + debian_bookworm, + debian_trixie, + exherbo, + rhel5, + rhel6, + rhel7, + fedora, + gentoo, + open_suse, + ubuntu_hardy, + ubuntu_intrepid, + ubuntu_jaunty, + ubuntu_karmic, + ubuntu_lucid, + ubuntu_maverick, + ubuntu_natty, + ubuntu_oneiric, + ubuntu_precise, + ubuntu_quantal, + ubuntu_raring, + ubuntu_saucy, + ubuntu_trusty, + ubuntu_utopic, + ubuntu_vivid, + ubuntu_wily, + ubuntu_xenial, + ubuntu_yakkety, + ubuntu_zesty, + ubuntu_artful, + ubuntu_bionic, + ubuntu_cosmic, + ubuntu_disco, + ubuntu_eoan, + ubuntu_focal, + ubuntu_groovy, + ubuntu_hirsute, + ubuntu_impish, + ubuntu_jammy, + ubuntu_kinetic, + ubuntu_lunar, + unknown, + + pub fn getHashStyle(self: Tag) HashStyle { + if (self.isOpenSUSE()) return .both; + return switch (self) { + .ubuntu_lucid, + .ubuntu_jaunty, + .ubuntu_karmic, + => .both, + else => .gnu, + }; + } + + pub fn isRedhat(self: Tag) bool { + return switch (self) { + .fedora, + .rhel5, + .rhel6, + .rhel7, + => true, + else => false, + }; + } + + pub fn isOpenSUSE(self: Tag) bool { + return self == .open_suse; + } + + pub fn isDebian(self: Tag) bool { + return switch (self) { + .debian_lenny, + .debian_squeeze, + .debian_wheezy, + .debian_jessie, + .debian_stretch, + .debian_buster, + .debian_bullseye, + .debian_bookworm, + .debian_trixie, + => true, + else => false, + }; + } + pub fn isUbuntu(self: Tag) bool { + return switch (self) { + .ubuntu_hardy, + .ubuntu_intrepid, + .ubuntu_jaunty, + .ubuntu_karmic, + .ubuntu_lucid, + .ubuntu_maverick, + .ubuntu_natty, + .ubuntu_oneiric, + .ubuntu_precise, + .ubuntu_quantal, + .ubuntu_raring, + .ubuntu_saucy, + .ubuntu_trusty, + .ubuntu_utopic, + .ubuntu_vivid, + .ubuntu_wily, + .ubuntu_xenial, + .ubuntu_yakkety, + .ubuntu_zesty, + .ubuntu_artful, + .ubuntu_bionic, + .ubuntu_cosmic, + .ubuntu_disco, + .ubuntu_eoan, + .ubuntu_focal, + .ubuntu_groovy, + .ubuntu_hirsute, + .ubuntu_impish, + .ubuntu_jammy, + .ubuntu_kinetic, + .ubuntu_lunar, + => true, + + else => false, + }; + } + pub fn isAlpine(self: Tag) bool { + return self == .alpine; + } + pub fn isGentoo(self: Tag) bool { + return self == .gentoo; + } +}; + +fn scanForOsRelease(buf: []const u8) ?Tag { + var it = mem.splitScalar(u8, buf, '\n'); + while (it.next()) |line| { + if (mem.startsWith(u8, line, "ID=")) { + const rest = line["ID=".len..]; + if (mem.eql(u8, rest, "alpine")) return .alpine; + if (mem.eql(u8, rest, "fedora")) return .fedora; + if (mem.eql(u8, rest, "gentoo")) return .gentoo; + if (mem.eql(u8, rest, "arch")) return .arch; + if (mem.eql(u8, rest, "sles")) return .open_suse; + if (mem.eql(u8, rest, "opensuse")) return .open_suse; + if (mem.eql(u8, rest, "exherbo")) return .exherbo; + } + } + return null; +} + +fn detectOsRelease(fs: Filesystem) ?Tag { + var buf: [MAX_BYTES]u8 = undefined; + const data = fs.readFile("/etc/os-release", &buf) orelse fs.readFile("/usr/lib/os-release", &buf) orelse return null; + return scanForOsRelease(data); +} + +fn scanForLSBRelease(buf: []const u8) ?Tag { + var it = mem.splitScalar(u8, buf, '\n'); + while (it.next()) |line| { + if (mem.startsWith(u8, line, "DISTRIB_CODENAME=")) { + const rest = line["DISTRIB_CODENAME=".len..]; + if (mem.eql(u8, rest, "hardy")) return .ubuntu_hardy; + if (mem.eql(u8, rest, "intrepid")) return .ubuntu_intrepid; + if (mem.eql(u8, rest, "jaunty")) return .ubuntu_jaunty; + if (mem.eql(u8, rest, "karmic")) return .ubuntu_karmic; + if (mem.eql(u8, rest, "lucid")) return .ubuntu_lucid; + if (mem.eql(u8, rest, "maverick")) return .ubuntu_maverick; + if (mem.eql(u8, rest, "natty")) return .ubuntu_natty; + if (mem.eql(u8, rest, "oneiric")) return .ubuntu_oneiric; + if (mem.eql(u8, rest, "precise")) return .ubuntu_precise; + if (mem.eql(u8, rest, "quantal")) return .ubuntu_quantal; + if (mem.eql(u8, rest, "raring")) return .ubuntu_raring; + if (mem.eql(u8, rest, "saucy")) return .ubuntu_saucy; + if (mem.eql(u8, rest, "trusty")) return .ubuntu_trusty; + if (mem.eql(u8, rest, "utopic")) return .ubuntu_utopic; + if (mem.eql(u8, rest, "vivid")) return .ubuntu_vivid; + if (mem.eql(u8, rest, "wily")) return .ubuntu_wily; + if (mem.eql(u8, rest, "xenial")) return .ubuntu_xenial; + if (mem.eql(u8, rest, "yakkety")) return .ubuntu_yakkety; + if (mem.eql(u8, rest, "zesty")) return .ubuntu_zesty; + if (mem.eql(u8, rest, "artful")) return .ubuntu_artful; + if (mem.eql(u8, rest, "bionic")) return .ubuntu_bionic; + if (mem.eql(u8, rest, "cosmic")) return .ubuntu_cosmic; + if (mem.eql(u8, rest, "disco")) return .ubuntu_disco; + if (mem.eql(u8, rest, "eoan")) return .ubuntu_eoan; + if (mem.eql(u8, rest, "focal")) return .ubuntu_focal; + if (mem.eql(u8, rest, "groovy")) return .ubuntu_groovy; + if (mem.eql(u8, rest, "hirsute")) return .ubuntu_hirsute; + if (mem.eql(u8, rest, "impish")) return .ubuntu_impish; + if (mem.eql(u8, rest, "jammy")) return .ubuntu_jammy; + if (mem.eql(u8, rest, "kinetic")) return .ubuntu_kinetic; + if (mem.eql(u8, rest, "lunar")) return .ubuntu_lunar; + } + } + return null; +} + +fn detectLSBRelease(fs: Filesystem) ?Tag { + var buf: [MAX_BYTES]u8 = undefined; + const data = fs.readFile("/etc/lsb-release", &buf) orelse return null; + + return scanForLSBRelease(data); +} + +fn scanForRedHat(buf: []const u8) Tag { + if (mem.startsWith(u8, buf, "Fedora release")) return .fedora; + if (mem.startsWith(u8, buf, "Red Hat Enterprise Linux") or mem.startsWith(u8, buf, "CentOS") or mem.startsWith(u8, buf, "Scientific Linux")) { + if (mem.indexOfPos(u8, buf, 0, "release 7") != null) return .rhel7; + if (mem.indexOfPos(u8, buf, 0, "release 6") != null) return .rhel6; + if (mem.indexOfPos(u8, buf, 0, "release 5") != null) return .rhel5; + } + + return .unknown; +} + +fn detectRedhat(fs: Filesystem) ?Tag { + var buf: [MAX_BYTES]u8 = undefined; + const data = fs.readFile("/etc/redhat-release", &buf) orelse return null; + return scanForRedHat(data); +} + +fn scanForDebian(buf: []const u8) Tag { + var it = mem.splitScalar(u8, buf, '.'); + if (std.fmt.parseInt(u8, it.next().?, 10)) |major| { + return switch (major) { + 5 => .debian_lenny, + 6 => .debian_squeeze, + 7 => .debian_wheezy, + 8 => .debian_jessie, + 9 => .debian_stretch, + 10 => .debian_buster, + 11 => .debian_bullseye, + 12 => .debian_bookworm, + 13 => .debian_trixie, + else => .unknown, + }; + } else |_| {} + + it = mem.splitScalar(u8, buf, '\n'); + const name = it.next().?; + if (mem.eql(u8, name, "squeeze/sid")) return .debian_squeeze; + if (mem.eql(u8, name, "wheezy/sid")) return .debian_wheezy; + if (mem.eql(u8, name, "jessie/sid")) return .debian_jessie; + if (mem.eql(u8, name, "stretch/sid")) return .debian_stretch; + if (mem.eql(u8, name, "buster/sid")) return .debian_buster; + if (mem.eql(u8, name, "bullseye/sid")) return .debian_bullseye; + if (mem.eql(u8, name, "bookworm/sid")) return .debian_bookworm; + + return .unknown; +} + +fn detectDebian(fs: Filesystem) ?Tag { + var buf: [MAX_BYTES]u8 = undefined; + const data = fs.readFile("/etc/debian_version", &buf) orelse return null; + return scanForDebian(data); +} + +pub fn detect(target: std.Target, fs: Filesystem) Tag { + if (target.os.tag != .linux) return .unknown; + + if (detectOsRelease(fs)) |tag| return tag; + if (detectLSBRelease(fs)) |tag| return tag; + if (detectRedhat(fs)) |tag| return tag; + if (detectDebian(fs)) |tag| return tag; + + if (fs.exists("/etc/gentoo-release")) return .gentoo; + + return .unknown; +} + +test scanForDebian { + try std.testing.expectEqual(Tag.debian_squeeze, scanForDebian("squeeze/sid")); + try std.testing.expectEqual(Tag.debian_bullseye, scanForDebian("11.1.2")); + try std.testing.expectEqual(Tag.unknown, scanForDebian("None")); + try std.testing.expectEqual(Tag.unknown, scanForDebian("")); +} + +test scanForRedHat { + try std.testing.expectEqual(Tag.fedora, scanForRedHat("Fedora release 7")); + try std.testing.expectEqual(Tag.rhel7, scanForRedHat("Red Hat Enterprise Linux release 7")); + try std.testing.expectEqual(Tag.rhel5, scanForRedHat("CentOS release 5")); + try std.testing.expectEqual(Tag.unknown, scanForRedHat("CentOS release 4")); + try std.testing.expectEqual(Tag.unknown, scanForRedHat("")); +} + +test scanForLSBRelease { + const text = + \\DISTRIB_ID=Ubuntu + \\DISTRIB_RELEASE=20.04 + \\DISTRIB_CODENAME=focal + \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS" + \\ + ; + try std.testing.expectEqual(Tag.ubuntu_focal, scanForLSBRelease(text).?); +} + +test scanForOsRelease { + const text = + \\NAME="Alpine Linux" + \\ID=alpine + \\VERSION_ID=3.18.2 + \\PRETTY_NAME="Alpine Linux v3.18" + \\HOME_URL="https://alpinelinux.org/" + \\BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues" + \\ + ; + try std.testing.expectEqual(Tag.alpine, scanForOsRelease(text).?); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Filesystem.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Filesystem.zig new file mode 100644 index 00000000..07cbeac0 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Filesystem.zig @@ -0,0 +1,239 @@ +const std = @import("std"); +const mem = std.mem; +const builtin = @import("builtin"); +const is_windows = builtin.os.tag == .windows; + +fn readFileFake(entries: []const Filesystem.Entry, path: []const u8, buf: []u8) ?[]const u8 { + @branchHint(.cold); + for (entries) |entry| { + if (mem.eql(u8, entry.path, path)) { + const len = @min(entry.contents.len, buf.len); + @memcpy(buf[0..len], entry.contents[0..len]); + return buf[0..len]; + } + } + return null; +} + +fn findProgramByNameFake(entries: []const Filesystem.Entry, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 { + @branchHint(.cold); + if (mem.indexOfScalar(u8, name, '/') != null) { + @memcpy(buf[0..name.len], name); + return buf[0..name.len]; + } + const path_env = path orelse return null; + var fib = std.heap.FixedBufferAllocator.init(buf); + + var it = mem.tokenizeScalar(u8, path_env, std.fs.path.delimiter); + while (it.next()) |path_dir| { + defer fib.reset(); + const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue; + if (canExecuteFake(entries, full_path)) return full_path; + } + + return null; +} + +fn canExecuteFake(entries: []const Filesystem.Entry, path: []const u8) bool { + @branchHint(.cold); + for (entries) |entry| { + if (mem.eql(u8, entry.path, path)) { + return entry.executable; + } + } + return false; +} + +fn existsFake(entries: []const Filesystem.Entry, path: []const u8) bool { + @branchHint(.cold); + var buf: [std.fs.max_path_bytes]u8 = undefined; + var fib = std.heap.FixedBufferAllocator.init(&buf); + const resolved = std.fs.path.resolvePosix(fib.allocator(), &.{path}) catch return false; + for (entries) |entry| { + if (mem.eql(u8, entry.path, resolved)) return true; + } + return false; +} + +fn canExecutePosix(path: []const u8) bool { + std.posix.access(path, std.posix.X_OK) catch return false; + // Todo: ensure path is not a directory + return true; +} + +/// TODO +fn canExecuteWindows(path: []const u8) bool { + _ = path; + return true; +} + +/// TODO +fn findProgramByNameWindows(allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 { + _ = path; + _ = buf; + _ = name; + _ = allocator; + return null; +} + +/// TODO: does WASI need special handling? +fn findProgramByNamePosix(name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 { + if (mem.indexOfScalar(u8, name, '/') != null) { + @memcpy(buf[0..name.len], name); + return buf[0..name.len]; + } + const path_env = path orelse return null; + var fib = std.heap.FixedBufferAllocator.init(buf); + + var it = mem.tokenizeScalar(u8, path_env, std.fs.path.delimiter); + while (it.next()) |path_dir| { + defer fib.reset(); + const full_path = std.fs.path.join(fib.allocator(), &.{ path_dir, name }) catch continue; + if (canExecutePosix(full_path)) return full_path; + } + + return null; +} + +pub const Filesystem = union(enum) { + real: void, + fake: []const Entry, + + const Entry = struct { + path: []const u8, + contents: []const u8 = "", + executable: bool = false, + }; + + const FakeDir = struct { + entries: []const Entry, + path: []const u8, + + fn iterate(self: FakeDir) FakeDir.Iterator { + return .{ + .entries = self.entries, + .base = self.path, + }; + } + + const Iterator = struct { + entries: []const Entry, + base: []const u8, + i: usize = 0, + + fn next(self: *@This()) !?std.fs.Dir.Entry { + while (self.i < self.entries.len) { + const entry = self.entries[self.i]; + self.i += 1; + if (entry.path.len == self.base.len) continue; + if (std.mem.startsWith(u8, entry.path, self.base)) { + const remaining = entry.path[self.base.len + 1 ..]; + if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue; + const extension = std.fs.path.extension(remaining); + const kind: std.fs.Dir.Entry.Kind = if (extension.len == 0) .directory else .file; + return .{ .name = remaining, .kind = kind }; + } + } + return null; + } + }; + }; + + const Dir = union(enum) { + dir: std.fs.Dir, + fake: FakeDir, + + pub fn iterate(self: Dir) Iterator { + return switch (self) { + .dir => |dir| .{ .iterator = dir.iterate() }, + .fake => |fake| .{ .fake = fake.iterate() }, + }; + } + + pub fn close(self: *Dir) void { + switch (self.*) { + .dir => |*d| d.close(), + .fake => {}, + } + } + }; + + const Iterator = union(enum) { + iterator: std.fs.Dir.Iterator, + fake: FakeDir.Iterator, + + pub fn next(self: *Iterator) std.fs.Dir.Iterator.Error!?std.fs.Dir.Entry { + return switch (self.*) { + .iterator => |*it| it.next(), + .fake => |*it| it.next(), + }; + } + }; + + pub fn exists(fs: Filesystem, path: []const u8) bool { + switch (fs) { + .real => { + std.fs.cwd().access(path, .{}) catch return false; + return true; + }, + .fake => |paths| return existsFake(paths, path), + } + } + + pub fn joinedExists(fs: Filesystem, parts: []const []const u8) bool { + var buf: [std.fs.max_path_bytes]u8 = undefined; + var fib = std.heap.FixedBufferAllocator.init(&buf); + const joined = std.fs.path.join(fib.allocator(), parts) catch return false; + return fs.exists(joined); + } + + pub fn canExecute(fs: Filesystem, path: []const u8) bool { + return switch (fs) { + .real => if (is_windows) canExecuteWindows(path) else canExecutePosix(path), + .fake => |entries| canExecuteFake(entries, path), + }; + } + + /// Search for an executable named `name` using platform-specific logic + /// If it's found, write the full path to `buf` and return a slice of it + /// Otherwise retun null + pub fn findProgramByName(fs: Filesystem, allocator: std.mem.Allocator, name: []const u8, path: ?[]const u8, buf: []u8) ?[]const u8 { + std.debug.assert(name.len > 0); + return switch (fs) { + .real => if (is_windows) findProgramByNameWindows(allocator, name, path, buf) else findProgramByNamePosix(name, path, buf), + .fake => |entries| findProgramByNameFake(entries, name, path, buf), + }; + } + + /// Read the file at `path` into `buf`. + /// Returns null if any errors are encountered + /// Otherwise returns a slice of `buf`. If the file is larger than `buf` partial contents are returned + pub fn readFile(fs: Filesystem, path: []const u8, buf: []u8) ?[]const u8 { + return switch (fs) { + .real => { + const file = std.fs.cwd().openFile(path, .{}) catch return null; + defer file.close(); + + const bytes_read = file.readAll(buf) catch return null; + return buf[0..bytes_read]; + }, + .fake => |entries| readFileFake(entries, path, buf), + }; + } + + pub fn openDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!Dir { + return switch (fs) { + .real => .{ .dir = try std.fs.cwd().openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) }, + .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } }, + }; + } +}; + +test "Fake filesystem" { + const fs: Filesystem = .{ .fake = &.{ + .{ .path = "/usr/bin" }, + } }; + try std.testing.expect(fs.exists("/usr/bin")); + try std.testing.expect(fs.exists("/usr/bin/foo/..")); + try std.testing.expect(!fs.exists("/usr/bin/bar")); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/GCCDetector.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/GCCDetector.zig new file mode 100644 index 00000000..80e94a3b --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/GCCDetector.zig @@ -0,0 +1,638 @@ +const std = @import("std"); +const Toolchain = @import("../Toolchain.zig"); +const target_util = @import("../target.zig"); +const system_defaults = @import("system_defaults"); +const GCCVersion = @import("GCCVersion.zig"); +const Multilib = @import("Multilib.zig"); + +const GCCDetector = @This(); + +is_valid: bool = false, +install_path: []const u8 = "", +parent_lib_path: []const u8 = "", +version: GCCVersion = .{}, +gcc_triple: []const u8 = "", +selected: Multilib = .{}, +biarch_sibling: ?Multilib = null, + +pub fn deinit(self: *GCCDetector) void { + if (!self.is_valid) return; +} + +pub fn appendToolPath(self: *const GCCDetector, tc: *Toolchain) !void { + if (!self.is_valid) return; + return tc.addPathFromComponents(&.{ + self.parent_lib_path, + "..", + self.gcc_triple, + "bin", + }, .program); +} + +fn addDefaultGCCPrefixes(prefixes: *std.ArrayListUnmanaged([]const u8), tc: *const Toolchain) !void { + const sysroot = tc.getSysroot(); + const target = tc.getTarget(); + if (sysroot.len == 0 and target.os.tag == .linux and tc.filesystem.exists("/opt/rh")) { + prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-12/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-11/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/gcc-toolset-10/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-12/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-11/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-10/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-9/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-8/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-7/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-6/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-4/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-3/root/usr"); + prefixes.appendAssumeCapacity("/opt/rh/devtoolset-2/root/usr"); + } + if (sysroot.len == 0) { + prefixes.appendAssumeCapacity("/usr"); + } else { + var usr_path = try tc.arena.alloc(u8, 4 + sysroot.len); + @memcpy(usr_path[0..4], "/usr"); + @memcpy(usr_path[4..], sysroot); + prefixes.appendAssumeCapacity(usr_path); + } +} + +fn collectLibDirsAndTriples( + tc: *Toolchain, + lib_dirs: *std.ArrayListUnmanaged([]const u8), + triple_aliases: *std.ArrayListUnmanaged([]const u8), + biarch_libdirs: *std.ArrayListUnmanaged([]const u8), + biarch_triple_aliases: *std.ArrayListUnmanaged([]const u8), +) !void { + const AArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const AArch64Triples: [4][]const u8 = .{ "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", "aarch64-suse-linux" }; + const AArch64beLibDirs: [1][]const u8 = .{"/lib"}; + const AArch64beTriples: [2][]const u8 = .{ "aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu" }; + + const ARMLibDirs: [1][]const u8 = .{"/lib"}; + const ARMTriples: [1][]const u8 = .{"arm-linux-gnueabi"}; + const ARMHFTriples: [4][]const u8 = .{ "arm-linux-gnueabihf", "armv7hl-redhat-linux-gnueabi", "armv6hl-suse-linux-gnueabi", "armv7hl-suse-linux-gnueabi" }; + + const ARMebLibDirs: [1][]const u8 = .{"/lib"}; + const ARMebTriples: [1][]const u8 = .{"armeb-linux-gnueabi"}; + const ARMebHFTriples: [2][]const u8 = .{ "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi" }; + + const AVRLibDirs: [1][]const u8 = .{"/lib"}; + const AVRTriples: [1][]const u8 = .{"avr"}; + + const CSKYLibDirs: [1][]const u8 = .{"/lib"}; + const CSKYTriples: [3][]const u8 = .{ "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2" }; + + const X86_64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const X86_64Triples: [11][]const u8 = .{ + "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", + "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E", + "x86_64-redhat-linux", "x86_64-suse-linux", + "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", + "x86_64-slackware-linux", "x86_64-unknown-linux", + "x86_64-amazon-linux", + }; + const X32Triples: [2][]const u8 = .{ "x86_64-linux-gnux32", "x86_64-pc-linux-gnux32" }; + const X32LibDirs: [2][]const u8 = .{ "/libx32", "/lib" }; + const X86LibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; + const X86Triples: [9][]const u8 = .{ + "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu", + "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux", + "i586-suse-linux", "i686-montavista-linux", "i686-gnu", + }; + + const LoongArch64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const LoongArch64Triples: [2][]const u8 = .{ "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu" }; + + const M68kLibDirs: [1][]const u8 = .{"/lib"}; + const M68kTriples: [3][]const u8 = .{ "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux" }; + + const MIPSLibDirs: [2][]const u8 = .{ "/libo32", "/lib" }; + const MIPSTriples: [5][]const u8 = .{ + "mips-linux-gnu", "mips-mti-linux", + "mips-mti-linux-gnu", "mips-img-linux-gnu", + "mipsisa32r6-linux-gnu", + }; + const MIPSELLibDirs: [2][]const u8 = .{ "/libo32", "/lib" }; + const MIPSELTriples: [3][]const u8 = .{ "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu" }; + + const MIPS64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const MIPS64Triples: [6][]const u8 = .{ + "mips64-linux-gnu", "mips-mti-linux-gnu", + "mips-img-linux-gnu", "mips64-linux-gnuabi64", + "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64", + }; + const MIPS64ELLibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const MIPS64ELTriples: [6][]const u8 = .{ + "mips64el-linux-gnu", "mips-mti-linux-gnu", + "mips-img-linux-gnu", "mips64el-linux-gnuabi64", + "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64", + }; + + const MIPSN32LibDirs: [1][]const u8 = .{"/lib32"}; + const MIPSN32Triples: [2][]const u8 = .{ "mips64-linux-gnuabin32", "mipsisa64r6-linux-gnuabin32" }; + const MIPSN32ELLibDirs: [1][]const u8 = .{"/lib32"}; + const MIPSN32ELTriples: [2][]const u8 = .{ "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32" }; + + const MSP430LibDirs: [1][]const u8 = .{"/lib"}; + const MSP430Triples: [1][]const u8 = .{"msp430-elf"}; + + const PPCLibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; + const PPCTriples: [5][]const u8 = .{ + "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", + // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a + // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux". + "powerpc64-suse-linux", "powerpc-montavista-linuxspe", + }; + const PPCLELibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; + const PPCLETriples: [3][]const u8 = .{ "powerpcle-linux-gnu", "powerpcle-unknown-linux-gnu", "powerpcle-linux-musl" }; + + const PPC64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const PPC64Triples: [4][]const u8 = .{ + "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu", + "powerpc64-suse-linux", "ppc64-redhat-linux", + }; + const PPC64LELibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const PPC64LETriples: [5][]const u8 = .{ + "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu", + "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux", + "ppc64le-redhat-linux", + }; + + const RISCV32LibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; + const RISCV32Triples: [3][]const u8 = .{ "riscv32-unknown-linux-gnu", "riscv32-linux-gnu", "riscv32-unknown-elf" }; + const RISCV64LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const RISCV64Triples: [3][]const u8 = .{ + "riscv64-unknown-linux-gnu", + "riscv64-linux-gnu", + "riscv64-unknown-elf", + }; + + const SPARCv8LibDirs: [2][]const u8 = .{ "/lib32", "/lib" }; + const SPARCv8Triples: [2][]const u8 = .{ "sparc-linux-gnu", "sparcv8-linux-gnu" }; + const SPARCv9LibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const SPARCv9Triples: [2][]const u8 = .{ "sparc64-linux-gnu", "sparcv9-linux-gnu" }; + + const SystemZLibDirs: [2][]const u8 = .{ "/lib64", "/lib" }; + const SystemZTriples: [5][]const u8 = .{ + "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", + "s390x-suse-linux", "s390x-redhat-linux", + }; + const target = tc.getTarget(); + if (target.os.tag == .solaris) { + // TODO + return; + } + if (target.abi.isAndroid()) { + const AArch64AndroidTriples: [1][]const u8 = .{"aarch64-linux-android"}; + const ARMAndroidTriples: [1][]const u8 = .{"arm-linux-androideabi"}; + const MIPSELAndroidTriples: [1][]const u8 = .{"mipsel-linux-android"}; + const MIPS64ELAndroidTriples: [1][]const u8 = .{"mips64el-linux-android"}; + const X86AndroidTriples: [1][]const u8 = .{"i686-linux-android"}; + const X86_64AndroidTriples: [1][]const u8 = .{"x86_64-linux-android"}; + + switch (target.cpu.arch) { + .aarch64 => { + lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&AArch64AndroidTriples); + }, + .arm, + .thumb, + => { + lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs); + triple_aliases.appendSliceAssumeCapacity(&ARMAndroidTriples); + }, + .mipsel => { + lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs); + triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples); + }, + .mips64el => { + lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); + triple_aliases.appendSliceAssumeCapacity(&MIPS64ELAndroidTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELAndroidTriples); + }, + .x86_64 => { + lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples); + biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples); + }, + .x86 => { + lib_dirs.appendSliceAssumeCapacity(&X86LibDirs); + triple_aliases.appendSliceAssumeCapacity(&X86AndroidTriples); + biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64AndroidTriples); + }, + else => {}, + } + return; + } + switch (target.cpu.arch) { + .aarch64 => { + lib_dirs.appendSliceAssumeCapacity(&AArch64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&AArch64Triples); + biarch_libdirs.appendSliceAssumeCapacity(&AArch64LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64Triples); + }, + .aarch64_be => { + lib_dirs.appendSliceAssumeCapacity(&AArch64beLibDirs); + triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples); + biarch_libdirs.appendSliceAssumeCapacity(&AArch64beLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&AArch64beTriples); + }, + .arm, .thumb => { + lib_dirs.appendSliceAssumeCapacity(&ARMLibDirs); + if (target.abi == .gnueabihf) { + triple_aliases.appendSliceAssumeCapacity(&ARMHFTriples); + } else { + triple_aliases.appendSliceAssumeCapacity(&ARMTriples); + } + }, + .armeb, .thumbeb => { + lib_dirs.appendSliceAssumeCapacity(&ARMebLibDirs); + if (target.abi == .gnueabihf) { + triple_aliases.appendSliceAssumeCapacity(&ARMebHFTriples); + } else { + triple_aliases.appendSliceAssumeCapacity(&ARMebTriples); + } + }, + .avr => { + lib_dirs.appendSliceAssumeCapacity(&AVRLibDirs); + triple_aliases.appendSliceAssumeCapacity(&AVRTriples); + }, + .csky => { + lib_dirs.appendSliceAssumeCapacity(&CSKYLibDirs); + triple_aliases.appendSliceAssumeCapacity(&CSKYTriples); + }, + .x86_64 => { + if (target.abi == .gnux32 or target.abi == .muslx32) { + lib_dirs.appendSliceAssumeCapacity(&X32LibDirs); + triple_aliases.appendSliceAssumeCapacity(&X32Triples); + biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples); + } else { + lib_dirs.appendSliceAssumeCapacity(&X86_64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&X86_64Triples); + biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples); + } + biarch_libdirs.appendSliceAssumeCapacity(&X86LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&X86Triples); + }, + .x86 => { + lib_dirs.appendSliceAssumeCapacity(&X86LibDirs); + // MCU toolchain is 32 bit only and its triple alias is TargetTriple + // itself, which will be appended below. + if (target.os.tag != .elfiamcu) { + triple_aliases.appendSliceAssumeCapacity(&X86Triples); + biarch_libdirs.appendSliceAssumeCapacity(&X86_64LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&X86_64Triples); + biarch_libdirs.appendSliceAssumeCapacity(&X32LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&X32Triples); + } + }, + .loongarch64 => { + lib_dirs.appendSliceAssumeCapacity(&LoongArch64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&LoongArch64Triples); + }, + .m68k => { + lib_dirs.appendSliceAssumeCapacity(&M68kLibDirs); + triple_aliases.appendSliceAssumeCapacity(&M68kTriples); + }, + .mips => { + lib_dirs.appendSliceAssumeCapacity(&MIPSLibDirs); + triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPS64LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples); + }, + .mipsel => { + lib_dirs.appendSliceAssumeCapacity(&MIPSELLibDirs); + triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples); + triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples); + }, + .mips64 => { + lib_dirs.appendSliceAssumeCapacity(&MIPS64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&MIPS64Triples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPSLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32Triples); + }, + .mips64el => { + lib_dirs.appendSliceAssumeCapacity(&MIPS64ELLibDirs); + triple_aliases.appendSliceAssumeCapacity(&MIPS64ELTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPSELLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSELTriples); + biarch_libdirs.appendSliceAssumeCapacity(&MIPSN32ELLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSN32ELTriples); + biarch_triple_aliases.appendSliceAssumeCapacity(&MIPSTriples); + }, + .msp430 => { + lib_dirs.appendSliceAssumeCapacity(&MSP430LibDirs); + triple_aliases.appendSliceAssumeCapacity(&MSP430Triples); + }, + .powerpc => { + lib_dirs.appendSliceAssumeCapacity(&PPCLibDirs); + triple_aliases.appendSliceAssumeCapacity(&PPCTriples); + biarch_libdirs.appendSliceAssumeCapacity(&PPC64LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64Triples); + }, + .powerpcle => { + lib_dirs.appendSliceAssumeCapacity(&PPCLELibDirs); + triple_aliases.appendSliceAssumeCapacity(&PPCLETriples); + biarch_libdirs.appendSliceAssumeCapacity(&PPC64LELibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples); + }, + .powerpc64 => { + lib_dirs.appendSliceAssumeCapacity(&PPC64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&PPC64Triples); + biarch_libdirs.appendSliceAssumeCapacity(&PPCLibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&PPCTriples); + }, + .powerpc64le => { + lib_dirs.appendSliceAssumeCapacity(&PPC64LELibDirs); + triple_aliases.appendSliceAssumeCapacity(&PPC64LETriples); + biarch_libdirs.appendSliceAssumeCapacity(&PPCLELibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&PPCLETriples); + }, + .riscv32 => { + lib_dirs.appendSliceAssumeCapacity(&RISCV32LibDirs); + triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples); + biarch_libdirs.appendSliceAssumeCapacity(&RISCV64LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples); + }, + .riscv64 => { + lib_dirs.appendSliceAssumeCapacity(&RISCV64LibDirs); + triple_aliases.appendSliceAssumeCapacity(&RISCV64Triples); + biarch_libdirs.appendSliceAssumeCapacity(&RISCV32LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&RISCV32Triples); + }, + .sparc => { + lib_dirs.appendSliceAssumeCapacity(&SPARCv8LibDirs); + triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples); + biarch_libdirs.appendSliceAssumeCapacity(&SPARCv9LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples); + }, + .sparc64 => { + lib_dirs.appendSliceAssumeCapacity(&SPARCv9LibDirs); + triple_aliases.appendSliceAssumeCapacity(&SPARCv9Triples); + biarch_libdirs.appendSliceAssumeCapacity(&SPARCv8LibDirs); + biarch_triple_aliases.appendSliceAssumeCapacity(&SPARCv8Triples); + }, + .s390x => { + lib_dirs.appendSliceAssumeCapacity(&SystemZLibDirs); + triple_aliases.appendSliceAssumeCapacity(&SystemZTriples); + }, + else => {}, + } +} + +pub fn discover(self: *GCCDetector, tc: *Toolchain) !void { + var path_buf: [std.fs.max_path_bytes]u8 = undefined; + var fib = std.heap.FixedBufferAllocator.init(&path_buf); + + const target = tc.getTarget(); + const biarch_variant_target = if (target.ptrBitWidth() == 32) + target_util.get64BitArchVariant(target) + else + target_util.get32BitArchVariant(target); + + var candidate_lib_dirs_buffer: [16][]const u8 = undefined; + var candidate_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_lib_dirs_buffer); + + var candidate_triple_aliases_buffer: [16][]const u8 = undefined; + var candidate_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_triple_aliases_buffer); + + var candidate_biarch_lib_dirs_buffer: [16][]const u8 = undefined; + var candidate_biarch_lib_dirs = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_lib_dirs_buffer); + + var candidate_biarch_triple_aliases_buffer: [16][]const u8 = undefined; + var candidate_biarch_triple_aliases = std.ArrayListUnmanaged([]const u8).initBuffer(&candidate_biarch_triple_aliases_buffer); + + try collectLibDirsAndTriples( + tc, + &candidate_lib_dirs, + &candidate_triple_aliases, + &candidate_biarch_lib_dirs, + &candidate_biarch_triple_aliases, + ); + + var target_buf: [64]u8 = undefined; + const triple_str = target_util.toLLVMTriple(target, &target_buf); + candidate_triple_aliases.appendAssumeCapacity(triple_str); + + // Also include the multiarch variant if it's different. + var biarch_buf: [64]u8 = undefined; + if (biarch_variant_target) |biarch_target| { + const biarch_triple_str = target_util.toLLVMTriple(biarch_target, &biarch_buf); + if (!std.mem.eql(u8, biarch_triple_str, triple_str)) { + candidate_triple_aliases.appendAssumeCapacity(biarch_triple_str); + } + } + + var prefixes_buf: [16][]const u8 = undefined; + var prefixes = std.ArrayListUnmanaged([]const u8).initBuffer(&prefixes_buf); + const gcc_toolchain_dir = gccToolchainDir(tc); + if (gcc_toolchain_dir.len != 0) { + const adjusted = if (gcc_toolchain_dir[gcc_toolchain_dir.len - 1] == '/') + gcc_toolchain_dir[0 .. gcc_toolchain_dir.len - 1] + else + gcc_toolchain_dir; + prefixes.appendAssumeCapacity(adjusted); + } else { + const sysroot = tc.getSysroot(); + if (sysroot.len > 0) { + prefixes.appendAssumeCapacity(sysroot); + try addDefaultGCCPrefixes(&prefixes, tc); + } + + if (sysroot.len == 0) { + try addDefaultGCCPrefixes(&prefixes, tc); + } + // TODO: Special-case handling for Gentoo + } + + const v0 = GCCVersion.parse("0.0.0"); + for (prefixes.items) |prefix| { + if (!tc.filesystem.exists(prefix)) continue; + + for (candidate_lib_dirs.items) |suffix| { + defer fib.reset(); + const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue; + if (!tc.filesystem.exists(lib_dir)) continue; + + const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" }); + const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" }); + + try self.scanLibDirForGCCTriple(tc, target, lib_dir, triple_str, false, gcc_dir_exists, gcc_cross_dir_exists); + for (candidate_triple_aliases.items) |candidate| { + try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, false, gcc_dir_exists, gcc_cross_dir_exists); + } + } + for (candidate_biarch_lib_dirs.items) |suffix| { + const lib_dir = std.fs.path.join(fib.allocator(), &.{ prefix, suffix }) catch continue; + if (!tc.filesystem.exists(lib_dir)) continue; + + const gcc_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc" }); + const gcc_cross_dir_exists = tc.filesystem.joinedExists(&.{ lib_dir, "/gcc-cross" }); + for (candidate_biarch_triple_aliases.items) |candidate| { + try self.scanLibDirForGCCTriple(tc, target, lib_dir, candidate, true, gcc_dir_exists, gcc_cross_dir_exists); + } + } + if (self.version.order(v0) == .gt) break; + } +} + +fn findBiarchMultilibs( + tc: *const Toolchain, + result: *Multilib.Detected, + target: std.Target, + path: [2][]const u8, + needs_biarch_suffix: bool, +) !bool { + const suff64 = if (target.os.tag == .solaris) switch (target.cpu.arch) { + .x86, .x86_64 => "/amd64", + .sparc => "/sparcv9", + else => "/64", + } else "/64"; + + const alt_64 = Multilib.init(suff64, suff64, &.{ "-m32", "+m64", "-mx32" }); + const alt_32 = Multilib.init("/32", "/32", &.{ "+m32", "-m64", "-mx32" }); + const alt_x32 = Multilib.init("/x32", "/x32", &.{ "-m32", "-m64", "+mx32" }); + + const multilib_filter = Multilib.Filter{ + .base = path, + .file = if (target.os.tag == .elfiamcu) "libgcc.a" else "crtbegin.o", + }; + + const Want = enum { + want32, + want64, + wantx32, + }; + const is_x32 = target.abi == .gnux32 or target.abi == .muslx32; + const target_ptr_width = target.ptrBitWidth(); + const want: Want = if (target_ptr_width == 32 and multilib_filter.exists(alt_32, tc.filesystem)) + .want64 + else if (target_ptr_width == 64 and is_x32 and multilib_filter.exists(alt_x32, tc.filesystem)) + .want64 + else if (target_ptr_width == 64 and !is_x32 and multilib_filter.exists(alt_64, tc.filesystem)) + .want32 + else if (target_ptr_width == 32) + if (needs_biarch_suffix) .want64 else .want32 + else if (is_x32) + if (needs_biarch_suffix) .want64 else .wantx32 + else if (needs_biarch_suffix) .want32 else .want64; + + const default = switch (want) { + .want32 => Multilib.init("", "", &.{ "+m32", "-m64", "-mx32" }), + .want64 => Multilib.init("", "", &.{ "-m32", "+m64", "-mx32" }), + .wantx32 => Multilib.init("", "", &.{ "-m32", "-m64", "+mx32" }), + }; + result.multilibs.appendSliceAssumeCapacity(&.{ + default, + alt_64, + alt_32, + alt_x32, + }); + result.filter(multilib_filter, tc.filesystem); + var flags: Multilib.Flags = .{}; + flags.appendAssumeCapacity(if (target_ptr_width == 64 and !is_x32) "+m64" else "-m64"); + flags.appendAssumeCapacity(if (target_ptr_width == 32) "+m32" else "-m32"); + flags.appendAssumeCapacity(if (target_ptr_width == 64 and is_x32) "+mx32" else "-mx32"); + + return result.select(flags); +} + +fn scanGCCForMultilibs( + self: *GCCDetector, + tc: *const Toolchain, + target: std.Target, + path: [2][]const u8, + needs_biarch_suffix: bool, +) !bool { + var detected: Multilib.Detected = .{}; + if (target.cpu.arch == .csky) { + // TODO + } else if (target.cpu.arch.isMIPS()) { + // TODO + } else if (target.cpu.arch.isRISCV()) { + // TODO + } else if (target.cpu.arch == .msp430) { + // TODO + } else if (target.cpu.arch == .avr) { + // No multilibs + } else if (!try findBiarchMultilibs(tc, &detected, target, path, needs_biarch_suffix)) { + return false; + } + self.selected = detected.selected; + self.biarch_sibling = detected.biarch_sibling; + return true; +} + +fn scanLibDirForGCCTriple( + self: *GCCDetector, + tc: *const Toolchain, + target: std.Target, + lib_dir: []const u8, + candidate_triple: []const u8, + needs_biarch_suffix: bool, + gcc_dir_exists: bool, + gcc_cross_dir_exists: bool, +) !void { + var path_buf: [std.fs.max_path_bytes]u8 = undefined; + var fib = std.heap.FixedBufferAllocator.init(&path_buf); + for (0..2) |i| { + if (i == 0 and !gcc_dir_exists) continue; + if (i == 1 and !gcc_cross_dir_exists) continue; + defer fib.reset(); + + const base: []const u8 = if (i == 0) "gcc" else "gcc-cross"; + var lib_suffix_buf: [64]u8 = undefined; + var suffix_buf_fib = std.heap.FixedBufferAllocator.init(&lib_suffix_buf); + const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue; + + const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue; + var parent_dir = tc.filesystem.openDir(dir_name) catch continue; + defer parent_dir.close(); + + var it = parent_dir.iterate(); + while (it.next() catch continue) |entry| { + if (entry.kind != .directory) continue; + + const version_text = entry.name; + const candidate_version = GCCVersion.parse(version_text); + if (candidate_version.major != -1) { + // TODO: cache path so we're not repeatedly scanning + } + if (candidate_version.isLessThan(4, 1, 1, "")) continue; + switch (candidate_version.order(self.version)) { + .lt, .eq => continue, + .gt => {}, + } + + if (!try self.scanGCCForMultilibs(tc, target, .{ dir_name, version_text }, needs_biarch_suffix)) continue; + + self.version = candidate_version; + self.gcc_triple = try tc.arena.dupe(u8, candidate_triple); + self.install_path = try std.fs.path.join(tc.arena, &.{ lib_dir, lib_suffix, version_text }); + self.parent_lib_path = try std.fs.path.join(tc.arena, &.{ self.install_path, "..", "..", ".." }); + self.is_valid = true; + } + } +} + +fn gccToolchainDir(tc: *const Toolchain) []const u8 { + const sysroot = tc.getSysroot(); + if (sysroot.len != 0) return ""; + return system_defaults.gcc_install_prefix; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/GCCVersion.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/GCCVersion.zig new file mode 100644 index 00000000..a9bdb470 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/GCCVersion.zig @@ -0,0 +1,132 @@ +const std = @import("std"); +const mem = std.mem; +const Order = std.math.Order; + +const GCCVersion = @This(); + +/// Raw version number text +raw: []const u8 = "", + +/// -1 indicates not present +major: i32 = -1, +/// -1 indicates not present +minor: i32 = -1, +/// -1 indicates not present +patch: i32 = -1, + +/// Text of parsed major version number +major_str: []const u8 = "", +/// Text of parsed major + minor version number +minor_str: []const u8 = "", + +/// Patch number suffix +suffix: []const u8 = "", + +/// This orders versions according to the preferred usage order, not a notion of release-time ordering +/// Higher version numbers are preferred, but nonexistent minor/patch/suffix is preferred to one that does exist +/// e.g. `4.1` is preferred over `4.0` but `4` is preferred over both `4.0` and `4.1` +pub fn isLessThan(self: GCCVersion, rhs_major: i32, rhs_minor: i32, rhs_patch: i32, rhs_suffix: []const u8) bool { + if (self.major != rhs_major) { + return self.major < rhs_major; + } + if (self.minor != rhs_minor) { + if (rhs_minor == -1) return true; + if (self.minor == -1) return false; + return self.minor < rhs_minor; + } + if (self.patch != rhs_patch) { + if (rhs_patch == -1) return true; + if (self.patch == -1) return false; + return self.patch < rhs_patch; + } + if (!mem.eql(u8, self.suffix, rhs_suffix)) { + if (rhs_suffix.len == 0) return true; + if (self.suffix.len == 0) return false; + return switch (std.mem.order(u8, self.suffix, rhs_suffix)) { + .lt => true, + .eq => unreachable, + .gt => false, + }; + } + return false; +} + +/// Strings in the returned GCCVersion struct have the same lifetime as `text` +pub fn parse(text: []const u8) GCCVersion { + const bad = GCCVersion{ .major = -1 }; + var good = bad; + + var it = mem.splitScalar(u8, text, '.'); + const first = it.next().?; + const second = it.next() orelse ""; + const rest = it.next() orelse ""; + + good.major = std.fmt.parseInt(i32, first, 10) catch return bad; + if (good.major < 0) return bad; + good.major_str = first; + + if (second.len == 0) return good; + var minor_str = second; + + if (rest.len == 0) { + const end = mem.indexOfNone(u8, minor_str, "0123456789") orelse minor_str.len; + if (end > 0) { + good.suffix = minor_str[end..]; + minor_str = minor_str[0..end]; + } + } + good.minor = std.fmt.parseInt(i32, minor_str, 10) catch return bad; + if (good.minor < 0) return bad; + good.minor_str = minor_str; + + if (rest.len > 0) { + const end = mem.indexOfNone(u8, rest, "0123456789") orelse rest.len; + if (end > 0) { + const patch_num_text = rest[0..end]; + good.patch = std.fmt.parseInt(i32, patch_num_text, 10) catch return bad; + if (good.patch < 0) return bad; + good.suffix = rest[end..]; + } + } + + return good; +} + +pub fn order(a: GCCVersion, b: GCCVersion) Order { + if (a.isLessThan(b.major, b.minor, b.patch, b.suffix)) return .lt; + if (b.isLessThan(a.major, a.minor, a.patch, a.suffix)) return .gt; + return .eq; +} + +/// Used for determining __GNUC__ macro values +/// This matches clang's logic for overflowing values +pub fn toUnsigned(self: GCCVersion) u32 { + var result: u32 = 0; + if (self.major > 0) result = @as(u32, @intCast(self.major)) *% 10_000; + if (self.minor > 0) result +%= @as(u32, @intCast(self.minor)) *% 100; + if (self.patch > 0) result +%= @as(u32, @intCast(self.patch)); + return result; +} + +test parse { + const versions = [10]GCCVersion{ + parse("5"), + parse("4"), + parse("4.2"), + parse("4.0"), + parse("4.0-patched"), + parse("4.0.2"), + parse("4.0.1"), + parse("4.0.1-patched"), + parse("4.0.0"), + parse("4.0.0-patched"), + }; + + for (versions[0 .. versions.len - 1], versions[1..versions.len]) |first, second| { + try std.testing.expectEqual(Order.eq, first.order(first)); + try std.testing.expectEqual(Order.gt, first.order(second)); + try std.testing.expectEqual(Order.lt, second.order(first)); + } + const last = versions[versions.len - 1]; + try std.testing.expectEqual(Order.eq, last.order(last)); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Multilib.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Multilib.zig new file mode 100644 index 00000000..1486cf47 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Driver/Multilib.zig @@ -0,0 +1,71 @@ +const std = @import("std"); +const Filesystem = @import("Filesystem.zig").Filesystem; + +pub const Flags = std.BoundedArray([]const u8, 6); + +/// Large enough for GCCDetector for Linux; may need to be increased to support other toolchains. +const max_multilibs = 4; + +const MultilibArray = std.BoundedArray(Multilib, max_multilibs); + +pub const Detected = struct { + multilibs: MultilibArray = .{}, + selected: Multilib = .{}, + biarch_sibling: ?Multilib = null, + + pub fn filter(self: *Detected, multilib_filter: Filter, fs: Filesystem) void { + var found_count: usize = 0; + for (self.multilibs.constSlice()) |multilib| { + if (multilib_filter.exists(multilib, fs)) { + self.multilibs.set(found_count, multilib); + found_count += 1; + } + } + self.multilibs.resize(found_count) catch unreachable; + } + + pub fn select(self: *Detected, flags: Flags) !bool { + var filtered: MultilibArray = .{}; + for (self.multilibs.constSlice()) |multilib| { + for (multilib.flags.constSlice()) |multilib_flag| { + const matched = for (flags.constSlice()) |arg_flag| { + if (std.mem.eql(u8, arg_flag[1..], multilib_flag[1..])) break arg_flag; + } else multilib_flag; + if (matched[0] != multilib_flag[0]) break; + } else { + filtered.appendAssumeCapacity(multilib); + } + } + if (filtered.len == 0) return false; + if (filtered.len == 1) { + self.selected = filtered.get(0); + return true; + } + return error.TooManyMultilibs; + } +}; + +pub const Filter = struct { + base: [2][]const u8, + file: []const u8, + pub fn exists(self: Filter, m: Multilib, fs: Filesystem) bool { + return fs.joinedExists(&.{ self.base[0], self.base[1], m.gcc_suffix, self.file }); + } +}; + +const Multilib = @This(); + +gcc_suffix: []const u8 = "", +os_suffix: []const u8 = "", +include_suffix: []const u8 = "", +flags: Flags = .{}, +priority: u32 = 0, + +pub fn init(gcc_suffix: []const u8, os_suffix: []const u8, flags: []const []const u8) Multilib { + var self: Multilib = .{ + .gcc_suffix = gcc_suffix, + .os_suffix = os_suffix, + }; + self.flags.appendSliceAssumeCapacity(flags); + return self; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Hideset.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Hideset.zig new file mode 100644 index 00000000..98712e41 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Hideset.zig @@ -0,0 +1,196 @@ +//! A hideset is a linked list (implemented as an array so that elements are identified by 4-byte indices) +//! of the set of identifiers from which a token was expanded. +//! During macro expansion, if a token would otherwise be expanded, but its hideset contains +//! the token itself, then it is not expanded +//! Most tokens have an empty hideset, and the hideset is not needed once expansion is complete, +//! so we use a hash map to store them instead of directly storing them with the token. +//! The C standard underspecifies the algorithm for updating a token's hideset; +//! we use the one here: https://www.spinellis.gr/blog/20060626/cpp.algo.pdf + +const std = @import("std"); +const mem = std.mem; +const Allocator = mem.Allocator; +const Source = @import("Source.zig"); +const Compilation = @import("Compilation.zig"); +const Tokenizer = @import("Tokenizer.zig"); + +pub const Hideset = @This(); + +const Identifier = struct { + id: Source.Id = .unused, + byte_offset: u32 = 0, + + fn slice(self: Identifier, comp: *const Compilation) []const u8 { + var tmp_tokenizer = Tokenizer{ + .buf = comp.getSource(self.id).buf, + .langopts = comp.langopts, + .index = self.byte_offset, + .source = .generated, + }; + const res = tmp_tokenizer.next(); + return tmp_tokenizer.buf[res.start..res.end]; + } + + fn fromLocation(loc: Source.Location) Identifier { + return .{ + .id = loc.id, + .byte_offset = loc.byte_offset, + }; + } +}; + +const Item = struct { + identifier: Identifier = .{}, + next: Index = .none, + + const List = std.MultiArrayList(Item); +}; + +pub const Index = enum(u32) { + none = std.math.maxInt(u32), + _, +}; + +map: std.AutoHashMapUnmanaged(Identifier, Index) = .empty, +/// Used for computing union/intersection of two lists; stored here so that allocations can be retained +/// until hideset is deinit'ed +tmp_map: std.AutoHashMapUnmanaged(Identifier, void) = .empty, +linked_list: Item.List = .{}, +comp: *const Compilation, + +/// Invalidated if the underlying MultiArrayList slice is reallocated due to resize +const Iterator = struct { + slice: Item.List.Slice, + i: Index, + + fn next(self: *Iterator) ?Identifier { + if (self.i == .none) return null; + defer self.i = self.slice.items(.next)[@intFromEnum(self.i)]; + return self.slice.items(.identifier)[@intFromEnum(self.i)]; + } +}; + +pub fn deinit(self: *Hideset) void { + self.map.deinit(self.comp.gpa); + self.tmp_map.deinit(self.comp.gpa); + self.linked_list.deinit(self.comp.gpa); +} + +pub fn clearRetainingCapacity(self: *Hideset) void { + self.linked_list.shrinkRetainingCapacity(0); + self.map.clearRetainingCapacity(); +} + +pub fn clearAndFree(self: *Hideset) void { + self.map.clearAndFree(self.comp.gpa); + self.tmp_map.clearAndFree(self.comp.gpa); + self.linked_list.shrinkAndFree(self.comp.gpa, 0); +} + +/// Iterator is invalidated if the underlying MultiArrayList slice is reallocated due to resize +fn iterator(self: *const Hideset, idx: Index) Iterator { + return Iterator{ + .slice = self.linked_list.slice(), + .i = idx, + }; +} + +pub fn get(self: *const Hideset, loc: Source.Location) Index { + return self.map.get(Identifier.fromLocation(loc)) orelse .none; +} + +pub fn put(self: *Hideset, loc: Source.Location, value: Index) !void { + try self.map.put(self.comp.gpa, Identifier.fromLocation(loc), value); +} + +fn ensureUnusedCapacity(self: *Hideset, new_size: usize) !void { + try self.linked_list.ensureUnusedCapacity(self.comp.gpa, new_size); +} + +/// Creates a one-item list with contents `identifier` +fn createNodeAssumeCapacity(self: *Hideset, identifier: Identifier) Index { + return self.createNodeAssumeCapacityExtra(identifier, .none); +} + +/// Creates a one-item list with contents `identifier` +fn createNodeAssumeCapacityExtra(self: *Hideset, identifier: Identifier, next: Index) Index { + const next_idx = self.linked_list.len; + self.linked_list.appendAssumeCapacity(.{ .identifier = identifier, .next = next }); + return @enumFromInt(next_idx); +} + +/// Create a new list with `identifier` at the front followed by `tail` +pub fn prepend(self: *Hideset, loc: Source.Location, tail: Index) !Index { + const new_idx = self.linked_list.len; + try self.linked_list.append(self.comp.gpa, .{ .identifier = Identifier.fromLocation(loc), .next = tail }); + return @enumFromInt(new_idx); +} + +/// Attach elements of `b` to the front of `a` (if they're not in `a`) +pub fn @"union"(self: *Hideset, a: Index, b: Index) !Index { + if (a == .none) return b; + if (b == .none) return a; + self.tmp_map.clearRetainingCapacity(); + + var it = self.iterator(b); + while (it.next()) |identifier| { + try self.tmp_map.put(self.comp.gpa, identifier, {}); + } + + var head: Index = b; + try self.ensureUnusedCapacity(self.len(a)); + it = self.iterator(a); + while (it.next()) |identifier| { + if (!self.tmp_map.contains(identifier)) { + head = self.createNodeAssumeCapacityExtra(identifier, head); + } + } + return head; +} + +pub fn contains(self: *const Hideset, list: Index, str: []const u8) bool { + var it = self.iterator(list); + while (it.next()) |identifier| { + if (mem.eql(u8, str, identifier.slice(self.comp))) return true; + } + return false; +} + +fn len(self: *const Hideset, list: Index) usize { + const nexts = self.linked_list.items(.next); + var cur = list; + var count: usize = 0; + while (cur != .none) : (count += 1) { + cur = nexts[@intFromEnum(cur)]; + } + return count; +} + +pub fn intersection(self: *Hideset, a: Index, b: Index) !Index { + if (a == .none or b == .none) return .none; + self.tmp_map.clearRetainingCapacity(); + + var cur: Index = .none; + var head: Index = .none; + var it = self.iterator(a); + var a_len: usize = 0; + while (it.next()) |identifier| : (a_len += 1) { + try self.tmp_map.put(self.comp.gpa, identifier, {}); + } + try self.ensureUnusedCapacity(@min(a_len, self.len(b))); + + it = self.iterator(b); + while (it.next()) |identifier| { + if (self.tmp_map.contains(identifier)) { + const new_idx = self.createNodeAssumeCapacity(identifier); + if (head == .none) { + head = new_idx; + } + if (cur != .none) { + self.linked_list.items(.next)[@intFromEnum(cur)] = new_idx; + } + cur = new_idx; + } + } + return head; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/InitList.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/InitList.zig new file mode 100644 index 00000000..5a576521 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/InitList.zig @@ -0,0 +1,153 @@ +//! Sparsely populated list of used indexes. +//! Used for detecting duplicate initializers. +const std = @import("std"); +const Allocator = std.mem.Allocator; +const testing = std.testing; +const Tree = @import("Tree.zig"); +const Token = Tree.Token; +const TokenIndex = Tree.TokenIndex; +const NodeIndex = Tree.NodeIndex; +const Type = @import("Type.zig"); +const Diagnostics = @import("Diagnostics.zig"); +const NodeList = std.ArrayList(NodeIndex); +const Parser = @import("Parser.zig"); + +const Item = struct { + list: InitList = .{}, + index: u64, + + fn order(_: void, a: Item, b: Item) std.math.Order { + return std.math.order(a.index, b.index); + } +}; + +const InitList = @This(); + +list: std.ArrayListUnmanaged(Item) = .empty, +node: NodeIndex = .none, +tok: TokenIndex = 0, + +/// Deinitialize freeing all memory. +pub fn deinit(il: *InitList, gpa: Allocator) void { + for (il.list.items) |*item| item.list.deinit(gpa); + il.list.deinit(gpa); + il.* = undefined; +} + +/// Insert initializer at index, returning previous entry if one exists. +pub fn put(il: *InitList, gpa: Allocator, index: usize, node: NodeIndex, tok: TokenIndex) !?TokenIndex { + const items = il.list.items; + var left: usize = 0; + var right: usize = items.len; + + // Append new value to empty list + if (left == right) { + const item = try il.list.addOne(gpa); + item.* = .{ + .list = .{ .node = node, .tok = tok }, + .index = index, + }; + return null; + } + + while (left < right) { + // Avoid overflowing in the midpoint calculation + const mid = left + (right - left) / 2; + // Compare the key with the midpoint element + switch (std.math.order(index, items[mid].index)) { + .eq => { + // Replace previous entry. + const prev = items[mid].list.tok; + items[mid].list.deinit(gpa); + items[mid] = .{ + .list = .{ .node = node, .tok = tok }, + .index = index, + }; + return prev; + }, + .gt => left = mid + 1, + .lt => right = mid, + } + } + + // Insert a new value into a sorted position. + try il.list.insert(gpa, left, .{ + .list = .{ .node = node, .tok = tok }, + .index = index, + }); + return null; +} + +/// Find item at index, create new if one does not exist. +pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList { + const items = il.list.items; + var left: usize = 0; + var right: usize = items.len; + + // Append new value to empty list + if (left == right) { + const item = try il.list.addOne(gpa); + item.* = .{ + .list = .{ .node = .none, .tok = 0 }, + .index = index, + }; + return &item.list; + } + + while (left < right) { + // Avoid overflowing in the midpoint calculation + const mid = left + (right - left) / 2; + // Compare the key with the midpoint element + switch (std.math.order(index, items[mid].index)) { + .eq => return &items[mid].list, + .gt => left = mid + 1, + .lt => right = mid, + } + } + + // Insert a new value into a sorted position. + try il.list.insert(gpa, left, .{ + .list = .{ .node = .none, .tok = 0 }, + .index = index, + }); + return &il.list.items[left].list; +} + +test "basic usage" { + const gpa = testing.allocator; + var il: InitList = .{}; + defer il.deinit(gpa); + + { + var i: usize = 0; + while (i < 5) : (i += 1) { + const prev = try il.put(gpa, i, .none, 0); + try testing.expect(prev == null); + } + } + + { + const failing = testing.failing_allocator; + var i: usize = 0; + while (i < 5) : (i += 1) { + _ = try il.find(failing, i); + } + } + + { + var item = try il.find(gpa, 0); + var i: usize = 1; + while (i < 5) : (i += 1) { + item = try item.find(gpa, i); + } + } + + { + const failing = testing.failing_allocator; + var item = try il.find(failing, 0); + var i: usize = 1; + while (i < 5) : (i += 1) { + item = try item.find(failing, i); + } + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/LangOpts.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/LangOpts.zig new file mode 100644 index 00000000..e7b2ebf6 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/LangOpts.zig @@ -0,0 +1,176 @@ +const std = @import("std"); +const DiagnosticTag = @import("Diagnostics.zig").Tag; +const char_info = @import("char_info.zig"); + +pub const Compiler = enum { + clang, + gcc, + msvc, +}; + +/// The floating-point evaluation method for intermediate results within a single expression +pub const FPEvalMethod = enum(i8) { + /// The evaluation method cannot be determined or is inconsistent for this target. + indeterminate = -1, + /// Use the type declared in the source + source = 0, + /// Use double as the floating-point evaluation method for all float expressions narrower than double. + double = 1, + /// Use long double as the floating-point evaluation method for all float expressions narrower than long double. + extended = 2, +}; + +pub const Standard = enum { + /// ISO C 1990 + c89, + /// ISO C 1990 with amendment 1 + iso9899, + /// ISO C 1990 with GNU extensions + gnu89, + /// ISO C 1999 + c99, + /// ISO C 1999 with GNU extensions + gnu99, + /// ISO C 2011 + c11, + /// ISO C 2011 with GNU extensions + gnu11, + /// ISO C 2017 + c17, + /// Default value if nothing specified; adds the GNU keywords to + /// C17 but does not suppress warnings about using GNU extensions + default, + /// ISO C 2017 with GNU extensions + gnu17, + /// Working Draft for ISO C23 + c23, + /// Working Draft for ISO C23 with GNU extensions + gnu23, + + const NameMap = std.StaticStringMap(Standard).initComptime(.{ + .{ "c89", .c89 }, .{ "c90", .c89 }, .{ "iso9899:1990", .c89 }, + .{ "iso9899:199409", .iso9899 }, .{ "gnu89", .gnu89 }, .{ "gnu90", .gnu89 }, + .{ "c99", .c99 }, .{ "iso9899:1999", .c99 }, .{ "c9x", .c99 }, + .{ "iso9899:199x", .c99 }, .{ "gnu99", .gnu99 }, .{ "gnu9x", .gnu99 }, + .{ "c11", .c11 }, .{ "iso9899:2011", .c11 }, .{ "c1x", .c11 }, + .{ "iso9899:201x", .c11 }, .{ "gnu11", .gnu11 }, .{ "c17", .c17 }, + .{ "iso9899:2017", .c17 }, .{ "c18", .c17 }, .{ "iso9899:2018", .c17 }, + .{ "gnu17", .gnu17 }, .{ "gnu18", .gnu17 }, .{ "c23", .c23 }, + .{ "gnu23", .gnu23 }, .{ "c2x", .c23 }, .{ "gnu2x", .gnu23 }, + }); + + pub fn atLeast(self: Standard, other: Standard) bool { + return @intFromEnum(self) >= @intFromEnum(other); + } + + pub fn isGNU(standard: Standard) bool { + return switch (standard) { + .gnu89, .gnu99, .gnu11, .default, .gnu17, .gnu23 => true, + else => false, + }; + } + + pub fn isExplicitGNU(standard: Standard) bool { + return standard.isGNU() and standard != .default; + } + + /// Value reported by __STDC_VERSION__ macro + pub fn StdCVersionMacro(standard: Standard) ?[]const u8 { + return switch (standard) { + .c89, .gnu89 => null, + .iso9899 => "199409L", + .c99, .gnu99 => "199901L", + .c11, .gnu11 => "201112L", + .default, .c17, .gnu17 => "201710L", + .c23, .gnu23 => "202311L", + }; + } + + pub fn codepointAllowedInIdentifier(standard: Standard, codepoint: u21, is_start: bool) bool { + if (is_start) { + return if (standard.atLeast(.c23)) + char_info.isXidStart(codepoint) + else if (standard.atLeast(.c11)) + char_info.isC11IdChar(codepoint) and !char_info.isC11DisallowedInitialIdChar(codepoint) + else + char_info.isC99IdChar(codepoint) and !char_info.isC99DisallowedInitialIDChar(codepoint); + } else { + return if (standard.atLeast(.c23)) + char_info.isXidContinue(codepoint) + else if (standard.atLeast(.c11)) + char_info.isC11IdChar(codepoint) + else + char_info.isC99IdChar(codepoint); + } + } +}; + +const LangOpts = @This(); + +emulate: Compiler = .clang, +standard: Standard = .default, +/// -fshort-enums option, makes enums only take up as much space as they need to hold all the values. +short_enums: bool = false, +dollars_in_identifiers: bool = true, +declspec_attrs: bool = false, +ms_extensions: bool = false, +/// true or false if digraph support explicitly enabled/disabled with -fdigraphs/-fno-digraphs +digraphs: ?bool = null, +/// If set, use the native half type instead of promoting to float +use_native_half_type: bool = false, +/// If set, function arguments and return values may be of type __fp16 even if there is no standard ABI for it +allow_half_args_and_returns: bool = false, +/// null indicates that the user did not select a value, use target to determine default +fp_eval_method: ?FPEvalMethod = null, +/// If set, use specified signedness for `char` instead of the target's default char signedness +char_signedness_override: ?std.builtin.Signedness = null, +/// If set, override the default availability of char8_t (by default, enabled in C23 and later; disabled otherwise) +has_char8_t_override: ?bool = null, + +/// Whether to allow GNU-style inline assembly +gnu_asm: bool = true, + +/// Preserve comments when preprocessing +preserve_comments: bool = false, +/// Preserve comments in macros when preprocessing +preserve_comments_in_macros: bool = false, + +/// Used ONLY for generating __GNUC__ and related macros. Does not control the presence/absence of any features +/// Encoded as major * 10,000 + minor * 100 + patch +/// e.g. 4.2.1 == 40201 +gnuc_version: u32 = 0, + +pub fn setStandard(self: *LangOpts, name: []const u8) error{InvalidStandard}!void { + self.standard = Standard.NameMap.get(name) orelse return error.InvalidStandard; +} + +pub fn enableMSExtensions(self: *LangOpts) void { + self.declspec_attrs = true; + self.ms_extensions = true; +} + +pub fn disableMSExtensions(self: *LangOpts) void { + self.declspec_attrs = false; + self.ms_extensions = true; +} + +pub fn hasChar8_T(self: *const LangOpts) bool { + return self.has_char8_t_override orelse self.standard.atLeast(.c23); +} + +pub fn hasDigraphs(self: *const LangOpts) bool { + return self.digraphs orelse self.standard.atLeast(.gnu89); +} + +pub fn setEmulatedCompiler(self: *LangOpts, compiler: Compiler) void { + self.emulate = compiler; + if (compiler == .msvc) self.enableMSExtensions(); +} + +pub fn setFpEvalMethod(self: *LangOpts, fp_eval_method: FPEvalMethod) void { + self.fp_eval_method = fp_eval_method; +} + +pub fn setCharSignedness(self: *LangOpts, signedness: std.builtin.Signedness) void { + self.char_signedness_override = signedness; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Parser.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Parser.zig new file mode 100644 index 00000000..83274698 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Parser.zig @@ -0,0 +1,8891 @@ +const std = @import("std"); +const mem = std.mem; +const Allocator = mem.Allocator; +const assert = std.debug.assert; +const big = std.math.big; +const Compilation = @import("Compilation.zig"); +const Source = @import("Source.zig"); +const Tokenizer = @import("Tokenizer.zig"); +const Preprocessor = @import("Preprocessor.zig"); +const Tree = @import("Tree.zig"); +const Token = Tree.Token; +const NumberPrefix = Token.NumberPrefix; +const NumberSuffix = Token.NumberSuffix; +const TokenIndex = Tree.TokenIndex; +const NodeIndex = Tree.NodeIndex; +const Type = @import("Type.zig"); +const Diagnostics = @import("Diagnostics.zig"); +const NodeList = std.ArrayList(NodeIndex); +const InitList = @import("InitList.zig"); +const Attribute = @import("Attribute.zig"); +const char_info = @import("char_info.zig"); +const text_literal = @import("text_literal.zig"); +const Value = @import("Value.zig"); +const SymbolStack = @import("SymbolStack.zig"); +const Symbol = SymbolStack.Symbol; +const record_layout = @import("record_layout.zig"); +const StrInt = @import("StringInterner.zig"); +const StringId = StrInt.StringId; +const Builtins = @import("Builtins.zig"); +const Builtin = Builtins.Builtin; +const evalBuiltin = @import("Builtins/eval.zig").eval; +const target_util = @import("target.zig"); + +const Switch = struct { + default: ?TokenIndex = null, + ranges: std.ArrayList(Range), + ty: Type, + comp: *Compilation, + + const Range = struct { + first: Value, + last: Value, + tok: TokenIndex, + }; + + fn add(self: *Switch, first: Value, last: Value, tok: TokenIndex) !?Range { + for (self.ranges.items) |range| { + if (last.compare(.gte, range.first, self.comp) and first.compare(.lte, range.last, self.comp)) { + return range; // They overlap. + } + } + try self.ranges.append(.{ + .first = first, + .last = last, + .tok = tok, + }); + return null; + } +}; + +const Label = union(enum) { + unresolved_goto: TokenIndex, + label: TokenIndex, +}; + +pub const Error = Compilation.Error || error{ParsingFailed}; + +/// An attribute that has been parsed but not yet validated in its context +const TentativeAttribute = struct { + attr: Attribute, + tok: TokenIndex, +}; + +/// How the parser handles const int decl references when it is expecting an integer +/// constant expression. +const ConstDeclFoldingMode = enum { + /// fold const decls as if they were literals + fold_const_decls, + /// fold const decls as if they were literals and issue GNU extension diagnostic + gnu_folding_extension, + /// fold const decls as if they were literals and issue VLA diagnostic + gnu_vla_folding_extension, + /// folding const decls is prohibited; return an unavailable value + no_const_decl_folding, +}; + +const Parser = @This(); + +// values from preprocessor +pp: *Preprocessor, +comp: *Compilation, +gpa: mem.Allocator, +tok_ids: []const Token.Id, +tok_i: TokenIndex = 0, + +// values of the incomplete Tree +arena: Allocator, +nodes: Tree.Node.List = .{}, +data: NodeList, +value_map: Tree.ValueMap, + +// buffers used during compilation +syms: SymbolStack = .{}, +strings: std.ArrayListAligned(u8, 4), +labels: std.ArrayList(Label), +list_buf: NodeList, +decl_buf: NodeList, +param_buf: std.ArrayList(Type.Func.Param), +enum_buf: std.ArrayList(Type.Enum.Field), +record_buf: std.ArrayList(Type.Record.Field), +attr_buf: std.MultiArrayList(TentativeAttribute) = .{}, +attr_application_buf: std.ArrayListUnmanaged(Attribute) = .empty, +field_attr_buf: std.ArrayList([]const Attribute), +/// type name -> variable name location for tentative definitions (top-level defs with thus-far-incomplete types) +/// e.g. `struct Foo bar;` where `struct Foo` is not defined yet. +/// The key is the StringId of `Foo` and the value is the TokenIndex of `bar` +/// Items are removed if the type is subsequently completed with a definition. +/// We only store the first tentative definition that uses a given type because this map is only used +/// for issuing an error message, and correcting the first error for a type will fix all of them for that type. +tentative_defs: std.AutoHashMapUnmanaged(StringId, TokenIndex) = .empty, + +// configuration and miscellaneous info +no_eval: bool = false, +in_macro: bool = false, +extension_suppressed: bool = false, +contains_address_of_label: bool = false, +label_count: u32 = 0, +const_decl_folding: ConstDeclFoldingMode = .fold_const_decls, +/// location of first computed goto in function currently being parsed +/// if a computed goto is used, the function must contain an +/// address-of-label expression (tracked with contains_address_of_label) +computed_goto_tok: ?TokenIndex = null, + +/// __auto_type may only be used with a single declarator. Keep track of the name +/// so that it is not used in its own initializer. +auto_type_decl_name: StringId = .empty, + +/// Various variables that are different for each function. +func: struct { + /// null if not in function, will always be plain func, var_args_func or old_style_func + ty: ?Type = null, + name: TokenIndex = 0, + ident: ?Result = null, + pretty_ident: ?Result = null, +} = .{}, +/// Various variables that are different for each record. +record: struct { + // invalid means we're not parsing a record + kind: Token.Id = .invalid, + flexible_field: ?TokenIndex = null, + start: usize = 0, + field_attr_start: usize = 0, + + fn addField(r: @This(), p: *Parser, name: StringId, tok: TokenIndex) Error!void { + var i = p.record_members.items.len; + while (i > r.start) { + i -= 1; + if (p.record_members.items[i].name == name) { + try p.errStr(.duplicate_member, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, p.record_members.items[i].tok); + break; + } + } + try p.record_members.append(p.gpa, .{ .name = name, .tok = tok }); + } + + fn addFieldsFromAnonymous(r: @This(), p: *Parser, ty: Type) Error!void { + for (ty.getRecord().?.fields) |f| { + if (f.isAnonymousRecord()) { + try r.addFieldsFromAnonymous(p, f.ty.canonicalize(.standard)); + } else if (f.name_tok != 0) { + try r.addField(p, f.name, f.name_tok); + } + } + } +} = .{}, +record_members: std.ArrayListUnmanaged(struct { tok: TokenIndex, name: StringId }) = .empty, +@"switch": ?*Switch = null, +in_loop: bool = false, +pragma_pack: ?u8 = null, +string_ids: struct { + declspec_id: StringId, + main_id: StringId, + file: StringId, + jmp_buf: StringId, + sigjmp_buf: StringId, + ucontext_t: StringId, +}, + +/// Checks codepoint for various pedantic warnings +/// Returns true if diagnostic issued +fn checkIdentifierCodepointWarnings(comp: *Compilation, codepoint: u21, loc: Source.Location) Compilation.Error!bool { + assert(codepoint >= 0x80); + + const err_start = comp.diagnostics.list.items.len; + + if (!char_info.isC99IdChar(codepoint)) { + try comp.addDiagnostic(.{ + .tag = .c99_compat, + .loc = loc, + }, &.{}); + } + if (char_info.isInvisible(codepoint)) { + try comp.addDiagnostic(.{ + .tag = .unicode_zero_width, + .loc = loc, + .extra = .{ .actual_codepoint = codepoint }, + }, &.{}); + } + if (char_info.homoglyph(codepoint)) |resembles| { + try comp.addDiagnostic(.{ + .tag = .unicode_homoglyph, + .loc = loc, + .extra = .{ .codepoints = .{ .actual = codepoint, .resembles = resembles } }, + }, &.{}); + } + return comp.diagnostics.list.items.len != err_start; +} + +/// Issues diagnostics for the current extended identifier token +/// Return value indicates whether the token should be considered an identifier +/// true means consider the token to actually be an identifier +/// false means it is not +fn validateExtendedIdentifier(p: *Parser) !bool { + assert(p.tok_ids[p.tok_i] == .extended_identifier); + + const slice = p.tokSlice(p.tok_i); + const view = std.unicode.Utf8View.init(slice) catch { + try p.errTok(.invalid_utf8, p.tok_i); + return error.FatalError; + }; + var it = view.iterator(); + + var valid_identifier = true; + var warned = false; + var len: usize = 0; + var invalid_char: u21 = undefined; + var loc = p.pp.tokens.items(.loc)[p.tok_i]; + + var normalized = true; + var last_canonical_class: char_info.CanonicalCombiningClass = .not_reordered; + const standard = p.comp.langopts.standard; + while (it.nextCodepoint()) |codepoint| { + defer { + len += 1; + loc.byte_offset += std.unicode.utf8CodepointSequenceLength(codepoint) catch unreachable; + } + if (codepoint == '$') { + warned = true; + if (p.comp.langopts.dollars_in_identifiers) try p.comp.addDiagnostic(.{ + .tag = .dollar_in_identifier_extension, + .loc = loc, + }, &.{}); + } + + if (codepoint <= 0x7F) continue; + if (!valid_identifier) continue; + + const allowed = standard.codepointAllowedInIdentifier(codepoint, len == 0); + if (!allowed) { + invalid_char = codepoint; + valid_identifier = false; + continue; + } + + if (!warned) { + warned = try checkIdentifierCodepointWarnings(p.comp, codepoint, loc); + } + + // Check NFC normalization. + if (!normalized) continue; + const canonical_class = char_info.getCanonicalClass(codepoint); + if (@intFromEnum(last_canonical_class) > @intFromEnum(canonical_class) and + canonical_class != .not_reordered) + { + normalized = false; + try p.errStr(.identifier_not_normalized, p.tok_i, slice); + continue; + } + if (char_info.isNormalized(codepoint) != .yes) { + normalized = false; + try p.errExtra(.identifier_not_normalized, p.tok_i, .{ .normalized = slice }); + } + last_canonical_class = canonical_class; + } + + if (!valid_identifier) { + if (len == 1) { + try p.errExtra(.unexpected_character, p.tok_i, .{ .actual_codepoint = invalid_char }); + return false; + } else { + try p.errExtra(.invalid_identifier_start_char, p.tok_i, .{ .actual_codepoint = invalid_char }); + } + } + + return true; +} + +fn eatIdentifier(p: *Parser) !?TokenIndex { + switch (p.tok_ids[p.tok_i]) { + .identifier => {}, + .extended_identifier => { + if (!try p.validateExtendedIdentifier()) { + p.tok_i += 1; + return null; + } + }, + else => return null, + } + p.tok_i += 1; + + // Handle illegal '$' characters in identifiers + if (!p.comp.langopts.dollars_in_identifiers) { + if (p.tok_ids[p.tok_i] == .invalid and p.tokSlice(p.tok_i)[0] == '$') { + try p.err(.dollars_in_identifiers); + p.tok_i += 1; + return error.ParsingFailed; + } + } + + return p.tok_i - 1; +} + +fn expectIdentifier(p: *Parser) Error!TokenIndex { + const actual = p.tok_ids[p.tok_i]; + if (actual != .identifier and actual != .extended_identifier) { + return p.errExpectedToken(.identifier, actual); + } + + return (try p.eatIdentifier()) orelse error.ParsingFailed; +} + +fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex { + assert(id != .identifier and id != .extended_identifier); // use eatIdentifier + if (p.tok_ids[p.tok_i] == id) { + defer p.tok_i += 1; + return p.tok_i; + } else return null; +} + +fn expectToken(p: *Parser, expected: Token.Id) Error!TokenIndex { + assert(expected != .identifier and expected != .extended_identifier); // use expectIdentifier + const actual = p.tok_ids[p.tok_i]; + if (actual != expected) return p.errExpectedToken(expected, actual); + defer p.tok_i += 1; + return p.tok_i; +} + +pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 { + if (p.tok_ids[tok].lexeme()) |some| return some; + const loc = p.pp.tokens.items(.loc)[tok]; + var tmp_tokenizer = Tokenizer{ + .buf = p.comp.getSource(loc.id).buf, + .langopts = p.comp.langopts, + .index = loc.byte_offset, + .source = .generated, + }; + const res = tmp_tokenizer.next(); + return tmp_tokenizer.buf[res.start..res.end]; +} + +fn expectClosing(p: *Parser, opening: TokenIndex, id: Token.Id) Error!void { + _ = p.expectToken(id) catch |e| { + if (e == error.ParsingFailed) { + try p.errTok(switch (id) { + .r_paren => .to_match_paren, + .r_brace => .to_match_brace, + .r_bracket => .to_match_brace, + else => unreachable, + }, opening); + } + return e; + }; +} + +fn errOverflow(p: *Parser, op_tok: TokenIndex, res: Result) !void { + try p.errStr(.overflow, op_tok, try res.str(p)); +} + +fn errExpectedToken(p: *Parser, expected: Token.Id, actual: Token.Id) Error { + switch (actual) { + .invalid => try p.errExtra(.expected_invalid, p.tok_i, .{ .tok_id_expected = expected }), + .eof => try p.errExtra(.expected_eof, p.tok_i, .{ .tok_id_expected = expected }), + else => try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ + .expected = expected, + .actual = actual, + } }), + } + return error.ParsingFailed; +} + +pub fn errStr(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, str: []const u8) Compilation.Error!void { + @branchHint(.cold); + return p.errExtra(tag, tok_i, .{ .str = str }); +} + +pub fn errExtra(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, extra: Diagnostics.Message.Extra) Compilation.Error!void { + @branchHint(.cold); + const tok = p.pp.tokens.get(tok_i); + var loc = tok.loc; + if (tok_i != 0 and tok.id == .eof) { + // if the token is EOF, point at the end of the previous token instead + const prev = p.pp.tokens.get(tok_i - 1); + loc = prev.loc; + loc.byte_offset += @intCast(p.tokSlice(tok_i - 1).len); + } + try p.comp.addDiagnostic(.{ + .tag = tag, + .loc = loc, + .extra = extra, + }, p.pp.expansionSlice(tok_i)); +} + +pub fn errTok(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex) Compilation.Error!void { + @branchHint(.cold); + return p.errExtra(tag, tok_i, .{ .none = {} }); +} + +pub fn err(p: *Parser, tag: Diagnostics.Tag) Compilation.Error!void { + @branchHint(.cold); + return p.errExtra(tag, p.tok_i, .{ .none = {} }); +} + +pub fn todo(p: *Parser, msg: []const u8) Error { + try p.errStr(.todo, p.tok_i, msg); + return error.ParsingFailed; +} + +pub fn removeNull(p: *Parser, str: Value) !Value { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + { + const bytes = p.comp.interner.get(str.ref()).bytes; + try p.strings.appendSlice(bytes[0 .. bytes.len - 1]); + } + return Value.intern(p.comp, .{ .bytes = p.strings.items[strings_top..] }); +} + +pub fn typeStr(p: *Parser, ty: Type) ![]const u8 { + if (@import("builtin").mode != .Debug) { + if (ty.is(.invalid)) { + return "Tried to render invalid type - this is an aro bug."; + } + } + if (Type.Builder.fromType(ty).str(p.comp.langopts)) |str| return str; + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + const mapper = p.comp.string_interner.getSlowTypeMapper(); + try ty.print(mapper, p.comp.langopts, p.strings.writer()); + return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); +} + +pub fn typePairStr(p: *Parser, a: Type, b: Type) ![]const u8 { + return p.typePairStrExtra(a, " and ", b); +} + +pub fn typePairStrExtra(p: *Parser, a: Type, msg: []const u8, b: Type) ![]const u8 { + if (@import("builtin").mode != .Debug) { + if (a.is(.invalid) or b.is(.invalid)) { + return "Tried to render invalid type - this is an aro bug."; + } + } + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + try p.strings.append('\''); + const mapper = p.comp.string_interner.getSlowTypeMapper(); + try a.print(mapper, p.comp.langopts, p.strings.writer()); + try p.strings.append('\''); + try p.strings.appendSlice(msg); + try p.strings.append('\''); + try b.print(mapper, p.comp.langopts, p.strings.writer()); + try p.strings.append('\''); + return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); +} + +pub fn valueChangedStr(p: *Parser, res: *Result, old_value: Value, int_ty: Type) ![]const u8 { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + var w = p.strings.writer(); + const type_pair_str = try p.typePairStrExtra(res.ty, " to ", int_ty); + try w.writeAll(type_pair_str); + + try w.writeAll(" changes "); + if (res.val.isZero(p.comp)) try w.writeAll("non-zero "); + try w.writeAll("value from "); + try old_value.print(res.ty, p.comp, w); + try w.writeAll(" to "); + try res.val.print(int_ty, p.comp, w); + + return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); +} + +fn checkDeprecatedUnavailable(p: *Parser, ty: Type, usage_tok: TokenIndex, decl_tok: TokenIndex) !void { + if (ty.getAttribute(.@"error")) |@"error"| { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + const w = p.strings.writer(); + const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes; + try w.print("call to '{s}' declared with attribute error: {}", .{ + p.tokSlice(@"error".__name_tok), std.zig.fmtEscapes(msg_str), + }); + const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); + try p.errStr(.error_attribute, usage_tok, str); + } + if (ty.getAttribute(.warning)) |warning| { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + const w = p.strings.writer(); + const msg_str = p.comp.interner.get(warning.msg.ref()).bytes; + try w.print("call to '{s}' declared with attribute warning: {}", .{ + p.tokSlice(warning.__name_tok), std.zig.fmtEscapes(msg_str), + }); + const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); + try p.errStr(.warning_attribute, usage_tok, str); + } + if (ty.getAttribute(.unavailable)) |unavailable| { + try p.errDeprecated(.unavailable, usage_tok, unavailable.msg); + try p.errStr(.unavailable_note, unavailable.__name_tok, p.tokSlice(decl_tok)); + return error.ParsingFailed; + } else if (ty.getAttribute(.deprecated)) |deprecated| { + try p.errDeprecated(.deprecated_declarations, usage_tok, deprecated.msg); + try p.errStr(.deprecated_note, deprecated.__name_tok, p.tokSlice(decl_tok)); + } +} + +fn errDeprecated(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, msg: ?Value) Compilation.Error!void { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + const w = p.strings.writer(); + try w.print("'{s}' is ", .{p.tokSlice(tok_i)}); + const reason: []const u8 = switch (tag) { + .unavailable => "unavailable", + .deprecated_declarations => "deprecated", + else => unreachable, + }; + try w.writeAll(reason); + if (msg) |m| { + const str = p.comp.interner.get(m.ref()).bytes; + try w.print(": {}", .{std.zig.fmtEscapes(str)}); + } + const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); + return p.errStr(tag, tok_i, str); +} + +fn addNode(p: *Parser, node: Tree.Node) Allocator.Error!NodeIndex { + if (p.in_macro) return .none; + const res = p.nodes.len; + try p.nodes.append(p.gpa, node); + return @enumFromInt(res); +} + +fn addList(p: *Parser, nodes: []const NodeIndex) Allocator.Error!Tree.Node.Range { + if (p.in_macro) return Tree.Node.Range{ .start = 0, .end = 0 }; + const start: u32 = @intCast(p.data.items.len); + try p.data.appendSlice(nodes); + const end: u32 = @intCast(p.data.items.len); + return Tree.Node.Range{ .start = start, .end = end }; +} + +fn findLabel(p: *Parser, name: []const u8) ?TokenIndex { + for (p.labels.items) |item| { + switch (item) { + .label => |l| if (mem.eql(u8, p.tokSlice(l), name)) return l, + .unresolved_goto => {}, + } + } + return null; +} + +fn nodeIs(p: *Parser, node: NodeIndex, tag: Tree.Tag) bool { + return p.getNode(node, tag) != null; +} + +pub fn getDecayedStringLiteral(p: *Parser, node: NodeIndex) ?Value { + const cast_node = p.getNode(node, .implicit_cast) orelse return null; + const data = p.nodes.items(.data)[@intFromEnum(cast_node)]; + if (data.cast.kind != .array_to_pointer) return null; + const literal_node = p.getNode(data.cast.operand, .string_literal_expr) orelse return null; + return p.value_map.get(literal_node); +} + +fn getNode(p: *Parser, node: NodeIndex, tag: Tree.Tag) ?NodeIndex { + var cur = node; + const tags = p.nodes.items(.tag); + const data = p.nodes.items(.data); + while (true) { + const cur_tag = tags[@intFromEnum(cur)]; + if (cur_tag == .paren_expr) { + cur = data[@intFromEnum(cur)].un; + } else if (cur_tag == tag) { + return cur; + } else { + return null; + } + } +} + +fn nodeIsCompoundLiteral(p: *Parser, node: NodeIndex) bool { + var cur = node; + const tags = p.nodes.items(.tag); + const data = p.nodes.items(.data); + while (true) { + switch (tags[@intFromEnum(cur)]) { + .paren_expr => cur = data[@intFromEnum(cur)].un, + .compound_literal_expr, + .static_compound_literal_expr, + .thread_local_compound_literal_expr, + .static_thread_local_compound_literal_expr, + => return true, + else => return false, + } + } +} + +fn tmpTree(p: *Parser) Tree { + return .{ + .nodes = p.nodes.slice(), + .data = p.data.items, + .value_map = p.value_map, + .comp = p.comp, + .arena = undefined, + .generated = undefined, + .tokens = undefined, + .root_decls = undefined, + }; +} + +fn pragma(p: *Parser) Compilation.Error!bool { + var found_pragma = false; + while (p.eatToken(.keyword_pragma)) |_| { + found_pragma = true; + + const name_tok = p.tok_i; + const name = p.tokSlice(name_tok); + + const end_idx = mem.indexOfScalarPos(Token.Id, p.tok_ids, p.tok_i, .nl).?; + const pragma_len = @as(TokenIndex, @intCast(end_idx)) - p.tok_i; + defer p.tok_i += pragma_len + 1; // skip past .nl as well + if (p.comp.getPragma(name)) |prag| { + try prag.parserCB(p, p.tok_i); + } + } + return found_pragma; +} + +/// Issue errors for top-level definitions whose type was never completed. +fn diagnoseIncompleteDefinitions(p: *Parser) !void { + @branchHint(.cold); + + const node_slices = p.nodes.slice(); + const tags = node_slices.items(.tag); + const tys = node_slices.items(.ty); + const data = node_slices.items(.data); + + for (p.decl_buf.items) |decl_node| { + const idx = @intFromEnum(decl_node); + switch (tags[idx]) { + .struct_forward_decl, .union_forward_decl, .enum_forward_decl => {}, + else => continue, + } + + const ty = tys[idx]; + const decl_type_name = if (ty.getRecord()) |rec| + rec.name + else if (ty.get(.@"enum")) |en| + en.data.@"enum".name + else + unreachable; + + const tentative_def_tok = p.tentative_defs.get(decl_type_name) orelse continue; + const type_str = try p.typeStr(ty); + try p.errStr(.tentative_definition_incomplete, tentative_def_tok, type_str); + try p.errStr(.forward_declaration_here, data[idx].decl_ref, type_str); + } +} + +/// root : (decl | assembly ';' | staticAssert)* +pub fn parse(pp: *Preprocessor) Compilation.Error!Tree { + assert(pp.linemarkers == .none); + pp.comp.pragmaEvent(.before_parse); + + var arena = std.heap.ArenaAllocator.init(pp.comp.gpa); + errdefer arena.deinit(); + var p = Parser{ + .pp = pp, + .comp = pp.comp, + .gpa = pp.comp.gpa, + .arena = arena.allocator(), + .tok_ids = pp.tokens.items(.id), + .strings = std.ArrayListAligned(u8, 4).init(pp.comp.gpa), + .value_map = Tree.ValueMap.init(pp.comp.gpa), + .data = NodeList.init(pp.comp.gpa), + .labels = std.ArrayList(Label).init(pp.comp.gpa), + .list_buf = NodeList.init(pp.comp.gpa), + .decl_buf = NodeList.init(pp.comp.gpa), + .param_buf = std.ArrayList(Type.Func.Param).init(pp.comp.gpa), + .enum_buf = std.ArrayList(Type.Enum.Field).init(pp.comp.gpa), + .record_buf = std.ArrayList(Type.Record.Field).init(pp.comp.gpa), + .field_attr_buf = std.ArrayList([]const Attribute).init(pp.comp.gpa), + .string_ids = .{ + .declspec_id = try StrInt.intern(pp.comp, "__declspec"), + .main_id = try StrInt.intern(pp.comp, "main"), + .file = try StrInt.intern(pp.comp, "FILE"), + .jmp_buf = try StrInt.intern(pp.comp, "jmp_buf"), + .sigjmp_buf = try StrInt.intern(pp.comp, "sigjmp_buf"), + .ucontext_t = try StrInt.intern(pp.comp, "ucontext_t"), + }, + }; + errdefer { + p.nodes.deinit(pp.comp.gpa); + p.value_map.deinit(); + } + defer { + p.data.deinit(); + p.labels.deinit(); + p.strings.deinit(); + p.syms.deinit(pp.comp.gpa); + p.list_buf.deinit(); + p.decl_buf.deinit(); + p.param_buf.deinit(); + p.enum_buf.deinit(); + p.record_buf.deinit(); + p.record_members.deinit(pp.comp.gpa); + p.attr_buf.deinit(pp.comp.gpa); + p.attr_application_buf.deinit(pp.comp.gpa); + p.tentative_defs.deinit(pp.comp.gpa); + assert(p.field_attr_buf.items.len == 0); + p.field_attr_buf.deinit(); + } + + try p.syms.pushScope(&p); + defer p.syms.popScope(); + + // NodeIndex 0 must be invalid + _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined, .loc = undefined }); + + { + if (p.comp.langopts.hasChar8_T()) { + try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "char8_t"), .{ .specifier = .uchar }, 0, .none); + } + try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__int128_t"), .{ .specifier = .int128 }, 0, .none); + try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__uint128_t"), .{ .specifier = .uint128 }, 0, .none); + + const elem_ty = try p.arena.create(Type); + elem_ty.* = .{ .specifier = .char }; + try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__builtin_ms_va_list"), .{ + .specifier = .pointer, + .data = .{ .sub_type = elem_ty }, + }, 0, .none); + + const ty = &pp.comp.types.va_list; + try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__builtin_va_list"), ty.*, 0, .none); + + if (ty.isArray()) ty.decayArray(); + + try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__NSConstantString"), pp.comp.types.ns_constant_string.ty, 0, .none); + + if (p.comp.float80Type()) |float80_ty| { + try p.syms.defineTypedef(&p, try StrInt.intern(p.comp, "__float80"), float80_ty, 0, .none); + } + } + + while (p.eatToken(.eof) == null) { + if (try p.pragma()) continue; + if (try p.parseOrNextDecl(staticAssert)) continue; + if (try p.parseOrNextDecl(decl)) continue; + if (p.eatToken(.keyword_extension)) |_| { + const saved_extension = p.extension_suppressed; + defer p.extension_suppressed = saved_extension; + p.extension_suppressed = true; + + if (try p.parseOrNextDecl(decl)) continue; + switch (p.tok_ids[p.tok_i]) { + .semicolon => p.tok_i += 1, + .keyword_static_assert, + .keyword_c23_static_assert, + .keyword_pragma, + .keyword_extension, + .keyword_asm, + .keyword_asm1, + .keyword_asm2, + => {}, + else => try p.err(.expected_external_decl), + } + continue; + } + if (p.assembly(.global) catch |er| switch (er) { + error.ParsingFailed => { + p.nextExternDecl(); + continue; + }, + else => |e| return e, + }) |node| { + try p.decl_buf.append(node); + continue; + } + if (p.eatToken(.semicolon)) |tok| { + try p.errTok(.extra_semi, tok); + continue; + } + try p.err(.expected_external_decl); + p.tok_i += 1; + } + if (p.tentative_defs.count() > 0) { + try p.diagnoseIncompleteDefinitions(); + } + + const root_decls = try p.decl_buf.toOwnedSlice(); + errdefer pp.comp.gpa.free(root_decls); + if (root_decls.len == 0) { + try p.errTok(.empty_translation_unit, p.tok_i - 1); + } + pp.comp.pragmaEvent(.after_parse); + + const data = try p.data.toOwnedSlice(); + errdefer pp.comp.gpa.free(data); + return Tree{ + .comp = pp.comp, + .tokens = pp.tokens.slice(), + .arena = arena, + .generated = pp.comp.generated_buf.items, + .nodes = p.nodes.toOwnedSlice(), + .data = data, + .root_decls = root_decls, + .value_map = p.value_map, + }; +} + +fn skipToPragmaSentinel(p: *Parser) void { + while (true) : (p.tok_i += 1) { + if (p.tok_ids[p.tok_i] == .nl) return; + if (p.tok_ids[p.tok_i] == .eof) { + p.tok_i -= 1; + return; + } + } +} + +fn parseOrNextDecl(p: *Parser, comptime func: fn (*Parser) Error!bool) Compilation.Error!bool { + return func(p) catch |er| switch (er) { + error.ParsingFailed => { + p.nextExternDecl(); + return true; + }, + else => |e| return e, + }; +} + +fn nextExternDecl(p: *Parser) void { + var parens: u32 = 0; + while (true) : (p.tok_i += 1) { + switch (p.tok_ids[p.tok_i]) { + .l_paren, .l_brace, .l_bracket => parens += 1, + .r_paren, .r_brace, .r_bracket => if (parens != 0) { + parens -= 1; + }, + .keyword_typedef, + .keyword_extern, + .keyword_static, + .keyword_auto, + .keyword_register, + .keyword_thread_local, + .keyword_c23_thread_local, + .keyword_inline, + .keyword_inline1, + .keyword_inline2, + .keyword_noreturn, + .keyword_void, + .keyword_bool, + .keyword_c23_bool, + .keyword_char, + .keyword_short, + .keyword_int, + .keyword_long, + .keyword_signed, + .keyword_signed1, + .keyword_signed2, + .keyword_unsigned, + .keyword_float, + .keyword_double, + .keyword_complex, + .keyword_atomic, + .keyword_enum, + .keyword_struct, + .keyword_union, + .keyword_alignas, + .keyword_c23_alignas, + .identifier, + .extended_identifier, + .keyword_typeof, + .keyword_typeof1, + .keyword_typeof2, + .keyword_typeof_unqual, + .keyword_extension, + .keyword_bit_int, + => if (parens == 0) return, + .keyword_pragma => p.skipToPragmaSentinel(), + .eof => return, + .semicolon => if (parens == 0) { + p.tok_i += 1; + return; + }, + else => {}, + } + } +} + +fn skipTo(p: *Parser, id: Token.Id) void { + var parens: u32 = 0; + while (true) : (p.tok_i += 1) { + if (p.tok_ids[p.tok_i] == id and parens == 0) { + p.tok_i += 1; + return; + } + switch (p.tok_ids[p.tok_i]) { + .l_paren, .l_brace, .l_bracket => parens += 1, + .r_paren, .r_brace, .r_bracket => if (parens != 0) { + parens -= 1; + }, + .keyword_pragma => p.skipToPragmaSentinel(), + .eof => return, + else => {}, + } + } +} + +/// Called after a typedef is defined +fn typedefDefined(p: *Parser, name: StringId, ty: Type) void { + if (name == p.string_ids.file) { + p.comp.types.file = ty; + } else if (name == p.string_ids.jmp_buf) { + p.comp.types.jmp_buf = ty; + } else if (name == p.string_ids.sigjmp_buf) { + p.comp.types.sigjmp_buf = ty; + } else if (name == p.string_ids.ucontext_t) { + p.comp.types.ucontext_t = ty; + } +} + +// ====== declarations ====== + +/// decl +/// : declSpec (initDeclarator ( ',' initDeclarator)*)? ';' +/// | declSpec declarator decl* compoundStmt +fn decl(p: *Parser) Error!bool { + _ = try p.pragma(); + const first_tok = p.tok_i; + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + + try p.attributeSpecifier(); + + var decl_spec = if (try p.declSpec()) |some| some else blk: { + if (p.func.ty != null) { + p.tok_i = first_tok; + return false; + } + switch (p.tok_ids[first_tok]) { + .asterisk, .l_paren, .identifier, .extended_identifier => {}, + else => if (p.tok_i != first_tok) { + try p.err(.expected_ident_or_l_paren); + return error.ParsingFailed; + } else return false, + } + var spec: Type.Builder = .{}; + break :blk DeclSpec{ .ty = try spec.finish(p) }; + }; + if (decl_spec.noreturn) |tok| { + const attr = Attribute{ .tag = .noreturn, .args = .{ .noreturn = .{} }, .syntax = .keyword }; + try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = tok }); + } + var init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse { + _ = try p.expectToken(.semicolon); + if (decl_spec.ty.is(.@"enum") or + (decl_spec.ty.isRecord() and !decl_spec.ty.isAnonymousRecord(p.comp) and + !decl_spec.ty.isTypeof())) // we follow GCC and clang's behavior here + { + const specifier = decl_spec.ty.canonicalize(.standard).specifier; + const attrs = p.attr_buf.items(.attr)[attr_buf_top..]; + const toks = p.attr_buf.items(.tok)[attr_buf_top..]; + for (attrs, toks) |attr, tok| { + try p.errExtra(.ignored_record_attr, tok, .{ + .ignored_record_attr = .{ .tag = attr.tag, .specifier = switch (specifier) { + .@"enum" => .@"enum", + .@"struct" => .@"struct", + .@"union" => .@"union", + else => unreachable, + } }, + }); + } + return true; + } + + try p.errTok(.missing_declaration, first_tok); + return true; + }; + + // Check for function definition. + if (init_d.d.func_declarator != null and init_d.initializer.node == .none and init_d.d.ty.isFunc()) fn_def: { + if (decl_spec.auto_type) |tok_i| { + try p.errStr(.auto_type_not_allowed, tok_i, "function return type"); + return error.ParsingFailed; + } + + switch (p.tok_ids[p.tok_i]) { + .comma, .semicolon => break :fn_def, + .l_brace => {}, + else => if (init_d.d.old_style_func == null) { + try p.err(.expected_fn_body); + return true; + }, + } + if (p.func.ty != null) try p.err(.func_not_in_root); + + const node = try p.addNode(undefined); // reserve space + const interned_declarator_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name)); + try p.syms.defineSymbol(p, interned_declarator_name, init_d.d.ty, init_d.d.name, node, .{}, false); + + const func = p.func; + p.func = .{ + .ty = init_d.d.ty, + .name = init_d.d.name, + }; + if (interned_declarator_name == p.string_ids.main_id and !init_d.d.ty.returnType().is(.int)) { + try p.errTok(.main_return_type, init_d.d.name); + } + defer p.func = func; + + try p.syms.pushScope(p); + defer p.syms.popScope(); + + // Collect old style parameter declarations. + if (init_d.d.old_style_func != null) { + var base_ty = init_d.d.ty.base(); + base_ty.specifier = .func; + + const param_buf_top = p.param_buf.items.len; + defer p.param_buf.items.len = param_buf_top; + + param_loop: while (true) { + const param_decl_spec = (try p.declSpec()) orelse break; + if (p.eatToken(.semicolon)) |semi| { + try p.errTok(.missing_declaration, semi); + continue :param_loop; + } + + while (true) { + const attr_buf_top_declarator = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top_declarator; + + var d = (try p.declarator(param_decl_spec.ty, .param)) orelse { + try p.errTok(.missing_declaration, first_tok); + _ = try p.expectToken(.semicolon); + continue :param_loop; + }; + try p.attributeSpecifier(); + + if (d.ty.hasIncompleteSize() and !d.ty.is(.void)) try p.errStr(.parameter_incomplete_ty, d.name, try p.typeStr(d.ty)); + if (d.ty.isFunc()) { + // Params declared as functions are converted to function pointers. + const elem_ty = try p.arena.create(Type); + elem_ty.* = d.ty; + d.ty = Type{ + .specifier = .pointer, + .data = .{ .sub_type = elem_ty }, + }; + } else if (d.ty.isArray()) { + // params declared as arrays are converted to pointers + d.ty.decayArray(); + } else if (d.ty.is(.void)) { + try p.errTok(.invalid_void_param, d.name); + } + + // find and correct parameter types + // TODO check for missing declarations and redefinitions + const name_str = p.tokSlice(d.name); + const interned_name = try StrInt.intern(p.comp, name_str); + for (init_d.d.ty.params()) |*param| { + if (param.name == interned_name) { + param.ty = d.ty; + break; + } + } else { + try p.errStr(.parameter_missing, d.name, name_str); + } + d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param); + + // bypass redefinition check to avoid duplicate errors + try p.syms.define(p.gpa, .{ + .kind = .def, + .name = interned_name, + .tok = d.name, + .ty = d.ty, + .val = .{}, + }); + if (p.eatToken(.comma) == null) break; + } + _ = try p.expectToken(.semicolon); + } + } else { + for (init_d.d.ty.params()) |param| { + if (param.ty.hasUnboundVLA()) try p.errTok(.unbound_vla, param.name_tok); + if (param.ty.hasIncompleteSize() and !param.ty.is(.void) and param.ty.specifier != .invalid) try p.errStr(.parameter_incomplete_ty, param.name_tok, try p.typeStr(param.ty)); + + if (param.name == .empty) { + try p.errTok(.omitting_parameter_name, param.name_tok); + continue; + } + + // bypass redefinition check to avoid duplicate errors + try p.syms.define(p.gpa, .{ + .kind = .def, + .name = param.name, + .tok = param.name_tok, + .ty = param.ty, + .val = .{}, + }); + } + } + + const body = (try p.compoundStmt(true, null)) orelse { + assert(init_d.d.old_style_func != null); + try p.err(.expected_fn_body); + return true; + }; + p.nodes.set(@intFromEnum(node), .{ + .ty = init_d.d.ty, + .tag = try decl_spec.validateFnDef(p), + .data = .{ .decl = .{ .name = init_d.d.name, .node = body } }, + .loc = @enumFromInt(init_d.d.name), + }); + try p.decl_buf.append(node); + + // check gotos + if (func.ty == null) { + for (p.labels.items) |item| { + if (item == .unresolved_goto) + try p.errStr(.undeclared_label, item.unresolved_goto, p.tokSlice(item.unresolved_goto)); + } + if (p.computed_goto_tok) |goto_tok| { + if (!p.contains_address_of_label) try p.errTok(.invalid_computed_goto, goto_tok); + } + p.labels.items.len = 0; + p.label_count = 0; + p.contains_address_of_label = false; + p.computed_goto_tok = null; + } + return true; + } + + // Declare all variable/typedef declarators. + var warned_auto = false; + while (true) { + if (init_d.d.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i); + const tag = try decl_spec.validate(p, &init_d.d.ty, init_d.initializer.node != .none); + + const tok = switch (decl_spec.storage_class) { + .auto, .@"extern", .register, .static, .typedef => |tok| tok, + .none => init_d.d.name, + }; + const node = try p.addNode(.{ + .ty = init_d.d.ty, + .tag = tag, + .data = .{ + .decl = .{ .name = init_d.d.name, .node = init_d.initializer.node }, + }, + .loc = @enumFromInt(tok), + }); + try p.decl_buf.append(node); + + const interned_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name)); + if (decl_spec.storage_class == .typedef) { + try p.syms.defineTypedef(p, interned_name, init_d.d.ty, init_d.d.name, node); + p.typedefDefined(interned_name, init_d.d.ty); + } else if (init_d.initializer.node != .none or + (p.func.ty != null and decl_spec.storage_class != .@"extern")) + { + // TODO validate global variable/constexpr initializer comptime known + try p.syms.defineSymbol( + p, + interned_name, + init_d.d.ty, + init_d.d.name, + node, + if (init_d.d.ty.isConst() or decl_spec.constexpr != null) init_d.initializer.val else .{}, + decl_spec.constexpr != null, + ); + } else { + try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, node); + } + + if (p.eatToken(.comma) == null) break; + + if (!warned_auto) { + if (decl_spec.auto_type) |tok_i| { + try p.errTok(.auto_type_requires_single_declarator, tok_i); + warned_auto = true; + } + if (p.comp.langopts.standard.atLeast(.c23) and decl_spec.storage_class == .auto) { + try p.errTok(.c23_auto_single_declarator, decl_spec.storage_class.auto); + warned_auto = true; + } + } + + init_d = (try p.initDeclarator(&decl_spec, attr_buf_top)) orelse { + try p.err(.expected_ident_or_l_paren); + continue; + }; + } + + _ = try p.expectToken(.semicolon); + return true; +} + +fn staticAssertMessage(p: *Parser, cond_node: NodeIndex, message: Result) !?[]const u8 { + const cond_tag = p.nodes.items(.tag)[@intFromEnum(cond_node)]; + if (cond_tag != .builtin_types_compatible_p and message.node == .none) return null; + + var buf = std.ArrayList(u8).init(p.gpa); + defer buf.deinit(); + + if (cond_tag == .builtin_types_compatible_p) { + const mapper = p.comp.string_interner.getSlowTypeMapper(); + const data = p.nodes.items(.data)[@intFromEnum(cond_node)].bin; + + try buf.appendSlice("'__builtin_types_compatible_p("); + + const lhs_ty = p.nodes.items(.ty)[@intFromEnum(data.lhs)]; + try lhs_ty.print(mapper, p.comp.langopts, buf.writer()); + try buf.appendSlice(", "); + + const rhs_ty = p.nodes.items(.ty)[@intFromEnum(data.rhs)]; + try rhs_ty.print(mapper, p.comp.langopts, buf.writer()); + + try buf.appendSlice(")'"); + } + if (message.node != .none) { + assert(p.nodes.items(.tag)[@intFromEnum(message.node)] == .string_literal_expr); + if (buf.items.len > 0) { + try buf.append(' '); + } + const bytes = p.comp.interner.get(message.val.ref()).bytes; + try buf.ensureUnusedCapacity(bytes.len); + try Value.printString(bytes, message.ty, p.comp, buf.writer()); + } + return try p.comp.diagnostics.arena.allocator().dupe(u8, buf.items); +} + +/// staticAssert +/// : keyword_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';' +/// | keyword_c23_static_assert '(' integerConstExpr (',' STRING_LITERAL)? ')' ';' +fn staticAssert(p: *Parser) Error!bool { + const static_assert = p.eatToken(.keyword_static_assert) orelse p.eatToken(.keyword_c23_static_assert) orelse return false; + const l_paren = try p.expectToken(.l_paren); + const res_token = p.tok_i; + var res = try p.constExpr(.gnu_folding_extension); + const res_node = res.node; + const str = if (p.eatToken(.comma) != null) + switch (p.tok_ids[p.tok_i]) { + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + .unterminated_string_literal, + => try p.stringLiteral(), + else => { + try p.err(.expected_str_literal); + return error.ParsingFailed; + }, + } + else + Result{}; + try p.expectClosing(l_paren, .r_paren); + _ = try p.expectToken(.semicolon); + if (str.node == .none) { + try p.errTok(.static_assert_missing_message, static_assert); + try p.errStr(.pre_c23_compat, static_assert, "'_Static_assert' with no message"); + } + + // Array will never be zero; a value of zero for a pointer is a null pointer constant + if ((res.ty.isArray() or res.ty.isPtr()) and !res.val.isZero(p.comp)) { + const err_start = p.comp.diagnostics.list.items.len; + try p.errTok(.const_decl_folded, res_token); + if (res.ty.isPtr() and err_start != p.comp.diagnostics.list.items.len) { + // Don't show the note if the .const_decl_folded diagnostic was not added + try p.errTok(.constant_expression_conversion_not_allowed, res_token); + } + } + try res.boolCast(p, .{ .specifier = .bool }, res_token); + if (res.val.opt_ref == .none) { + if (res.ty.specifier != .invalid) { + try p.errTok(.static_assert_not_constant, res_token); + } + } else { + if (!res.val.toBool(p.comp)) { + if (try p.staticAssertMessage(res_node, str)) |message| { + try p.errStr(.static_assert_failure_message, static_assert, message); + } else { + try p.errTok(.static_assert_failure, static_assert); + } + } + } + + const node = try p.addNode(.{ + .tag = .static_assert, + .data = .{ .bin = .{ + .lhs = res.node, + .rhs = str.node, + } }, + .loc = @enumFromInt(static_assert), + }); + try p.decl_buf.append(node); + return true; +} + +pub const DeclSpec = struct { + storage_class: union(enum) { + auto: TokenIndex, + @"extern": TokenIndex, + register: TokenIndex, + static: TokenIndex, + typedef: TokenIndex, + none, + } = .none, + thread_local: ?TokenIndex = null, + constexpr: ?TokenIndex = null, + @"inline": ?TokenIndex = null, + noreturn: ?TokenIndex = null, + auto_type: ?TokenIndex = null, + ty: Type, + + fn validateParam(d: DeclSpec, p: *Parser, ty: *Type) Error!void { + switch (d.storage_class) { + .none => {}, + .register => ty.qual.register = true, + .auto, .@"extern", .static, .typedef => |tok_i| try p.errTok(.invalid_storage_on_param, tok_i), + } + if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i); + if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline"); + if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn"); + if (d.constexpr) |tok_i| try p.errTok(.invalid_storage_on_param, tok_i); + if (d.auto_type) |tok_i| { + try p.errStr(.auto_type_not_allowed, tok_i, "function prototype"); + ty.* = Type.invalid; + } + } + + fn validateFnDef(d: DeclSpec, p: *Parser) Error!Tree.Tag { + switch (d.storage_class) { + .none, .@"extern", .static => {}, + .auto, .register, .typedef => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i), + } + if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i); + if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i); + + const is_static = d.storage_class == .static; + const is_inline = d.@"inline" != null; + if (is_static) { + if (is_inline) return .inline_static_fn_def; + return .static_fn_def; + } else { + if (is_inline) return .inline_fn_def; + return .fn_def; + } + } + + fn validate(d: DeclSpec, p: *Parser, ty: *Type, has_init: bool) Error!Tree.Tag { + const is_static = d.storage_class == .static; + if (ty.isFunc() and d.storage_class != .typedef) { + switch (d.storage_class) { + .none, .@"extern" => {}, + .static => |tok_i| if (p.func.ty != null) try p.errTok(.static_func_not_global, tok_i), + .typedef => unreachable, + .auto, .register => |tok_i| try p.errTok(.illegal_storage_on_func, tok_i), + } + if (d.thread_local) |tok_i| try p.errTok(.threadlocal_non_var, tok_i); + if (d.constexpr) |tok_i| try p.errTok(.illegal_storage_on_func, tok_i); + + const is_inline = d.@"inline" != null; + if (is_static) { + if (is_inline) return .inline_static_fn_proto; + return .static_fn_proto; + } else { + if (is_inline) return .inline_fn_proto; + return .fn_proto; + } + } else { + if (d.@"inline") |tok_i| try p.errStr(.func_spec_non_func, tok_i, "inline"); + // TODO move to attribute validation + if (d.noreturn) |tok_i| try p.errStr(.func_spec_non_func, tok_i, "_Noreturn"); + switch (d.storage_class) { + .auto => if (p.func.ty == null and !p.comp.langopts.standard.atLeast(.c23)) { + try p.err(.illegal_storage_on_global); + }, + .register => if (p.func.ty == null) try p.err(.illegal_storage_on_global), + .typedef => return .typedef, + else => {}, + } + ty.qual.register = d.storage_class == .register; + + const is_extern = d.storage_class == .@"extern" and !has_init; + if (d.thread_local != null) { + if (is_static) return .threadlocal_static_var; + if (is_extern) return .threadlocal_extern_var; + return .threadlocal_var; + } else { + if (is_static) return .static_var; + if (is_extern) return .extern_var; + return .@"var"; + } + } + } +}; + +/// typeof +/// : keyword_typeof '(' typeName ')' +/// | keyword_typeof '(' expr ')' +fn typeof(p: *Parser) Error!?Type { + var unqual = false; + switch (p.tok_ids[p.tok_i]) { + .keyword_typeof, .keyword_typeof1, .keyword_typeof2 => p.tok_i += 1, + .keyword_typeof_unqual => { + p.tok_i += 1; + unqual = true; + }, + else => return null, + } + const l_paren = try p.expectToken(.l_paren); + if (try p.typeName()) |ty| { + try p.expectClosing(l_paren, .r_paren); + if (ty.is(.invalid)) return null; + + const typeof_ty = try p.arena.create(Type); + typeof_ty.* = .{ + .data = ty.data, + .qual = if (unqual) .{} else ty.qual.inheritFromTypeof(), + .specifier = ty.specifier, + }; + + return Type{ + .data = .{ .sub_type = typeof_ty }, + .specifier = .typeof_type, + }; + } + const typeof_expr = try p.parseNoEval(expr); + try typeof_expr.expect(p); + try p.expectClosing(l_paren, .r_paren); + // Special case nullptr_t since it's defined as typeof(nullptr) + if (typeof_expr.ty.is(.nullptr_t)) { + return Type{ + .specifier = .nullptr_t, + .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(), + }; + } else if (typeof_expr.ty.is(.invalid)) { + return null; + } + + const inner = try p.arena.create(Type.Expr); + inner.* = .{ + .node = typeof_expr.node, + .ty = .{ + .data = typeof_expr.ty.data, + .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(), + .specifier = typeof_expr.ty.specifier, + .decayed = typeof_expr.ty.decayed, + }, + }; + + return Type{ + .data = .{ .expr = inner }, + .specifier = .typeof_expr, + .decayed = typeof_expr.ty.decayed, + }; +} + +/// declSpec: (storageClassSpec | typeSpec | typeQual | funcSpec | alignSpec)+ +/// funcSpec : keyword_inline | keyword_noreturn +fn declSpec(p: *Parser) Error!?DeclSpec { + var d: DeclSpec = .{ .ty = .{ .specifier = undefined } }; + var spec: Type.Builder = .{}; + + var combined_auto = !p.comp.langopts.standard.atLeast(.c23); + const start = p.tok_i; + while (true) { + if (!combined_auto and d.storage_class == .auto) { + try spec.combine(p, .c23_auto, d.storage_class.auto); + combined_auto = true; + } + if (try p.storageClassSpec(&d)) continue; + if (try p.typeSpec(&spec)) continue; + const id = p.tok_ids[p.tok_i]; + switch (id) { + .keyword_inline, .keyword_inline1, .keyword_inline2 => { + if (d.@"inline" != null) { + try p.errStr(.duplicate_decl_spec, p.tok_i, "inline"); + } + d.@"inline" = p.tok_i; + }, + .keyword_noreturn => { + if (d.noreturn != null) { + try p.errStr(.duplicate_decl_spec, p.tok_i, "_Noreturn"); + } + d.noreturn = p.tok_i; + }, + else => break, + } + p.tok_i += 1; + } + + if (p.tok_i == start) return null; + + d.ty = try spec.finish(p); + d.auto_type = spec.auto_type_tok; + return d; +} + +/// storageClassSpec: +/// : keyword_typedef +/// | keyword_extern +/// | keyword_static +/// | keyword_threadlocal +/// | keyword_auto +/// | keyword_register +fn storageClassSpec(p: *Parser, d: *DeclSpec) Error!bool { + const start = p.tok_i; + while (true) { + const id = p.tok_ids[p.tok_i]; + switch (id) { + .keyword_typedef, + .keyword_extern, + .keyword_static, + .keyword_auto, + .keyword_register, + => { + if (d.storage_class != .none) { + try p.errStr(.multiple_storage_class, p.tok_i, @tagName(d.storage_class)); + return error.ParsingFailed; + } + if (d.thread_local != null) { + switch (id) { + .keyword_extern, .keyword_static => {}, + else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?), + } + if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?); + } + if (d.constexpr != null) { + switch (id) { + .keyword_auto, .keyword_register, .keyword_static => {}, + else => try p.errStr(.cannot_combine_spec, p.tok_i, id.lexeme().?), + } + if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?); + } + switch (id) { + .keyword_typedef => d.storage_class = .{ .typedef = p.tok_i }, + .keyword_extern => d.storage_class = .{ .@"extern" = p.tok_i }, + .keyword_static => d.storage_class = .{ .static = p.tok_i }, + .keyword_auto => d.storage_class = .{ .auto = p.tok_i }, + .keyword_register => d.storage_class = .{ .register = p.tok_i }, + else => unreachable, + } + }, + .keyword_thread_local, + .keyword_c23_thread_local, + => { + if (d.thread_local != null) { + try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?); + } + if (d.constexpr) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?); + switch (d.storage_class) { + .@"extern", .none, .static => {}, + else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)), + } + d.thread_local = p.tok_i; + }, + .keyword_constexpr => { + if (d.constexpr != null) { + try p.errStr(.duplicate_decl_spec, p.tok_i, id.lexeme().?); + } + if (d.thread_local) |tok| try p.errStr(.cannot_combine_spec, p.tok_i, p.tok_ids[tok].lexeme().?); + switch (d.storage_class) { + .auto, .register, .none, .static => {}, + else => try p.errStr(.cannot_combine_spec, p.tok_i, @tagName(d.storage_class)), + } + d.constexpr = p.tok_i; + }, + else => break, + } + p.tok_i += 1; + } + return p.tok_i != start; +} + +const InitDeclarator = struct { d: Declarator, initializer: Result = .{} }; + +/// attribute +/// : attrIdentifier +/// | attrIdentifier '(' identifier ')' +/// | attrIdentifier '(' identifier (',' expr)+ ')' +/// | attrIdentifier '(' (expr (',' expr)*)? ')' +fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?TentativeAttribute { + const name_tok = p.tok_i; + switch (p.tok_ids[p.tok_i]) { + .keyword_const, .keyword_const1, .keyword_const2 => p.tok_i += 1, + else => _ = try p.expectIdentifier(), + } + const name = p.tokSlice(name_tok); + + const attr = Attribute.fromString(kind, namespace, name) orelse { + const tag: Diagnostics.Tag = if (kind == .declspec) .declspec_attr_not_supported else .unknown_attribute; + try p.errStr(tag, name_tok, name); + if (p.eatToken(.l_paren)) |_| p.skipTo(.r_paren); + return null; + }; + + const required_count = Attribute.requiredArgCount(attr); + var arguments = Attribute.initArguments(attr, name_tok); + var arg_idx: u32 = 0; + + switch (p.tok_ids[p.tok_i]) { + .comma, .r_paren => {}, // will be consumed in attributeList + .l_paren => blk: { + p.tok_i += 1; + if (p.eatToken(.r_paren)) |_| break :blk; + + if (Attribute.wantsIdentEnum(attr)) { + if (try p.eatIdentifier()) |ident| { + if (Attribute.diagnoseIdent(attr, &arguments, p.tokSlice(ident))) |msg| { + try p.errExtra(msg.tag, ident, msg.extra); + p.skipTo(.r_paren); + return error.ParsingFailed; + } + } else { + try p.errExtra(.attribute_requires_identifier, name_tok, .{ .str = name }); + return error.ParsingFailed; + } + } else { + const arg_start = p.tok_i; + var first_expr = try p.assignExpr(); + try first_expr.expect(p); + if (try p.diagnose(attr, &arguments, arg_idx, first_expr)) |msg| { + try p.errExtra(msg.tag, arg_start, msg.extra); + p.skipTo(.r_paren); + return error.ParsingFailed; + } + } + arg_idx += 1; + while (p.eatToken(.r_paren) == null) : (arg_idx += 1) { + _ = try p.expectToken(.comma); + + const arg_start = p.tok_i; + var arg_expr = try p.assignExpr(); + try arg_expr.expect(p); + if (try p.diagnose(attr, &arguments, arg_idx, arg_expr)) |msg| { + try p.errExtra(msg.tag, arg_start, msg.extra); + p.skipTo(.r_paren); + return error.ParsingFailed; + } + } + }, + else => {}, + } + if (arg_idx < required_count) { + try p.errExtra(.attribute_not_enough_args, name_tok, .{ .attr_arg_count = .{ .attribute = attr, .expected = required_count } }); + return error.ParsingFailed; + } + return TentativeAttribute{ .attr = .{ .tag = attr, .args = arguments, .syntax = kind.toSyntax() }, .tok = name_tok }; +} + +fn diagnose(p: *Parser, attr: Attribute.Tag, arguments: *Attribute.Arguments, arg_idx: u32, res: Result) !?Diagnostics.Message { + if (Attribute.wantsAlignment(attr, arg_idx)) { + return Attribute.diagnoseAlignment(attr, arguments, arg_idx, res, p); + } + const node = p.nodes.get(@intFromEnum(res.node)); + return Attribute.diagnose(attr, arguments, arg_idx, res, node, p); +} + +/// attributeList : (attribute (',' attribute)*)? +fn gnuAttributeList(p: *Parser) Error!void { + if (p.tok_ids[p.tok_i] == .r_paren) return; + + if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr); + while (p.tok_ids[p.tok_i] != .r_paren) { + _ = try p.expectToken(.comma); + if (try p.attribute(.gnu, null)) |attr| try p.attr_buf.append(p.gpa, attr); + } +} + +fn c23AttributeList(p: *Parser) Error!void { + while (p.tok_ids[p.tok_i] != .r_bracket) { + const namespace_tok = try p.expectIdentifier(); + var namespace: ?[]const u8 = null; + if (p.eatToken(.colon_colon)) |_| { + namespace = p.tokSlice(namespace_tok); + } else { + p.tok_i -= 1; + } + if (try p.attribute(.c23, namespace)) |attr| try p.attr_buf.append(p.gpa, attr); + _ = p.eatToken(.comma); + } +} + +fn msvcAttributeList(p: *Parser) Error!void { + while (p.tok_ids[p.tok_i] != .r_paren) { + if (try p.attribute(.declspec, null)) |attr| try p.attr_buf.append(p.gpa, attr); + _ = p.eatToken(.comma); + } +} + +fn c23Attribute(p: *Parser) !bool { + if (!p.comp.langopts.standard.atLeast(.c23)) return false; + const bracket1 = p.eatToken(.l_bracket) orelse return false; + const bracket2 = p.eatToken(.l_bracket) orelse { + p.tok_i -= 1; + return false; + }; + + try p.c23AttributeList(); + + _ = try p.expectClosing(bracket2, .r_bracket); + _ = try p.expectClosing(bracket1, .r_bracket); + + return true; +} + +fn msvcAttribute(p: *Parser) !bool { + _ = p.eatToken(.keyword_declspec) orelse return false; + const l_paren = try p.expectToken(.l_paren); + try p.msvcAttributeList(); + _ = try p.expectClosing(l_paren, .r_paren); + + return true; +} + +fn gnuAttribute(p: *Parser) !bool { + switch (p.tok_ids[p.tok_i]) { + .keyword_attribute1, .keyword_attribute2 => p.tok_i += 1, + else => return false, + } + const paren1 = try p.expectToken(.l_paren); + const paren2 = try p.expectToken(.l_paren); + + try p.gnuAttributeList(); + + _ = try p.expectClosing(paren2, .r_paren); + _ = try p.expectClosing(paren1, .r_paren); + return true; +} + +fn attributeSpecifier(p: *Parser) Error!void { + return attributeSpecifierExtra(p, null); +} + +/// attributeSpecifier : (keyword_attribute '( '(' attributeList ')' ')')* +fn attributeSpecifierExtra(p: *Parser, declarator_name: ?TokenIndex) Error!void { + while (true) { + if (try p.gnuAttribute()) continue; + if (try p.c23Attribute()) continue; + const maybe_declspec_tok = p.tok_i; + const attr_buf_top = p.attr_buf.len; + if (try p.msvcAttribute()) { + if (declarator_name) |name_tok| { + try p.errTok(.declspec_not_allowed_after_declarator, maybe_declspec_tok); + try p.errTok(.declarator_name_tok, name_tok); + p.attr_buf.len = attr_buf_top; + } + continue; + } + break; + } +} + +/// initDeclarator : declarator assembly? attributeSpecifier? ('=' initializer)? +fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?InitDeclarator { + const this_attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = this_attr_buf_top; + + var init_d = InitDeclarator{ + .d = (try p.declarator(decl_spec.ty, .normal)) orelse return null, + }; + + if (decl_spec.ty.is(.c23_auto) and !init_d.d.ty.is(.c23_auto)) { + try p.errTok(.c23_auto_plain_declarator, decl_spec.storage_class.auto); + return error.ParsingFailed; + } + + try p.attributeSpecifierExtra(init_d.d.name); + _ = try p.assembly(.decl_label); + try p.attributeSpecifierExtra(init_d.d.name); + + var apply_var_attributes = false; + if (decl_spec.storage_class == .typedef) { + if (decl_spec.auto_type) |tok_i| { + try p.errStr(.auto_type_not_allowed, tok_i, "typedef"); + return error.ParsingFailed; + } + init_d.d.ty = try Attribute.applyTypeAttributes(p, init_d.d.ty, attr_buf_top, null); + } else if (init_d.d.ty.isFunc()) { + init_d.d.ty = try Attribute.applyFunctionAttributes(p, init_d.d.ty, attr_buf_top); + } else { + apply_var_attributes = true; + } + const c23_auto = init_d.d.ty.is(.c23_auto); + const auto_type = init_d.d.ty.is(.auto_type); + + if (p.eatToken(.equal)) |eq| init: { + if (decl_spec.storage_class == .typedef or + (init_d.d.func_declarator != null and init_d.d.ty.isFunc())) + { + try p.errTok(.illegal_initializer, eq); + } else if (init_d.d.ty.is(.variable_len_array)) { + try p.errTok(.vla_init, eq); + } else if (decl_spec.storage_class == .@"extern") { + try p.err(.extern_initializer); + decl_spec.storage_class = .none; + } + + if (init_d.d.ty.hasIncompleteSize() and !init_d.d.ty.is(.incomplete_array)) { + try p.errStr(.variable_incomplete_ty, init_d.d.name, try p.typeStr(init_d.d.ty)); + return error.ParsingFailed; + } + if (p.tok_ids[p.tok_i] == .l_brace and init_d.d.ty.is(.c23_auto)) { + try p.errTok(.c23_auto_scalar_init, decl_spec.storage_class.auto); + return error.ParsingFailed; + } + + try p.syms.pushScope(p); + defer p.syms.popScope(); + + const interned_name = try StrInt.intern(p.comp, p.tokSlice(init_d.d.name)); + try p.syms.declareSymbol(p, interned_name, init_d.d.ty, init_d.d.name, .none); + if (c23_auto or auto_type) { + p.auto_type_decl_name = interned_name; + } + defer p.auto_type_decl_name = .empty; + + var init_list_expr = try p.initializer(init_d.d.ty); + init_d.initializer = init_list_expr; + if (!init_list_expr.ty.isArray()) break :init; + if (init_d.d.ty.is(.incomplete_array)) { + init_d.d.ty.setIncompleteArrayLen(init_list_expr.ty.arrayLen() orelse break :init); + } + } + + const name = init_d.d.name; + if (auto_type or c23_auto) { + if (init_d.initializer.node == .none) { + init_d.d.ty = Type.invalid; + if (c23_auto) { + try p.errStr(.c32_auto_requires_initializer, decl_spec.storage_class.auto, p.tokSlice(name)); + } else { + try p.errStr(.auto_type_requires_initializer, name, p.tokSlice(name)); + } + return init_d; + } else { + init_d.d.ty.specifier = init_d.initializer.ty.specifier; + init_d.d.ty.data = init_d.initializer.ty.data; + init_d.d.ty.decayed = init_d.initializer.ty.decayed; + } + } + if (apply_var_attributes) { + init_d.d.ty = try Attribute.applyVariableAttributes(p, init_d.d.ty, attr_buf_top, null); + } + if (decl_spec.storage_class != .typedef and init_d.d.ty.hasIncompleteSize()) incomplete: { + const specifier = init_d.d.ty.canonicalize(.standard).specifier; + if (decl_spec.storage_class == .@"extern") switch (specifier) { + .@"struct", .@"union", .@"enum" => break :incomplete, + .incomplete_array => { + init_d.d.ty.decayArray(); + break :incomplete; + }, + else => {}, + }; + // if there was an initializer expression it must have contained an error + if (init_d.initializer.node != .none) break :incomplete; + + if (p.func.ty == null) { + if (specifier == .incomplete_array) { + // TODO properly check this after finishing parsing + try p.errStr(.tentative_array, name, try p.typeStr(init_d.d.ty)); + break :incomplete; + } else if (init_d.d.ty.getRecord()) |record| { + _ = try p.tentative_defs.getOrPutValue(p.gpa, record.name, init_d.d.name); + break :incomplete; + } else if (init_d.d.ty.get(.@"enum")) |en| { + _ = try p.tentative_defs.getOrPutValue(p.gpa, en.data.@"enum".name, init_d.d.name); + break :incomplete; + } + } + try p.errStr(.variable_incomplete_ty, name, try p.typeStr(init_d.d.ty)); + } + return init_d; +} + +/// typeSpec +/// : keyword_void +/// | keyword_auto_type +/// | keyword_char +/// | keyword_short +/// | keyword_int +/// | keyword_long +/// | keyword_float +/// | keyword_double +/// | keyword_signed +/// | keyword_signed1 +/// | keyword_signed2 +/// | keyword_unsigned +/// | keyword_bool +/// | keyword_c23_bool +/// | keyword_complex +/// | atomicTypeSpec +/// | recordSpec +/// | enumSpec +/// | typedef // IDENTIFIER +/// | typeof +/// | keyword_bit_int '(' integerConstExpr ')' +/// atomicTypeSpec : keyword_atomic '(' typeName ')' +/// alignSpec +/// : keyword_alignas '(' typeName ')' +/// | keyword_alignas '(' integerConstExpr ')' +/// | keyword_c23_alignas '(' typeName ')' +/// | keyword_c23_alignas '(' integerConstExpr ')' +fn typeSpec(p: *Parser, ty: *Type.Builder) Error!bool { + const start = p.tok_i; + while (true) { + try p.attributeSpecifier(); + + if (try p.typeof()) |inner_ty| { + try ty.combineFromTypeof(p, inner_ty, start); + continue; + } + if (try p.typeQual(&ty.qual)) continue; + switch (p.tok_ids[p.tok_i]) { + .keyword_void => try ty.combine(p, .void, p.tok_i), + .keyword_auto_type => { + try p.errTok(.auto_type_extension, p.tok_i); + try ty.combine(p, .auto_type, p.tok_i); + }, + .keyword_bool, .keyword_c23_bool => try ty.combine(p, .bool, p.tok_i), + .keyword_int8, .keyword_int8_2, .keyword_char => try ty.combine(p, .char, p.tok_i), + .keyword_int16, .keyword_int16_2, .keyword_short => try ty.combine(p, .short, p.tok_i), + .keyword_int32, .keyword_int32_2, .keyword_int => try ty.combine(p, .int, p.tok_i), + .keyword_long => try ty.combine(p, .long, p.tok_i), + .keyword_int64, .keyword_int64_2 => try ty.combine(p, .long_long, p.tok_i), + .keyword_int128 => try ty.combine(p, .int128, p.tok_i), + .keyword_signed, .keyword_signed1, .keyword_signed2 => try ty.combine(p, .signed, p.tok_i), + .keyword_unsigned => try ty.combine(p, .unsigned, p.tok_i), + .keyword_fp16 => try ty.combine(p, .fp16, p.tok_i), + .keyword_float16 => try ty.combine(p, .float16, p.tok_i), + .keyword_float => try ty.combine(p, .float, p.tok_i), + .keyword_double => try ty.combine(p, .double, p.tok_i), + .keyword_complex => try ty.combine(p, .complex, p.tok_i), + .keyword_float128_1, .keyword_float128_2 => { + if (!p.comp.hasFloat128()) { + try p.errStr(.type_not_supported_on_target, p.tok_i, p.tok_ids[p.tok_i].lexeme().?); + } + try ty.combine(p, .float128, p.tok_i); + }, + .keyword_atomic => { + const atomic_tok = p.tok_i; + p.tok_i += 1; + const l_paren = p.eatToken(.l_paren) orelse { + // _Atomic qualifier not _Atomic(typeName) + p.tok_i = atomic_tok; + break; + }; + const inner_ty = (try p.typeName()) orelse { + try p.err(.expected_type); + return error.ParsingFailed; + }; + try p.expectClosing(l_paren, .r_paren); + + const new_spec = Type.Builder.fromType(inner_ty); + try ty.combine(p, new_spec, atomic_tok); + + if (ty.qual.atomic != null) + try p.errStr(.duplicate_decl_spec, atomic_tok, "atomic") + else + ty.qual.atomic = atomic_tok; + continue; + }, + .keyword_alignas, + .keyword_c23_alignas, + => { + const align_tok = p.tok_i; + p.tok_i += 1; + const l_paren = try p.expectToken(.l_paren); + const typename_start = p.tok_i; + if (try p.typeName()) |inner_ty| { + if (!inner_ty.alignable()) { + try p.errStr(.invalid_alignof, typename_start, try p.typeStr(inner_ty)); + } + const alignment = Attribute.Alignment{ .requested = inner_ty.alignof(p.comp) }; + try p.attr_buf.append(p.gpa, .{ + .attr = .{ .tag = .aligned, .args = .{ + .aligned = .{ .alignment = alignment, .__name_tok = align_tok }, + }, .syntax = .keyword }, + .tok = align_tok, + }); + } else { + const arg_start = p.tok_i; + const res = try p.integerConstExpr(.no_const_decl_folding); + if (!res.val.isZero(p.comp)) { + var args = Attribute.initArguments(.aligned, align_tok); + if (try p.diagnose(.aligned, &args, 0, res)) |msg| { + try p.errExtra(msg.tag, arg_start, msg.extra); + p.skipTo(.r_paren); + return error.ParsingFailed; + } + args.aligned.alignment.?.node = res.node; + try p.attr_buf.append(p.gpa, .{ + .attr = .{ .tag = .aligned, .args = args, .syntax = .keyword }, + .tok = align_tok, + }); + } + } + try p.expectClosing(l_paren, .r_paren); + continue; + }, + .keyword_stdcall, + .keyword_stdcall2, + .keyword_thiscall, + .keyword_thiscall2, + .keyword_vectorcall, + .keyword_vectorcall2, + => try p.attr_buf.append(p.gpa, .{ + .attr = .{ .tag = .calling_convention, .args = .{ + .calling_convention = .{ .cc = switch (p.tok_ids[p.tok_i]) { + .keyword_stdcall, + .keyword_stdcall2, + => .stdcall, + .keyword_thiscall, + .keyword_thiscall2, + => .thiscall, + .keyword_vectorcall, + .keyword_vectorcall2, + => .vectorcall, + else => unreachable, + } }, + }, .syntax = .keyword }, + .tok = p.tok_i, + }), + .keyword_struct, .keyword_union => { + const tag_tok = p.tok_i; + const record_ty = try p.recordSpec(); + try ty.combine(p, Type.Builder.fromType(record_ty), tag_tok); + continue; + }, + .keyword_enum => { + const tag_tok = p.tok_i; + const enum_ty = try p.enumSpec(); + try ty.combine(p, Type.Builder.fromType(enum_ty), tag_tok); + continue; + }, + .identifier, .extended_identifier => { + var interned_name = try StrInt.intern(p.comp, p.tokSlice(p.tok_i)); + var declspec_found = false; + + if (interned_name == p.string_ids.declspec_id) { + try p.errTok(.declspec_not_enabled, p.tok_i); + p.tok_i += 1; + if (p.eatToken(.l_paren)) |_| { + p.skipTo(.r_paren); + continue; + } + declspec_found = true; + } + if (ty.typedef != null) break; + if (declspec_found) { + interned_name = try StrInt.intern(p.comp, p.tokSlice(p.tok_i)); + } + const typedef = (try p.syms.findTypedef(p, interned_name, p.tok_i, ty.specifier != .none)) orelse break; + if (!ty.combineTypedef(p, typedef.ty, typedef.tok)) break; + }, + .keyword_bit_int => { + try p.err(.bit_int); + const bit_int_tok = p.tok_i; + p.tok_i += 1; + const l_paren = try p.expectToken(.l_paren); + const res = try p.integerConstExpr(.gnu_folding_extension); + try p.expectClosing(l_paren, .r_paren); + + var bits: u64 = undefined; + if (res.val.opt_ref == .none) { + try p.errTok(.expected_integer_constant_expr, bit_int_tok); + return error.ParsingFailed; + } else if (res.val.compare(.lte, Value.zero, p.comp)) { + bits = 0; + } else { + bits = res.val.toInt(u64, p.comp) orelse std.math.maxInt(u64); + } + + try ty.combine(p, .{ .bit_int = bits }, bit_int_tok); + continue; + }, + else => break, + } + // consume single token specifiers here + p.tok_i += 1; + } + return p.tok_i != start; +} + +fn getAnonymousName(p: *Parser, kind_tok: TokenIndex) !StringId { + const loc = p.pp.tokens.items(.loc)[kind_tok]; + const source = p.comp.getSource(loc.id); + const line_col = source.lineCol(loc); + + const kind_str = switch (p.tok_ids[kind_tok]) { + .keyword_struct, .keyword_union, .keyword_enum => p.tokSlice(kind_tok), + else => "record field", + }; + + const str = try std.fmt.allocPrint( + p.arena, + "(anonymous {s} at {s}:{d}:{d})", + .{ kind_str, source.path, line_col.line_no, line_col.col }, + ); + return StrInt.intern(p.comp, str); +} + +/// recordSpec +/// : (keyword_struct | keyword_union) IDENTIFIER? { recordDecl* } +/// | (keyword_struct | keyword_union) IDENTIFIER +fn recordSpec(p: *Parser) Error!Type { + const starting_pragma_pack = p.pragma_pack; + const kind_tok = p.tok_i; + const is_struct = p.tok_ids[kind_tok] == .keyword_struct; + p.tok_i += 1; + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + try p.attributeSpecifier(); + + const maybe_ident = try p.eatIdentifier(); + const l_brace = p.eatToken(.l_brace) orelse { + const ident = maybe_ident orelse { + try p.err(.ident_or_l_brace); + return error.ParsingFailed; + }; + // check if this is a reference to a previous type + const interned_name = try StrInt.intern(p.comp, p.tokSlice(ident)); + if (try p.syms.findTag(p, interned_name, p.tok_ids[kind_tok], ident, p.tok_ids[p.tok_i])) |prev| { + return prev.ty; + } else { + // this is a forward declaration, create a new record Type. + const record_ty = try Type.Record.create(p.arena, interned_name); + const ty = try Attribute.applyTypeAttributes(p, .{ + .specifier = if (is_struct) .@"struct" else .@"union", + .data = .{ .record = record_ty }, + }, attr_buf_top, null); + try p.syms.define(p.gpa, .{ + .kind = if (is_struct) .@"struct" else .@"union", + .name = interned_name, + .tok = ident, + .ty = ty, + .val = .{}, + }); + try p.decl_buf.append(try p.addNode(.{ + .tag = if (is_struct) .struct_forward_decl else .union_forward_decl, + .ty = ty, + .data = .{ .decl_ref = ident }, + .loc = @enumFromInt(ident), + })); + return ty; + } + }; + + var done = false; + errdefer if (!done) p.skipTo(.r_brace); + + // Get forward declared type or create a new one + var defined = false; + const record_ty: *Type.Record = if (maybe_ident) |ident| record_ty: { + const ident_str = p.tokSlice(ident); + const interned_name = try StrInt.intern(p.comp, ident_str); + if (try p.syms.defineTag(p, interned_name, p.tok_ids[kind_tok], ident)) |prev| { + if (!prev.ty.hasIncompleteSize()) { + // if the record isn't incomplete, this is a redefinition + try p.errStr(.redefinition, ident, ident_str); + try p.errTok(.previous_definition, prev.tok); + } else { + defined = true; + break :record_ty prev.ty.get(if (is_struct) .@"struct" else .@"union").?.data.record; + } + } + break :record_ty try Type.Record.create(p.arena, interned_name); + } else try Type.Record.create(p.arena, try p.getAnonymousName(kind_tok)); + + // Initially create ty as a regular non-attributed type, since attributes for a record + // can be specified after the closing rbrace, which we haven't encountered yet. + var ty = Type{ + .specifier = if (is_struct) .@"struct" else .@"union", + .data = .{ .record = record_ty }, + }; + + // declare a symbol for the type + // We need to replace the symbol's type if it has attributes + if (maybe_ident != null and !defined) { + try p.syms.define(p.gpa, .{ + .kind = if (is_struct) .@"struct" else .@"union", + .name = record_ty.name, + .tok = maybe_ident.?, + .ty = ty, + .val = .{}, + }); + } + + // reserve space for this record + try p.decl_buf.append(.none); + const decl_buf_top = p.decl_buf.items.len; + const record_buf_top = p.record_buf.items.len; + errdefer p.decl_buf.items.len = decl_buf_top - 1; + defer { + p.decl_buf.items.len = decl_buf_top; + p.record_buf.items.len = record_buf_top; + } + + const old_record = p.record; + const old_members = p.record_members.items.len; + const old_field_attr_start = p.field_attr_buf.items.len; + p.record = .{ + .kind = p.tok_ids[kind_tok], + .start = p.record_members.items.len, + .field_attr_start = p.field_attr_buf.items.len, + }; + defer p.record = old_record; + defer p.record_members.items.len = old_members; + defer p.field_attr_buf.items.len = old_field_attr_start; + + try p.recordDecls(); + + if (p.record.flexible_field) |some| { + if (p.record_buf.items[record_buf_top..].len == 1 and is_struct) { + try p.errTok(.flexible_in_empty, some); + } + } + + for (p.record_buf.items[record_buf_top..]) |field| { + if (field.ty.hasIncompleteSize() and !field.ty.is(.incomplete_array)) break; + } else { + record_ty.fields = try p.arena.dupe(Type.Record.Field, p.record_buf.items[record_buf_top..]); + } + const attr_count = p.field_attr_buf.items.len - old_field_attr_start; + const record_decls = p.decl_buf.items[decl_buf_top..]; + if (attr_count > 0) { + if (attr_count != record_decls.len) { + // A mismatch here means that non-field decls were parsed. This can happen if there were + // parse errors during attribute parsing. Bail here because if there are any field attributes, + // there must be exactly one per field. + return error.ParsingFailed; + } + const field_attr_slice = p.field_attr_buf.items[old_field_attr_start..]; + const duped = try p.arena.dupe([]const Attribute, field_attr_slice); + record_ty.field_attributes = duped.ptr; + } + + if (p.record_buf.items.len == record_buf_top) { + try p.errStr(.empty_record, kind_tok, p.tokSlice(kind_tok)); + try p.errStr(.empty_record_size, kind_tok, p.tokSlice(kind_tok)); + } + try p.expectClosing(l_brace, .r_brace); + done = true; + try p.attributeSpecifier(); + + ty = try Attribute.applyTypeAttributes(p, .{ + .specifier = if (is_struct) .@"struct" else .@"union", + .data = .{ .record = record_ty }, + }, attr_buf_top, null); + if (ty.specifier == .attributed and maybe_ident != null) { + const ident_str = p.tokSlice(maybe_ident.?); + const interned_name = try StrInt.intern(p.comp, ident_str); + const ptr = p.syms.getPtr(interned_name, .tags); + ptr.ty = ty; + } + + if (!ty.hasIncompleteSize()) { + const pragma_pack_value = switch (p.comp.langopts.emulate) { + .clang => starting_pragma_pack, + .gcc => p.pragma_pack, + // TODO: msvc considers `#pragma pack` on a per-field basis + .msvc => p.pragma_pack, + }; + record_layout.compute(record_ty, ty, p.comp, pragma_pack_value) catch |er| switch (er) { + error.Overflow => try p.errStr(.record_too_large, maybe_ident orelse kind_tok, try p.typeStr(ty)), + }; + } + + // finish by creating a node + var node: Tree.Node = .{ + .tag = if (is_struct) .struct_decl_two else .union_decl_two, + .ty = ty, + .data = .{ .two = .{ .none, .none } }, + .loc = @enumFromInt(maybe_ident orelse kind_tok), + }; + switch (record_decls.len) { + 0 => {}, + 1 => node.data = .{ .two = .{ record_decls[0], .none } }, + 2 => node.data = .{ .two = .{ record_decls[0], record_decls[1] } }, + else => { + node.tag = if (is_struct) .struct_decl else .union_decl; + node.data = .{ .range = try p.addList(record_decls) }; + }, + } + p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node); + if (p.func.ty == null) { + _ = p.tentative_defs.remove(record_ty.name); + } + return ty; +} + +/// recordDecl +/// : specQual (recordDeclarator (',' recordDeclarator)*)? ; +/// | staticAssert +fn recordDecls(p: *Parser) Error!void { + while (true) { + if (try p.pragma()) continue; + if (try p.parseOrNextDecl(staticAssert)) continue; + if (p.eatToken(.keyword_extension)) |_| { + const saved_extension = p.extension_suppressed; + defer p.extension_suppressed = saved_extension; + p.extension_suppressed = true; + + if (try p.parseOrNextDecl(recordDeclarator)) continue; + try p.err(.expected_type); + p.nextExternDecl(); + continue; + } + if (try p.parseOrNextDecl(recordDeclarator)) continue; + break; + } +} + +/// recordDeclarator : keyword_extension? declarator (':' integerConstExpr)? +fn recordDeclarator(p: *Parser) Error!bool { + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + const base_ty = (try p.specQual()) orelse return false; + + try p.attributeSpecifier(); // .record + while (true) { + const this_decl_top = p.attr_buf.len; + defer p.attr_buf.len = this_decl_top; + + try p.attributeSpecifier(); + + // 0 means unnamed + var name_tok: TokenIndex = 0; + var ty = base_ty; + if (ty.is(.auto_type)) { + try p.errStr(.auto_type_not_allowed, p.tok_i, if (p.record.kind == .keyword_struct) "struct member" else "union member"); + ty = Type.invalid; + } + var bits_node: NodeIndex = .none; + var bits: ?u32 = null; + const first_tok = p.tok_i; + if (try p.declarator(ty, .record)) |d| { + name_tok = d.name; + ty = d.ty; + } + + if (p.eatToken(.colon)) |_| bits: { + const bits_tok = p.tok_i; + const res = try p.integerConstExpr(.gnu_folding_extension); + if (!ty.isInt()) { + try p.errStr(.non_int_bitfield, first_tok, try p.typeStr(ty)); + break :bits; + } + + if (res.val.opt_ref == .none) { + try p.errTok(.expected_integer_constant_expr, bits_tok); + break :bits; + } else if (res.val.compare(.lt, Value.zero, p.comp)) { + try p.errStr(.negative_bitwidth, first_tok, try res.str(p)); + break :bits; + } + + // incomplete size error is reported later + const bit_size = ty.bitSizeof(p.comp) orelse break :bits; + const bits_unchecked = res.val.toInt(u32, p.comp) orelse std.math.maxInt(u32); + if (bits_unchecked > bit_size) { + try p.errTok(.bitfield_too_big, name_tok); + break :bits; + } else if (bits_unchecked == 0 and name_tok != 0) { + try p.errTok(.zero_width_named_field, name_tok); + break :bits; + } + + bits = bits_unchecked; + bits_node = res.node; + } + + try p.attributeSpecifier(); // .record + const to_append = try Attribute.applyFieldAttributes(p, &ty, attr_buf_top); + + const any_fields_have_attrs = p.field_attr_buf.items.len > p.record.field_attr_start; + + if (any_fields_have_attrs) { + try p.field_attr_buf.append(to_append); + } else { + if (to_append.len > 0) { + const preceding = p.record_members.items.len - p.record.start; + if (preceding > 0) { + try p.field_attr_buf.appendNTimes(&.{}, preceding); + } + try p.field_attr_buf.append(to_append); + } + } + + if (name_tok == 0 and bits_node == .none) unnamed: { + if (ty.is(.@"enum") or ty.hasIncompleteSize()) break :unnamed; + if (ty.isAnonymousRecord(p.comp)) { + // An anonymous record appears as indirect fields on the parent + try p.record_buf.append(.{ + .name = try p.getAnonymousName(first_tok), + .ty = ty, + }); + const node = try p.addNode(.{ + .tag = .indirect_record_field_decl, + .ty = ty, + .data = undefined, + .loc = @enumFromInt(first_tok), + }); + try p.decl_buf.append(node); + try p.record.addFieldsFromAnonymous(p, ty); + break; // must be followed by a semicolon + } + try p.err(.missing_declaration); + } else { + const interned_name = if (name_tok != 0) try StrInt.intern(p.comp, p.tokSlice(name_tok)) else try p.getAnonymousName(first_tok); + try p.record_buf.append(.{ + .name = interned_name, + .ty = ty, + .name_tok = name_tok, + .bit_width = bits, + }); + if (name_tok != 0) try p.record.addField(p, interned_name, name_tok); + const node = try p.addNode(.{ + .tag = .record_field_decl, + .ty = ty, + .data = .{ .decl = .{ .name = name_tok, .node = bits_node } }, + .loc = @enumFromInt(if (name_tok != 0) name_tok else first_tok), + }); + try p.decl_buf.append(node); + } + + if (ty.isFunc()) { + try p.errTok(.func_field, first_tok); + } else if (ty.is(.variable_len_array)) { + try p.errTok(.vla_field, first_tok); + } else if (ty.is(.incomplete_array)) { + if (p.record.kind == .keyword_union) { + try p.errTok(.flexible_in_union, first_tok); + } + if (p.record.flexible_field) |some| { + if (p.record.kind == .keyword_struct) { + try p.errTok(.flexible_non_final, some); + } + } + p.record.flexible_field = first_tok; + } else if (ty.specifier != .invalid and ty.hasIncompleteSize()) { + try p.errStr(.field_incomplete_ty, first_tok, try p.typeStr(ty)); + } else if (p.record.flexible_field) |some| { + if (some != first_tok and p.record.kind == .keyword_struct) try p.errTok(.flexible_non_final, some); + } + if (p.eatToken(.comma) == null) break; + } + + if (p.eatToken(.semicolon) == null) { + const tok_id = p.tok_ids[p.tok_i]; + if (tok_id == .r_brace) { + try p.err(.missing_semicolon); + } else { + return p.errExpectedToken(.semicolon, tok_id); + } + } + + return true; +} + +/// specQual : (typeSpec | typeQual | alignSpec)+ +fn specQual(p: *Parser) Error!?Type { + var spec: Type.Builder = .{}; + if (try p.typeSpec(&spec)) { + return try spec.finish(p); + } + return null; +} + +/// enumSpec +/// : keyword_enum IDENTIFIER? (: typeName)? { enumerator (',' enumerator)? ',') } +/// | keyword_enum IDENTIFIER (: typeName)? +fn enumSpec(p: *Parser) Error!Type { + const enum_tok = p.tok_i; + p.tok_i += 1; + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + try p.attributeSpecifier(); + + const maybe_ident = try p.eatIdentifier(); + const fixed_ty = if (p.eatToken(.colon)) |colon| fixed: { + const ty_start = p.tok_i; + const fixed = (try p.specQual()) orelse { + if (p.record.kind != .invalid) { + // This is a bit field. + p.tok_i -= 1; + break :fixed null; + } + try p.err(.expected_type); + try p.errTok(.enum_fixed, colon); + break :fixed null; + }; + + if (!fixed.isInt() or fixed.is(.@"enum")) { + try p.errStr(.invalid_type_underlying_enum, ty_start, try p.typeStr(fixed)); + break :fixed Type.int; + } + + try p.errTok(.enum_fixed, colon); + break :fixed fixed; + } else null; + + const l_brace = p.eatToken(.l_brace) orelse { + const ident = maybe_ident orelse { + try p.err(.ident_or_l_brace); + return error.ParsingFailed; + }; + // check if this is a reference to a previous type + const interned_name = try StrInt.intern(p.comp, p.tokSlice(ident)); + if (try p.syms.findTag(p, interned_name, .keyword_enum, ident, p.tok_ids[p.tok_i])) |prev| { + // only check fixed underlying type in forward declarations and not in references. + if (p.tok_ids[p.tok_i] == .semicolon) + try p.checkEnumFixedTy(fixed_ty, ident, prev); + return prev.ty; + } else { + // this is a forward declaration, create a new enum Type. + const enum_ty = try Type.Enum.create(p.arena, interned_name, fixed_ty); + const ty = try Attribute.applyTypeAttributes(p, .{ + .specifier = .@"enum", + .data = .{ .@"enum" = enum_ty }, + }, attr_buf_top, null); + try p.syms.define(p.gpa, .{ + .kind = .@"enum", + .name = interned_name, + .tok = ident, + .ty = ty, + .val = .{}, + }); + try p.decl_buf.append(try p.addNode(.{ + .tag = .enum_forward_decl, + .ty = ty, + .data = .{ .decl_ref = ident }, + .loc = @enumFromInt(ident), + })); + return ty; + } + }; + + var done = false; + errdefer if (!done) p.skipTo(.r_brace); + + // Get forward declared type or create a new one + var defined = false; + const enum_ty: *Type.Enum = if (maybe_ident) |ident| enum_ty: { + const ident_str = p.tokSlice(ident); + const interned_name = try StrInt.intern(p.comp, ident_str); + if (try p.syms.defineTag(p, interned_name, .keyword_enum, ident)) |prev| { + const enum_ty = prev.ty.get(.@"enum").?.data.@"enum"; + if (!enum_ty.isIncomplete() and !enum_ty.fixed) { + // if the enum isn't incomplete, this is a redefinition + try p.errStr(.redefinition, ident, ident_str); + try p.errTok(.previous_definition, prev.tok); + } else { + try p.checkEnumFixedTy(fixed_ty, ident, prev); + defined = true; + break :enum_ty enum_ty; + } + } + break :enum_ty try Type.Enum.create(p.arena, interned_name, fixed_ty); + } else try Type.Enum.create(p.arena, try p.getAnonymousName(enum_tok), fixed_ty); + + // reserve space for this enum + try p.decl_buf.append(.none); + const decl_buf_top = p.decl_buf.items.len; + const list_buf_top = p.list_buf.items.len; + const enum_buf_top = p.enum_buf.items.len; + errdefer p.decl_buf.items.len = decl_buf_top - 1; + defer { + p.decl_buf.items.len = decl_buf_top; + p.list_buf.items.len = list_buf_top; + p.enum_buf.items.len = enum_buf_top; + } + + var e = Enumerator.init(fixed_ty); + while (try p.enumerator(&e)) |field_and_node| { + try p.enum_buf.append(field_and_node.field); + try p.list_buf.append(field_and_node.node); + if (p.eatToken(.comma) == null) break; + } + + if (p.enum_buf.items.len == enum_buf_top) try p.err(.empty_enum); + try p.expectClosing(l_brace, .r_brace); + done = true; + try p.attributeSpecifier(); + + const ty = try Attribute.applyTypeAttributes(p, .{ + .specifier = .@"enum", + .data = .{ .@"enum" = enum_ty }, + }, attr_buf_top, null); + if (!enum_ty.fixed) { + const tag_specifier = try e.getTypeSpecifier(p, ty.enumIsPacked(p.comp), maybe_ident orelse enum_tok); + enum_ty.tag_ty = .{ .specifier = tag_specifier }; + } + + const enum_fields = p.enum_buf.items[enum_buf_top..]; + const field_nodes = p.list_buf.items[list_buf_top..]; + + if (fixed_ty == null) { + for (enum_fields, 0..) |*field, i| { + if (field.ty.eql(Type.int, p.comp, false)) continue; + + const sym = p.syms.get(field.name, .vars) orelse continue; + if (sym.kind != .enumeration) continue; // already an error + + var res = Result{ .node = field.node, .ty = field.ty, .val = sym.val }; + const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some| + Type{ .specifier = some } + else if (try res.intFitsInType(p, Type.int)) + Type.int + else if (!res.ty.eql(enum_ty.tag_ty, p.comp, false)) + enum_ty.tag_ty + else + continue; + + const symbol = p.syms.getPtr(field.name, .vars); + _ = try symbol.val.intCast(dest_ty, p.comp); + symbol.ty = dest_ty; + p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty; + field.ty = dest_ty; + res.ty = dest_ty; + + if (res.node != .none) { + try res.implicitCast(p, .int_cast); + field.node = res.node; + p.nodes.items(.data)[@intFromEnum(field_nodes[i])].decl.node = res.node; + } + } + } + + enum_ty.fields = try p.arena.dupe(Type.Enum.Field, enum_fields); + + // declare a symbol for the type + if (maybe_ident != null and !defined) { + try p.syms.define(p.gpa, .{ + .kind = .@"enum", + .name = enum_ty.name, + .ty = ty, + .tok = maybe_ident.?, + .val = .{}, + }); + } + + // finish by creating a node + var node: Tree.Node = .{ + .tag = .enum_decl_two, + .ty = ty, + .data = .{ + .two = .{ .none, .none }, + }, + .loc = @enumFromInt(maybe_ident orelse enum_tok), + }; + switch (field_nodes.len) { + 0 => {}, + 1 => node.data = .{ .two = .{ field_nodes[0], .none } }, + 2 => node.data = .{ .two = .{ field_nodes[0], field_nodes[1] } }, + else => { + node.tag = .enum_decl; + node.data = .{ .range = try p.addList(field_nodes) }; + }, + } + p.decl_buf.items[decl_buf_top - 1] = try p.addNode(node); + if (p.func.ty == null) { + _ = p.tentative_defs.remove(enum_ty.name); + } + return ty; +} + +fn checkEnumFixedTy(p: *Parser, fixed_ty: ?Type, ident_tok: TokenIndex, prev: Symbol) !void { + const enum_ty = prev.ty.get(.@"enum").?.data.@"enum"; + if (fixed_ty) |some| { + if (!enum_ty.fixed) { + try p.errTok(.enum_prev_nonfixed, ident_tok); + try p.errTok(.previous_definition, prev.tok); + return error.ParsingFailed; + } + + if (!enum_ty.tag_ty.eql(some, p.comp, false)) { + const str = try p.typePairStrExtra(some, " (was ", enum_ty.tag_ty); + try p.errStr(.enum_different_explicit_ty, ident_tok, str); + try p.errTok(.previous_definition, prev.tok); + return error.ParsingFailed; + } + } else if (enum_ty.fixed) { + try p.errTok(.enum_prev_fixed, ident_tok); + try p.errTok(.previous_definition, prev.tok); + return error.ParsingFailed; + } +} + +const Enumerator = struct { + res: Result, + num_positive_bits: usize = 0, + num_negative_bits: usize = 0, + fixed: bool, + + fn init(fixed_ty: ?Type) Enumerator { + return .{ + .res = .{ .ty = fixed_ty orelse .{ .specifier = .int } }, + .fixed = fixed_ty != null, + }; + } + + /// Increment enumerator value adjusting type if needed. + fn incr(e: *Enumerator, p: *Parser, tok: TokenIndex) !void { + e.res.node = .none; + const old_val = e.res.val; + if (old_val.opt_ref == .none) { + // First enumerator, set to 0 fits in all types. + e.res.val = Value.zero; + return; + } + if (try e.res.val.add(e.res.val, Value.one, e.res.ty, p.comp)) { + if (e.fixed) { + try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty)); + return; + } + const new_ty = if (p.comp.nextLargestIntSameSign(e.res.ty)) |larger| blk: { + try p.errTok(.enumerator_overflow, tok); + break :blk larger; + } else blk: { + const signed = !e.res.ty.isUnsignedInt(p.comp); + const bit_size: u8 = @intCast(e.res.ty.bitSizeof(p.comp).? - @intFromBool(signed)); + try p.errExtra(.enum_not_representable, tok, .{ .pow_2_as_string = bit_size }); + break :blk Type{ .specifier = .ulong_long }; + }; + e.res.ty = new_ty; + _ = try e.res.val.add(old_val, Value.one, e.res.ty, p.comp); + } + } + + /// Set enumerator value to specified value. + fn set(e: *Enumerator, p: *Parser, res: Result, tok: TokenIndex) !void { + if (res.ty.specifier == .invalid) return; + if (e.fixed and !res.ty.eql(e.res.ty, p.comp, false)) { + if (!try res.intFitsInType(p, e.res.ty)) { + try p.errStr(.enum_not_representable_fixed, tok, try p.typeStr(e.res.ty)); + return error.ParsingFailed; + } + var copy = res; + copy.ty = e.res.ty; + try copy.implicitCast(p, .int_cast); + e.res = copy; + } else { + e.res = res; + try e.res.intCast(p, e.res.ty.integerPromotion(p.comp), tok); + } + } + + fn getTypeSpecifier(e: *const Enumerator, p: *Parser, is_packed: bool, tok: TokenIndex) !Type.Specifier { + if (p.comp.fixedEnumTagSpecifier()) |tag_specifier| return tag_specifier; + + const char_width = (Type{ .specifier = .schar }).sizeof(p.comp).? * 8; + const short_width = (Type{ .specifier = .short }).sizeof(p.comp).? * 8; + const int_width = (Type{ .specifier = .int }).sizeof(p.comp).? * 8; + if (e.num_negative_bits > 0) { + if (is_packed and e.num_negative_bits <= char_width and e.num_positive_bits < char_width) { + return .schar; + } else if (is_packed and e.num_negative_bits <= short_width and e.num_positive_bits < short_width) { + return .short; + } else if (e.num_negative_bits <= int_width and e.num_positive_bits < int_width) { + return .int; + } + const long_width = (Type{ .specifier = .long }).sizeof(p.comp).? * 8; + if (e.num_negative_bits <= long_width and e.num_positive_bits < long_width) { + return .long; + } + const long_long_width = (Type{ .specifier = .long_long }).sizeof(p.comp).? * 8; + if (e.num_negative_bits > long_long_width or e.num_positive_bits >= long_long_width) { + try p.errTok(.enum_too_large, tok); + } + return .long_long; + } + if (is_packed and e.num_positive_bits <= char_width) { + return .uchar; + } else if (is_packed and e.num_positive_bits <= short_width) { + return .ushort; + } else if (e.num_positive_bits <= int_width) { + return .uint; + } else if (e.num_positive_bits <= (Type{ .specifier = .long }).sizeof(p.comp).? * 8) { + return .ulong; + } + return .ulong_long; + } +}; + +const EnumFieldAndNode = struct { field: Type.Enum.Field, node: NodeIndex }; + +/// enumerator : IDENTIFIER ('=' integerConstExpr) +fn enumerator(p: *Parser, e: *Enumerator) Error!?EnumFieldAndNode { + _ = try p.pragma(); + const name_tok = (try p.eatIdentifier()) orelse { + if (p.tok_ids[p.tok_i] == .r_brace) return null; + try p.err(.expected_identifier); + p.skipTo(.r_brace); + return error.ParsingFailed; + }; + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + try p.attributeSpecifier(); + + const err_start = p.comp.diagnostics.list.items.len; + if (p.eatToken(.equal)) |_| { + const specified = try p.integerConstExpr(.gnu_folding_extension); + if (specified.val.opt_ref == .none) { + try p.errTok(.enum_val_unavailable, name_tok + 2); + try e.incr(p, name_tok); + } else { + try e.set(p, specified, name_tok); + } + } else { + try e.incr(p, name_tok); + } + + var res = e.res; + res.ty = try Attribute.applyEnumeratorAttributes(p, res.ty, attr_buf_top); + + if (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, Value.zero, p.comp)) { + e.num_positive_bits = @max(e.num_positive_bits, res.val.minUnsignedBits(p.comp)); + } else { + e.num_negative_bits = @max(e.num_negative_bits, res.val.minSignedBits(p.comp)); + } + + if (err_start == p.comp.diagnostics.list.items.len) { + // only do these warnings if we didn't already warn about overflow or non-representable values + if (e.res.val.compare(.lt, Value.zero, p.comp)) { + const min_val = try Value.minInt(Type.int, p.comp); + if (e.res.val.compare(.lt, min_val, p.comp)) { + try p.errStr(.enumerator_too_small, name_tok, try e.res.str(p)); + } + } else { + const max_val = try Value.maxInt(Type.int, p.comp); + if (e.res.val.compare(.gt, max_val, p.comp)) { + try p.errStr(.enumerator_too_large, name_tok, try e.res.str(p)); + } + } + } + + const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok)); + try p.syms.defineEnumeration(p, interned_name, res.ty, name_tok, e.res.val); + const node = try p.addNode(.{ + .tag = .enum_field_decl, + .ty = res.ty, + .data = .{ .decl = .{ + .name = name_tok, + .node = res.node, + } }, + .loc = @enumFromInt(name_tok), + }); + try p.value_map.put(node, e.res.val); + return EnumFieldAndNode{ .field = .{ + .name = interned_name, + .ty = res.ty, + .name_tok = name_tok, + .node = res.node, + }, .node = node }; +} + +/// typeQual : keyword_const | keyword_restrict | keyword_volatile | keyword_atomic +fn typeQual(p: *Parser, b: *Type.Qualifiers.Builder) Error!bool { + var any = false; + while (true) { + switch (p.tok_ids[p.tok_i]) { + .keyword_restrict, .keyword_restrict1, .keyword_restrict2 => { + if (b.restrict != null) + try p.errStr(.duplicate_decl_spec, p.tok_i, "restrict") + else + b.restrict = p.tok_i; + }, + .keyword_const, .keyword_const1, .keyword_const2 => { + if (b.@"const" != null) + try p.errStr(.duplicate_decl_spec, p.tok_i, "const") + else + b.@"const" = p.tok_i; + }, + .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => { + if (b.@"volatile" != null) + try p.errStr(.duplicate_decl_spec, p.tok_i, "volatile") + else + b.@"volatile" = p.tok_i; + }, + .keyword_atomic => { + // _Atomic(typeName) instead of just _Atomic + if (p.tok_ids[p.tok_i + 1] == .l_paren) break; + if (b.atomic != null) + try p.errStr(.duplicate_decl_spec, p.tok_i, "atomic") + else + b.atomic = p.tok_i; + }, + else => break, + } + p.tok_i += 1; + any = true; + } + return any; +} + +const Declarator = struct { + name: TokenIndex, + ty: Type, + func_declarator: ?TokenIndex = null, + old_style_func: ?TokenIndex = null, +}; +const DeclaratorKind = enum { normal, abstract, param, record }; + +/// declarator : pointer? (IDENTIFIER | '(' declarator ')') directDeclarator* +/// abstractDeclarator +/// : pointer? ('(' abstractDeclarator ')')? directAbstractDeclarator* +fn declarator( + p: *Parser, + base_type: Type, + kind: DeclaratorKind, +) Error!?Declarator { + const start = p.tok_i; + var d = Declarator{ .name = 0, .ty = try p.pointer(base_type) }; + if (base_type.is(.auto_type) and !d.ty.is(.auto_type)) { + try p.errTok(.auto_type_requires_plain_declarator, start); + return error.ParsingFailed; + } + + const maybe_ident = p.tok_i; + if (kind != .abstract and (try p.eatIdentifier()) != null) { + d.name = maybe_ident; + const combine_tok = p.tok_i; + d.ty = try p.directDeclarator(d.ty, &d, kind); + try d.ty.validateCombinedType(p, combine_tok); + return d; + } else if (p.eatToken(.l_paren)) |l_paren| blk: { + var res = (try p.declarator(.{ .specifier = .void }, kind)) orelse { + p.tok_i = l_paren; + break :blk; + }; + try p.expectClosing(l_paren, .r_paren); + const suffix_start = p.tok_i; + const outer = try p.directDeclarator(d.ty, &d, kind); + try res.ty.combine(outer); + try res.ty.validateCombinedType(p, suffix_start); + res.old_style_func = d.old_style_func; + if (d.func_declarator) |some| res.func_declarator = some; + return res; + } + + const expected_ident = p.tok_i; + + d.ty = try p.directDeclarator(d.ty, &d, kind); + + if (kind == .normal and !d.ty.isEnumOrRecord()) { + try p.errTok(.expected_ident_or_l_paren, expected_ident); + return error.ParsingFailed; + } + try d.ty.validateCombinedType(p, expected_ident); + if (start == p.tok_i) return null; + return d; +} + +/// directDeclarator +/// : '[' typeQual* assignExpr? ']' directDeclarator? +/// | '[' keyword_static typeQual* assignExpr ']' directDeclarator? +/// | '[' typeQual+ keyword_static assignExpr ']' directDeclarator? +/// | '[' typeQual* '*' ']' directDeclarator? +/// | '(' paramDecls ')' directDeclarator? +/// | '(' (IDENTIFIER (',' IDENTIFIER))? ')' directDeclarator? +/// directAbstractDeclarator +/// : '[' typeQual* assignExpr? ']' +/// | '[' keyword_static typeQual* assignExpr ']' +/// | '[' typeQual+ keyword_static assignExpr ']' +/// | '[' '*' ']' +/// | '(' paramDecls? ')' +fn directDeclarator(p: *Parser, base_type: Type, d: *Declarator, kind: DeclaratorKind) Error!Type { + if (p.eatToken(.l_bracket)) |l_bracket| { + if (p.tok_ids[p.tok_i] == .l_bracket) { + switch (kind) { + .normal, .record => if (p.comp.langopts.standard.atLeast(.c23)) { + p.tok_i -= 1; + return base_type; + }, + .param, .abstract => {}, + } + try p.err(.expected_expr); + return error.ParsingFailed; + } + var res_ty = Type{ + // so that we can get any restrict type that might be present + .specifier = .pointer, + }; + var quals = Type.Qualifiers.Builder{}; + + var got_quals = try p.typeQual(&quals); + var static = p.eatToken(.keyword_static); + if (static != null and !got_quals) got_quals = try p.typeQual(&quals); + var star = p.eatToken(.asterisk); + const size_tok = p.tok_i; + + const const_decl_folding = p.const_decl_folding; + p.const_decl_folding = .gnu_vla_folding_extension; + const size = if (star) |_| Result{} else try p.assignExpr(); + p.const_decl_folding = const_decl_folding; + + try p.expectClosing(l_bracket, .r_bracket); + + if (star != null and static != null) { + try p.errTok(.invalid_static_star, static.?); + static = null; + } + if (kind != .param) { + if (static != null) + try p.errTok(.static_non_param, l_bracket) + else if (got_quals) + try p.errTok(.array_qualifiers, l_bracket); + if (star) |some| try p.errTok(.star_non_param, some); + static = null; + quals = .{}; + star = null; + } else { + try quals.finish(p, &res_ty); + } + if (static) |_| try size.expect(p); + + if (base_type.is(.auto_type)) { + try p.errStr(.array_of_auto_type, d.name, p.tokSlice(d.name)); + return error.ParsingFailed; + } + + const outer = try p.directDeclarator(base_type, d, kind); + + if (!size.ty.isInt()) { + try p.errStr(.array_size_non_int, size_tok, try p.typeStr(size.ty)); + return error.ParsingFailed; + } + if (base_type.is(.c23_auto) or outer.is(.invalid)) { + // issue error later + return Type.invalid; + } else if (size.val.opt_ref == .none) { + if (size.node != .none) { + try p.errTok(.vla, size_tok); + if (p.func.ty == null and kind != .param and p.record.kind == .invalid) { + try p.errTok(.variable_len_array_file_scope, d.name); + } + const expr_ty = try p.arena.create(Type.Expr); + expr_ty.ty = .{ .specifier = .void }; + expr_ty.node = size.node; + res_ty.data = .{ .expr = expr_ty }; + res_ty.specifier = .variable_len_array; + + if (static) |some| try p.errTok(.useless_static, some); + } else if (star) |_| { + const elem_ty = try p.arena.create(Type); + elem_ty.* = .{ .specifier = .void }; + res_ty.data = .{ .sub_type = elem_ty }; + res_ty.specifier = .unspecified_variable_len_array; + } else { + const arr_ty = try p.arena.create(Type.Array); + arr_ty.elem = .{ .specifier = .void }; + arr_ty.len = 0; + res_ty.data = .{ .array = arr_ty }; + res_ty.specifier = .incomplete_array; + } + } else { + // `outer` is validated later so it may be invalid here + const outer_size = outer.sizeof(p.comp); + const max_elems = p.comp.maxArrayBytes() / @max(1, outer_size orelse 1); + + var size_val = size.val; + if (size_val.isZero(p.comp)) { + try p.errTok(.zero_length_array, l_bracket); + } else if (size_val.compare(.lt, Value.zero, p.comp)) { + try p.errTok(.negative_array_size, l_bracket); + return error.ParsingFailed; + } + const arr_ty = try p.arena.create(Type.Array); + arr_ty.elem = .{ .specifier = .void }; + arr_ty.len = size_val.toInt(u64, p.comp) orelse std.math.maxInt(u64); + if (arr_ty.len > max_elems) { + try p.errTok(.array_too_large, l_bracket); + arr_ty.len = max_elems; + } + res_ty.data = .{ .array = arr_ty }; + res_ty.specifier = if (static != null) .static_array else .array; + } + + try res_ty.combine(outer); + return res_ty; + } else if (p.eatToken(.l_paren)) |l_paren| { + d.func_declarator = l_paren; + + const func_ty = try p.arena.create(Type.Func); + func_ty.params = &.{}; + func_ty.return_type.specifier = .void; + var specifier: Type.Specifier = .func; + + if (p.eatToken(.ellipsis)) |_| { + try p.err(.param_before_var_args); + try p.expectClosing(l_paren, .r_paren); + var res_ty = Type{ .specifier = .func, .data = .{ .func = func_ty } }; + + const outer = try p.directDeclarator(base_type, d, kind); + try res_ty.combine(outer); + return res_ty; + } + + if (try p.paramDecls(d)) |params| { + func_ty.params = params; + if (p.eatToken(.ellipsis)) |_| specifier = .var_args_func; + } else if (p.tok_ids[p.tok_i] == .r_paren) { + specifier = if (p.comp.langopts.standard.atLeast(.c23)) + .func + else + .old_style_func; + } else if (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) { + d.old_style_func = p.tok_i; + const param_buf_top = p.param_buf.items.len; + try p.syms.pushScope(p); + defer { + p.param_buf.items.len = param_buf_top; + p.syms.popScope(); + } + + specifier = .old_style_func; + while (true) { + const name_tok = try p.expectIdentifier(); + const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok)); + try p.syms.defineParam(p, interned_name, undefined, name_tok); + try p.param_buf.append(.{ + .name = interned_name, + .name_tok = name_tok, + .ty = .{ .specifier = .int }, + }); + if (p.eatToken(.comma) == null) break; + } + func_ty.params = try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]); + } else { + try p.err(.expected_param_decl); + } + + try p.expectClosing(l_paren, .r_paren); + var res_ty = Type{ + .specifier = specifier, + .data = .{ .func = func_ty }, + }; + + const outer = try p.directDeclarator(base_type, d, kind); + try res_ty.combine(outer); + return res_ty; + } else return base_type; +} + +/// pointer : '*' typeQual* pointer? +fn pointer(p: *Parser, base_ty: Type) Error!Type { + var ty = base_ty; + while (p.eatToken(.asterisk)) |_| { + if (!ty.is(.invalid)) { + const elem_ty = try p.arena.create(Type); + elem_ty.* = ty; + ty = Type{ + .specifier = .pointer, + .data = .{ .sub_type = elem_ty }, + }; + } + var quals = Type.Qualifiers.Builder{}; + _ = try p.typeQual(&quals); + try quals.finish(p, &ty); + } + return ty; +} + +/// paramDecls : paramDecl (',' paramDecl)* (',' '...') +/// paramDecl : declSpec (declarator | abstractDeclarator) +fn paramDecls(p: *Parser, d: *Declarator) Error!?[]Type.Func.Param { + // TODO warn about visibility of types declared here + const param_buf_top = p.param_buf.items.len; + defer p.param_buf.items.len = param_buf_top; + try p.syms.pushScope(p); + defer p.syms.popScope(); + + while (true) { + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + const param_decl_spec = if (try p.declSpec()) |some| + some + else if (p.comp.langopts.standard.atLeast(.c23) and + (p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier)) + { + // handle deprecated K&R style parameters + const identifier = try p.expectIdentifier(); + try p.errStr(.unknown_type_name, identifier, p.tokSlice(identifier)); + if (d.old_style_func == null) d.old_style_func = identifier; + + try p.param_buf.append(.{ + .name = try StrInt.intern(p.comp, p.tokSlice(identifier)), + .name_tok = identifier, + .ty = .{ .specifier = .int }, + }); + + if (p.eatToken(.comma) == null) break; + if (p.tok_ids[p.tok_i] == .ellipsis) break; + continue; + } else if (p.param_buf.items.len == param_buf_top) { + return null; + } else blk: { + var spec: Type.Builder = .{}; + break :blk DeclSpec{ .ty = try spec.finish(p) }; + }; + + var name_tok: TokenIndex = 0; + const first_tok = p.tok_i; + var param_ty = param_decl_spec.ty; + if (try p.declarator(param_decl_spec.ty, .param)) |some| { + if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i); + try p.attributeSpecifier(); + + name_tok = some.name; + param_ty = some.ty; + if (some.name != 0) { + const interned_name = try StrInt.intern(p.comp, p.tokSlice(name_tok)); + try p.syms.defineParam(p, interned_name, param_ty, name_tok); + } + } + param_ty = try Attribute.applyParameterAttributes(p, param_ty, attr_buf_top, .alignas_on_param); + + if (param_ty.isFunc()) { + // params declared as functions are converted to function pointers + const elem_ty = try p.arena.create(Type); + elem_ty.* = param_ty; + param_ty = Type{ + .specifier = .pointer, + .data = .{ .sub_type = elem_ty }, + }; + } else if (param_ty.isArray()) { + // params declared as arrays are converted to pointers + param_ty.decayArray(); + } else if (param_ty.is(.void)) { + // validate void parameters + if (p.param_buf.items.len == param_buf_top) { + if (p.tok_ids[p.tok_i] != .r_paren) { + try p.err(.void_only_param); + if (param_ty.anyQual()) try p.err(.void_param_qualified); + return error.ParsingFailed; + } + return &[0]Type.Func.Param{}; + } + try p.err(.void_must_be_first_param); + return error.ParsingFailed; + } + + try param_decl_spec.validateParam(p, ¶m_ty); + try p.param_buf.append(.{ + .name = if (name_tok == 0) .empty else try StrInt.intern(p.comp, p.tokSlice(name_tok)), + .name_tok = if (name_tok == 0) first_tok else name_tok, + .ty = param_ty, + }); + + if (p.eatToken(.comma) == null) break; + if (p.tok_ids[p.tok_i] == .ellipsis) break; + } + return try p.arena.dupe(Type.Func.Param, p.param_buf.items[param_buf_top..]); +} + +/// typeName : specQual abstractDeclarator +fn typeName(p: *Parser) Error!?Type { + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + const ty = (try p.specQual()) orelse return null; + if (try p.declarator(ty, .abstract)) |some| { + if (some.old_style_func) |tok_i| try p.errTok(.invalid_old_style_params, tok_i); + return try Attribute.applyTypeAttributes(p, some.ty, attr_buf_top, .align_ignored); + } + return try Attribute.applyTypeAttributes(p, ty, attr_buf_top, .align_ignored); +} + +fn complexInitializer(p: *Parser, init_ty: Type) Error!Result { + assert(p.tok_ids[p.tok_i] == .l_brace); + assert(init_ty.isComplex()); + + const real_ty = init_ty.makeReal(); + if (real_ty.isInt()) { + return p.todo("Complex integer initializers"); + } + const l_brace = p.tok_i; + p.tok_i += 1; + try p.errTok(.complex_component_init, l_brace); + + const first_tok = p.tok_i; + var first = try p.assignExpr(); + try first.expect(p); + try p.coerceInit(&first, first_tok, real_ty); + + var second: Result = .{ + .ty = real_ty, + .val = Value.zero, + }; + if (p.eatToken(.comma)) |_| { + const second_tok = p.tok_i; + const maybe_second = try p.assignExpr(); + if (!maybe_second.empty(p)) { + second = maybe_second; + try p.coerceInit(&second, second_tok, real_ty); + } + } + + // Eat excess initializers + var extra_tok: ?TokenIndex = null; + while (p.eatToken(.comma)) |_| { + if (p.tok_ids[p.tok_i] == .r_brace) break; + extra_tok = p.tok_i; + const extra = try p.assignExpr(); + if (extra.empty(p)) { + try p.errTok(.expected_expr, p.tok_i); + p.skipTo(.r_brace); + return error.ParsingFailed; + } + } + try p.expectClosing(l_brace, .r_brace); + if (extra_tok) |tok| { + try p.errTok(.excess_scalar_init, tok); + } + + const arr_init_node: Tree.Node = .{ + .tag = .array_init_expr_two, + .ty = init_ty, + .data = .{ .two = .{ first.node, second.node } }, + .loc = @enumFromInt(l_brace), + }; + var res: Result = .{ + .node = try p.addNode(arr_init_node), + .ty = init_ty, + }; + if (first.val.opt_ref != .none and second.val.opt_ref != .none) { + res.val = try Value.intern(p.comp, switch (real_ty.bitSizeof(p.comp).?) { + 32 => .{ .complex = .{ .cf32 = .{ first.val.toFloat(f32, p.comp), second.val.toFloat(f32, p.comp) } } }, + 64 => .{ .complex = .{ .cf64 = .{ first.val.toFloat(f64, p.comp), second.val.toFloat(f64, p.comp) } } }, + 80 => .{ .complex = .{ .cf80 = .{ first.val.toFloat(f80, p.comp), second.val.toFloat(f80, p.comp) } } }, + 128 => .{ .complex = .{ .cf128 = .{ first.val.toFloat(f128, p.comp), second.val.toFloat(f128, p.comp) } } }, + else => unreachable, + }); + } + return res; +} + +/// initializer +/// : assignExpr +/// | '{' initializerItems '}' +fn initializer(p: *Parser, init_ty: Type) Error!Result { + // fast path for non-braced initializers + if (p.tok_ids[p.tok_i] != .l_brace) { + const tok = p.tok_i; + var res = try p.assignExpr(); + try res.expect(p); + if (try p.coerceArrayInit(&res, tok, init_ty)) return res; + try p.coerceInit(&res, tok, init_ty); + return res; + } + if (init_ty.is(.auto_type)) { + try p.err(.auto_type_with_init_list); + return error.ParsingFailed; + } + + if (init_ty.isComplex()) { + return p.complexInitializer(init_ty); + } + var il: InitList = .{}; + defer il.deinit(p.gpa); + + _ = try p.initializerItem(&il, init_ty); + + const res = try p.convertInitList(il, init_ty); + var res_ty = p.nodes.items(.ty)[@intFromEnum(res)]; + res_ty.qual = init_ty.qual; + return Result{ .ty = res_ty, .node = res }; +} + +/// initializerItems : designation? initializer (',' designation? initializer)* ','? +/// designation : designator+ '=' +/// designator +/// : '[' integerConstExpr ']' +/// | '.' identifier +fn initializerItem(p: *Parser, il: *InitList, init_ty: Type) Error!bool { + const l_brace = p.eatToken(.l_brace) orelse { + const tok = p.tok_i; + var res = try p.assignExpr(); + if (res.empty(p)) return false; + + const arr = try p.coerceArrayInit(&res, tok, init_ty); + if (!arr) try p.coerceInit(&res, tok, init_ty); + if (il.tok != 0) { + try p.errTok(.initializer_overrides, tok); + try p.errTok(.previous_initializer, il.tok); + } + il.node = res.node; + il.tok = tok; + return true; + }; + + const is_scalar = init_ty.isScalar(); + const is_complex = init_ty.isComplex(); + const scalar_inits_needed: usize = if (is_complex) 2 else 1; + if (p.eatToken(.r_brace)) |_| { + if (is_scalar) try p.errTok(.empty_scalar_init, l_brace); + if (il.tok != 0) { + try p.errTok(.initializer_overrides, l_brace); + try p.errTok(.previous_initializer, il.tok); + } + il.node = .none; + il.tok = l_brace; + return true; + } + + var count: u64 = 0; + var warned_excess = false; + var is_str_init = false; + var index_hint: ?u64 = null; + while (true) : (count += 1) { + errdefer p.skipTo(.r_brace); + + var first_tok = p.tok_i; + var cur_ty = init_ty; + var cur_il = il; + var designation = false; + var cur_index_hint: ?u64 = null; + while (true) { + if (p.eatToken(.l_bracket)) |l_bracket| { + if (!cur_ty.isArray()) { + try p.errStr(.invalid_array_designator, l_bracket, try p.typeStr(cur_ty)); + return error.ParsingFailed; + } + const expr_tok = p.tok_i; + const index_res = try p.integerConstExpr(.gnu_folding_extension); + try p.expectClosing(l_bracket, .r_bracket); + + if (index_res.val.opt_ref == .none) { + try p.errTok(.expected_integer_constant_expr, expr_tok); + return error.ParsingFailed; + } else if (index_res.val.compare(.lt, Value.zero, p.comp)) { + try p.errStr(.negative_array_designator, l_bracket + 1, try index_res.str(p)); + return error.ParsingFailed; + } + + const max_len = cur_ty.arrayLen() orelse std.math.maxInt(usize); + const index_int = index_res.val.toInt(u64, p.comp) orelse std.math.maxInt(u64); + if (index_int >= max_len) { + try p.errStr(.oob_array_designator, l_bracket + 1, try index_res.str(p)); + return error.ParsingFailed; + } + cur_index_hint = cur_index_hint orelse index_int; + + cur_il = try cur_il.find(p.gpa, index_int); + cur_ty = cur_ty.elemType(); + designation = true; + } else if (p.eatToken(.period)) |period| { + const field_tok = try p.expectIdentifier(); + const field_str = p.tokSlice(field_tok); + const field_name = try StrInt.intern(p.comp, field_str); + cur_ty = cur_ty.canonicalize(.standard); + if (!cur_ty.isRecord()) { + try p.errStr(.invalid_field_designator, period, try p.typeStr(cur_ty)); + return error.ParsingFailed; + } else if (!cur_ty.hasField(field_name)) { + try p.errStr(.no_such_field_designator, period, field_str); + return error.ParsingFailed; + } + + // TODO check if union already has field set + outer: while (true) { + for (cur_ty.data.record.fields, 0..) |f, i| { + if (f.isAnonymousRecord()) { + // Recurse into anonymous field if it has a field by the name. + if (!f.ty.hasField(field_name)) continue; + cur_ty = f.ty.canonicalize(.standard); + cur_il = try il.find(p.gpa, i); + cur_index_hint = cur_index_hint orelse i; + continue :outer; + } + if (field_name == f.name) { + cur_il = try cur_il.find(p.gpa, i); + cur_ty = f.ty; + cur_index_hint = cur_index_hint orelse i; + break :outer; + } + } + unreachable; // we already checked that the starting type has this field + } + designation = true; + } else break; + } + if (designation) index_hint = null; + defer index_hint = cur_index_hint orelse null; + + if (designation) _ = try p.expectToken(.equal); + + if (!designation and cur_ty.hasAttribute(.designated_init)) { + try p.err(.designated_init_needed); + } + + var saw = false; + if (is_str_init and p.isStringInit(init_ty)) { + // discard further strings + var tmp_il = InitList{}; + defer tmp_il.deinit(p.gpa); + saw = try p.initializerItem(&tmp_il, .{ .specifier = .void }); + } else if (count == 0 and p.isStringInit(init_ty)) { + is_str_init = true; + saw = try p.initializerItem(il, init_ty); + } else if (is_scalar and count >= scalar_inits_needed) { + // discard further scalars + var tmp_il = InitList{}; + defer tmp_il.deinit(p.gpa); + saw = try p.initializerItem(&tmp_il, .{ .specifier = .void }); + } else if (p.tok_ids[p.tok_i] == .l_brace) { + if (designation) { + // designation overrides previous value, let existing mechanism handle it + saw = try p.initializerItem(cur_il, cur_ty); + } else if (try p.findAggregateInitializer(&cur_il, &cur_ty, &index_hint)) { + saw = try p.initializerItem(cur_il, cur_ty); + } else { + // discard further values + var tmp_il = InitList{}; + defer tmp_il.deinit(p.gpa); + saw = try p.initializerItem(&tmp_il, .{ .specifier = .void }); + if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok); + warned_excess = true; + } + } else single_item: { + first_tok = p.tok_i; + var res = try p.assignExpr(); + saw = !res.empty(p); + if (!saw) break :single_item; + + excess: { + if (index_hint) |*hint| { + if (try p.findScalarInitializerAt(&cur_il, &cur_ty, &res, first_tok, hint)) break :excess; + } else if (try p.findScalarInitializer(&cur_il, &cur_ty, &res, first_tok)) break :excess; + + if (designation) break :excess; + if (!warned_excess) try p.errTok(if (init_ty.isArray()) .excess_array_init else .excess_struct_init, first_tok); + warned_excess = true; + + break :single_item; + } + + const arr = try p.coerceArrayInit(&res, first_tok, cur_ty); + if (!arr) try p.coerceInit(&res, first_tok, cur_ty); + if (cur_il.tok != 0) { + try p.errTok(.initializer_overrides, first_tok); + try p.errTok(.previous_initializer, cur_il.tok); + } + cur_il.node = res.node; + cur_il.tok = first_tok; + } + + if (!saw) { + if (designation) { + try p.err(.expected_expr); + return error.ParsingFailed; + } + break; + } else if (count == 1) { + if (is_str_init) try p.errTok(.excess_str_init, first_tok); + if (is_scalar and !is_complex) try p.errTok(.excess_scalar_init, first_tok); + } else if (count == 2) { + if (is_scalar and is_complex) try p.errTok(.excess_scalar_init, first_tok); + } + + if (p.eatToken(.comma) == null) break; + } + try p.expectClosing(l_brace, .r_brace); + + if (is_complex and count == 1) { // count of 1 means we saw exactly 2 items in the initializer list + try p.errTok(.complex_component_init, l_brace); + } + if (is_scalar or is_str_init) return true; + if (il.tok != 0) { + try p.errTok(.initializer_overrides, l_brace); + try p.errTok(.previous_initializer, il.tok); + } + il.node = .none; + il.tok = l_brace; + return true; +} + +/// Returns true if the value is unused. +fn findScalarInitializerAt(p: *Parser, il: **InitList, ty: *Type, res: *Result, first_tok: TokenIndex, start_index: *u64) Error!bool { + if (ty.isArray()) { + if (il.*.node != .none) return false; + start_index.* += 1; + + const arr_ty = ty.*; + const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64); + if (elem_count == 0) { + try p.errTok(.empty_aggregate_init_braces, first_tok); + return error.ParsingFailed; + } + const elem_ty = arr_ty.elemType(); + const arr_il = il.*; + if (start_index.* < elem_count) { + ty.* = elem_ty; + il.* = try arr_il.find(p.gpa, start_index.*); + _ = try p.findScalarInitializer(il, ty, res, first_tok); + return true; + } + return false; + } else if (ty.get(.@"struct")) |struct_ty| { + if (il.*.node != .none) return false; + start_index.* += 1; + + const fields = struct_ty.data.record.fields; + if (fields.len == 0) { + try p.errTok(.empty_aggregate_init_braces, first_tok); + return error.ParsingFailed; + } + const struct_il = il.*; + if (start_index.* < fields.len) { + const field = fields[@intCast(start_index.*)]; + ty.* = field.ty; + il.* = try struct_il.find(p.gpa, start_index.*); + _ = try p.findScalarInitializer(il, ty, res, first_tok); + return true; + } + return false; + } else if (ty.get(.@"union")) |_| { + return false; + } + return il.*.node == .none; +} + +/// Returns true if the value is unused. +fn findScalarInitializer(p: *Parser, il: **InitList, ty: *Type, res: *Result, first_tok: TokenIndex) Error!bool { + const actual_ty = res.ty; + if (ty.isArray() or ty.isComplex()) { + if (il.*.node != .none) return false; + if (try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true; + const start_index = il.*.list.items.len; + var index = if (start_index != 0) il.*.list.items[start_index - 1].index else start_index; + + const arr_ty = ty.*; + const elem_count: u64 = arr_ty.expectedInitListSize() orelse std.math.maxInt(u64); + if (elem_count == 0) { + try p.errTok(.empty_aggregate_init_braces, first_tok); + return error.ParsingFailed; + } + const elem_ty = arr_ty.elemType(); + const arr_il = il.*; + while (index < elem_count) : (index += 1) { + ty.* = elem_ty; + il.* = try arr_il.find(p.gpa, index); + if (il.*.node == .none and actual_ty.eql(elem_ty, p.comp, false)) return true; + if (try p.findScalarInitializer(il, ty, res, first_tok)) return true; + } + return false; + } else if (ty.get(.@"struct")) |struct_ty| { + if (il.*.node != .none) return false; + if (actual_ty.eql(ty.*, p.comp, false)) return true; + const start_index = il.*.list.items.len; + var index = if (start_index != 0) il.*.list.items[start_index - 1].index + 1 else start_index; + + const fields = struct_ty.data.record.fields; + if (fields.len == 0) { + try p.errTok(.empty_aggregate_init_braces, first_tok); + return error.ParsingFailed; + } + const struct_il = il.*; + while (index < fields.len) : (index += 1) { + const field = fields[@intCast(index)]; + ty.* = field.ty; + il.* = try struct_il.find(p.gpa, index); + if (il.*.node == .none and actual_ty.eql(field.ty, p.comp, false)) return true; + if (il.*.node == .none and try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true; + if (try p.findScalarInitializer(il, ty, res, first_tok)) return true; + } + return false; + } else if (ty.get(.@"union")) |union_ty| { + if (il.*.node != .none) return false; + if (actual_ty.eql(ty.*, p.comp, false)) return true; + if (union_ty.data.record.fields.len == 0) { + try p.errTok(.empty_aggregate_init_braces, first_tok); + return error.ParsingFailed; + } + ty.* = union_ty.data.record.fields[0].ty; + il.* = try il.*.find(p.gpa, 0); + // if (il.*.node == .none and actual_ty.eql(ty, p.comp, false)) return true; + if (try p.coerceArrayInitExtra(res, first_tok, ty.*, false)) return true; + if (try p.findScalarInitializer(il, ty, res, first_tok)) return true; + return false; + } + return il.*.node == .none; +} + +fn findAggregateInitializer(p: *Parser, il: **InitList, ty: *Type, start_index: *?u64) Error!bool { + if (ty.isArray()) { + if (il.*.node != .none) return false; + const list_index = il.*.list.items.len; + const index = if (start_index.*) |*some| blk: { + some.* += 1; + break :blk some.*; + } else if (list_index != 0) + il.*.list.items[list_index - 1].index + 1 + else + list_index; + + const arr_ty = ty.*; + const elem_count = arr_ty.arrayLen() orelse std.math.maxInt(u64); + const elem_ty = arr_ty.elemType(); + if (index < elem_count) { + ty.* = elem_ty; + il.* = try il.*.find(p.gpa, index); + return true; + } + return false; + } else if (ty.get(.@"struct")) |struct_ty| { + if (il.*.node != .none) return false; + const list_index = il.*.list.items.len; + const index = if (start_index.*) |*some| blk: { + some.* += 1; + break :blk some.*; + } else if (list_index != 0) + il.*.list.items[list_index - 1].index + 1 + else + list_index; + + const field_count = struct_ty.data.record.fields.len; + if (index < field_count) { + ty.* = struct_ty.data.record.fields[@intCast(index)].ty; + il.* = try il.*.find(p.gpa, index); + return true; + } + return false; + } else if (ty.get(.@"union")) |union_ty| { + if (il.*.node != .none) return false; + if (start_index.*) |_| return false; // overrides + if (union_ty.data.record.fields.len == 0) return false; + + ty.* = union_ty.data.record.fields[0].ty; + il.* = try il.*.find(p.gpa, 0); + return true; + } else { + try p.err(.too_many_scalar_init_braces); + return il.*.node == .none; + } +} + +fn coerceArrayInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !bool { + return p.coerceArrayInitExtra(item, tok, target, true); +} + +fn coerceArrayInitExtra(p: *Parser, item: *Result, tok: TokenIndex, target: Type, report_err: bool) !bool { + if (!target.isArray()) return false; + + const is_str_lit = p.nodeIs(item.node, .string_literal_expr); + if (!is_str_lit and !p.nodeIsCompoundLiteral(item.node) or !item.ty.isArray()) { + if (!report_err) return false; + try p.errTok(.array_init_str, tok); + return true; // do not do further coercion + } + + const target_spec = target.elemType().canonicalize(.standard).specifier; + const item_spec = item.ty.elemType().canonicalize(.standard).specifier; + + const compatible = target.elemType().eql(item.ty.elemType(), p.comp, false) or + (is_str_lit and item_spec == .char and (target_spec == .uchar or target_spec == .schar)) or + (is_str_lit and item_spec == .uchar and (target_spec == .uchar or target_spec == .schar or target_spec == .char)); + if (!compatible) { + if (!report_err) return false; + const e_msg = " with array of type "; + try p.errStr(.incompatible_array_init, tok, try p.typePairStrExtra(target, e_msg, item.ty)); + return true; // do not do further coercion + } + + if (target.get(.array)) |arr_ty| { + assert(item.ty.specifier == .array); + const len = item.ty.arrayLen().?; + const array_len = arr_ty.arrayLen().?; + if (is_str_lit) { + // the null byte of a string can be dropped + if (len - 1 > array_len and report_err) { + try p.errTok(.str_init_too_long, tok); + } + } else if (len > array_len and report_err) { + try p.errStr( + .arr_init_too_long, + tok, + try p.typePairStrExtra(target, " with array of type ", item.ty), + ); + } + } + return true; +} + +fn coerceInit(p: *Parser, item: *Result, tok: TokenIndex, target: Type) !void { + if (target.is(.void)) return; // Do not do type coercion on excess items + + const node = item.node; + try item.lvalConversion(p); + if (target.is(.auto_type)) { + if (p.getNode(node, .member_access_expr) orelse p.getNode(node, .member_access_ptr_expr)) |member_node| { + if (p.tmpTree().isBitfield(member_node)) try p.errTok(.auto_type_from_bitfield, tok); + } + return; + } else if (target.is(.c23_auto)) { + return; + } + + try item.coerce(p, target, tok, .init); +} + +fn isStringInit(p: *Parser, ty: Type) bool { + if (!ty.isArray() or !ty.elemType().isInt()) return false; + var i = p.tok_i; + while (true) : (i += 1) { + switch (p.tok_ids[i]) { + .l_paren => {}, + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + => return true, + else => return false, + } + } +} + +/// Convert InitList into an AST +fn convertInitList(p: *Parser, il: InitList, init_ty: Type) Error!NodeIndex { + const is_complex = init_ty.isComplex(); + if (init_ty.isScalar() and !is_complex) { + if (il.node == .none) { + return p.addNode(.{ .tag = .default_init_expr, .ty = init_ty, .data = undefined }); + } + return il.node; + } else if (init_ty.is(.variable_len_array)) { + return error.ParsingFailed; // vla invalid, reported earlier + } else if (init_ty.isArray() or is_complex) { + if (il.node != .none) { + return il.node; + } + const list_buf_top = p.list_buf.items.len; + defer p.list_buf.items.len = list_buf_top; + + const elem_ty = init_ty.elemType(); + + const max_items: u64 = init_ty.expectedInitListSize() orelse std.math.maxInt(usize); + var start: u64 = 0; + for (il.list.items) |*init| { + if (init.index > start) { + const elem = try p.addNode(.{ + .tag = .array_filler_expr, + .ty = elem_ty, + .data = .{ .int = init.index - start }, + }); + try p.list_buf.append(elem); + } + start = init.index + 1; + + const elem = try p.convertInitList(init.list, elem_ty); + try p.list_buf.append(elem); + } + + var arr_init_node: Tree.Node = .{ + .tag = .array_init_expr_two, + .ty = init_ty, + .data = .{ .two = .{ .none, .none } }, + }; + + const max_elems = p.comp.maxArrayBytes() / (@max(1, elem_ty.sizeof(p.comp) orelse 1)); + if (start > max_elems) { + try p.errTok(.array_too_large, il.tok); + start = max_elems; + } + + if (init_ty.specifier == .incomplete_array) { + arr_init_node.ty.specifier = .array; + arr_init_node.ty.data.array.len = start; + } else if (init_ty.is(.incomplete_array)) { + const arr_ty = try p.arena.create(Type.Array); + arr_ty.* = .{ .elem = init_ty.elemType(), .len = start }; + arr_init_node.ty = .{ + .specifier = .array, + .data = .{ .array = arr_ty }, + }; + } else if (start < max_items) { + const elem = try p.addNode(.{ + .tag = .array_filler_expr, + .ty = elem_ty, + .data = .{ .int = max_items - start }, + }); + try p.list_buf.append(elem); + } + + const items = p.list_buf.items[list_buf_top..]; + switch (items.len) { + 0 => {}, + 1 => arr_init_node.data.two[0] = items[0], + 2 => arr_init_node.data.two = .{ items[0], items[1] }, + else => { + arr_init_node.tag = .array_init_expr; + arr_init_node.data = .{ .range = try p.addList(items) }; + }, + } + return try p.addNode(arr_init_node); + } else if (init_ty.get(.@"struct")) |struct_ty| { + assert(!struct_ty.hasIncompleteSize()); + if (il.node != .none) { + return il.node; + } + + const list_buf_top = p.list_buf.items.len; + defer p.list_buf.items.len = list_buf_top; + + var init_index: usize = 0; + for (struct_ty.data.record.fields, 0..) |f, i| { + if (init_index < il.list.items.len and il.list.items[init_index].index == i) { + const item = try p.convertInitList(il.list.items[init_index].list, f.ty); + try p.list_buf.append(item); + init_index += 1; + } else { + const item = try p.addNode(.{ .tag = .default_init_expr, .ty = f.ty, .data = undefined }); + try p.list_buf.append(item); + } + } + + var struct_init_node: Tree.Node = .{ + .tag = .struct_init_expr_two, + .ty = init_ty, + .data = .{ .two = .{ .none, .none } }, + }; + const items = p.list_buf.items[list_buf_top..]; + switch (items.len) { + 0 => {}, + 1 => struct_init_node.data.two[0] = items[0], + 2 => struct_init_node.data.two = .{ items[0], items[1] }, + else => { + struct_init_node.tag = .struct_init_expr; + struct_init_node.data = .{ .range = try p.addList(items) }; + }, + } + return try p.addNode(struct_init_node); + } else if (init_ty.get(.@"union")) |union_ty| { + if (il.node != .none) { + return il.node; + } + + var union_init_node: Tree.Node = .{ + .tag = .union_init_expr, + .ty = init_ty, + .data = .{ .union_init = .{ .field_index = 0, .node = .none } }, + }; + if (union_ty.data.record.fields.len == 0) { + // do nothing for empty unions + } else if (il.list.items.len == 0) { + union_init_node.data.union_init.node = try p.addNode(.{ + .tag = .default_init_expr, + .ty = init_ty, + .data = undefined, + }); + } else { + const init = il.list.items[0]; + const index: u32 = @truncate(init.index); + const field_ty = union_ty.data.record.fields[index].ty; + union_init_node.data.union_init = .{ + .field_index = index, + .node = try p.convertInitList(init.list, field_ty), + }; + } + return try p.addNode(union_init_node); + } else { + return error.ParsingFailed; // initializer target is invalid, reported earlier + } +} + +fn msvcAsmStmt(p: *Parser) Error!?NodeIndex { + return p.todo("MSVC assembly statements"); +} + +/// asmOperand : ('[' IDENTIFIER ']')? asmStr '(' expr ')' +fn asmOperand(p: *Parser, names: *std.ArrayList(?TokenIndex), constraints: *NodeList, exprs: *NodeList) Error!void { + if (p.eatToken(.l_bracket)) |l_bracket| { + const ident = (try p.eatIdentifier()) orelse { + try p.err(.expected_identifier); + return error.ParsingFailed; + }; + try names.append(ident); + try p.expectClosing(l_bracket, .r_bracket); + } else { + try names.append(null); + } + const constraint = try p.asmStr(); + try constraints.append(constraint.node); + + const l_paren = p.eatToken(.l_paren) orelse { + try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .l_paren } }); + return error.ParsingFailed; + }; + const res = try p.expr(); + try p.expectClosing(l_paren, .r_paren); + try res.expect(p); + try exprs.append(res.node); +} + +/// gnuAsmStmt +/// : asmStr +/// | asmStr ':' asmOperand* +/// | asmStr ':' asmOperand* ':' asmOperand* +/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)* +/// | asmStr ':' asmOperand* ':' asmOperand* : asmStr? (',' asmStr)* : IDENTIFIER (',' IDENTIFIER)* +fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, asm_tok: TokenIndex, l_paren: TokenIndex) Error!NodeIndex { + const asm_str = try p.asmStr(); + try p.checkAsmStr(asm_str.val, l_paren); + + if (p.tok_ids[p.tok_i] == .r_paren) { + return p.addNode(.{ + .tag = .gnu_asm_simple, + .ty = .{ .specifier = .void }, + .data = .{ .un = asm_str.node }, + .loc = @enumFromInt(asm_tok), + }); + } + + const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names + const bytes_needed = expected_items * @sizeOf(?TokenIndex) + expected_items * 3 * @sizeOf(NodeIndex); + + var stack_fallback = std.heap.stackFallback(bytes_needed, p.gpa); + const allocator = stack_fallback.get(); + + // TODO: Consider using a TokenIndex of 0 instead of null if we need to store the names in the tree + var names = std.ArrayList(?TokenIndex).initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded + defer names.deinit(); + var constraints = NodeList.initCapacity(allocator, expected_items) catch unreachable; // stack allocation already succeeded + defer constraints.deinit(); + var exprs = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded + defer exprs.deinit(); + var clobbers = NodeList.initCapacity(allocator, expected_items) catch unreachable; //stack allocation already succeeded + defer clobbers.deinit(); + + // Outputs + var ate_extra_colon = false; + if (p.eatToken(.colon) orelse p.eatToken(.colon_colon)) |tok_i| { + ate_extra_colon = p.tok_ids[tok_i] == .colon_colon; + if (!ate_extra_colon) { + if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) { + while (true) { + try p.asmOperand(&names, &constraints, &exprs); + if (p.eatToken(.comma) == null) break; + } + } + } + } + + const num_outputs = names.items.len; + + // Inputs + if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) { + if (ate_extra_colon) { + ate_extra_colon = false; + } else { + ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon; + p.tok_i += 1; + } + if (!ate_extra_colon) { + if (p.tok_ids[p.tok_i].isStringLiteral() or p.tok_ids[p.tok_i] == .l_bracket) { + while (true) { + try p.asmOperand(&names, &constraints, &exprs); + if (p.eatToken(.comma) == null) break; + } + } + } + } + std.debug.assert(names.items.len == constraints.items.len and constraints.items.len == exprs.items.len); + const num_inputs = names.items.len - num_outputs; + _ = num_inputs; + + // Clobbers + if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon or p.tok_ids[p.tok_i] == .colon_colon) { + if (ate_extra_colon) { + ate_extra_colon = false; + } else { + ate_extra_colon = p.tok_ids[p.tok_i] == .colon_colon; + p.tok_i += 1; + } + if (!ate_extra_colon and p.tok_ids[p.tok_i].isStringLiteral()) { + while (true) { + const clobber = try p.asmStr(); + try clobbers.append(clobber.node); + if (p.eatToken(.comma) == null) break; + } + } + } + + if (!quals.goto and (p.tok_ids[p.tok_i] != .r_paren or ate_extra_colon)) { + try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .r_paren } }); + return error.ParsingFailed; + } + + // Goto labels + var num_labels: u32 = 0; + if (ate_extra_colon or p.tok_ids[p.tok_i] == .colon) { + if (!ate_extra_colon) { + p.tok_i += 1; + } + while (true) { + const ident = (try p.eatIdentifier()) orelse { + try p.err(.expected_identifier); + return error.ParsingFailed; + }; + const ident_str = p.tokSlice(ident); + const label = p.findLabel(ident_str) orelse blk: { + try p.labels.append(.{ .unresolved_goto = ident }); + break :blk ident; + }; + try names.append(ident); + + const elem_ty = try p.arena.create(Type); + elem_ty.* = .{ .specifier = .void }; + const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } }; + + const label_addr_node = try p.addNode(.{ + .tag = .addr_of_label, + .data = .{ .decl_ref = label }, + .ty = result_ty, + .loc = @enumFromInt(ident), + }); + try exprs.append(label_addr_node); + + num_labels += 1; + if (p.eatToken(.comma) == null) break; + } + } else if (quals.goto) { + try p.errExtra(.expected_token, p.tok_i, .{ .tok_id = .{ .actual = p.tok_ids[p.tok_i], .expected = .colon } }); + return error.ParsingFailed; + } + + // TODO: validate and insert into AST + return .none; +} + +fn checkAsmStr(p: *Parser, asm_str: Value, tok: TokenIndex) !void { + if (!p.comp.langopts.gnu_asm) { + const str = p.comp.interner.get(asm_str.ref()).bytes; + if (str.len > 1) { + // Empty string (just a NUL byte) is ok because it does not emit any assembly + try p.errTok(.gnu_asm_disabled, tok); + } + } +} + +/// assembly +/// : keyword_asm asmQual* '(' asmStr ')' +/// | keyword_asm asmQual* '(' gnuAsmStmt ')' +/// | keyword_asm msvcAsmStmt +fn assembly(p: *Parser, kind: enum { global, decl_label, stmt }) Error!?NodeIndex { + const asm_tok = p.tok_i; + switch (p.tok_ids[p.tok_i]) { + .keyword_asm => { + try p.err(.extension_token_used); + p.tok_i += 1; + }, + .keyword_asm1, .keyword_asm2 => p.tok_i += 1, + else => return null, + } + + if (!p.tok_ids[p.tok_i].canOpenGCCAsmStmt()) { + return p.msvcAsmStmt(); + } + + var quals: Tree.GNUAssemblyQualifiers = .{}; + while (true) : (p.tok_i += 1) switch (p.tok_ids[p.tok_i]) { + .keyword_volatile, .keyword_volatile1, .keyword_volatile2 => { + if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "volatile"); + if (quals.@"volatile") try p.errStr(.duplicate_asm_qual, p.tok_i, "volatile"); + quals.@"volatile" = true; + }, + .keyword_inline, .keyword_inline1, .keyword_inline2 => { + if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "inline"); + if (quals.@"inline") try p.errStr(.duplicate_asm_qual, p.tok_i, "inline"); + quals.@"inline" = true; + }, + .keyword_goto => { + if (kind != .stmt) try p.errStr(.meaningless_asm_qual, p.tok_i, "goto"); + if (quals.goto) try p.errStr(.duplicate_asm_qual, p.tok_i, "goto"); + quals.goto = true; + }, + else => break, + }; + + const l_paren = try p.expectToken(.l_paren); + var result_node: NodeIndex = .none; + switch (kind) { + .decl_label => { + const asm_str = try p.asmStr(); + const str = try p.removeNull(asm_str.val); + + const attr = Attribute{ .tag = .asm_label, .args = .{ .asm_label = .{ .name = str } }, .syntax = .keyword }; + try p.attr_buf.append(p.gpa, .{ .attr = attr, .tok = asm_tok }); + }, + .global => { + const asm_str = try p.asmStr(); + try p.checkAsmStr(asm_str.val, l_paren); + result_node = try p.addNode(.{ + .tag = .file_scope_asm, + .ty = .{ .specifier = .void }, + .data = .{ .decl = .{ .name = asm_tok, .node = asm_str.node } }, + .loc = @enumFromInt(asm_tok), + }); + }, + .stmt => result_node = try p.gnuAsmStmt(quals, asm_tok, l_paren), + } + try p.expectClosing(l_paren, .r_paren); + + if (kind != .decl_label) _ = try p.expectToken(.semicolon); + return result_node; +} + +/// Same as stringLiteral but errors on unicode and wide string literals +fn asmStr(p: *Parser) Error!Result { + var i = p.tok_i; + while (true) : (i += 1) switch (p.tok_ids[i]) { + .string_literal, .unterminated_string_literal => {}, + .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32 => { + try p.errStr(.invalid_asm_str, p.tok_i, "unicode"); + return error.ParsingFailed; + }, + .string_literal_wide => { + try p.errStr(.invalid_asm_str, p.tok_i, "wide"); + return error.ParsingFailed; + }, + else => { + if (i == p.tok_i) { + try p.errStr(.expected_str_literal_in, p.tok_i, "asm"); + return error.ParsingFailed; + } + break; + }, + }; + return try p.stringLiteral(); +} + +// ====== statements ====== + +/// stmt +/// : labeledStmt +/// | compoundStmt +/// | keyword_if '(' expr ')' stmt (keyword_else stmt)? +/// | keyword_switch '(' expr ')' stmt +/// | keyword_while '(' expr ')' stmt +/// | keyword_do stmt while '(' expr ')' ';' +/// | keyword_for '(' (decl | expr? ';') expr? ';' expr? ')' stmt +/// | keyword_goto (IDENTIFIER | ('*' expr)) ';' +/// | keyword_continue ';' +/// | keyword_break ';' +/// | keyword_return expr? ';' +/// | assembly ';' +/// | expr? ';' +fn stmt(p: *Parser) Error!NodeIndex { + if (try p.labeledStmt()) |some| return some; + if (try p.compoundStmt(false, null)) |some| return some; + if (p.eatToken(.keyword_if)) |kw_if| { + const l_paren = try p.expectToken(.l_paren); + const cond_tok = p.tok_i; + var cond = try p.expr(); + try cond.expect(p); + try cond.lvalConversion(p); + try cond.usualUnaryConversion(p, cond_tok); + if (!cond.ty.isScalar()) + try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty)); + try cond.saveValue(p); + try p.expectClosing(l_paren, .r_paren); + + const then = try p.stmt(); + const @"else" = if (p.eatToken(.keyword_else)) |_| try p.stmt() else .none; + + if (then != .none and @"else" != .none) + return try p.addNode(.{ + .tag = .if_then_else_stmt, + .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then, @"else" })).start } }, + .loc = @enumFromInt(kw_if), + }) + else + return try p.addNode(.{ + .tag = .if_then_stmt, + .data = .{ .bin = .{ .lhs = cond.node, .rhs = then } }, + .loc = @enumFromInt(kw_if), + }); + } + if (p.eatToken(.keyword_switch)) |kw_switch| { + const l_paren = try p.expectToken(.l_paren); + const cond_tok = p.tok_i; + var cond = try p.expr(); + try cond.expect(p); + try cond.lvalConversion(p); + try cond.usualUnaryConversion(p, cond_tok); + + if (!cond.ty.isInt()) + try p.errStr(.statement_int, l_paren + 1, try p.typeStr(cond.ty)); + try cond.saveValue(p); + try p.expectClosing(l_paren, .r_paren); + + const old_switch = p.@"switch"; + var @"switch" = Switch{ + .ranges = std.ArrayList(Switch.Range).init(p.gpa), + .ty = cond.ty, + .comp = p.comp, + }; + p.@"switch" = &@"switch"; + defer { + @"switch".ranges.deinit(); + p.@"switch" = old_switch; + } + + const body = try p.stmt(); + + return try p.addNode(.{ + .tag = .switch_stmt, + .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } }, + .loc = @enumFromInt(kw_switch), + }); + } + if (p.eatToken(.keyword_while)) |kw_while| { + const l_paren = try p.expectToken(.l_paren); + const cond_tok = p.tok_i; + var cond = try p.expr(); + try cond.expect(p); + try cond.lvalConversion(p); + try cond.usualUnaryConversion(p, cond_tok); + if (!cond.ty.isScalar()) + try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty)); + try cond.saveValue(p); + try p.expectClosing(l_paren, .r_paren); + + const body = body: { + const old_loop = p.in_loop; + p.in_loop = true; + defer p.in_loop = old_loop; + break :body try p.stmt(); + }; + + return try p.addNode(.{ + .tag = .while_stmt, + .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } }, + .loc = @enumFromInt(kw_while), + }); + } + if (p.eatToken(.keyword_do)) |kw_do| { + const body = body: { + const old_loop = p.in_loop; + p.in_loop = true; + defer p.in_loop = old_loop; + break :body try p.stmt(); + }; + + _ = try p.expectToken(.keyword_while); + const l_paren = try p.expectToken(.l_paren); + const cond_tok = p.tok_i; + var cond = try p.expr(); + try cond.expect(p); + try cond.lvalConversion(p); + try cond.usualUnaryConversion(p, cond_tok); + + if (!cond.ty.isScalar()) + try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty)); + try cond.saveValue(p); + try p.expectClosing(l_paren, .r_paren); + + _ = try p.expectToken(.semicolon); + return try p.addNode(.{ + .tag = .do_while_stmt, + .data = .{ .bin = .{ .lhs = cond.node, .rhs = body } }, + .loc = @enumFromInt(kw_do), + }); + } + if (p.eatToken(.keyword_for)) |kw_for| { + try p.syms.pushScope(p); + defer p.syms.popScope(); + const decl_buf_top = p.decl_buf.items.len; + defer p.decl_buf.items.len = decl_buf_top; + + const l_paren = try p.expectToken(.l_paren); + const got_decl = try p.decl(); + + // for (init + const init_start = p.tok_i; + var err_start = p.comp.diagnostics.list.items.len; + var init = if (!got_decl) try p.expr() else Result{}; + try init.saveValue(p); + try init.maybeWarnUnused(p, init_start, err_start); + if (!got_decl) _ = try p.expectToken(.semicolon); + + // for (init; cond + const cond_tok = p.tok_i; + var cond = try p.expr(); + if (cond.node != .none) { + try cond.lvalConversion(p); + try cond.usualUnaryConversion(p, cond_tok); + if (!cond.ty.isScalar()) + try p.errStr(.statement_scalar, l_paren + 1, try p.typeStr(cond.ty)); + } + try cond.saveValue(p); + _ = try p.expectToken(.semicolon); + + // for (init; cond; incr + const incr_start = p.tok_i; + err_start = p.comp.diagnostics.list.items.len; + var incr = try p.expr(); + try incr.maybeWarnUnused(p, incr_start, err_start); + try incr.saveValue(p); + try p.expectClosing(l_paren, .r_paren); + + const body = body: { + const old_loop = p.in_loop; + p.in_loop = true; + defer p.in_loop = old_loop; + break :body try p.stmt(); + }; + + if (got_decl) { + const start = (try p.addList(p.decl_buf.items[decl_buf_top..])).start; + const end = (try p.addList(&.{ cond.node, incr.node, body })).end; + + return try p.addNode(.{ + .tag = .for_decl_stmt, + .data = .{ .range = .{ .start = start, .end = end } }, + .loc = @enumFromInt(kw_for), + }); + } else if (init.node == .none and cond.node == .none and incr.node == .none) { + return try p.addNode(.{ + .tag = .forever_stmt, + .data = .{ .un = body }, + .loc = @enumFromInt(kw_for), + }); + } else return try p.addNode(.{ + .tag = .for_stmt, + .data = .{ .if3 = .{ + .cond = body, + .body = (try p.addList(&.{ init.node, cond.node, incr.node })).start, + } }, + .loc = @enumFromInt(kw_for), + }); + } + if (p.eatToken(.keyword_goto)) |goto_tok| { + if (p.eatToken(.asterisk)) |_| { + const expr_tok = p.tok_i; + var e = try p.expr(); + try e.expect(p); + try e.lvalConversion(p); + p.computed_goto_tok = p.computed_goto_tok orelse goto_tok; + if (!e.ty.isPtr()) { + const elem_ty = try p.arena.create(Type); + elem_ty.* = .{ .specifier = .void, .qual = .{ .@"const" = true } }; + const result_ty = Type{ + .specifier = .pointer, + .data = .{ .sub_type = elem_ty }, + }; + if (!e.ty.isInt()) { + try p.errStr(.incompatible_arg, expr_tok, try p.typePairStrExtra(e.ty, " to parameter of incompatible type ", result_ty)); + return error.ParsingFailed; + } + if (e.val.isZero(p.comp)) { + try e.nullCast(p, result_ty); + } else { + try p.errStr(.implicit_int_to_ptr, expr_tok, try p.typePairStrExtra(e.ty, " to ", result_ty)); + try e.ptrCast(p, result_ty); + } + } + + try e.un(p, .computed_goto_stmt, goto_tok); + _ = try p.expectToken(.semicolon); + return e.node; + } + const name_tok = try p.expectIdentifier(); + const str = p.tokSlice(name_tok); + if (p.findLabel(str) == null) { + try p.labels.append(.{ .unresolved_goto = name_tok }); + } + _ = try p.expectToken(.semicolon); + return try p.addNode(.{ + .tag = .goto_stmt, + .data = .{ .decl_ref = name_tok }, + .loc = @enumFromInt(goto_tok), + }); + } + if (p.eatToken(.keyword_continue)) |cont| { + if (!p.in_loop) try p.errTok(.continue_not_in_loop, cont); + _ = try p.expectToken(.semicolon); + return try p.addNode(.{ .tag = .continue_stmt, .data = undefined, .loc = @enumFromInt(cont) }); + } + if (p.eatToken(.keyword_break)) |br| { + if (!p.in_loop and p.@"switch" == null) try p.errTok(.break_not_in_loop_or_switch, br); + _ = try p.expectToken(.semicolon); + return try p.addNode(.{ .tag = .break_stmt, .data = undefined, .loc = @enumFromInt(br) }); + } + if (try p.returnStmt()) |some| return some; + if (try p.assembly(.stmt)) |some| return some; + + const expr_start = p.tok_i; + const err_start = p.comp.diagnostics.list.items.len; + + const e = try p.expr(); + if (e.node != .none) { + _ = try p.expectToken(.semicolon); + try e.maybeWarnUnused(p, expr_start, err_start); + return e.node; + } + + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + try p.attributeSpecifier(); + + if (p.eatToken(.semicolon)) |semicolon| { + var null_node: Tree.Node = .{ .tag = .null_stmt, .data = undefined, .loc = @enumFromInt(semicolon) }; + null_node.ty = try Attribute.applyStatementAttributes(p, null_node.ty, expr_start, attr_buf_top); + return p.addNode(null_node); + } + + try p.err(.expected_stmt); + return error.ParsingFailed; +} + +/// labeledStmt +/// : IDENTIFIER ':' stmt +/// | keyword_case integerConstExpr ':' stmt +/// | keyword_default ':' stmt +fn labeledStmt(p: *Parser) Error!?NodeIndex { + if ((p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) and p.tok_ids[p.tok_i + 1] == .colon) { + const name_tok = try p.expectIdentifier(); + const str = p.tokSlice(name_tok); + if (p.findLabel(str)) |some| { + try p.errStr(.duplicate_label, name_tok, str); + try p.errStr(.previous_label, some, str); + } else { + p.label_count += 1; + try p.labels.append(.{ .label = name_tok }); + var i: usize = 0; + while (i < p.labels.items.len) { + if (p.labels.items[i] == .unresolved_goto and + mem.eql(u8, p.tokSlice(p.labels.items[i].unresolved_goto), str)) + { + _ = p.labels.swapRemove(i); + } else i += 1; + } + } + + p.tok_i += 1; + const attr_buf_top = p.attr_buf.len; + defer p.attr_buf.len = attr_buf_top; + try p.attributeSpecifier(); + + var labeled_stmt = Tree.Node{ + .tag = .labeled_stmt, + .data = .{ .decl = .{ .name = name_tok, .node = try p.labelableStmt() } }, + .loc = @enumFromInt(name_tok), + }; + labeled_stmt.ty = try Attribute.applyLabelAttributes(p, labeled_stmt.ty, attr_buf_top); + return try p.addNode(labeled_stmt); + } else if (p.eatToken(.keyword_case)) |case| { + const first_item = try p.integerConstExpr(.gnu_folding_extension); + const ellipsis = p.tok_i; + const second_item = if (p.eatToken(.ellipsis) != null) blk: { + try p.errTok(.gnu_switch_range, ellipsis); + break :blk try p.integerConstExpr(.gnu_folding_extension); + } else null; + _ = try p.expectToken(.colon); + + if (p.@"switch") |some| check: { + if (some.ty.hasIncompleteSize()) break :check; // error already reported for incomplete size + + const first = first_item.val; + const last = if (second_item) |second| second.val else first; + if (first.opt_ref == .none) { + try p.errTok(.case_val_unavailable, case + 1); + break :check; + } else if (last.opt_ref == .none) { + try p.errTok(.case_val_unavailable, ellipsis + 1); + break :check; + } else if (last.compare(.lt, first, p.comp)) { + try p.errTok(.empty_case_range, case + 1); + break :check; + } + + // TODO cast to target type + const prev = (try some.add(first, last, case + 1)) orelse break :check; + + // TODO check which value was already handled + try p.errStr(.duplicate_switch_case, case + 1, try first_item.str(p)); + try p.errTok(.previous_case, prev.tok); + } else { + try p.errStr(.case_not_in_switch, case, "case"); + } + + const s = try p.labelableStmt(); + if (second_item) |some| return try p.addNode(.{ + .tag = .case_range_stmt, + .data = .{ .if3 = .{ .cond = s, .body = (try p.addList(&.{ first_item.node, some.node })).start } }, + .loc = @enumFromInt(case), + }) else return try p.addNode(.{ + .tag = .case_stmt, + .data = .{ .bin = .{ .lhs = first_item.node, .rhs = s } }, + .loc = @enumFromInt(case), + }); + } else if (p.eatToken(.keyword_default)) |default| { + _ = try p.expectToken(.colon); + const s = try p.labelableStmt(); + const node = try p.addNode(.{ + .tag = .default_stmt, + .data = .{ .un = s }, + .loc = @enumFromInt(default), + }); + const @"switch" = p.@"switch" orelse { + try p.errStr(.case_not_in_switch, default, "default"); + return node; + }; + if (@"switch".default) |previous| { + try p.errTok(.multiple_default, default); + try p.errTok(.previous_case, previous); + } else { + @"switch".default = default; + } + return node; + } else return null; +} + +fn labelableStmt(p: *Parser) Error!NodeIndex { + if (p.tok_ids[p.tok_i] == .r_brace) { + try p.err(.label_compound_end); + return p.addNode(.{ .tag = .null_stmt, .data = undefined, .loc = @enumFromInt(p.tok_i) }); + } + return p.stmt(); +} + +const StmtExprState = struct { + last_expr_tok: TokenIndex = 0, + last_expr_res: Result = .{ .ty = .{ .specifier = .void } }, +}; + +/// compoundStmt : '{' ( decl | keyword_extension decl | staticAssert | stmt)* '}' +fn compoundStmt(p: *Parser, is_fn_body: bool, stmt_expr_state: ?*StmtExprState) Error!?NodeIndex { + const l_brace = p.eatToken(.l_brace) orelse return null; + + const decl_buf_top = p.decl_buf.items.len; + defer p.decl_buf.items.len = decl_buf_top; + + // the parameters of a function are in the same scope as the body + if (!is_fn_body) try p.syms.pushScope(p); + defer if (!is_fn_body) p.syms.popScope(); + + var noreturn_index: ?TokenIndex = null; + var noreturn_label_count: u32 = 0; + + while (p.eatToken(.r_brace) == null) : (_ = try p.pragma()) { + if (stmt_expr_state) |state| state.* = .{}; + if (try p.parseOrNextStmt(staticAssert, l_brace)) continue; + if (try p.parseOrNextStmt(decl, l_brace)) continue; + if (p.eatToken(.keyword_extension)) |ext| { + const saved_extension = p.extension_suppressed; + defer p.extension_suppressed = saved_extension; + p.extension_suppressed = true; + + if (try p.parseOrNextStmt(decl, l_brace)) continue; + p.tok_i = ext; + } + const stmt_tok = p.tok_i; + const s = p.stmt() catch |er| switch (er) { + error.ParsingFailed => { + try p.nextStmt(l_brace); + continue; + }, + else => |e| return e, + }; + if (s == .none) continue; + if (stmt_expr_state) |state| { + state.* = .{ + .last_expr_tok = stmt_tok, + .last_expr_res = .{ + .node = s, + .ty = p.nodes.items(.ty)[@intFromEnum(s)], + }, + }; + } + try p.decl_buf.append(s); + + if (noreturn_index == null and p.nodeIsNoreturn(s) == .yes) { + noreturn_index = p.tok_i; + noreturn_label_count = p.label_count; + } + switch (p.nodes.items(.tag)[@intFromEnum(s)]) { + .case_stmt, .default_stmt, .labeled_stmt => noreturn_index = null, + else => {}, + } + } + const r_brace = p.tok_i - 1; + + if (noreturn_index) |some| { + // if new labels were defined we cannot be certain that the code is unreachable + if (some != p.tok_i - 1 and noreturn_label_count == p.label_count) try p.errTok(.unreachable_code, some); + } + if (is_fn_body) { + const last_noreturn = if (p.decl_buf.items.len == decl_buf_top) + .no + else + p.nodeIsNoreturn(p.decl_buf.items[p.decl_buf.items.len - 1]); + + if (last_noreturn != .yes) { + const ret_ty = p.func.ty.?.returnType(); + var return_zero = false; + if (last_noreturn == .no and !ret_ty.is(.void) and !ret_ty.isFunc() and !ret_ty.isArray()) { + const func_name = p.tokSlice(p.func.name); + const interned_name = try StrInt.intern(p.comp, func_name); + if (interned_name == p.string_ids.main_id and ret_ty.is(.int)) { + return_zero = true; + } else { + try p.errStr(.func_does_not_return, p.tok_i - 1, func_name); + } + } + try p.decl_buf.append(try p.addNode(.{ .tag = .implicit_return, .ty = p.func.ty.?.returnType(), .data = .{ .return_zero = return_zero }, .loc = @enumFromInt(r_brace) })); + } + if (p.func.ident) |some| try p.decl_buf.insert(decl_buf_top, some.node); + if (p.func.pretty_ident) |some| try p.decl_buf.insert(decl_buf_top, some.node); + } + + var node: Tree.Node = .{ + .tag = .compound_stmt_two, + .data = .{ .two = .{ .none, .none } }, + .loc = @enumFromInt(l_brace), + }; + const statements = p.decl_buf.items[decl_buf_top..]; + switch (statements.len) { + 0 => {}, + 1 => node.data = .{ .two = .{ statements[0], .none } }, + 2 => node.data = .{ .two = .{ statements[0], statements[1] } }, + else => { + node.tag = .compound_stmt; + node.data = .{ .range = try p.addList(statements) }; + }, + } + return try p.addNode(node); +} + +const NoreturnKind = enum { no, yes, complex }; + +fn nodeIsNoreturn(p: *Parser, node: NodeIndex) NoreturnKind { + switch (p.nodes.items(.tag)[@intFromEnum(node)]) { + .break_stmt, .continue_stmt, .return_stmt => return .yes, + .if_then_else_stmt => { + const data = p.data.items[p.nodes.items(.data)[@intFromEnum(node)].if3.body..]; + const then_type = p.nodeIsNoreturn(data[0]); + const else_type = p.nodeIsNoreturn(data[1]); + if (then_type == .complex or else_type == .complex) return .complex; + if (then_type == .yes and else_type == .yes) return .yes; + return .no; + }, + .compound_stmt_two => { + const data = p.nodes.items(.data)[@intFromEnum(node)]; + const lhs_type = if (data.two[0] != .none) p.nodeIsNoreturn(data.two[0]) else .no; + const rhs_type = if (data.two[1] != .none) p.nodeIsNoreturn(data.two[1]) else .no; + if (lhs_type == .complex or rhs_type == .complex) return .complex; + if (lhs_type == .yes or rhs_type == .yes) return .yes; + return .no; + }, + .compound_stmt => { + const data = p.nodes.items(.data)[@intFromEnum(node)]; + var it = data.range.start; + while (it != data.range.end) : (it += 1) { + const kind = p.nodeIsNoreturn(p.data.items[it]); + if (kind != .no) return kind; + } + return .no; + }, + .labeled_stmt => { + const data = p.nodes.items(.data)[@intFromEnum(node)]; + return p.nodeIsNoreturn(data.decl.node); + }, + .default_stmt => { + const data = p.nodes.items(.data)[@intFromEnum(node)]; + if (data.un == .none) return .no; + return p.nodeIsNoreturn(data.un); + }, + .while_stmt, .do_while_stmt, .for_decl_stmt, .forever_stmt, .for_stmt, .switch_stmt => return .complex, + else => return .no, + } +} + +fn parseOrNextStmt(p: *Parser, comptime func: fn (*Parser) Error!bool, l_brace: TokenIndex) !bool { + return func(p) catch |er| switch (er) { + error.ParsingFailed => { + try p.nextStmt(l_brace); + return true; + }, + else => |e| return e, + }; +} + +fn nextStmt(p: *Parser, l_brace: TokenIndex) !void { + var parens: u32 = 0; + while (p.tok_i < p.tok_ids.len) : (p.tok_i += 1) { + switch (p.tok_ids[p.tok_i]) { + .l_paren, .l_brace, .l_bracket => parens += 1, + .r_paren, .r_bracket => if (parens != 0) { + parens -= 1; + }, + .r_brace => if (parens == 0) + return + else { + parens -= 1; + }, + .semicolon => if (parens == 0) { + p.tok_i += 1; + return; + }, + .keyword_for, + .keyword_while, + .keyword_do, + .keyword_if, + .keyword_goto, + .keyword_switch, + .keyword_case, + .keyword_default, + .keyword_continue, + .keyword_break, + .keyword_return, + .keyword_typedef, + .keyword_extern, + .keyword_static, + .keyword_auto, + .keyword_register, + .keyword_thread_local, + .keyword_c23_thread_local, + .keyword_inline, + .keyword_inline1, + .keyword_inline2, + .keyword_noreturn, + .keyword_void, + .keyword_bool, + .keyword_c23_bool, + .keyword_char, + .keyword_short, + .keyword_int, + .keyword_long, + .keyword_signed, + .keyword_signed1, + .keyword_signed2, + .keyword_unsigned, + .keyword_float, + .keyword_double, + .keyword_complex, + .keyword_atomic, + .keyword_enum, + .keyword_struct, + .keyword_union, + .keyword_alignas, + .keyword_c23_alignas, + .keyword_typeof, + .keyword_typeof1, + .keyword_typeof2, + .keyword_typeof_unqual, + .keyword_extension, + => if (parens == 0) return, + .keyword_pragma => p.skipToPragmaSentinel(), + else => {}, + } + } + p.tok_i -= 1; // So we can consume EOF + try p.expectClosing(l_brace, .r_brace); + unreachable; +} + +fn returnStmt(p: *Parser) Error!?NodeIndex { + const ret_tok = p.eatToken(.keyword_return) orelse return null; + + const e_tok = p.tok_i; + var e = try p.expr(); + _ = try p.expectToken(.semicolon); + const ret_ty = p.func.ty.?.returnType(); + + if (p.func.ty.?.hasAttribute(.noreturn)) { + try p.errStr(.invalid_noreturn, e_tok, p.tokSlice(p.func.name)); + } + + if (e.node == .none) { + if (!ret_ty.is(.void)) try p.errStr(.func_should_return, ret_tok, p.tokSlice(p.func.name)); + return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node }, .loc = @enumFromInt(ret_tok) }); + } else if (ret_ty.is(.void)) { + try p.errStr(.void_func_returns_value, e_tok, p.tokSlice(p.func.name)); + return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node }, .loc = @enumFromInt(ret_tok) }); + } + + try e.lvalConversion(p); + try e.coerce(p, ret_ty, e_tok, .ret); + + try e.saveValue(p); + return try p.addNode(.{ .tag = .return_stmt, .data = .{ .un = e.node }, .loc = @enumFromInt(ret_tok) }); +} + +// ====== expressions ====== + +pub fn macroExpr(p: *Parser) Compilation.Error!bool { + const res = p.condExpr() catch |e| switch (e) { + error.OutOfMemory => return error.OutOfMemory, + error.FatalError => return error.FatalError, + error.ParsingFailed => return false, + }; + if (res.val.opt_ref == .none) { + try p.errTok(.expected_expr, p.tok_i); + return false; + } + return res.val.toBool(p.comp); +} + +const CallExpr = union(enum) { + standard: NodeIndex, + builtin: struct { + node: NodeIndex, + tag: Builtin.Tag, + }, + + fn init(p: *Parser, call_node: NodeIndex, func_node: NodeIndex) CallExpr { + if (p.getNode(call_node, .builtin_call_expr_one)) |node| { + const data = p.nodes.items(.data)[@intFromEnum(node)]; + const name = p.tokSlice(data.decl.name); + const builtin_ty = p.comp.builtins.lookup(name); + return .{ .builtin = .{ .node = node, .tag = builtin_ty.builtin.tag } }; + } + return .{ .standard = func_node }; + } + + fn shouldPerformLvalConversion(self: CallExpr, arg_idx: u32) bool { + return switch (self) { + .standard => true, + .builtin => |builtin| switch (builtin.tag) { + Builtin.tagFromName("__builtin_va_start").?, + Builtin.tagFromName("__va_start").?, + Builtin.tagFromName("va_start").?, + => arg_idx != 1, + else => true, + }, + }; + } + + fn shouldPromoteVarArg(self: CallExpr, arg_idx: u32) bool { + return switch (self) { + .standard => true, + .builtin => |builtin| switch (builtin.tag) { + Builtin.tagFromName("__builtin_va_start").?, + Builtin.tagFromName("__va_start").?, + Builtin.tagFromName("va_start").?, + => arg_idx != 1, + Builtin.tagFromName("__builtin_add_overflow").?, + Builtin.tagFromName("__builtin_complex").?, + Builtin.tagFromName("__builtin_isinf").?, + Builtin.tagFromName("__builtin_isinf_sign").?, + Builtin.tagFromName("__builtin_mul_overflow").?, + Builtin.tagFromName("__builtin_isnan").?, + Builtin.tagFromName("__builtin_sub_overflow").?, + => false, + else => true, + }, + }; + } + + fn shouldCoerceArg(self: CallExpr, arg_idx: u32) bool { + _ = self; + _ = arg_idx; + return true; + } + + fn checkVarArg(self: CallExpr, p: *Parser, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, arg_idx: u32) !void { + if (self == .standard) return; + + const builtin_tok = p.nodes.items(.data)[@intFromEnum(self.builtin.node)].decl.name; + switch (self.builtin.tag) { + Builtin.tagFromName("__builtin_va_start").?, + Builtin.tagFromName("__va_start").?, + Builtin.tagFromName("va_start").?, + => return p.checkVaStartArg(builtin_tok, first_after, param_tok, arg, arg_idx), + Builtin.tagFromName("__builtin_complex").? => return p.checkComplexArg(builtin_tok, first_after, param_tok, arg, arg_idx), + Builtin.tagFromName("__builtin_add_overflow").?, + Builtin.tagFromName("__builtin_sub_overflow").?, + Builtin.tagFromName("__builtin_mul_overflow").?, + => return p.checkArithOverflowArg(builtin_tok, first_after, param_tok, arg, arg_idx), + + else => {}, + } + } + + /// Some functions cannot be expressed as standard C prototypes. For example `__builtin_complex` requires + /// two arguments of the same real floating point type (e.g. two doubles or two floats). These functions are + /// encoded as varargs functions with custom typechecking. Since varargs functions do not have a fixed number + /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for + /// these custom-typechecked functions. + fn paramCountOverride(self: CallExpr) ?u32 { + return switch (self) { + .standard => null, + .builtin => |builtin| switch (builtin.tag) { + Builtin.tagFromName("__c11_atomic_thread_fence").?, + Builtin.tagFromName("__c11_atomic_signal_fence").?, + Builtin.tagFromName("__c11_atomic_is_lock_free").?, + Builtin.tagFromName("__builtin_isinf").?, + Builtin.tagFromName("__builtin_isinf_sign").?, + Builtin.tagFromName("__builtin_isnan").?, + => 1, + + Builtin.tagFromName("__builtin_complex").?, + Builtin.tagFromName("__c11_atomic_load").?, + Builtin.tagFromName("__c11_atomic_init").?, + => 2, + + Builtin.tagFromName("__c11_atomic_store").?, + Builtin.tagFromName("__c11_atomic_exchange").?, + Builtin.tagFromName("__c11_atomic_fetch_add").?, + Builtin.tagFromName("__c11_atomic_fetch_sub").?, + Builtin.tagFromName("__c11_atomic_fetch_or").?, + Builtin.tagFromName("__c11_atomic_fetch_xor").?, + Builtin.tagFromName("__c11_atomic_fetch_and").?, + Builtin.tagFromName("__atomic_fetch_add").?, + Builtin.tagFromName("__atomic_fetch_sub").?, + Builtin.tagFromName("__atomic_fetch_and").?, + Builtin.tagFromName("__atomic_fetch_xor").?, + Builtin.tagFromName("__atomic_fetch_or").?, + Builtin.tagFromName("__atomic_fetch_nand").?, + Builtin.tagFromName("__atomic_add_fetch").?, + Builtin.tagFromName("__atomic_sub_fetch").?, + Builtin.tagFromName("__atomic_and_fetch").?, + Builtin.tagFromName("__atomic_xor_fetch").?, + Builtin.tagFromName("__atomic_or_fetch").?, + Builtin.tagFromName("__atomic_nand_fetch").?, + Builtin.tagFromName("__builtin_add_overflow").?, + Builtin.tagFromName("__builtin_sub_overflow").?, + Builtin.tagFromName("__builtin_mul_overflow").?, + => 3, + + Builtin.tagFromName("__c11_atomic_compare_exchange_strong").?, + Builtin.tagFromName("__c11_atomic_compare_exchange_weak").?, + => 5, + + Builtin.tagFromName("__atomic_compare_exchange").?, + Builtin.tagFromName("__atomic_compare_exchange_n").?, + => 6, + else => null, + }, + }; + } + + fn returnType(self: CallExpr, p: *Parser, callable_ty: Type) Type { + return switch (self) { + .standard => callable_ty.returnType(), + .builtin => |builtin| switch (builtin.tag) { + Builtin.tagFromName("__c11_atomic_exchange").? => { + if (p.list_buf.items.len != 4) return Type.invalid; // wrong number of arguments; already an error + const second_param = p.list_buf.items[2]; + return p.nodes.items(.ty)[@intFromEnum(second_param)]; + }, + Builtin.tagFromName("__c11_atomic_load").? => { + if (p.list_buf.items.len != 3) return Type.invalid; // wrong number of arguments; already an error + const first_param = p.list_buf.items[1]; + const ty = p.nodes.items(.ty)[@intFromEnum(first_param)]; + if (!ty.isPtr()) return Type.invalid; + return ty.elemType(); + }, + + Builtin.tagFromName("__atomic_fetch_add").?, + Builtin.tagFromName("__atomic_add_fetch").?, + Builtin.tagFromName("__c11_atomic_fetch_add").?, + + Builtin.tagFromName("__atomic_fetch_sub").?, + Builtin.tagFromName("__atomic_sub_fetch").?, + Builtin.tagFromName("__c11_atomic_fetch_sub").?, + + Builtin.tagFromName("__atomic_fetch_and").?, + Builtin.tagFromName("__atomic_and_fetch").?, + Builtin.tagFromName("__c11_atomic_fetch_and").?, + + Builtin.tagFromName("__atomic_fetch_xor").?, + Builtin.tagFromName("__atomic_xor_fetch").?, + Builtin.tagFromName("__c11_atomic_fetch_xor").?, + + Builtin.tagFromName("__atomic_fetch_or").?, + Builtin.tagFromName("__atomic_or_fetch").?, + Builtin.tagFromName("__c11_atomic_fetch_or").?, + + Builtin.tagFromName("__atomic_fetch_nand").?, + Builtin.tagFromName("__atomic_nand_fetch").?, + Builtin.tagFromName("__c11_atomic_fetch_nand").?, + => { + if (p.list_buf.items.len != 3) return Type.invalid; // wrong number of arguments; already an error + const second_param = p.list_buf.items[2]; + return p.nodes.items(.ty)[@intFromEnum(second_param)]; + }, + Builtin.tagFromName("__builtin_complex").? => { + if (p.list_buf.items.len < 1) return Type.invalid; // not enough arguments; already an error + const last_param = p.list_buf.items[p.list_buf.items.len - 1]; + return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex(); + }, + Builtin.tagFromName("__atomic_compare_exchange").?, + Builtin.tagFromName("__atomic_compare_exchange_n").?, + Builtin.tagFromName("__c11_atomic_is_lock_free").?, + => .{ .specifier = .bool }, + else => callable_ty.returnType(), + + Builtin.tagFromName("__c11_atomic_compare_exchange_strong").?, + Builtin.tagFromName("__c11_atomic_compare_exchange_weak").?, + => { + if (p.list_buf.items.len != 6) return Type.invalid; // wrong number of arguments + const third_param = p.list_buf.items[3]; + return p.nodes.items(.ty)[@intFromEnum(third_param)]; + }, + }, + }; + } + + fn finish(self: CallExpr, p: *Parser, ty: Type, list_buf_top: usize, arg_count: u32) Error!Result { + const ret_ty = self.returnType(p, ty); + switch (self) { + .standard => |func_node| { + var call_node: Tree.Node = .{ + .tag = .call_expr_one, + .ty = ret_ty, + .data = .{ .two = .{ func_node, .none } }, + }; + const args = p.list_buf.items[list_buf_top..]; + switch (arg_count) { + 0 => {}, + 1 => call_node.data.two[1] = args[1], // args[0] == func.node + else => { + call_node.tag = .call_expr; + call_node.data = .{ .range = try p.addList(args) }; + }, + } + return Result{ .node = try p.addNode(call_node), .ty = ret_ty }; + }, + .builtin => |builtin| { + const index = @intFromEnum(builtin.node); + var call_node = p.nodes.get(index); + defer p.nodes.set(index, call_node); + call_node.ty = ret_ty; + const args = p.list_buf.items[list_buf_top..]; + switch (arg_count) { + 0 => {}, + 1 => call_node.data.decl.node = args[1], // args[0] == func.node + else => { + call_node.tag = .builtin_call_expr; + args[0] = @enumFromInt(call_node.data.decl.name); + call_node.data = .{ .range = try p.addList(args) }; + }, + } + const val = try evalBuiltin(builtin.tag, p, args[1..]); + return Result{ .node = builtin.node, .ty = ret_ty, .val = val }; + }, + } + } +}; + +pub const Result = struct { + node: NodeIndex = .none, + ty: Type = .{ .specifier = .int }, + val: Value = .{}, + + const invalid: Result = .{ .ty = Type.invalid }; + + pub fn str(res: Result, p: *Parser) ![]const u8 { + switch (res.val.opt_ref) { + .none => return "(none)", + .null => return "nullptr_t", + else => {}, + } + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + try res.val.print(res.ty, p.comp, p.strings.writer()); + return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); + } + + fn expect(res: Result, p: *Parser) Error!void { + if (p.in_macro) { + if (res.val.opt_ref == .none) { + try p.errTok(.expected_expr, p.tok_i); + return error.ParsingFailed; + } + return; + } + if (res.node == .none) { + try p.errTok(.expected_expr, p.tok_i); + return error.ParsingFailed; + } + } + + fn empty(res: Result, p: *Parser) bool { + if (p.in_macro) return res.val.opt_ref == .none; + return res.node == .none; + } + + fn maybeWarnUnused(res: Result, p: *Parser, expr_start: TokenIndex, err_start: usize) Error!void { + if (res.ty.is(.void) or res.node == .none) return; + // don't warn about unused result if the expression contained errors besides other unused results + for (p.comp.diagnostics.list.items[err_start..]) |err_item| { + if (err_item.tag != .unused_value) return; + } + var cur_node = res.node; + while (true) switch (p.nodes.items(.tag)[@intFromEnum(cur_node)]) { + .invalid, // So that we don't need to check for node == 0 + .assign_expr, + .mul_assign_expr, + .div_assign_expr, + .mod_assign_expr, + .add_assign_expr, + .sub_assign_expr, + .shl_assign_expr, + .shr_assign_expr, + .bit_and_assign_expr, + .bit_xor_assign_expr, + .bit_or_assign_expr, + .pre_inc_expr, + .pre_dec_expr, + .post_inc_expr, + .post_dec_expr, + => return, + .call_expr, .call_expr_one => { + const tmp_tree = p.tmpTree(); + const child_nodes = tmp_tree.childNodes(cur_node); + const fn_ptr = child_nodes[0]; + const call_info = tmp_tree.callableResultUsage(fn_ptr) orelse return; + if (call_info.nodiscard) try p.errStr(.nodiscard_unused, expr_start, p.tokSlice(call_info.tok)); + if (call_info.warn_unused_result) try p.errStr(.warn_unused_result, expr_start, p.tokSlice(call_info.tok)); + return; + }, + .stmt_expr => { + const body = p.nodes.items(.data)[@intFromEnum(cur_node)].un; + switch (p.nodes.items(.tag)[@intFromEnum(body)]) { + .compound_stmt_two => { + const body_stmt = p.nodes.items(.data)[@intFromEnum(body)].two; + cur_node = if (body_stmt[1] != .none) body_stmt[1] else body_stmt[0]; + }, + .compound_stmt => { + const data = p.nodes.items(.data)[@intFromEnum(body)]; + cur_node = p.data.items[data.range.end - 1]; + }, + else => unreachable, + } + }, + .comma_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].bin.rhs, + .paren_expr => cur_node = p.nodes.items(.data)[@intFromEnum(cur_node)].un, + else => break, + }; + try p.errTok(.unused_value, expr_start); + } + + fn boolRes(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result, tok_i: TokenIndex) !void { + if (lhs.val.opt_ref == .null) { + lhs.val = Value.zero; + } + if (lhs.ty.specifier != .invalid) { + lhs.ty = Type.int; + } + return lhs.bin(p, tag, rhs, tok_i); + } + + fn bin(lhs: *Result, p: *Parser, tag: Tree.Tag, rhs: Result, tok_i: TokenIndex) !void { + lhs.node = try p.addNode(.{ + .tag = tag, + .ty = lhs.ty, + .data = .{ .bin = .{ .lhs = lhs.node, .rhs = rhs.node } }, + .loc = @enumFromInt(tok_i), + }); + } + + fn un(operand: *Result, p: *Parser, tag: Tree.Tag, tok_i: TokenIndex) Error!void { + operand.node = try p.addNode(.{ + .tag = tag, + .ty = operand.ty, + .data = .{ .un = operand.node }, + .loc = @enumFromInt(tok_i), + }); + } + + fn implicitCast(operand: *Result, p: *Parser, kind: Tree.CastKind) Error!void { + operand.node = try p.addNode(.{ + .tag = .implicit_cast, + .ty = operand.ty, + .data = .{ .cast = .{ .operand = operand.node, .kind = kind } }, + }); + } + + fn adjustCondExprPtrs(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) !bool { + assert(a.ty.isPtr() and b.ty.isPtr()); + + const a_elem = a.ty.elemType(); + const b_elem = b.ty.elemType(); + if (a_elem.eql(b_elem, p.comp, true)) return true; + + var adjusted_elem_ty = try p.arena.create(Type); + adjusted_elem_ty.* = a_elem; + + const has_void_star_branch = a.ty.isVoidStar() or b.ty.isVoidStar(); + const only_quals_differ = a_elem.eql(b_elem, p.comp, false); + const pointers_compatible = only_quals_differ or has_void_star_branch; + + if (!pointers_compatible or has_void_star_branch) { + if (!pointers_compatible) { + try p.errStr(.pointer_mismatch, tok, try p.typePairStrExtra(a.ty, " and ", b.ty)); + } + adjusted_elem_ty.* = .{ .specifier = .void }; + } + if (pointers_compatible) { + adjusted_elem_ty.qual = a_elem.qual.mergeCV(b_elem.qual); + } + if (!adjusted_elem_ty.eql(a_elem, p.comp, true)) { + a.ty = .{ + .data = .{ .sub_type = adjusted_elem_ty }, + .specifier = .pointer, + }; + try a.implicitCast(p, .bitcast); + } + if (!adjusted_elem_ty.eql(b_elem, p.comp, true)) { + b.ty = .{ + .data = .{ .sub_type = adjusted_elem_ty }, + .specifier = .pointer, + }; + try b.implicitCast(p, .bitcast); + } + return true; + } + + /// Adjust types for binary operation, returns true if the result can and should be evaluated. + fn adjustTypes(a: *Result, tok: TokenIndex, b: *Result, p: *Parser, kind: enum { + integer, + arithmetic, + boolean_logic, + relational, + equality, + conditional, + add, + sub, + }) !bool { + if (b.ty.specifier == .invalid) { + try a.saveValue(p); + a.ty = Type.invalid; + } + if (a.ty.specifier == .invalid) { + return false; + } + try a.lvalConversion(p); + try b.lvalConversion(p); + + const a_vec = a.ty.is(.vector); + const b_vec = b.ty.is(.vector); + if (a_vec and b_vec) { + if (a.ty.eql(b.ty, p.comp, false)) { + return a.shouldEval(b, p); + } + return a.invalidBinTy(tok, b, p); + } else if (a_vec) { + if (b.coerceExtra(p, a.ty.elemType(), tok, .test_coerce)) { + try b.saveValue(p); + try b.implicitCast(p, .vector_splat); + return a.shouldEval(b, p); + } else |er| switch (er) { + error.CoercionFailed => return a.invalidBinTy(tok, b, p), + else => |e| return e, + } + } else if (b_vec) { + if (a.coerceExtra(p, b.ty.elemType(), tok, .test_coerce)) { + try a.saveValue(p); + try a.implicitCast(p, .vector_splat); + return a.shouldEval(b, p); + } else |er| switch (er) { + error.CoercionFailed => return a.invalidBinTy(tok, b, p), + else => |e| return e, + } + } + + const a_int = a.ty.isInt(); + const b_int = b.ty.isInt(); + if (a_int and b_int) { + try a.usualArithmeticConversion(b, p, tok); + return a.shouldEval(b, p); + } + if (kind == .integer) return a.invalidBinTy(tok, b, p); + + const a_float = a.ty.isFloat(); + const b_float = b.ty.isFloat(); + const a_arithmetic = a_int or a_float; + const b_arithmetic = b_int or b_float; + if (a_arithmetic and b_arithmetic) { + // <, <=, >, >= only work on real types + if (kind == .relational and (!a.ty.isReal() or !b.ty.isReal())) + return a.invalidBinTy(tok, b, p); + + try a.usualArithmeticConversion(b, p, tok); + return a.shouldEval(b, p); + } + if (kind == .arithmetic) return a.invalidBinTy(tok, b, p); + + const a_nullptr = a.ty.is(.nullptr_t); + const b_nullptr = b.ty.is(.nullptr_t); + const a_ptr = a.ty.isPtr(); + const b_ptr = b.ty.isPtr(); + const a_scalar = a_arithmetic or a_ptr; + const b_scalar = b_arithmetic or b_ptr; + switch (kind) { + .boolean_logic => { + if (!(a_scalar or a_nullptr) or !(b_scalar or b_nullptr)) return a.invalidBinTy(tok, b, p); + + // Do integer promotions but nothing else + if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok); + if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok); + return a.shouldEval(b, p); + }, + .relational, .equality => { + if (kind == .equality and (a_nullptr or b_nullptr)) { + if (a_nullptr and b_nullptr) return a.shouldEval(b, p); + const nullptr_res = if (a_nullptr) a else b; + const other_res = if (a_nullptr) b else a; + if (other_res.ty.isPtr()) { + try nullptr_res.nullCast(p, other_res.ty); + return other_res.shouldEval(nullptr_res, p); + } else if (other_res.val.isZero(p.comp)) { + other_res.val = Value.null; + try other_res.nullCast(p, nullptr_res.ty); + return other_res.shouldEval(nullptr_res, p); + } + return a.invalidBinTy(tok, b, p); + } + // comparisons between floats and pointes not allowed + if (!a_scalar or !b_scalar or (a_float and b_ptr) or (b_float and a_ptr)) + return a.invalidBinTy(tok, b, p); + + if ((a_int or b_int) and !(a.val.isZero(p.comp) or b.val.isZero(p.comp))) { + try p.errStr(.comparison_ptr_int, tok, try p.typePairStr(a.ty, b.ty)); + } else if (a_ptr and b_ptr) { + if (!a.ty.isVoidStar() and !b.ty.isVoidStar() and !a.ty.eql(b.ty, p.comp, false)) + try p.errStr(.comparison_distinct_ptr, tok, try p.typePairStr(a.ty, b.ty)); + } else if (a_ptr) { + try b.ptrCast(p, a.ty); + } else { + assert(b_ptr); + try a.ptrCast(p, b.ty); + } + + return a.shouldEval(b, p); + }, + .conditional => { + // doesn't matter what we return here, as the result is ignored + if (a.ty.is(.void) or b.ty.is(.void)) { + try a.toVoid(p); + try b.toVoid(p); + return true; + } + if (a_nullptr and b_nullptr) return true; + if ((a_ptr and b_int) or (a_int and b_ptr)) { + if (a.val.isZero(p.comp) or b.val.isZero(p.comp)) { + try a.nullCast(p, b.ty); + try b.nullCast(p, a.ty); + return true; + } + const int_ty = if (a_int) a else b; + const ptr_ty = if (a_ptr) a else b; + try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(int_ty.ty, " to ", ptr_ty.ty)); + try int_ty.ptrCast(p, ptr_ty.ty); + + return true; + } + if (a_ptr and b_ptr) return a.adjustCondExprPtrs(tok, b, p); + if ((a_ptr and b_nullptr) or (a_nullptr and b_ptr)) { + const nullptr_res = if (a_nullptr) a else b; + const ptr_res = if (a_nullptr) b else a; + try nullptr_res.nullCast(p, ptr_res.ty); + return true; + } + if (a.ty.isRecord() and b.ty.isRecord() and a.ty.eql(b.ty, p.comp, false)) { + return true; + } + return a.invalidBinTy(tok, b, p); + }, + .add => { + // if both aren't arithmetic one should be pointer and the other an integer + if (a_ptr == b_ptr or a_int == b_int) return a.invalidBinTy(tok, b, p); + + // Do integer promotions but nothing else + if (a_int) try a.intCast(p, a.ty.integerPromotion(p.comp), tok); + if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok); + + // The result type is the type of the pointer operand + if (a_int) a.ty = b.ty else b.ty = a.ty; + return a.shouldEval(b, p); + }, + .sub => { + // if both aren't arithmetic then either both should be pointers or just a + if (!a_ptr or !(b_ptr or b_int)) return a.invalidBinTy(tok, b, p); + + if (a_ptr and b_ptr) { + if (!a.ty.eql(b.ty, p.comp, false)) try p.errStr(.incompatible_pointers, tok, try p.typePairStr(a.ty, b.ty)); + a.ty = p.comp.types.ptrdiff; + } + + // Do integer promotion on b if needed + if (b_int) try b.intCast(p, b.ty.integerPromotion(p.comp), tok); + return a.shouldEval(b, p); + }, + else => return a.invalidBinTy(tok, b, p), + } + } + + fn lvalConversion(res: *Result, p: *Parser) Error!void { + if (res.ty.isFunc()) { + if (res.ty.isInvalidFunc()) { + res.ty = .{ .specifier = .invalid }; + } else { + const elem_ty = try p.arena.create(Type); + elem_ty.* = res.ty; + res.ty.specifier = .pointer; + res.ty.data = .{ .sub_type = elem_ty }; + } + try res.implicitCast(p, .function_to_pointer); + } else if (res.ty.isArray()) { + res.val = .{}; + res.ty.decayArray(); + try res.implicitCast(p, .array_to_pointer); + } else if (!p.in_macro and p.tmpTree().isLval(res.node)) { + res.ty.qual = .{}; + try res.implicitCast(p, .lval_to_rval); + } + } + + fn boolCast(res: *Result, p: *Parser, bool_ty: Type, tok: TokenIndex) Error!void { + if (res.ty.isArray()) { + if (res.val.is(.bytes, p.comp)) { + try p.errStr(.string_literal_to_bool, tok, try p.typePairStrExtra(res.ty, " to ", bool_ty)); + } else { + try p.errStr(.array_address_to_bool, tok, p.tokSlice(tok)); + } + try res.lvalConversion(p); + res.val = Value.one; + res.ty = bool_ty; + try res.implicitCast(p, .pointer_to_bool); + } else if (res.ty.isPtr()) { + res.val.boolCast(p.comp); + res.ty = bool_ty; + try res.implicitCast(p, .pointer_to_bool); + } else if (res.ty.isInt() and !res.ty.is(.bool)) { + res.val.boolCast(p.comp); + res.ty = bool_ty; + try res.implicitCast(p, .int_to_bool); + } else if (res.ty.isFloat()) { + const old_value = res.val; + const value_change_kind = try res.val.floatToInt(bool_ty, p.comp); + try res.floatToIntWarning(p, bool_ty, old_value, value_change_kind, tok); + if (!res.ty.isReal()) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_float_to_real); + } + res.ty = bool_ty; + try res.implicitCast(p, .float_to_bool); + } + } + + fn intCast(res: *Result, p: *Parser, int_ty: Type, tok: TokenIndex) Error!void { + if (int_ty.hasIncompleteSize()) return error.ParsingFailed; // Diagnostic already issued + if (res.ty.is(.bool)) { + res.ty = int_ty.makeReal(); + try res.implicitCast(p, .bool_to_int); + if (!int_ty.isReal()) { + res.ty = int_ty; + try res.implicitCast(p, .real_to_complex_int); + } + } else if (res.ty.isPtr()) { + res.ty = int_ty.makeReal(); + try res.implicitCast(p, .pointer_to_int); + if (!int_ty.isReal()) { + res.ty = int_ty; + try res.implicitCast(p, .real_to_complex_int); + } + } else if (res.ty.isFloat()) { + const old_value = res.val; + const value_change_kind = try res.val.floatToInt(int_ty, p.comp); + try res.floatToIntWarning(p, int_ty, old_value, value_change_kind, tok); + const old_real = res.ty.isReal(); + const new_real = int_ty.isReal(); + if (old_real and new_real) { + res.ty = int_ty; + try res.implicitCast(p, .float_to_int); + } else if (old_real) { + res.ty = int_ty.makeReal(); + try res.implicitCast(p, .float_to_int); + res.ty = int_ty; + try res.implicitCast(p, .real_to_complex_int); + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_float_to_real); + res.ty = int_ty; + try res.implicitCast(p, .float_to_int); + } else { + res.ty = int_ty; + try res.implicitCast(p, .complex_float_to_complex_int); + } + } else if (!res.ty.eql(int_ty, p.comp, true)) { + const old_val = res.val; + const value_change_kind = try res.val.intCast(int_ty, p.comp); + switch (value_change_kind) { + .none => {}, + .truncated => try p.errStr(.int_value_changed, tok, try p.valueChangedStr(res, old_val, int_ty)), + .sign_changed => try p.errStr(.sign_conversion, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)), + } + + const old_real = res.ty.isReal(); + const new_real = int_ty.isReal(); + if (old_real and new_real) { + res.ty = int_ty; + try res.implicitCast(p, .int_cast); + } else if (old_real) { + const real_int_ty = int_ty.makeReal(); + if (!res.ty.eql(real_int_ty, p.comp, false)) { + res.ty = real_int_ty; + try res.implicitCast(p, .int_cast); + } + res.ty = int_ty; + try res.implicitCast(p, .real_to_complex_int); + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_int_to_real); + res.ty = int_ty; + try res.implicitCast(p, .int_cast); + } else { + res.ty = int_ty; + try res.implicitCast(p, .complex_int_cast); + } + } + } + + fn floatToIntWarning(res: *Result, p: *Parser, int_ty: Type, old_value: Value, change_kind: Value.FloatToIntChangeKind, tok: TokenIndex) !void { + switch (change_kind) { + .none => return p.errStr(.float_to_int, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)), + .out_of_range => return p.errStr(.float_out_of_range, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)), + .overflow => return p.errStr(.float_overflow_conversion, tok, try p.typePairStrExtra(res.ty, " to ", int_ty)), + .nonzero_to_zero => return p.errStr(.float_zero_conversion, tok, try p.valueChangedStr(res, old_value, int_ty)), + .value_changed => return p.errStr(.float_value_changed, tok, try p.valueChangedStr(res, old_value, int_ty)), + } + } + + fn floatCast(res: *Result, p: *Parser, float_ty: Type) Error!void { + if (res.ty.is(.bool)) { + try res.val.intToFloat(float_ty, p.comp); + res.ty = float_ty.makeReal(); + try res.implicitCast(p, .bool_to_float); + if (!float_ty.isReal()) { + res.ty = float_ty; + try res.implicitCast(p, .real_to_complex_float); + } + } else if (res.ty.isInt()) { + try res.val.intToFloat(float_ty, p.comp); + const old_real = res.ty.isReal(); + const new_real = float_ty.isReal(); + if (old_real and new_real) { + res.ty = float_ty; + try res.implicitCast(p, .int_to_float); + } else if (old_real) { + res.ty = float_ty.makeReal(); + try res.implicitCast(p, .int_to_float); + res.ty = float_ty; + try res.implicitCast(p, .real_to_complex_float); + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_int_to_real); + res.ty = float_ty; + try res.implicitCast(p, .int_to_float); + } else { + res.ty = float_ty; + try res.implicitCast(p, .complex_int_to_complex_float); + } + } else if (!res.ty.eql(float_ty, p.comp, true)) { + try res.val.floatCast(float_ty, p.comp); + const old_real = res.ty.isReal(); + const new_real = float_ty.isReal(); + if (old_real and new_real) { + res.ty = float_ty; + try res.implicitCast(p, .float_cast); + } else if (old_real) { + if (res.ty.floatRank() != float_ty.floatRank()) { + res.ty = float_ty.makeReal(); + try res.implicitCast(p, .float_cast); + } + res.ty = float_ty; + try res.implicitCast(p, .real_to_complex_float); + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_float_to_real); + if (res.ty.floatRank() != float_ty.floatRank()) { + res.ty = float_ty; + try res.implicitCast(p, .float_cast); + } + } else { + res.ty = float_ty; + try res.implicitCast(p, .complex_float_cast); + } + } + } + + /// Converts a bool or integer to a pointer + fn ptrCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void { + if (res.ty.is(.bool)) { + res.ty = ptr_ty; + try res.implicitCast(p, .bool_to_pointer); + } else if (res.ty.isInt()) { + _ = try res.val.intCast(ptr_ty, p.comp); + res.ty = ptr_ty; + try res.implicitCast(p, .int_to_pointer); + } + } + + /// Convert pointer to one with a different child type + fn ptrChildTypeCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void { + res.ty = ptr_ty; + return res.implicitCast(p, .bitcast); + } + + fn toVoid(res: *Result, p: *Parser) Error!void { + if (!res.ty.is(.void)) { + res.ty = .{ .specifier = .void }; + try res.implicitCast(p, .to_void); + } + } + + fn nullCast(res: *Result, p: *Parser, ptr_ty: Type) Error!void { + if (!res.ty.is(.nullptr_t) and !res.val.isZero(p.comp)) return; + res.ty = ptr_ty; + try res.implicitCast(p, .null_to_pointer); + } + + fn usualUnaryConversion(res: *Result, p: *Parser, tok: TokenIndex) Error!void { + if (res.ty.isFloat()) fp_eval: { + const eval_method = p.comp.langopts.fp_eval_method orelse break :fp_eval; + switch (eval_method) { + .source => {}, + .indeterminate => unreachable, + .double => { + if (res.ty.floatRank() < (Type{ .specifier = .double }).floatRank()) { + const spec: Type.Specifier = if (res.ty.isReal()) .double else .complex_double; + return res.floatCast(p, .{ .specifier = spec }); + } + }, + .extended => { + if (res.ty.floatRank() < (Type{ .specifier = .long_double }).floatRank()) { + const spec: Type.Specifier = if (res.ty.isReal()) .long_double else .complex_long_double; + return res.floatCast(p, .{ .specifier = spec }); + } + }, + } + } + + if (res.ty.is(.fp16) and !p.comp.langopts.use_native_half_type) { + return res.floatCast(p, .{ .specifier = .float }); + } + if (res.ty.isInt()) { + if (p.tmpTree().bitfieldWidth(res.node, true)) |width| { + if (res.ty.bitfieldPromotion(p.comp, width)) |promotion_ty| { + return res.intCast(p, promotion_ty, tok); + } + } + return res.intCast(p, res.ty.integerPromotion(p.comp), tok); + } + } + + fn usualArithmeticConversion(a: *Result, b: *Result, p: *Parser, tok: TokenIndex) Error!void { + try a.usualUnaryConversion(p, tok); + try b.usualUnaryConversion(p, tok); + + // if either is a float cast to that type + if (a.ty.isFloat() or b.ty.isFloat()) { + const float_types = [6][2]Type.Specifier{ + .{ .complex_long_double, .long_double }, + .{ .complex_float128, .float128 }, + .{ .complex_double, .double }, + .{ .complex_float, .float }, + // No `_Complex __fp16` type + .{ .invalid, .fp16 }, + .{ .complex_float16, .float16 }, + }; + const a_spec = a.ty.canonicalize(.standard).specifier; + const b_spec = b.ty.canonicalize(.standard).specifier; + if (p.comp.target.cTypeBitSize(.longdouble) == 128) { + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return; + } + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[1])) return; + if (p.comp.target.cTypeBitSize(.longdouble) == 80) { + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return; + } + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[2])) return; + if (p.comp.target.cTypeBitSize(.longdouble) == 64) { + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[0])) return; + } + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[3])) return; + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[4])) return; + if (try a.floatConversion(b, a_spec, b_spec, p, float_types[5])) return; + unreachable; + } + + if (a.ty.eql(b.ty, p.comp, true)) { + // cast to promoted type + try a.intCast(p, a.ty, tok); + try b.intCast(p, b.ty, tok); + return; + } + + const target = a.ty.integerConversion(b.ty, p.comp); + if (!target.isReal()) { + try a.saveValue(p); + try b.saveValue(p); + } + try a.intCast(p, target, tok); + try b.intCast(p, target, tok); + } + + fn floatConversion(a: *Result, b: *Result, a_spec: Type.Specifier, b_spec: Type.Specifier, p: *Parser, pair: [2]Type.Specifier) !bool { + if (a_spec == pair[0] or a_spec == pair[1] or + b_spec == pair[0] or b_spec == pair[1]) + { + const both_real = a.ty.isReal() and b.ty.isReal(); + const res_spec = pair[@intFromBool(both_real)]; + const ty = Type{ .specifier = res_spec }; + try a.floatCast(p, ty); + try b.floatCast(p, ty); + return true; + } + return false; + } + + fn invalidBinTy(a: *Result, tok: TokenIndex, b: *Result, p: *Parser) Error!bool { + try p.errStr(.invalid_bin_types, tok, try p.typePairStr(a.ty, b.ty)); + a.val = .{}; + b.val = .{}; + a.ty = Type.invalid; + return false; + } + + fn shouldEval(a: *Result, b: *Result, p: *Parser) Error!bool { + if (p.no_eval) return false; + if (a.val.opt_ref != .none and b.val.opt_ref != .none) + return true; + + try a.saveValue(p); + try b.saveValue(p); + return p.no_eval; + } + + /// Saves value and replaces it with `.unavailable`. + fn saveValue(res: *Result, p: *Parser) !void { + assert(!p.in_macro); + if (res.val.opt_ref == .none or res.val.opt_ref == .null) return; + if (!p.in_macro) try p.value_map.put(res.node, res.val); + res.val = .{}; + } + + fn castType(res: *Result, p: *Parser, to: Type, operand_tok: TokenIndex, l_paren: TokenIndex) !void { + var cast_kind: Tree.CastKind = undefined; + + if (to.is(.void)) { + // everything can cast to void + cast_kind = .to_void; + res.val = .{}; + } else if (to.is(.nullptr_t)) { + if (res.ty.is(.nullptr_t)) { + cast_kind = .no_op; + } else { + try p.errStr(.invalid_object_cast, l_paren, try p.typePairStrExtra(res.ty, " to ", to)); + return error.ParsingFailed; + } + } else if (res.ty.is(.nullptr_t)) { + if (to.is(.bool)) { + try res.nullCast(p, res.ty); + res.val.boolCast(p.comp); + res.ty = .{ .specifier = .bool }; + try res.implicitCast(p, .pointer_to_bool); + try res.saveValue(p); + } else if (to.isPtr()) { + try res.nullCast(p, to); + } else { + try p.errStr(.invalid_object_cast, l_paren, try p.typePairStrExtra(res.ty, " to ", to)); + return error.ParsingFailed; + } + cast_kind = .no_op; + } else if (res.val.isZero(p.comp) and to.isPtr()) { + cast_kind = .null_to_pointer; + } else if (to.isScalar()) cast: { + const old_float = res.ty.isFloat(); + const new_float = to.isFloat(); + + if (new_float and res.ty.isPtr()) { + try p.errStr(.invalid_cast_to_float, l_paren, try p.typeStr(to)); + return error.ParsingFailed; + } else if (old_float and to.isPtr()) { + try p.errStr(.invalid_cast_to_pointer, l_paren, try p.typeStr(res.ty)); + return error.ParsingFailed; + } + const old_real = res.ty.isReal(); + const new_real = to.isReal(); + + if (to.eql(res.ty, p.comp, false)) { + cast_kind = .no_op; + } else if (to.is(.bool)) { + if (res.ty.isPtr()) { + cast_kind = .pointer_to_bool; + } else if (res.ty.isInt()) { + if (!old_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_int_to_real); + } + cast_kind = .int_to_bool; + } else if (old_float) { + if (!old_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_float_to_real); + } + cast_kind = .float_to_bool; + } + } else if (to.isInt()) { + if (res.ty.is(.bool)) { + if (!new_real) { + res.ty = to.makeReal(); + try res.implicitCast(p, .bool_to_int); + cast_kind = .real_to_complex_int; + } else { + cast_kind = .bool_to_int; + } + } else if (res.ty.isInt()) { + if (old_real and new_real) { + cast_kind = .int_cast; + } else if (old_real) { + res.ty = to.makeReal(); + try res.implicitCast(p, .int_cast); + cast_kind = .real_to_complex_int; + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_int_to_real); + cast_kind = .int_cast; + } else { + cast_kind = .complex_int_cast; + } + } else if (res.ty.isPtr()) { + if (!new_real) { + res.ty = to.makeReal(); + try res.implicitCast(p, .pointer_to_int); + cast_kind = .real_to_complex_int; + } else { + cast_kind = .pointer_to_int; + } + } else if (old_real and new_real) { + cast_kind = .float_to_int; + } else if (old_real) { + res.ty = to.makeReal(); + try res.implicitCast(p, .float_to_int); + cast_kind = .real_to_complex_int; + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_float_to_real); + cast_kind = .float_to_int; + } else { + cast_kind = .complex_float_to_complex_int; + } + } else if (to.isPtr()) { + if (res.ty.isArray()) + cast_kind = .array_to_pointer + else if (res.ty.isPtr()) + cast_kind = .bitcast + else if (res.ty.isFunc()) + cast_kind = .function_to_pointer + else if (res.ty.is(.bool)) + cast_kind = .bool_to_pointer + else if (res.ty.isInt()) { + if (!old_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_int_to_real); + } + cast_kind = .int_to_pointer; + } else { + try p.errStr(.cond_expr_type, operand_tok, try p.typeStr(res.ty)); + return error.ParsingFailed; + } + } else if (new_float) { + if (res.ty.is(.bool)) { + if (!new_real) { + res.ty = to.makeReal(); + try res.implicitCast(p, .bool_to_float); + cast_kind = .real_to_complex_float; + } else { + cast_kind = .bool_to_float; + } + } else if (res.ty.isInt()) { + if (old_real and new_real) { + cast_kind = .int_to_float; + } else if (old_real) { + res.ty = to.makeReal(); + try res.implicitCast(p, .int_to_float); + cast_kind = .real_to_complex_float; + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_int_to_real); + cast_kind = .int_to_float; + } else { + cast_kind = .complex_int_to_complex_float; + } + } else if (old_real and new_real) { + cast_kind = .float_cast; + } else if (old_real) { + res.ty = to.makeReal(); + try res.implicitCast(p, .float_cast); + cast_kind = .real_to_complex_float; + } else if (new_real) { + res.ty = res.ty.makeReal(); + try res.implicitCast(p, .complex_float_to_real); + cast_kind = .float_cast; + } else { + cast_kind = .complex_float_cast; + } + } + if (res.val.opt_ref == .none) break :cast; + + const old_int = res.ty.isInt() or res.ty.isPtr(); + const new_int = to.isInt() or to.isPtr(); + if (to.is(.bool)) { + res.val.boolCast(p.comp); + } else if (old_float and new_int) { + if (to.hasIncompleteSize()) { + try p.errStr(.cast_to_incomplete_type, l_paren, try p.typeStr(to)); + return error.ParsingFailed; + } + // Explicit cast, no conversion warning + _ = try res.val.floatToInt(to, p.comp); + } else if (new_float and old_int) { + try res.val.intToFloat(to, p.comp); + } else if (new_float and old_float) { + try res.val.floatCast(to, p.comp); + } else if (old_int and new_int) { + if (to.hasIncompleteSize()) { + try p.errStr(.cast_to_incomplete_type, l_paren, try p.typeStr(to)); + return error.ParsingFailed; + } + _ = try res.val.intCast(to, p.comp); + } + } else if (to.get(.@"union")) |union_ty| { + if (union_ty.data.record.hasFieldOfType(res.ty, p.comp)) { + cast_kind = .union_cast; + try p.errTok(.gnu_union_cast, l_paren); + } else { + if (union_ty.data.record.isIncomplete()) { + try p.errStr(.cast_to_incomplete_type, l_paren, try p.typeStr(to)); + } else { + try p.errStr(.invalid_union_cast, l_paren, try p.typeStr(res.ty)); + } + return error.ParsingFailed; + } + } else { + if (to.is(.auto_type)) { + try p.errTok(.invalid_cast_to_auto_type, l_paren); + } else { + try p.errStr(.invalid_cast_type, l_paren, try p.typeStr(to)); + } + return error.ParsingFailed; + } + if (to.anyQual()) try p.errStr(.qual_cast, l_paren, try p.typeStr(to)); + if (to.isInt() and res.ty.isPtr() and to.sizeCompare(res.ty, p.comp) == .lt) { + try p.errStr(.cast_to_smaller_int, l_paren, try p.typePairStrExtra(to, " from ", res.ty)); + } + res.ty = to; + res.ty.qual = .{}; + res.node = try p.addNode(.{ + .tag = .explicit_cast, + .ty = res.ty, + .data = .{ .cast = .{ .operand = res.node, .kind = cast_kind } }, + .loc = @enumFromInt(l_paren), + }); + } + + fn intFitsInType(res: Result, p: *Parser, ty: Type) !bool { + const max_int = try Value.maxInt(ty, p.comp); + const min_int = try Value.minInt(ty, p.comp); + return res.val.compare(.lte, max_int, p.comp) and + (res.ty.isUnsignedInt(p.comp) or res.val.compare(.gte, min_int, p.comp)); + } + + const CoerceContext = union(enum) { + assign, + init, + ret, + arg: TokenIndex, + test_coerce, + + fn note(c: CoerceContext, p: *Parser) !void { + switch (c) { + .arg => |tok| try p.errTok(.parameter_here, tok), + .test_coerce => unreachable, + else => {}, + } + } + + fn typePairStr(c: CoerceContext, p: *Parser, dest_ty: Type, src_ty: Type) ![]const u8 { + switch (c) { + .assign, .init => return p.typePairStrExtra(dest_ty, " from incompatible type ", src_ty), + .ret => return p.typePairStrExtra(src_ty, " from a function with incompatible result type ", dest_ty), + .arg => return p.typePairStrExtra(src_ty, " to parameter of incompatible type ", dest_ty), + .test_coerce => unreachable, + } + } + }; + + /// Perform assignment-like coercion to `dest_ty`. + fn coerce(res: *Result, p: *Parser, dest_ty: Type, tok: TokenIndex, c: CoerceContext) Error!void { + if (res.ty.specifier == .invalid or dest_ty.specifier == .invalid) { + res.ty = Type.invalid; + return; + } + return res.coerceExtra(p, dest_ty, tok, c) catch |er| switch (er) { + error.CoercionFailed => unreachable, + else => |e| return e, + }; + } + + fn coerceExtra( + res: *Result, + p: *Parser, + dest_ty: Type, + tok: TokenIndex, + c: CoerceContext, + ) (Error || error{CoercionFailed})!void { + // Subject of the coercion does not need to be qualified. + var unqual_ty = dest_ty.canonicalize(.standard); + unqual_ty.qual = .{}; + if (unqual_ty.is(.nullptr_t)) { + if (res.ty.is(.nullptr_t)) return; + } else if (unqual_ty.is(.bool)) { + if (res.ty.isScalar() and !res.ty.is(.nullptr_t)) { + // this is ridiculous but it's what clang does + try res.boolCast(p, unqual_ty, tok); + return; + } + } else if (unqual_ty.isInt()) { + if (res.ty.isInt() or res.ty.isFloat()) { + try res.intCast(p, unqual_ty, tok); + return; + } else if (res.ty.isPtr()) { + if (c == .test_coerce) return error.CoercionFailed; + try p.errStr(.implicit_ptr_to_int, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty)); + try c.note(p); + try res.intCast(p, unqual_ty, tok); + return; + } + } else if (unqual_ty.isFloat()) { + if (res.ty.isInt() or res.ty.isFloat()) { + try res.floatCast(p, unqual_ty); + return; + } + } else if (unqual_ty.isPtr()) { + if (res.ty.is(.nullptr_t) or res.val.isZero(p.comp)) { + try res.nullCast(p, dest_ty); + return; + } else if (res.ty.isInt() and res.ty.isReal()) { + if (c == .test_coerce) return error.CoercionFailed; + try p.errStr(.implicit_int_to_ptr, tok, try p.typePairStrExtra(res.ty, " to ", dest_ty)); + try c.note(p); + try res.ptrCast(p, unqual_ty); + return; + } else if (res.ty.isVoidStar() or unqual_ty.eql(res.ty, p.comp, true)) { + return; // ok + } else if (unqual_ty.isVoidStar() and res.ty.isPtr() or (res.ty.isInt() and res.ty.isReal())) { + return; // ok + } else if (unqual_ty.eql(res.ty, p.comp, false)) { + if (!unqual_ty.elemType().qual.hasQuals(res.ty.elemType().qual)) { + try p.errStr(switch (c) { + .assign => .ptr_assign_discards_quals, + .init => .ptr_init_discards_quals, + .ret => .ptr_ret_discards_quals, + .arg => .ptr_arg_discards_quals, + .test_coerce => return error.CoercionFailed, + }, tok, try c.typePairStr(p, dest_ty, res.ty)); + } + try res.ptrCast(p, unqual_ty); + return; + } else if (res.ty.isPtr()) { + const different_sign_only = unqual_ty.elemType().sameRankDifferentSign(res.ty.elemType(), p.comp); + try p.errStr(switch (c) { + .assign => ([2]Diagnostics.Tag{ .incompatible_ptr_assign, .incompatible_ptr_assign_sign })[@intFromBool(different_sign_only)], + .init => ([2]Diagnostics.Tag{ .incompatible_ptr_init, .incompatible_ptr_init_sign })[@intFromBool(different_sign_only)], + .ret => ([2]Diagnostics.Tag{ .incompatible_return, .incompatible_return_sign })[@intFromBool(different_sign_only)], + .arg => ([2]Diagnostics.Tag{ .incompatible_ptr_arg, .incompatible_ptr_arg_sign })[@intFromBool(different_sign_only)], + .test_coerce => return error.CoercionFailed, + }, tok, try c.typePairStr(p, dest_ty, res.ty)); + try c.note(p); + try res.ptrChildTypeCast(p, unqual_ty); + return; + } + } else if (unqual_ty.isRecord()) { + if (unqual_ty.eql(res.ty, p.comp, false)) { + return; // ok + } + + if (c == .arg) if (unqual_ty.get(.@"union")) |union_ty| { + if (dest_ty.hasAttribute(.transparent_union)) transparent_union: { + res.coerceExtra(p, union_ty.data.record.fields[0].ty, tok, .test_coerce) catch |er| switch (er) { + error.CoercionFailed => break :transparent_union, + else => |e| return e, + }; + res.node = try p.addNode(.{ + .tag = .union_init_expr, + .ty = dest_ty, + .data = .{ .union_init = .{ .field_index = 0, .node = res.node } }, + }); + res.ty = dest_ty; + return; + } + }; + } else if (unqual_ty.is(.vector)) { + if (unqual_ty.eql(res.ty, p.comp, false)) { + return; // ok + } + } else { + if (c == .assign and (unqual_ty.isArray() or unqual_ty.isFunc())) { + try p.errTok(.not_assignable, tok); + return; + } else if (c == .test_coerce) { + return error.CoercionFailed; + } + // This case should not be possible and an error should have already been emitted but we + // might still have attempted to parse further so return error.ParsingFailed here to stop. + return error.ParsingFailed; + } + + try p.errStr(switch (c) { + .assign => .incompatible_assign, + .init => .incompatible_init, + .ret => .incompatible_return, + .arg => .incompatible_arg, + .test_coerce => return error.CoercionFailed, + }, tok, try c.typePairStr(p, dest_ty, res.ty)); + try c.note(p); + } +}; + +/// expr : assignExpr (',' assignExpr)* +fn expr(p: *Parser) Error!Result { + var expr_start = p.tok_i; + var err_start = p.comp.diagnostics.list.items.len; + var lhs = try p.assignExpr(); + if (p.tok_ids[p.tok_i] == .comma) try lhs.expect(p); + while (p.eatToken(.comma)) |comma| { + try lhs.maybeWarnUnused(p, expr_start, err_start); + expr_start = p.tok_i; + err_start = p.comp.diagnostics.list.items.len; + + var rhs = try p.assignExpr(); + try rhs.expect(p); + try rhs.lvalConversion(p); + lhs.val = rhs.val; + lhs.ty = rhs.ty; + try lhs.bin(p, .comma_expr, rhs, comma); + } + return lhs; +} + +fn tokToTag(p: *Parser, tok: TokenIndex) Tree.Tag { + return switch (p.tok_ids[tok]) { + .equal => .assign_expr, + .asterisk_equal => .mul_assign_expr, + .slash_equal => .div_assign_expr, + .percent_equal => .mod_assign_expr, + .plus_equal => .add_assign_expr, + .minus_equal => .sub_assign_expr, + .angle_bracket_angle_bracket_left_equal => .shl_assign_expr, + .angle_bracket_angle_bracket_right_equal => .shr_assign_expr, + .ampersand_equal => .bit_and_assign_expr, + .caret_equal => .bit_xor_assign_expr, + .pipe_equal => .bit_or_assign_expr, + .equal_equal => .equal_expr, + .bang_equal => .not_equal_expr, + .angle_bracket_left => .less_than_expr, + .angle_bracket_left_equal => .less_than_equal_expr, + .angle_bracket_right => .greater_than_expr, + .angle_bracket_right_equal => .greater_than_equal_expr, + .angle_bracket_angle_bracket_left => .shl_expr, + .angle_bracket_angle_bracket_right => .shr_expr, + .plus => .add_expr, + .minus => .sub_expr, + .asterisk => .mul_expr, + .slash => .div_expr, + .percent => .mod_expr, + else => unreachable, + }; +} + +/// assignExpr +/// : condExpr +/// | unExpr ('=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=') assignExpr +fn assignExpr(p: *Parser) Error!Result { + var lhs = try p.condExpr(); + if (lhs.empty(p)) return lhs; + + const tok = p.tok_i; + const eq = p.eatToken(.equal); + const mul = eq orelse p.eatToken(.asterisk_equal); + const div = mul orelse p.eatToken(.slash_equal); + const mod = div orelse p.eatToken(.percent_equal); + const add = mod orelse p.eatToken(.plus_equal); + const sub = add orelse p.eatToken(.minus_equal); + const shl = sub orelse p.eatToken(.angle_bracket_angle_bracket_left_equal); + const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right_equal); + const bit_and = shr orelse p.eatToken(.ampersand_equal); + const bit_xor = bit_and orelse p.eatToken(.caret_equal); + const bit_or = bit_xor orelse p.eatToken(.pipe_equal); + + const tag = p.tokToTag(bit_or orelse return lhs); + var rhs = try p.assignExpr(); + try rhs.expect(p); + try rhs.lvalConversion(p); + + var is_const: bool = undefined; + if (!p.tmpTree().isLvalExtra(lhs.node, &is_const) or is_const) { + try p.errTok(.not_assignable, tok); + return error.ParsingFailed; + } + + // adjustTypes will do do lvalue conversion but we do not want that + var lhs_copy = lhs; + switch (tag) { + .assign_expr => {}, // handle plain assignment separately + .mul_assign_expr, + .div_assign_expr, + .mod_assign_expr, + => { + if (rhs.val.isZero(p.comp) and lhs.ty.isInt() and rhs.ty.isInt()) { + switch (tag) { + .div_assign_expr => try p.errStr(.division_by_zero, div.?, "division"), + .mod_assign_expr => try p.errStr(.division_by_zero, mod.?, "remainder"), + else => {}, + } + } + _ = try lhs_copy.adjustTypes(tok, &rhs, p, if (tag == .mod_assign_expr) .integer else .arithmetic); + try lhs.bin(p, tag, rhs, bit_or.?); + return lhs; + }, + .sub_assign_expr, + .add_assign_expr, + => { + if (lhs.ty.isPtr() and rhs.ty.isInt()) { + try rhs.ptrCast(p, lhs.ty); + } else { + _ = try lhs_copy.adjustTypes(tok, &rhs, p, .arithmetic); + } + try lhs.bin(p, tag, rhs, bit_or.?); + return lhs; + }, + .shl_assign_expr, + .shr_assign_expr, + .bit_and_assign_expr, + .bit_xor_assign_expr, + .bit_or_assign_expr, + => { + _ = try lhs_copy.adjustTypes(tok, &rhs, p, .integer); + try lhs.bin(p, tag, rhs, bit_or.?); + return lhs; + }, + else => unreachable, + } + + try rhs.coerce(p, lhs.ty, tok, .assign); + + try lhs.bin(p, tag, rhs, bit_or.?); + return lhs; +} + +/// Returns a parse error if the expression is not an integer constant +/// integerConstExpr : constExpr +fn integerConstExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result { + const start = p.tok_i; + const res = try p.constExpr(decl_folding); + if (!res.ty.isInt() and res.ty.specifier != .invalid) { + try p.errTok(.expected_integer_constant_expr, start); + return error.ParsingFailed; + } + return res; +} + +/// Caller is responsible for issuing a diagnostic if result is invalid/unavailable +/// constExpr : condExpr +fn constExpr(p: *Parser, decl_folding: ConstDeclFoldingMode) Error!Result { + const const_decl_folding = p.const_decl_folding; + defer p.const_decl_folding = const_decl_folding; + p.const_decl_folding = decl_folding; + + const res = try p.condExpr(); + try res.expect(p); + + if (res.ty.specifier == .invalid or res.val.opt_ref == .none) return res; + + // saveValue sets val to unavailable + var copy = res; + try copy.saveValue(p); + return res; +} + +/// condExpr : lorExpr ('?' expression? ':' condExpr)? +fn condExpr(p: *Parser) Error!Result { + const cond_tok = p.tok_i; + var cond = try p.lorExpr(); + if (cond.empty(p) or p.eatToken(.question_mark) == null) return cond; + try cond.lvalConversion(p); + const saved_eval = p.no_eval; + + if (!cond.ty.isScalar()) { + try p.errStr(.cond_expr_type, cond_tok, try p.typeStr(cond.ty)); + return error.ParsingFailed; + } + + // Prepare for possible binary conditional expression. + const maybe_colon = p.eatToken(.colon); + + // Depending on the value of the condition, avoid evaluating unreachable branches. + var then_expr = blk: { + defer p.no_eval = saved_eval; + if (cond.val.opt_ref != .none and !cond.val.toBool(p.comp)) p.no_eval = true; + break :blk try p.expr(); + }; + try then_expr.expect(p); + + // If we saw a colon then this is a binary conditional expression. + if (maybe_colon) |colon| { + var cond_then = cond; + cond_then.node = try p.addNode(.{ .tag = .cond_dummy_expr, .ty = cond.ty, .data = .{ .un = cond.node } }); + _ = try cond_then.adjustTypes(colon, &then_expr, p, .conditional); + cond.ty = then_expr.ty; + cond.node = try p.addNode(.{ + .tag = .binary_cond_expr, + .ty = cond.ty, + .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ cond_then.node, then_expr.node })).start } }, + .loc = @enumFromInt(cond_tok), + }); + return cond; + } + + const colon = try p.expectToken(.colon); + var else_expr = blk: { + defer p.no_eval = saved_eval; + if (cond.val.opt_ref != .none and cond.val.toBool(p.comp)) p.no_eval = true; + break :blk try p.condExpr(); + }; + try else_expr.expect(p); + + _ = try then_expr.adjustTypes(colon, &else_expr, p, .conditional); + + if (cond.val.opt_ref != .none) { + cond.val = if (cond.val.toBool(p.comp)) then_expr.val else else_expr.val; + } else { + try then_expr.saveValue(p); + try else_expr.saveValue(p); + } + cond.ty = then_expr.ty; + cond.node = try p.addNode(.{ + .tag = .cond_expr, + .ty = cond.ty, + .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } }, + .loc = @enumFromInt(cond_tok), + }); + return cond; +} + +/// lorExpr : landExpr ('||' landExpr)* +fn lorExpr(p: *Parser) Error!Result { + var lhs = try p.landExpr(); + if (lhs.empty(p)) return lhs; + const saved_eval = p.no_eval; + defer p.no_eval = saved_eval; + + while (p.eatToken(.pipe_pipe)) |tok| { + if (lhs.val.opt_ref != .none and lhs.val.toBool(p.comp)) p.no_eval = true; + var rhs = try p.landExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) { + const res = lhs.val.toBool(p.comp) or rhs.val.toBool(p.comp); + lhs.val = Value.fromBool(res); + } else { + lhs.val.boolCast(p.comp); + } + try lhs.boolRes(p, .bool_or_expr, rhs, tok); + } + return lhs; +} + +/// landExpr : orExpr ('&&' orExpr)* +fn landExpr(p: *Parser) Error!Result { + var lhs = try p.orExpr(); + if (lhs.empty(p)) return lhs; + const saved_eval = p.no_eval; + defer p.no_eval = saved_eval; + + while (p.eatToken(.ampersand_ampersand)) |tok| { + if (lhs.val.opt_ref != .none and !lhs.val.toBool(p.comp)) p.no_eval = true; + var rhs = try p.orExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(tok, &rhs, p, .boolean_logic)) { + const res = lhs.val.toBool(p.comp) and rhs.val.toBool(p.comp); + lhs.val = Value.fromBool(res); + } else { + lhs.val.boolCast(p.comp); + } + try lhs.boolRes(p, .bool_and_expr, rhs, tok); + } + return lhs; +} + +/// orExpr : xorExpr ('|' xorExpr)* +fn orExpr(p: *Parser) Error!Result { + var lhs = try p.xorExpr(); + if (lhs.empty(p)) return lhs; + while (p.eatToken(.pipe)) |tok| { + var rhs = try p.xorExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(tok, &rhs, p, .integer)) { + lhs.val = try lhs.val.bitOr(rhs.val, p.comp); + } + try lhs.bin(p, .bit_or_expr, rhs, tok); + } + return lhs; +} + +/// xorExpr : andExpr ('^' andExpr)* +fn xorExpr(p: *Parser) Error!Result { + var lhs = try p.andExpr(); + if (lhs.empty(p)) return lhs; + while (p.eatToken(.caret)) |tok| { + var rhs = try p.andExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(tok, &rhs, p, .integer)) { + lhs.val = try lhs.val.bitXor(rhs.val, p.comp); + } + try lhs.bin(p, .bit_xor_expr, rhs, tok); + } + return lhs; +} + +/// andExpr : eqExpr ('&' eqExpr)* +fn andExpr(p: *Parser) Error!Result { + var lhs = try p.eqExpr(); + if (lhs.empty(p)) return lhs; + while (p.eatToken(.ampersand)) |tok| { + var rhs = try p.eqExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(tok, &rhs, p, .integer)) { + lhs.val = try lhs.val.bitAnd(rhs.val, p.comp); + } + try lhs.bin(p, .bit_and_expr, rhs, tok); + } + return lhs; +} + +/// eqExpr : compExpr (('==' | '!=') compExpr)* +fn eqExpr(p: *Parser) Error!Result { + var lhs = try p.compExpr(); + if (lhs.empty(p)) return lhs; + while (true) { + const eq = p.eatToken(.equal_equal); + const ne = eq orelse p.eatToken(.bang_equal); + const tag = p.tokToTag(ne orelse break); + var rhs = try p.compExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(ne.?, &rhs, p, .equality)) { + const op: std.math.CompareOperator = if (tag == .equal_expr) .eq else .neq; + const res = lhs.val.compare(op, rhs.val, p.comp); + lhs.val = Value.fromBool(res); + } else { + lhs.val.boolCast(p.comp); + } + try lhs.boolRes(p, tag, rhs, ne.?); + } + return lhs; +} + +/// compExpr : shiftExpr (('<' | '<=' | '>' | '>=') shiftExpr)* +fn compExpr(p: *Parser) Error!Result { + var lhs = try p.shiftExpr(); + if (lhs.empty(p)) return lhs; + while (true) { + const lt = p.eatToken(.angle_bracket_left); + const le = lt orelse p.eatToken(.angle_bracket_left_equal); + const gt = le orelse p.eatToken(.angle_bracket_right); + const ge = gt orelse p.eatToken(.angle_bracket_right_equal); + const tag = p.tokToTag(ge orelse break); + var rhs = try p.shiftExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(ge.?, &rhs, p, .relational)) { + const op: std.math.CompareOperator = switch (tag) { + .less_than_expr => .lt, + .less_than_equal_expr => .lte, + .greater_than_expr => .gt, + .greater_than_equal_expr => .gte, + else => unreachable, + }; + const res = lhs.val.compare(op, rhs.val, p.comp); + lhs.val = Value.fromBool(res); + } else { + lhs.val.boolCast(p.comp); + } + try lhs.boolRes(p, tag, rhs, ge.?); + } + return lhs; +} + +/// shiftExpr : addExpr (('<<' | '>>') addExpr)* +fn shiftExpr(p: *Parser) Error!Result { + var lhs = try p.addExpr(); + if (lhs.empty(p)) return lhs; + while (true) { + const shl = p.eatToken(.angle_bracket_angle_bracket_left); + const shr = shl orelse p.eatToken(.angle_bracket_angle_bracket_right); + const tag = p.tokToTag(shr orelse break); + var rhs = try p.addExpr(); + try rhs.expect(p); + + if (try lhs.adjustTypes(shr.?, &rhs, p, .integer)) { + if (rhs.val.compare(.lt, Value.zero, p.comp)) { + try p.errStr(.negative_shift_count, shl orelse shr.?, try rhs.str(p)); + } + if (rhs.val.compare(.gte, try Value.int(lhs.ty.bitSizeof(p.comp).?, p.comp), p.comp)) { + try p.errStr(.too_big_shift_count, shl orelse shr.?, try rhs.str(p)); + } + if (shl != null) { + if (try lhs.val.shl(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(shl.?, lhs); + } else { + lhs.val = try lhs.val.shr(rhs.val, lhs.ty, p.comp); + } + } + try lhs.bin(p, tag, rhs, shr.?); + } + return lhs; +} + +/// addExpr : mulExpr (('+' | '-') mulExpr)* +fn addExpr(p: *Parser) Error!Result { + var lhs = try p.mulExpr(); + if (lhs.empty(p)) return lhs; + while (true) { + const plus = p.eatToken(.plus); + const minus = plus orelse p.eatToken(.minus); + const tag = p.tokToTag(minus orelse break); + var rhs = try p.mulExpr(); + try rhs.expect(p); + + const lhs_ty = lhs.ty; + if (try lhs.adjustTypes(minus.?, &rhs, p, if (plus != null) .add else .sub)) { + if (plus != null) { + if (try lhs.val.add(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(plus.?, lhs); + } else { + if (try lhs.val.sub(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(minus.?, lhs); + } + } + if (lhs.ty.specifier != .invalid and lhs_ty.isPtr() and !lhs_ty.isVoidStar() and lhs_ty.elemType().hasIncompleteSize()) { + try p.errStr(.ptr_arithmetic_incomplete, minus.?, try p.typeStr(lhs_ty.elemType())); + lhs.ty = Type.invalid; + } + try lhs.bin(p, tag, rhs, minus.?); + } + return lhs; +} + +/// mulExpr : castExpr (('*' | '/' | '%') castExpr)*´ +fn mulExpr(p: *Parser) Error!Result { + var lhs = try p.castExpr(); + if (lhs.empty(p)) return lhs; + while (true) { + const mul = p.eatToken(.asterisk); + const div = mul orelse p.eatToken(.slash); + const percent = div orelse p.eatToken(.percent); + const tag = p.tokToTag(percent orelse break); + var rhs = try p.castExpr(); + try rhs.expect(p); + + if (rhs.val.isZero(p.comp) and mul == null and !p.no_eval and lhs.ty.isInt() and rhs.ty.isInt()) { + const err_tag: Diagnostics.Tag = if (p.in_macro) .division_by_zero_macro else .division_by_zero; + lhs.val = .{}; + if (div != null) { + try p.errStr(err_tag, div.?, "division"); + } else { + try p.errStr(err_tag, percent.?, "remainder"); + } + if (p.in_macro) return error.ParsingFailed; + } + + if (try lhs.adjustTypes(percent.?, &rhs, p, if (tag == .mod_expr) .integer else .arithmetic)) { + if (mul != null) { + if (try lhs.val.mul(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(mul.?, lhs); + } else if (div != null) { + if (try lhs.val.div(lhs.val, rhs.val, lhs.ty, p.comp) and + lhs.ty.signedness(p.comp) != .unsigned) try p.errOverflow(div.?, lhs); + } else { + var res = try Value.rem(lhs.val, rhs.val, lhs.ty, p.comp); + if (res.opt_ref == .none) { + if (p.in_macro) { + // match clang behavior by defining invalid remainder to be zero in macros + res = Value.zero; + } else { + try lhs.saveValue(p); + try rhs.saveValue(p); + } + } + lhs.val = res; + } + } + + try lhs.bin(p, tag, rhs, percent.?); + } + return lhs; +} + +/// This will always be the last message, if present +fn removeUnusedWarningForTok(p: *Parser, last_expr_tok: TokenIndex) void { + if (last_expr_tok == 0) return; + if (p.comp.diagnostics.list.items.len == 0) return; + + const last_expr_loc = p.pp.tokens.items(.loc)[last_expr_tok]; + const last_msg = p.comp.diagnostics.list.items[p.comp.diagnostics.list.items.len - 1]; + + if (last_msg.tag == .unused_value and last_msg.loc.eql(last_expr_loc)) { + p.comp.diagnostics.list.items.len = p.comp.diagnostics.list.items.len - 1; + } +} + +/// castExpr +/// : '(' compoundStmt ')' suffixExpr* +/// | '(' typeName ')' castExpr +/// | '(' typeName ')' '{' initializerItems '}' +/// | __builtin_choose_expr '(' integerConstExpr ',' assignExpr ',' assignExpr ')' +/// | __builtin_va_arg '(' assignExpr ',' typeName ')' +/// | __builtin_offsetof '(' typeName ',' offsetofMemberDesignator ')' +/// | __builtin_bitoffsetof '(' typeName ',' offsetofMemberDesignator ')' +/// | unExpr +fn castExpr(p: *Parser) Error!Result { + if (p.eatToken(.l_paren)) |l_paren| cast_expr: { + if (p.tok_ids[p.tok_i] == .l_brace) { + const tok = p.tok_i; + try p.err(.gnu_statement_expression); + if (p.func.ty == null) { + try p.err(.stmt_expr_not_allowed_file_scope); + return error.ParsingFailed; + } + var stmt_expr_state: StmtExprState = .{}; + const body_node = (try p.compoundStmt(false, &stmt_expr_state)).?; // compoundStmt only returns null if .l_brace isn't the first token + p.removeUnusedWarningForTok(stmt_expr_state.last_expr_tok); + + var res = Result{ + .node = body_node, + .ty = stmt_expr_state.last_expr_res.ty, + .val = stmt_expr_state.last_expr_res.val, + }; + try p.expectClosing(l_paren, .r_paren); + try res.un(p, .stmt_expr, tok); + while (true) { + const suffix = try p.suffixExpr(res); + if (suffix.empty(p)) break; + res = suffix; + } + return res; + } + const ty = (try p.typeName()) orelse { + p.tok_i -= 1; + break :cast_expr; + }; + try p.expectClosing(l_paren, .r_paren); + + if (p.tok_ids[p.tok_i] == .l_brace) { + // Compound literal; handled in unExpr + p.tok_i = l_paren; + break :cast_expr; + } + + const operand_tok = p.tok_i; + var operand = try p.castExpr(); + try operand.expect(p); + try operand.lvalConversion(p); + try operand.castType(p, ty, operand_tok, l_paren); + return operand; + } + switch (p.tok_ids[p.tok_i]) { + .builtin_choose_expr => return p.builtinChooseExpr(), + .builtin_va_arg => return p.builtinVaArg(), + .builtin_offsetof => return p.builtinOffsetof(false), + .builtin_bitoffsetof => return p.builtinOffsetof(true), + .builtin_types_compatible_p => return p.typesCompatible(), + // TODO: other special-cased builtins + else => {}, + } + return p.unExpr(); +} + +fn typesCompatible(p: *Parser) Error!Result { + const builtin_tok = p.tok_i; + p.tok_i += 1; + const l_paren = try p.expectToken(.l_paren); + + const first_tok = p.tok_i; + const first = (try p.typeName()) orelse { + try p.err(.expected_type); + p.skipTo(.r_paren); + return error.ParsingFailed; + }; + const lhs = try p.addNode(.{ .tag = .invalid, .ty = first, .data = undefined, .loc = @enumFromInt(first_tok) }); + _ = try p.expectToken(.comma); + + const second_tok = p.tok_i; + const second = (try p.typeName()) orelse { + try p.err(.expected_type); + p.skipTo(.r_paren); + return error.ParsingFailed; + }; + const rhs = try p.addNode(.{ .tag = .invalid, .ty = second, .data = undefined, .loc = @enumFromInt(second_tok) }); + + try p.expectClosing(l_paren, .r_paren); + + var first_unqual = first.canonicalize(.standard); + first_unqual.qual.@"const" = false; + first_unqual.qual.@"volatile" = false; + var second_unqual = second.canonicalize(.standard); + second_unqual.qual.@"const" = false; + second_unqual.qual.@"volatile" = false; + + const compatible = first_unqual.eql(second_unqual, p.comp, true); + + const res = Result{ + .val = Value.fromBool(compatible), + .node = try p.addNode(.{ + .tag = .builtin_types_compatible_p, + .ty = Type.int, + .data = .{ .bin = .{ + .lhs = lhs, + .rhs = rhs, + } }, + .loc = @enumFromInt(builtin_tok), + }), + }; + try p.value_map.put(res.node, res.val); + return res; +} + +fn builtinChooseExpr(p: *Parser) Error!Result { + p.tok_i += 1; + const l_paren = try p.expectToken(.l_paren); + const cond_tok = p.tok_i; + var cond = try p.integerConstExpr(.no_const_decl_folding); + if (cond.val.opt_ref == .none) { + try p.errTok(.builtin_choose_cond, cond_tok); + return error.ParsingFailed; + } + + _ = try p.expectToken(.comma); + + var then_expr = if (cond.val.toBool(p.comp)) try p.assignExpr() else try p.parseNoEval(assignExpr); + try then_expr.expect(p); + + _ = try p.expectToken(.comma); + + var else_expr = if (!cond.val.toBool(p.comp)) try p.assignExpr() else try p.parseNoEval(assignExpr); + try else_expr.expect(p); + + try p.expectClosing(l_paren, .r_paren); + + if (cond.val.toBool(p.comp)) { + cond.val = then_expr.val; + cond.ty = then_expr.ty; + } else { + cond.val = else_expr.val; + cond.ty = else_expr.ty; + } + cond.node = try p.addNode(.{ + .tag = .builtin_choose_expr, + .ty = cond.ty, + .data = .{ .if3 = .{ .cond = cond.node, .body = (try p.addList(&.{ then_expr.node, else_expr.node })).start } }, + }); + return cond; +} + +fn builtinVaArg(p: *Parser) Error!Result { + const builtin_tok = p.tok_i; + p.tok_i += 1; + + const l_paren = try p.expectToken(.l_paren); + const va_list_tok = p.tok_i; + var va_list = try p.assignExpr(); + try va_list.expect(p); + try va_list.lvalConversion(p); + + _ = try p.expectToken(.comma); + + const ty = (try p.typeName()) orelse { + try p.err(.expected_type); + return error.ParsingFailed; + }; + try p.expectClosing(l_paren, .r_paren); + + if (!va_list.ty.eql(p.comp.types.va_list, p.comp, true)) { + try p.errStr(.incompatible_va_arg, va_list_tok, try p.typeStr(va_list.ty)); + return error.ParsingFailed; + } + + return Result{ .ty = ty, .node = try p.addNode(.{ + .tag = .special_builtin_call_one, + .ty = ty, + .data = .{ .decl = .{ .name = builtin_tok, .node = va_list.node } }, + }) }; +} + +fn builtinOffsetof(p: *Parser, want_bits: bool) Error!Result { + const builtin_tok = p.tok_i; + p.tok_i += 1; + + const l_paren = try p.expectToken(.l_paren); + const ty_tok = p.tok_i; + + const ty = (try p.typeName()) orelse { + try p.err(.expected_type); + p.skipTo(.r_paren); + return error.ParsingFailed; + }; + + if (!ty.isRecord()) { + try p.errStr(.offsetof_ty, ty_tok, try p.typeStr(ty)); + p.skipTo(.r_paren); + return error.ParsingFailed; + } else if (ty.hasIncompleteSize()) { + try p.errStr(.offsetof_incomplete, ty_tok, try p.typeStr(ty)); + p.skipTo(.r_paren); + return error.ParsingFailed; + } + + _ = try p.expectToken(.comma); + + const offsetof_expr = try p.offsetofMemberDesignator(ty, want_bits); + + try p.expectClosing(l_paren, .r_paren); + + return Result{ + .ty = p.comp.types.size, + .val = offsetof_expr.val, + .node = try p.addNode(.{ + .tag = .special_builtin_call_one, + .ty = p.comp.types.size, + .data = .{ .decl = .{ .name = builtin_tok, .node = offsetof_expr.node } }, + }), + }; +} + +/// offsetofMemberDesignator: IDENTIFIER ('.' IDENTIFIER | '[' expr ']' )* +fn offsetofMemberDesignator(p: *Parser, base_ty: Type, want_bits: bool) Error!Result { + errdefer p.skipTo(.r_paren); + const base_field_name_tok = try p.expectIdentifier(); + const base_field_name = try StrInt.intern(p.comp, p.tokSlice(base_field_name_tok)); + const base_record_ty = base_ty.getRecord().?; + try p.validateFieldAccess(base_record_ty, base_ty, base_field_name_tok, base_field_name); + const base_node = try p.addNode(.{ .tag = .default_init_expr, .ty = base_ty, .data = undefined }); + + var cur_offset: u64 = 0; + var lhs = try p.fieldAccessExtra(base_node, base_record_ty, base_field_name, false, &cur_offset); + + var total_offset = cur_offset; + while (true) switch (p.tok_ids[p.tok_i]) { + .period => { + p.tok_i += 1; + const field_name_tok = try p.expectIdentifier(); + const field_name = try StrInt.intern(p.comp, p.tokSlice(field_name_tok)); + + const lhs_record_ty = lhs.ty.getRecord() orelse { + try p.errStr(.offsetof_ty, field_name_tok, try p.typeStr(lhs.ty)); + return error.ParsingFailed; + }; + try p.validateFieldAccess(lhs_record_ty, lhs.ty, field_name_tok, field_name); + lhs = try p.fieldAccessExtra(lhs.node, lhs_record_ty, field_name, false, &cur_offset); + total_offset += cur_offset; + }, + .l_bracket => { + const l_bracket_tok = p.tok_i; + p.tok_i += 1; + var index = try p.expr(); + try index.expect(p); + _ = try p.expectClosing(l_bracket_tok, .r_bracket); + + if (!lhs.ty.isArray()) { + try p.errStr(.offsetof_array, l_bracket_tok, try p.typeStr(lhs.ty)); + return error.ParsingFailed; + } + var ptr = lhs; + try ptr.lvalConversion(p); + try index.lvalConversion(p); + + if (index.ty.isInt()) { + try p.checkArrayBounds(index, lhs, l_bracket_tok); + } else { + try p.errTok(.invalid_index, l_bracket_tok); + } + + try index.saveValue(p); + try ptr.bin(p, .array_access_expr, index, l_bracket_tok); + lhs = ptr; + }, + else => break, + }; + const val = try Value.int(if (want_bits) total_offset else total_offset / 8, p.comp); + return Result{ .ty = base_ty, .val = val, .node = lhs.node }; +} + +/// unExpr +/// : (compoundLiteral | primaryExpr) suffixExpr* +/// | '&&' IDENTIFIER +/// | ('&' | '*' | '+' | '-' | '~' | '!' | '++' | '--' | keyword_extension | keyword_imag | keyword_real) castExpr +/// | keyword_sizeof unExpr +/// | keyword_sizeof '(' typeName ')' +/// | keyword_alignof '(' typeName ')' +/// | keyword_c23_alignof '(' typeName ')' +fn unExpr(p: *Parser) Error!Result { + const tok = p.tok_i; + switch (p.tok_ids[tok]) { + .ampersand_ampersand => { + const address_tok = p.tok_i; + p.tok_i += 1; + const name_tok = try p.expectIdentifier(); + try p.errTok(.gnu_label_as_value, address_tok); + p.contains_address_of_label = true; + + const str = p.tokSlice(name_tok); + if (p.findLabel(str) == null) { + try p.labels.append(.{ .unresolved_goto = name_tok }); + } + const elem_ty = try p.arena.create(Type); + elem_ty.* = .{ .specifier = .void }; + const result_ty = Type{ .specifier = .pointer, .data = .{ .sub_type = elem_ty } }; + return Result{ + .node = try p.addNode(.{ + .tag = .addr_of_label, + .data = .{ .decl_ref = name_tok }, + .ty = result_ty, + .loc = @enumFromInt(address_tok), + }), + .ty = result_ty, + }; + }, + .ampersand => { + if (p.in_macro) { + try p.err(.invalid_preproc_operator); + return error.ParsingFailed; + } + p.tok_i += 1; + var operand = try p.castExpr(); + try operand.expect(p); + + const tree = p.tmpTree(); + if (p.getNode(operand.node, .member_access_expr) orelse + p.getNode(operand.node, .member_access_ptr_expr)) |member_node| + { + if (tree.isBitfield(member_node)) try p.errTok(.addr_of_bitfield, tok); + } + if (!tree.isLval(operand.node) and !operand.ty.is(.invalid)) { + try p.errTok(.addr_of_rvalue, tok); + } + if (operand.ty.qual.register) try p.errTok(.addr_of_register, tok); + + if (!operand.ty.is(.invalid)) { + const elem_ty = try p.arena.create(Type); + elem_ty.* = operand.ty; + operand.ty = Type{ + .specifier = .pointer, + .data = .{ .sub_type = elem_ty }, + }; + } + try operand.saveValue(p); + try operand.un(p, .addr_of_expr, tok); + return operand; + }, + .asterisk => { + const asterisk_loc = p.tok_i; + p.tok_i += 1; + var operand = try p.castExpr(); + try operand.expect(p); + + if (operand.ty.isArray() or operand.ty.isPtr() or operand.ty.isFunc()) { + try operand.lvalConversion(p); + operand.ty = operand.ty.elemType(); + } else { + try p.errTok(.indirection_ptr, tok); + } + if (operand.ty.hasIncompleteSize() and !operand.ty.is(.void)) { + try p.errStr(.deref_incomplete_ty_ptr, asterisk_loc, try p.typeStr(operand.ty)); + } + operand.ty.qual = .{}; + try operand.un(p, .deref_expr, tok); + return operand; + }, + .plus => { + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + try operand.lvalConversion(p); + if (!operand.ty.isInt() and !operand.ty.isFloat()) + try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty)); + + try operand.usualUnaryConversion(p, tok); + + return operand; + }, + .minus => { + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + try operand.lvalConversion(p); + if (!operand.ty.isInt() and !operand.ty.isFloat()) + try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty)); + + try operand.usualUnaryConversion(p, tok); + if (operand.val.isArithmetic(p.comp)) { + _ = try operand.val.sub(Value.zero, operand.val, operand.ty, p.comp); + } else { + operand.val = .{}; + } + try operand.un(p, .negate_expr, tok); + return operand; + }, + .plus_plus => { + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + if (!operand.ty.isScalar()) + try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty)); + if (operand.ty.isComplex()) + try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty)); + + if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) { + try p.errTok(.not_assignable, tok); + return error.ParsingFailed; + } + try operand.usualUnaryConversion(p, tok); + + if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) { + if (try operand.val.add(operand.val, Value.one, operand.ty, p.comp)) + try p.errOverflow(tok, operand); + } else { + operand.val = .{}; + } + + try operand.un(p, .pre_inc_expr, tok); + return operand; + }, + .minus_minus => { + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + if (!operand.ty.isScalar()) + try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty)); + if (operand.ty.isComplex()) + try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty)); + + if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) { + try p.errTok(.not_assignable, tok); + return error.ParsingFailed; + } + try operand.usualUnaryConversion(p, tok); + + if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) { + if (try operand.val.sub(operand.val, Value.one, operand.ty, p.comp)) + try p.errOverflow(tok, operand); + } else { + operand.val = .{}; + } + + try operand.un(p, .pre_dec_expr, tok); + return operand; + }, + .tilde => { + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + try operand.lvalConversion(p); + try operand.usualUnaryConversion(p, tok); + if (operand.ty.isInt()) { + if (operand.val.is(.int, p.comp)) { + operand.val = try operand.val.bitNot(operand.ty, p.comp); + } + } else if (operand.ty.isComplex()) { + try p.errStr(.complex_conj, tok, try p.typeStr(operand.ty)); + if (operand.val.is(.complex, p.comp)) { + operand.val = try operand.val.complexConj(operand.ty, p.comp); + } + } else { + try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty)); + operand.val = .{}; + } + try operand.un(p, .bit_not_expr, tok); + return operand; + }, + .bang => { + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + try operand.lvalConversion(p); + if (!operand.ty.isScalar()) + try p.errStr(.invalid_argument_un, tok, try p.typeStr(operand.ty)); + + try operand.usualUnaryConversion(p, tok); + if (operand.val.is(.int, p.comp)) { + operand.val = Value.fromBool(!operand.val.toBool(p.comp)); + } else if (operand.val.opt_ref == .null) { + operand.val = Value.one; + } else { + if (operand.ty.isDecayed()) { + operand.val = Value.zero; + } else { + operand.val = .{}; + } + } + operand.ty = .{ .specifier = .int }; + try operand.un(p, .bool_not_expr, tok); + return operand; + }, + .keyword_sizeof => { + p.tok_i += 1; + const expected_paren = p.tok_i; + var res = Result{}; + if (try p.typeName()) |ty| { + res.ty = ty; + try p.errTok(.expected_parens_around_typename, expected_paren); + } else if (p.eatToken(.l_paren)) |l_paren| { + if (try p.typeName()) |ty| { + res.ty = ty; + try p.expectClosing(l_paren, .r_paren); + } else { + p.tok_i = expected_paren; + res = try p.parseNoEval(unExpr); + } + } else { + res = try p.parseNoEval(unExpr); + } + + if (res.ty.is(.void)) { + try p.errStr(.pointer_arith_void, tok, "sizeof"); + } else if (res.ty.isDecayed()) { + const array_ty = res.ty.originalTypeOfDecayedArray(); + const err_str = try p.typePairStrExtra(res.ty, " instead of ", array_ty); + try p.errStr(.sizeof_array_arg, tok, err_str); + } + if (res.ty.sizeof(p.comp)) |size| { + if (size == 0) { + try p.errTok(.sizeof_returns_zero, tok); + } + res.val = try Value.int(size, p.comp); + res.ty = p.comp.types.size; + } else { + res.val = .{}; + if (res.ty.hasIncompleteSize()) { + try p.errStr(.invalid_sizeof, expected_paren - 1, try p.typeStr(res.ty)); + res.ty = Type.invalid; + } else { + res.ty = p.comp.types.size; + } + } + try res.un(p, .sizeof_expr, tok); + return res; + }, + .keyword_alignof, + .keyword_alignof1, + .keyword_alignof2, + .keyword_c23_alignof, + => { + p.tok_i += 1; + const expected_paren = p.tok_i; + var res = Result{}; + if (try p.typeName()) |ty| { + res.ty = ty; + try p.errTok(.expected_parens_around_typename, expected_paren); + } else if (p.eatToken(.l_paren)) |l_paren| { + if (try p.typeName()) |ty| { + res.ty = ty; + try p.expectClosing(l_paren, .r_paren); + } else { + p.tok_i = expected_paren; + res = try p.parseNoEval(unExpr); + try p.errTok(.alignof_expr, expected_paren); + } + } else { + res = try p.parseNoEval(unExpr); + try p.errTok(.alignof_expr, expected_paren); + } + + if (res.ty.is(.void)) { + try p.errStr(.pointer_arith_void, tok, "alignof"); + } + if (res.ty.alignable()) { + res.val = try Value.int(res.ty.alignof(p.comp), p.comp); + res.ty = p.comp.types.size; + } else { + try p.errStr(.invalid_alignof, expected_paren, try p.typeStr(res.ty)); + res.ty = Type.invalid; + } + try res.un(p, .alignof_expr, tok); + return res; + }, + .keyword_extension => { + p.tok_i += 1; + const saved_extension = p.extension_suppressed; + defer p.extension_suppressed = saved_extension; + p.extension_suppressed = true; + + var child = try p.castExpr(); + try child.expect(p); + return child; + }, + .keyword_imag1, .keyword_imag2 => { + const imag_tok = p.tok_i; + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + try operand.lvalConversion(p); + if (operand.ty.is(.invalid)) return Result.invalid; + if (!operand.ty.isInt() and !operand.ty.isFloat()) { + try p.errStr(.invalid_imag, imag_tok, try p.typeStr(operand.ty)); + } + if (operand.ty.isComplex()) { + operand.val = try operand.val.imaginaryPart(p.comp); + } else if (operand.ty.isReal()) { + switch (p.comp.langopts.emulate) { + .msvc => {}, // Doesn't support `_Complex` or `__imag` in the first place + .gcc => operand.val = Value.zero, + .clang => { + if (operand.val.is(.int, p.comp) or operand.val.is(.float, p.comp)) { + operand.val = Value.zero; + } else { + operand.val = .{}; + } + }, + } + } + // convert _Complex T to T + operand.ty = operand.ty.makeReal(); + try operand.un(p, .imag_expr, tok); + return operand; + }, + .keyword_real1, .keyword_real2 => { + const real_tok = p.tok_i; + p.tok_i += 1; + + var operand = try p.castExpr(); + try operand.expect(p); + try operand.lvalConversion(p); + if (operand.ty.is(.invalid)) return Result.invalid; + if (!operand.ty.isInt() and !operand.ty.isFloat()) { + try p.errStr(.invalid_real, real_tok, try p.typeStr(operand.ty)); + } + // convert _Complex T to T + operand.ty = operand.ty.makeReal(); + operand.val = try operand.val.realPart(p.comp); + try operand.un(p, .real_expr, tok); + return operand; + }, + else => { + var lhs = try p.compoundLiteral(); + if (lhs.empty(p)) { + lhs = try p.primaryExpr(); + if (lhs.empty(p)) return lhs; + } + while (true) { + const suffix = try p.suffixExpr(lhs); + if (suffix.empty(p)) break; + lhs = suffix; + } + return lhs; + }, + } +} + +/// compoundLiteral +/// : '(' storageClassSpec* type_name ')' '{' initializer_list '}' +/// | '(' storageClassSpec* type_name ')' '{' initializer_list ',' '}' +fn compoundLiteral(p: *Parser) Error!Result { + const l_paren = p.eatToken(.l_paren) orelse return Result{}; + + var d: DeclSpec = .{ .ty = .{ .specifier = undefined } }; + const any = if (p.comp.langopts.standard.atLeast(.c23)) + try p.storageClassSpec(&d) + else + false; + + const tag: Tree.Tag = switch (d.storage_class) { + .static => if (d.thread_local != null) + .static_thread_local_compound_literal_expr + else + .static_compound_literal_expr, + .register, .none => if (d.thread_local != null) + .thread_local_compound_literal_expr + else + .compound_literal_expr, + .auto, .@"extern", .typedef => |tok| blk: { + try p.errStr(.invalid_compound_literal_storage_class, tok, @tagName(d.storage_class)); + d.storage_class = .none; + break :blk if (d.thread_local != null) + .thread_local_compound_literal_expr + else + .compound_literal_expr; + }, + }; + + var ty = (try p.typeName()) orelse { + p.tok_i = l_paren; + if (any) { + try p.err(.expected_type); + return error.ParsingFailed; + } + return Result{}; + }; + if (d.storage_class == .register) ty.qual.register = true; + try p.expectClosing(l_paren, .r_paren); + + if (ty.isFunc()) { + try p.err(.func_init); + } else if (ty.is(.variable_len_array)) { + try p.err(.vla_init); + } else if (ty.hasIncompleteSize() and !ty.is(.incomplete_array)) { + try p.errStr(.variable_incomplete_ty, p.tok_i, try p.typeStr(ty)); + return error.ParsingFailed; + } + var init_list_expr = try p.initializer(ty); + if (d.constexpr) |_| { + // TODO error if not constexpr + } + try init_list_expr.un(p, tag, l_paren); + return init_list_expr; +} + +/// suffixExpr +/// : '[' expr ']' +/// | '(' argumentExprList? ')' +/// | '.' IDENTIFIER +/// | '->' IDENTIFIER +/// | '++' +/// | '--' +/// argumentExprList : assignExpr (',' assignExpr)* +fn suffixExpr(p: *Parser, lhs: Result) Error!Result { + assert(!lhs.empty(p)); + switch (p.tok_ids[p.tok_i]) { + .l_paren => return p.callExpr(lhs), + .plus_plus => { + defer p.tok_i += 1; + + var operand = lhs; + if (!operand.ty.isScalar()) + try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty)); + if (operand.ty.isComplex()) + try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty)); + + if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) { + try p.err(.not_assignable); + return error.ParsingFailed; + } + try operand.usualUnaryConversion(p, p.tok_i); + + try operand.un(p, .post_inc_expr, p.tok_i); + return operand; + }, + .minus_minus => { + defer p.tok_i += 1; + + var operand = lhs; + if (!operand.ty.isScalar()) + try p.errStr(.invalid_argument_un, p.tok_i, try p.typeStr(operand.ty)); + if (operand.ty.isComplex()) + try p.errStr(.complex_prefix_postfix_op, p.tok_i, try p.typeStr(operand.ty)); + + if (!p.tmpTree().isLval(operand.node) or operand.ty.isConst()) { + try p.err(.not_assignable); + return error.ParsingFailed; + } + try operand.usualUnaryConversion(p, p.tok_i); + + try operand.un(p, .post_dec_expr, p.tok_i); + return operand; + }, + .l_bracket => { + const l_bracket = p.tok_i; + p.tok_i += 1; + var index = try p.expr(); + try index.expect(p); + try p.expectClosing(l_bracket, .r_bracket); + + const array_before_conversion = lhs; + const index_before_conversion = index; + var ptr = lhs; + try ptr.lvalConversion(p); + try index.lvalConversion(p); + if (ptr.ty.isPtr()) { + ptr.ty = ptr.ty.elemType(); + if (index.ty.isInt()) { + try p.checkArrayBounds(index_before_conversion, array_before_conversion, l_bracket); + } else { + try p.errTok(.invalid_index, l_bracket); + } + } else if (index.ty.isPtr()) { + index.ty = index.ty.elemType(); + if (ptr.ty.isInt()) { + try p.checkArrayBounds(array_before_conversion, index_before_conversion, l_bracket); + } else { + try p.errTok(.invalid_index, l_bracket); + } + std.mem.swap(Result, &ptr, &index); + } else { + try p.errTok(.invalid_subscript, l_bracket); + } + + try ptr.saveValue(p); + try index.saveValue(p); + try ptr.bin(p, .array_access_expr, index, l_bracket); + return ptr; + }, + .period => { + p.tok_i += 1; + const name = try p.expectIdentifier(); + return p.fieldAccess(lhs, name, false); + }, + .arrow => { + p.tok_i += 1; + const name = try p.expectIdentifier(); + if (lhs.ty.isArray()) { + var copy = lhs; + copy.ty.decayArray(); + try copy.implicitCast(p, .array_to_pointer); + return p.fieldAccess(copy, name, true); + } + return p.fieldAccess(lhs, name, true); + }, + else => return Result{}, + } +} + +fn fieldAccess( + p: *Parser, + lhs: Result, + field_name_tok: TokenIndex, + is_arrow: bool, +) !Result { + const expr_ty = lhs.ty; + const is_ptr = expr_ty.isPtr(); + const expr_base_ty = if (is_ptr) expr_ty.elemType() else expr_ty; + const record_ty = expr_base_ty.getRecord() orelse { + try p.errStr(.expected_record_ty, field_name_tok, try p.typeStr(expr_ty)); + return error.ParsingFailed; + }; + + if (record_ty.isIncomplete()) { + try p.errStr(.deref_incomplete_ty_ptr, field_name_tok - 2, try p.typeStr(expr_base_ty)); + return error.ParsingFailed; + } + if (is_arrow and !is_ptr) try p.errStr(.member_expr_not_ptr, field_name_tok, try p.typeStr(expr_ty)); + if (!is_arrow and is_ptr) try p.errStr(.member_expr_ptr, field_name_tok, try p.typeStr(expr_ty)); + + const field_name = try StrInt.intern(p.comp, p.tokSlice(field_name_tok)); + try p.validateFieldAccess(record_ty, expr_ty, field_name_tok, field_name); + var discard: u64 = 0; + return p.fieldAccessExtra(lhs.node, record_ty, field_name, is_arrow, &discard); +} + +fn validateFieldAccess(p: *Parser, record_ty: *const Type.Record, expr_ty: Type, field_name_tok: TokenIndex, field_name: StringId) Error!void { + if (record_ty.hasField(field_name)) return; + + p.strings.items.len = 0; + + try p.strings.writer().print("'{s}' in '", .{p.tokSlice(field_name_tok)}); + const mapper = p.comp.string_interner.getSlowTypeMapper(); + try expr_ty.print(mapper, p.comp.langopts, p.strings.writer()); + try p.strings.append('\''); + + const duped = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items); + try p.errStr(.no_such_member, field_name_tok, duped); + return error.ParsingFailed; +} + +fn fieldAccessExtra(p: *Parser, lhs: NodeIndex, record_ty: *const Type.Record, field_name: StringId, is_arrow: bool, offset_bits: *u64) Error!Result { + for (record_ty.fields, 0..) |f, i| { + if (f.isAnonymousRecord()) { + if (!f.ty.hasField(field_name)) continue; + const inner = try p.addNode(.{ + .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr, + .ty = f.ty, + .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } }, + }); + const ret = p.fieldAccessExtra(inner, f.ty.getRecord().?, field_name, false, offset_bits); + offset_bits.* = f.layout.offset_bits; + return ret; + } + if (field_name == f.name) { + offset_bits.* = f.layout.offset_bits; + return Result{ + .ty = f.ty, + .node = try p.addNode(.{ + .tag = if (is_arrow) .member_access_ptr_expr else .member_access_expr, + .ty = f.ty, + .data = .{ .member = .{ .lhs = lhs, .index = @intCast(i) } }, + }), + }; + } + } + // We already checked that this container has a field by the name. + unreachable; +} + +fn checkVaStartArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void { + assert(idx != 0); + if (idx > 1) { + try p.errTok(.closing_paren, first_after); + return error.ParsingFailed; + } + + var func_ty = p.func.ty orelse { + try p.errTok(.va_start_not_in_func, builtin_tok); + return; + }; + const func_params = func_ty.params(); + if (func_ty.specifier != .var_args_func or func_params.len == 0) { + return p.errTok(.va_start_fixed_args, builtin_tok); + } + const last_param_name = func_params[func_params.len - 1].name; + const decl_ref = p.getNode(arg.node, .decl_ref_expr); + if (decl_ref == null or last_param_name != try StrInt.intern(p.comp, p.tokSlice(p.nodes.items(.data)[@intFromEnum(decl_ref.?)].decl_ref))) { + try p.errTok(.va_start_not_last_param, param_tok); + } +} + +fn checkArithOverflowArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void { + _ = builtin_tok; + _ = first_after; + if (idx <= 1) { + if (!arg.ty.isInt()) { + return p.errStr(.overflow_builtin_requires_int, param_tok, try p.typeStr(arg.ty)); + } + } else if (idx == 2) { + if (!arg.ty.isPtr()) return p.errStr(.overflow_result_requires_ptr, param_tok, try p.typeStr(arg.ty)); + const child = arg.ty.elemType(); + if (!child.isInt() or child.is(.bool) or child.is(.@"enum") or child.qual.@"const") return p.errStr(.overflow_result_requires_ptr, param_tok, try p.typeStr(arg.ty)); + } +} + +fn checkComplexArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void { + _ = builtin_tok; + _ = first_after; + if (idx <= 1 and !arg.ty.isFloat()) { + try p.errStr(.not_floating_type, param_tok, try p.typeStr(arg.ty)); + } else if (idx == 1) { + const prev_idx = p.list_buf.items[p.list_buf.items.len - 1]; + const prev_ty = p.nodes.items(.ty)[@intFromEnum(prev_idx)]; + if (!prev_ty.eql(arg.ty, p.comp, false)) { + try p.errStr(.argument_types_differ, param_tok, try p.typePairStrExtra(prev_ty, " vs ", arg.ty)); + } + } +} + +fn callExpr(p: *Parser, lhs: Result) Error!Result { + const l_paren = p.tok_i; + p.tok_i += 1; + const ty = lhs.ty.isCallable() orelse { + try p.errStr(.not_callable, l_paren, try p.typeStr(lhs.ty)); + return error.ParsingFailed; + }; + const params = ty.params(); + var func = lhs; + try func.lvalConversion(p); + + const list_buf_top = p.list_buf.items.len; + defer p.list_buf.items.len = list_buf_top; + try p.list_buf.append(func.node); + var arg_count: u32 = 0; + var first_after = l_paren; + + const call_expr = CallExpr.init(p, lhs.node, func.node); + + while (p.eatToken(.r_paren) == null) { + const param_tok = p.tok_i; + if (arg_count == params.len) first_after = p.tok_i; + var arg = try p.assignExpr(); + try arg.expect(p); + + if (call_expr.shouldPerformLvalConversion(arg_count)) { + try arg.lvalConversion(p); + } + if (arg.ty.hasIncompleteSize() and !arg.ty.is(.void)) return error.ParsingFailed; + + if (arg_count >= params.len) { + if (call_expr.shouldPromoteVarArg(arg_count)) { + if (arg.ty.isInt()) try arg.intCast(p, arg.ty.integerPromotion(p.comp), param_tok); + if (arg.ty.is(.float)) try arg.floatCast(p, .{ .specifier = .double }); + } + try call_expr.checkVarArg(p, first_after, param_tok, &arg, arg_count); + try arg.saveValue(p); + try p.list_buf.append(arg.node); + arg_count += 1; + + _ = p.eatToken(.comma) orelse { + try p.expectClosing(l_paren, .r_paren); + break; + }; + continue; + } + const p_ty = params[arg_count].ty; + if (p_ty.specifier == .static_array) { + const arg_array_len: u64 = arg.ty.arrayLen() orelse std.math.maxInt(u64); + const param_array_len: u64 = p_ty.arrayLen().?; + if (arg_array_len < param_array_len) { + const extra = Diagnostics.Message.Extra{ .arguments = .{ + .expected = @intCast(arg_array_len), + .actual = @intCast(param_array_len), + } }; + try p.errExtra(.array_argument_too_small, param_tok, extra); + try p.errTok(.callee_with_static_array, params[arg_count].name_tok); + } + if (arg.val.isZero(p.comp)) { + try p.errTok(.non_null_argument, param_tok); + try p.errTok(.callee_with_static_array, params[arg_count].name_tok); + } + } + + if (call_expr.shouldCoerceArg(arg_count)) { + try arg.coerce(p, p_ty, param_tok, .{ .arg = params[arg_count].name_tok }); + } + try arg.saveValue(p); + try p.list_buf.append(arg.node); + arg_count += 1; + + _ = p.eatToken(.comma) orelse { + try p.expectClosing(l_paren, .r_paren); + break; + }; + } + + const actual: u32 = @intCast(arg_count); + const extra = Diagnostics.Message.Extra{ .arguments = .{ + .expected = @intCast(params.len), + .actual = actual, + } }; + if (call_expr.paramCountOverride()) |expected| { + if (expected != actual) { + try p.errExtra(.expected_arguments, first_after, .{ .arguments = .{ .expected = expected, .actual = actual } }); + } + } else if (ty.is(.func) and params.len != arg_count) { + try p.errExtra(.expected_arguments, first_after, extra); + } else if (ty.is(.old_style_func) and params.len != arg_count) { + if (params.len == 0) + try p.errTok(.passing_args_to_kr, first_after) + else + try p.errExtra(.expected_arguments_old, first_after, extra); + } else if (ty.is(.var_args_func) and arg_count < params.len) { + try p.errExtra(.expected_at_least_arguments, first_after, extra); + } + + return call_expr.finish(p, ty, list_buf_top, arg_count); +} + +fn checkArrayBounds(p: *Parser, index: Result, array: Result, tok: TokenIndex) !void { + if (index.val.opt_ref == .none) return; + + const array_len = array.ty.arrayLen() orelse return; + if (array_len == 0) return; + + if (array_len == 1) { + if (p.getNode(array.node, .member_access_expr) orelse p.getNode(array.node, .member_access_ptr_expr)) |node| { + const data = p.nodes.items(.data)[@intFromEnum(node)]; + var lhs = p.nodes.items(.ty)[@intFromEnum(data.member.lhs)]; + if (lhs.get(.pointer)) |ptr| { + lhs = ptr.data.sub_type.*; + } + if (lhs.is(.@"struct")) { + const record = lhs.getRecord().?; + if (data.member.index + 1 == record.fields.len) { + if (!index.val.isZero(p.comp)) { + try p.errStr(.old_style_flexible_struct, tok, try index.str(p)); + } + return; + } + } + } + } + const index_int = index.val.toInt(u64, p.comp) orelse std.math.maxInt(u64); + if (index.ty.isUnsignedInt(p.comp)) { + if (index_int >= array_len) { + try p.errStr(.array_after, tok, try index.str(p)); + } + } else { + if (index.val.compare(.lt, Value.zero, p.comp)) { + try p.errStr(.array_before, tok, try index.str(p)); + } else if (index_int >= array_len) { + try p.errStr(.array_after, tok, try index.str(p)); + } + } +} + +/// primaryExpr +/// : IDENTIFIER +/// | keyword_true +/// | keyword_false +/// | keyword_nullptr +/// | INTEGER_LITERAL +/// | FLOAT_LITERAL +/// | IMAGINARY_LITERAL +/// | CHAR_LITERAL +/// | STRING_LITERAL +/// | '(' expr ')' +/// | genericSelection +fn primaryExpr(p: *Parser) Error!Result { + if (p.eatToken(.l_paren)) |l_paren| { + var e = try p.expr(); + try e.expect(p); + try p.expectClosing(l_paren, .r_paren); + try e.un(p, .paren_expr, l_paren); + return e; + } + switch (p.tok_ids[p.tok_i]) { + .identifier, .extended_identifier => { + const name_tok = try p.expectIdentifier(); + const name = p.tokSlice(name_tok); + const interned_name = try StrInt.intern(p.comp, name); + if (interned_name == p.auto_type_decl_name) { + try p.errStr(.auto_type_self_initialized, name_tok, name); + return error.ParsingFailed; + } + if (p.syms.findSymbol(interned_name)) |sym| { + try p.checkDeprecatedUnavailable(sym.ty, name_tok, sym.tok); + if (sym.kind == .constexpr) { + return Result{ + .val = sym.val, + .ty = sym.ty, + .node = try p.addNode(.{ + .tag = .decl_ref_expr, + .ty = sym.ty, + .data = .{ .decl_ref = name_tok }, + .loc = @enumFromInt(name_tok), + }), + }; + } + if (sym.val.is(.int, p.comp)) { + switch (p.const_decl_folding) { + .gnu_folding_extension => try p.errTok(.const_decl_folded, name_tok), + .gnu_vla_folding_extension => try p.errTok(.const_decl_folded_vla, name_tok), + else => {}, + } + } + return Result{ + .val = if (p.const_decl_folding == .no_const_decl_folding and sym.kind != .enumeration) Value{} else sym.val, + .ty = sym.ty, + .node = try p.addNode(.{ + .tag = if (sym.kind == .enumeration) .enumeration_ref else .decl_ref_expr, + .ty = sym.ty, + .data = .{ .decl_ref = name_tok }, + .loc = @enumFromInt(name_tok), + }), + }; + } + if (try p.comp.builtins.getOrCreate(p.comp, name, p.arena)) |some| { + for (p.tok_ids[p.tok_i..]) |id| switch (id) { + .r_paren => {}, // closing grouped expr + .l_paren => break, // beginning of a call + else => { + try p.errTok(.builtin_must_be_called, name_tok); + return error.ParsingFailed; + }, + }; + if (some.builtin.properties.header != .none) { + try p.errStr(.implicit_builtin, name_tok, name); + try p.errExtra(.implicit_builtin_header_note, name_tok, .{ .builtin_with_header = .{ + .builtin = some.builtin.tag, + .header = some.builtin.properties.header, + } }); + } + + return Result{ + .ty = some.ty, + .node = try p.addNode(.{ + .tag = .builtin_call_expr_one, + .ty = some.ty, + .data = .{ .decl = .{ .name = name_tok, .node = .none } }, + .loc = @enumFromInt(name_tok), + }), + }; + } + if (p.tok_ids[p.tok_i] == .l_paren and !p.comp.langopts.standard.atLeast(.c23)) { + // allow implicitly declaring functions before C99 like `puts("foo")` + if (mem.startsWith(u8, name, "__builtin_")) + try p.errStr(.unknown_builtin, name_tok, name) + else + try p.errStr(.implicit_func_decl, name_tok, name); + + const func_ty = try p.arena.create(Type.Func); + func_ty.* = .{ .return_type = .{ .specifier = .int }, .params = &.{} }; + const ty: Type = .{ .specifier = .old_style_func, .data = .{ .func = func_ty } }; + const node = try p.addNode(.{ + .ty = ty, + .tag = .fn_proto, + .data = .{ .decl = .{ .name = name_tok } }, + .loc = @enumFromInt(name_tok), + }); + + try p.decl_buf.append(node); + try p.syms.declareSymbol(p, interned_name, ty, name_tok, node); + + return Result{ + .ty = ty, + .node = try p.addNode(.{ + .tag = .decl_ref_expr, + .ty = ty, + .data = .{ .decl_ref = name_tok }, + .loc = @enumFromInt(name_tok), + }), + }; + } + try p.errStr(.undeclared_identifier, name_tok, p.tokSlice(name_tok)); + return error.ParsingFailed; + }, + .keyword_true, .keyword_false => |id| { + const tok_i = p.tok_i; + p.tok_i += 1; + const res = Result{ + .val = Value.fromBool(id == .keyword_true), + .ty = .{ .specifier = .bool }, + .node = try p.addNode(.{ .tag = .bool_literal, .ty = .{ .specifier = .bool }, .data = undefined, .loc = @enumFromInt(tok_i) }), + }; + std.debug.assert(!p.in_macro); // Should have been replaced with .one / .zero + try p.value_map.put(res.node, res.val); + return res; + }, + .keyword_nullptr => { + defer p.tok_i += 1; + try p.errStr(.pre_c23_compat, p.tok_i, "'nullptr'"); + return Result{ + .val = Value.null, + .ty = .{ .specifier = .nullptr_t }, + .node = try p.addNode(.{ + .tag = .nullptr_literal, + .ty = .{ .specifier = .nullptr_t }, + .data = undefined, + .loc = @enumFromInt(p.tok_i), + }), + }; + }, + .macro_func, .macro_function => { + defer p.tok_i += 1; + var ty: Type = undefined; + var tok = p.tok_i; + if (p.func.ident) |some| { + ty = some.ty; + tok = p.nodes.items(.data)[@intFromEnum(some.node)].decl.name; + } else if (p.func.ty) |_| { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + try p.strings.appendSlice(p.tokSlice(p.func.name)); + try p.strings.append(0); + const predef = try p.makePredefinedIdentifier(strings_top); + ty = predef.ty; + p.func.ident = predef; + } else { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + try p.strings.append(0); + const predef = try p.makePredefinedIdentifier(strings_top); + ty = predef.ty; + p.func.ident = predef; + try p.decl_buf.append(predef.node); + } + if (p.func.ty == null) try p.err(.predefined_top_level); + return Result{ + .ty = ty, + .node = try p.addNode(.{ + .tag = .decl_ref_expr, + .ty = ty, + .data = .{ .decl_ref = tok }, + .loc = @enumFromInt(tok), + }), + }; + }, + .macro_pretty_func => { + defer p.tok_i += 1; + var ty: Type = undefined; + if (p.func.pretty_ident) |some| { + ty = some.ty; + } else if (p.func.ty) |func_ty| { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + const mapper = p.comp.string_interner.getSlowTypeMapper(); + try Type.printNamed(func_ty, p.tokSlice(p.func.name), mapper, p.comp.langopts, p.strings.writer()); + try p.strings.append(0); + const predef = try p.makePredefinedIdentifier(strings_top); + ty = predef.ty; + p.func.pretty_ident = predef; + } else { + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + try p.strings.appendSlice("top level\x00"); + const predef = try p.makePredefinedIdentifier(strings_top); + ty = predef.ty; + p.func.pretty_ident = predef; + try p.decl_buf.append(predef.node); + } + if (p.func.ty == null) try p.err(.predefined_top_level); + return Result{ + .ty = ty, + .node = try p.addNode(.{ + .tag = .decl_ref_expr, + .ty = ty, + .data = .{ .decl_ref = p.tok_i }, + .loc = @enumFromInt(p.tok_i), + }), + }; + }, + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + .unterminated_string_literal, + => return p.stringLiteral(), + .char_literal, + .char_literal_utf_8, + .char_literal_utf_16, + .char_literal_utf_32, + .char_literal_wide, + .empty_char_literal, + .unterminated_char_literal, + => return p.charLiteral(), + .zero => { + defer p.tok_i += 1; + var res: Result = .{ .val = Value.zero, .ty = if (p.in_macro) p.comp.types.intmax else Type.int }; + res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined, .loc = @enumFromInt(p.tok_i) }); + if (!p.in_macro) try p.value_map.put(res.node, res.val); + return res; + }, + .one => { + defer p.tok_i += 1; + var res: Result = .{ .val = Value.one, .ty = if (p.in_macro) p.comp.types.intmax else Type.int }; + res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined, .loc = @enumFromInt(p.tok_i) }); + if (!p.in_macro) try p.value_map.put(res.node, res.val); + return res; + }, + .pp_num => return p.ppNum(), + .embed_byte => { + assert(!p.in_macro); + const loc = p.pp.tokens.items(.loc)[p.tok_i]; + defer p.tok_i += 1; + const buf = p.comp.getSource(.generated).buf[loc.byte_offset..]; + var byte: u8 = buf[0] - '0'; + for (buf[1..]) |c| { + if (!std.ascii.isDigit(c)) break; + byte *= 10; + byte += c - '0'; + } + var res: Result = .{ .val = try Value.int(byte, p.comp) }; + res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined, .loc = @enumFromInt(p.tok_i) }); + try p.value_map.put(res.node, res.val); + return res; + }, + .keyword_generic => return p.genericSelection(), + else => return Result{}, + } +} + +fn makePredefinedIdentifier(p: *Parser, strings_top: usize) !Result { + const end: u32 = @intCast(p.strings.items.len); + const elem_ty: Type = .{ .specifier = .char, .qual = .{ .@"const" = true } }; + const arr_ty = try p.arena.create(Type.Array); + arr_ty.* = .{ .elem = elem_ty, .len = end - strings_top }; + const ty: Type = .{ .specifier = .array, .data = .{ .array = arr_ty } }; + + const slice = p.strings.items[strings_top..]; + const val = try Value.intern(p.comp, .{ .bytes = slice }); + + const str_lit = try p.addNode(.{ .tag = .string_literal_expr, .ty = ty, .data = undefined, .loc = @enumFromInt(p.tok_i) }); + if (!p.in_macro) try p.value_map.put(str_lit, val); + + return Result{ .ty = ty, .node = try p.addNode(.{ + .tag = .implicit_static_var, + .ty = ty, + .data = .{ .decl = .{ .name = p.tok_i, .node = str_lit } }, + .loc = @enumFromInt(p.tok_i), + }) }; +} + +fn stringLiteral(p: *Parser) Error!Result { + const string_start = p.tok_i; + var string_end = p.tok_i; + var string_kind: text_literal.Kind = .char; + while (text_literal.Kind.classify(p.tok_ids[string_end], .string_literal)) |next| : (string_end += 1) { + string_kind = string_kind.concat(next) catch { + try p.errTok(.unsupported_str_cat, string_end); + while (p.tok_ids[p.tok_i].isStringLiteral()) : (p.tok_i += 1) {} + return error.ParsingFailed; + }; + if (string_kind == .unterminated) { + try p.errTok(.unterminated_string_literal_error, string_end); + p.tok_i = string_end + 1; + return error.ParsingFailed; + } + } + const count = string_end - p.tok_i; + assert(count > 0); + + const char_width = string_kind.charUnitSize(p.comp); + + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + + const literal_start = mem.alignForward(usize, strings_top, @intFromEnum(char_width)); + try p.strings.resize(literal_start); + + while (p.tok_i < string_end) : (p.tok_i += 1) { + const this_kind = text_literal.Kind.classify(p.tok_ids[p.tok_i], .string_literal).?; + const slice = this_kind.contentSlice(p.tokSlice(p.tok_i)); + var char_literal_parser = text_literal.Parser.init(slice, this_kind, 0x10ffff, p.comp); + + try p.strings.ensureUnusedCapacity((slice.len + 1) * @intFromEnum(char_width)); // +1 for null terminator + while (char_literal_parser.next()) |item| switch (item) { + .value => |v| { + switch (char_width) { + .@"1" => p.strings.appendAssumeCapacity(@intCast(v)), + .@"2" => { + const word: u16 = @intCast(v); + p.strings.appendSliceAssumeCapacity(mem.asBytes(&word)); + }, + .@"4" => p.strings.appendSliceAssumeCapacity(mem.asBytes(&v)), + } + }, + .codepoint => |c| { + switch (char_width) { + .@"1" => { + var buf: [4]u8 = undefined; + const written = std.unicode.utf8Encode(c, &buf) catch unreachable; + const encoded = buf[0..written]; + p.strings.appendSliceAssumeCapacity(encoded); + }, + .@"2" => { + var utf16_buf: [2]u16 = undefined; + var utf8_buf: [4]u8 = undefined; + const utf8_written = std.unicode.utf8Encode(c, &utf8_buf) catch unreachable; + const utf16_written = std.unicode.utf8ToUtf16Le(&utf16_buf, utf8_buf[0..utf8_written]) catch unreachable; + const bytes = std.mem.sliceAsBytes(utf16_buf[0..utf16_written]); + p.strings.appendSliceAssumeCapacity(bytes); + }, + .@"4" => { + const val: u32 = c; + p.strings.appendSliceAssumeCapacity(mem.asBytes(&val)); + }, + } + }, + .improperly_encoded => |bytes| { + if (count > 1) { + try p.errTok(.illegal_char_encoding_error, p.tok_i); + return error.ParsingFailed; + } + p.strings.appendSliceAssumeCapacity(bytes); + }, + .utf8_text => |view| { + switch (char_width) { + .@"1" => p.strings.appendSliceAssumeCapacity(view.bytes), + .@"2" => { + const capacity_slice: []align(@alignOf(u16)) u8 = @alignCast(p.strings.allocatedSlice()[literal_start..]); + const dest_len = std.mem.alignBackward(usize, capacity_slice.len, 2); + const dest = std.mem.bytesAsSlice(u16, capacity_slice[0..dest_len]); + const words_written = std.unicode.utf8ToUtf16Le(dest, view.bytes) catch unreachable; + p.strings.resize(p.strings.items.len + words_written * 2) catch unreachable; + }, + .@"4" => { + var it = view.iterator(); + while (it.nextCodepoint()) |codepoint| { + const val: u32 = codepoint; + p.strings.appendSliceAssumeCapacity(mem.asBytes(&val)); + } + }, + } + }, + }; + for (char_literal_parser.errors()) |item| { + try p.errExtra(item.tag, p.tok_i, item.extra); + } + } + p.strings.appendNTimesAssumeCapacity(0, @intFromEnum(char_width)); + const slice = p.strings.items[literal_start..]; + + // TODO this won't do anything if there is a cache hit + const interned_align = mem.alignForward( + usize, + p.comp.interner.strings.items.len, + string_kind.internalStorageAlignment(p.comp), + ); + try p.comp.interner.strings.resize(p.gpa, interned_align); + + const val = try Value.intern(p.comp, .{ .bytes = slice }); + + const arr_ty = try p.arena.create(Type.Array); + arr_ty.* = .{ .elem = string_kind.elementType(p.comp), .len = @divExact(slice.len, @intFromEnum(char_width)) }; + var res: Result = .{ + .ty = .{ + .specifier = .array, + .data = .{ .array = arr_ty }, + }, + .val = val, + }; + res.node = try p.addNode(.{ .tag = .string_literal_expr, .ty = res.ty, .data = undefined, .loc = @enumFromInt(string_start) }); + if (!p.in_macro) try p.value_map.put(res.node, res.val); + return res; +} + +fn charLiteral(p: *Parser) Error!Result { + defer p.tok_i += 1; + const tok_id = p.tok_ids[p.tok_i]; + const char_kind = text_literal.Kind.classify(tok_id, .char_literal) orelse { + if (tok_id == .empty_char_literal) { + try p.err(.empty_char_literal_error); + } else if (tok_id == .unterminated_char_literal) { + try p.err(.unterminated_char_literal_error); + } else unreachable; + return .{ + .ty = Type.int, + .val = Value.zero, + .node = try p.addNode(.{ .tag = .char_literal, .ty = Type.int, .data = undefined, .loc = @enumFromInt(p.tok_i) }), + }; + }; + if (char_kind == .utf_8) try p.err(.u8_char_lit); + var val: u32 = 0; + + const slice = char_kind.contentSlice(p.tokSlice(p.tok_i)); + + var is_multichar = false; + if (slice.len == 1 and std.ascii.isASCII(slice[0])) { + // fast path: single unescaped ASCII char + val = slice[0]; + } else { + const max_codepoint = char_kind.maxCodepoint(p.comp); + var char_literal_parser = text_literal.Parser.init(slice, char_kind, max_codepoint, p.comp); + + const max_chars_expected = 4; + var stack_fallback = std.heap.stackFallback(max_chars_expected * @sizeOf(u32), p.comp.gpa); + var chars = std.ArrayList(u32).initCapacity(stack_fallback.get(), max_chars_expected) catch unreachable; // stack allocation already succeeded + defer chars.deinit(); + + while (char_literal_parser.next()) |item| switch (item) { + .value => |v| try chars.append(v), + .codepoint => |c| try chars.append(c), + .improperly_encoded => |s| { + try chars.ensureUnusedCapacity(s.len); + for (s) |c| chars.appendAssumeCapacity(c); + }, + .utf8_text => |view| { + var it = view.iterator(); + var max_codepoint_seen: u21 = 0; + try chars.ensureUnusedCapacity(view.bytes.len); + while (it.nextCodepoint()) |c| { + max_codepoint_seen = @max(max_codepoint_seen, c); + chars.appendAssumeCapacity(c); + } + if (max_codepoint_seen > max_codepoint) { + char_literal_parser.err(.char_too_large, .{ .none = {} }); + } + }, + }; + + is_multichar = chars.items.len > 1; + if (is_multichar) { + if (char_kind == .char and chars.items.len == 4) { + char_literal_parser.warn(.four_char_char_literal, .{ .none = {} }); + } else if (char_kind == .char) { + char_literal_parser.warn(.multichar_literal_warning, .{ .none = {} }); + } else { + const kind = switch (char_kind) { + .wide => "wide", + .utf_8, .utf_16, .utf_32 => "Unicode", + else => unreachable, + }; + char_literal_parser.err(.invalid_multichar_literal, .{ .str = kind }); + } + } + + var multichar_overflow = false; + if (char_kind == .char and is_multichar) { + for (chars.items) |item| { + val, const overflowed = @shlWithOverflow(val, 8); + multichar_overflow = multichar_overflow or overflowed != 0; + val += @as(u8, @truncate(item)); + } + } else if (chars.items.len > 0) { + val = chars.items[chars.items.len - 1]; + } + + if (multichar_overflow) { + char_literal_parser.err(.char_lit_too_wide, .{ .none = {} }); + } + + for (char_literal_parser.errors()) |item| { + try p.errExtra(item.tag, p.tok_i, item.extra); + } + } + + const ty = char_kind.charLiteralType(p.comp); + // This is the type the literal will have if we're in a macro; macros always operate on intmax_t/uintmax_t values + const macro_ty = if (ty.isUnsignedInt(p.comp) or (char_kind == .char and p.comp.getCharSignedness() == .unsigned)) + p.comp.types.intmax.makeIntegerUnsigned() + else + p.comp.types.intmax; + + var value = try Value.int(val, p.comp); + // C99 6.4.4.4.10 + // > If an integer character constant contains a single character or escape sequence, + // > its value is the one that results when an object with type char whose value is + // > that of the single character or escape sequence is converted to type int. + // This conversion only matters if `char` is signed and has a high-order bit of `1` + if (char_kind == .char and !is_multichar and val > 0x7F and p.comp.getCharSignedness() == .signed) { + _ = try value.intCast(.{ .specifier = .char }, p.comp); + } + + const res = Result{ + .ty = if (p.in_macro) macro_ty else ty, + .val = value, + .node = try p.addNode(.{ .tag = .char_literal, .ty = ty, .data = undefined, .loc = @enumFromInt(p.tok_i) }), + }; + if (!p.in_macro) try p.value_map.put(res.node, res.val); + return res; +} + +fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result { + const ty = Type{ .specifier = switch (suffix) { + .None, .I => .double, + .F, .IF => .float, + .F16, .IF16 => .float16, + .L, .IL => .long_double, + .W, .IW => p.comp.float80Type().?.specifier, + .Q, .IQ, .F128, .IF128 => .float128, + else => unreachable, + } }; + const val = try Value.intern(p.comp, key: { + try p.strings.ensureUnusedCapacity(buf.len); + + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + for (buf) |c| { + if (c != '\'') p.strings.appendAssumeCapacity(c); + } + + const float = std.fmt.parseFloat(f128, p.strings.items[strings_top..]) catch unreachable; + const bits = ty.bitSizeof(p.comp).?; + break :key switch (bits) { + 16 => .{ .float = .{ .f16 = @floatCast(float) } }, + 32 => .{ .float = .{ .f32 = @floatCast(float) } }, + 64 => .{ .float = .{ .f64 = @floatCast(float) } }, + 80 => .{ .float = .{ .f80 = @floatCast(float) } }, + 128 => .{ .float = .{ .f128 = @floatCast(float) } }, + else => unreachable, + }; + }); + var res = Result{ + .ty = ty, + .node = try p.addNode(.{ .tag = .float_literal, .ty = ty, .data = undefined, .loc = @enumFromInt(tok_i) }), + .val = val, + }; + if (suffix.isImaginary()) { + try p.err(.gnu_imaginary_constant); + res.ty = .{ .specifier = switch (suffix) { + .I => .complex_double, + .IF16 => .complex_float16, + .IF => .complex_float, + .IL => .complex_long_double, + .IW => p.comp.float80Type().?.makeComplex().specifier, + .IQ, .IF128 => .complex_float128, + else => unreachable, + } }; + res.val = try Value.intern(p.comp, switch (res.ty.bitSizeof(p.comp).?) { + 32 => .{ .complex = .{ .cf16 = .{ 0.0, val.toFloat(f16, p.comp) } } }, + 64 => .{ .complex = .{ .cf32 = .{ 0.0, val.toFloat(f32, p.comp) } } }, + 128 => .{ .complex = .{ .cf64 = .{ 0.0, val.toFloat(f64, p.comp) } } }, + 160 => .{ .complex = .{ .cf80 = .{ 0.0, val.toFloat(f80, p.comp) } } }, + 256 => .{ .complex = .{ .cf128 = .{ 0.0, val.toFloat(f128, p.comp) } } }, + else => unreachable, + }); + try res.un(p, .imaginary_literal, tok_i); + } + return res; +} + +fn getIntegerPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 { + if (buf[0] == '.') return ""; + + if (!prefix.digitAllowed(buf[0])) { + switch (prefix) { + .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(buf[0]) }), + .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(buf[0]) }), + .hex => try p.errStr(.invalid_int_suffix, tok_i, buf), + .decimal => unreachable, + } + return error.ParsingFailed; + } + + for (buf, 0..) |c, idx| { + if (idx == 0) continue; + switch (c) { + '.' => return buf[0..idx], + 'p', 'P' => return if (prefix == .hex) buf[0..idx] else { + try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]); + return error.ParsingFailed; + }, + 'e', 'E' => { + switch (prefix) { + .hex => continue, + .decimal => return buf[0..idx], + .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }), + .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }), + } + return error.ParsingFailed; + }, + '0'...'9', 'a'...'d', 'A'...'D', 'f', 'F' => { + if (!prefix.digitAllowed(c)) { + switch (prefix) { + .binary => try p.errExtra(.invalid_binary_digit, tok_i, .{ .ascii = @intCast(c) }), + .octal => try p.errExtra(.invalid_octal_digit, tok_i, .{ .ascii = @intCast(c) }), + .decimal, .hex => try p.errStr(.invalid_int_suffix, tok_i, buf[idx..]), + } + return error.ParsingFailed; + } + }, + '\'' => {}, + else => return buf[0..idx], + } + } + return buf; +} + +fn fixedSizeInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result { + var val: u64 = 0; + var overflow = false; + for (buf) |c| { + const digit: u64 = switch (c) { + '0'...'9' => c - '0', + 'A'...'Z' => c - 'A' + 10, + 'a'...'z' => c - 'a' + 10, + '\'' => continue, + else => unreachable, + }; + + if (val != 0) { + const product, const overflowed = @mulWithOverflow(val, base); + if (overflowed != 0) { + overflow = true; + } + val = product; + } + const sum, const overflowed = @addWithOverflow(val, digit); + if (overflowed != 0) overflow = true; + val = sum; + } + var res: Result = .{ .val = try Value.int(val, p.comp) }; + if (overflow) { + try p.errTok(.int_literal_too_big, tok_i); + res.ty = .{ .specifier = .ulong_long }; + res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined, .loc = @enumFromInt(tok_i) }); + if (!p.in_macro) try p.value_map.put(res.node, res.val); + return res; + } + const interned_val = try Value.int(val, p.comp); + if (suffix.isSignedInteger()) { + const max_int = try Value.maxInt(p.comp.types.intmax, p.comp); + if (interned_val.compare(.gt, max_int, p.comp)) { + try p.errTok(.implicitly_unsigned_literal, tok_i); + } + } + + const signed_specs = .{ .int, .long, .long_long }; + const unsigned_specs = .{ .uint, .ulong, .ulong_long }; + const signed_oct_hex_specs = .{ .int, .uint, .long, .ulong, .long_long, .ulong_long }; + const specs: []const Type.Specifier = if (suffix.signedness() == .unsigned) + &unsigned_specs + else if (base == 10) + &signed_specs + else + &signed_oct_hex_specs; + + const suffix_ty: Type = .{ .specifier = switch (suffix) { + .None, .I => .int, + .U, .IU => .uint, + .UL, .IUL => .ulong, + .ULL, .IULL => .ulong_long, + .L, .IL => .long, + .LL, .ILL => .long_long, + else => unreachable, + } }; + + for (specs) |spec| { + res.ty = Type{ .specifier = spec }; + if (res.ty.compareIntegerRanks(suffix_ty, p.comp).compare(.lt)) continue; + const max_int = try Value.maxInt(res.ty, p.comp); + if (interned_val.compare(.lte, max_int, p.comp)) break; + } else { + res.ty = .{ .specifier = spec: { + if (p.comp.langopts.emulate == .gcc) { + if (target_util.hasInt128(p.comp.target)) { + break :spec .int128; + } else { + break :spec .long_long; + } + } else { + break :spec .ulong_long; + } + } }; + } + + res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined, .loc = @enumFromInt(tok_i) }); + if (!p.in_macro) try p.value_map.put(res.node, res.val); + return res; +} + +fn parseInt(p: *Parser, prefix: NumberPrefix, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) !Result { + if (prefix == .binary) { + try p.errTok(.binary_integer_literal, tok_i); + } + const base = @intFromEnum(prefix); + var res = if (suffix.isBitInt()) + try p.bitInt(base, buf, suffix, tok_i) + else + try p.fixedSizeInt(base, buf, suffix, tok_i); + + if (suffix.isImaginary()) { + try p.errTok(.gnu_imaginary_constant, tok_i); + res.ty = res.ty.makeComplex(); + res.val = .{}; + try res.un(p, .imaginary_literal, tok_i); + } + return res; +} + +fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: TokenIndex) Error!Result { + try p.errStr(.pre_c23_compat, tok_i, "'_BitInt' suffix for literals"); + try p.errTok(.bitint_suffix, tok_i); + + var managed = try big.int.Managed.init(p.gpa); + defer managed.deinit(); + + { + try p.strings.ensureUnusedCapacity(buf.len); + + const strings_top = p.strings.items.len; + defer p.strings.items.len = strings_top; + for (buf) |c| { + if (c != '\'') p.strings.appendAssumeCapacity(c); + } + + managed.setString(base, p.strings.items[strings_top..]) catch |e| switch (e) { + error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16 + error.InvalidCharacter => unreachable, // digits validated by Tokenizer + else => |er| return er, + }; + } + const c = managed.toConst(); + const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: { + // Literal `0` requires at least 1 bit + const count = @max(1, c.bitCountTwosComp()); + // The wb suffix results in a _BitInt that includes space for the sign bit even if the + // value of the constant is positive or was specified in hexadecimal or octal notation. + const sign_bits = @intFromBool(suffix.isSignedInteger()); + const bits_needed = count + sign_bits; + break :blk @intCast(bits_needed); + }; + + var res: Result = .{ + .val = try Value.intern(p.comp, .{ .int = .{ .big_int = c } }), + .ty = .{ + .specifier = .bit_int, + .data = .{ .int = .{ .bits = bits_needed, .signedness = suffix.signedness() } }, + }, + }; + res.node = try p.addNode(.{ .tag = .int_literal, .ty = res.ty, .data = undefined, .loc = @enumFromInt(tok_i) }); + if (!p.in_macro) try p.value_map.put(res.node, res.val); + return res; +} + +fn getFracPart(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 { + if (buf.len == 0 or buf[0] != '.') return ""; + assert(prefix != .octal); + if (prefix == .binary) { + try p.errStr(.invalid_int_suffix, tok_i, buf); + return error.ParsingFailed; + } + for (buf, 0..) |c, idx| { + if (idx == 0) continue; + if (c == '\'') continue; + if (!prefix.digitAllowed(c)) return buf[0..idx]; + } + return buf; +} + +fn getExponent(p: *Parser, buf: []const u8, prefix: NumberPrefix, tok_i: TokenIndex) ![]const u8 { + if (buf.len == 0) return ""; + + switch (buf[0]) { + 'e', 'E' => assert(prefix == .decimal), + 'p', 'P' => if (prefix != .hex) { + try p.errStr(.invalid_float_suffix, tok_i, buf); + return error.ParsingFailed; + }, + else => return "", + } + const end = for (buf, 0..) |c, idx| { + if (idx == 0) continue; + if (idx == 1 and (c == '+' or c == '-')) continue; + switch (c) { + '0'...'9' => {}, + '\'' => continue, + else => break idx, + } + } else buf.len; + const exponent = buf[0..end]; + if (std.mem.indexOfAny(u8, exponent, "0123456789") == null) { + try p.errTok(.exponent_has_no_digits, tok_i); + return error.ParsingFailed; + } + return exponent; +} + +/// Using an explicit `tok_i` parameter instead of `p.tok_i` makes it easier +/// to parse numbers in pragma handlers. +pub fn parseNumberToken(p: *Parser, tok_i: TokenIndex) !Result { + const buf = p.tokSlice(tok_i); + const prefix = NumberPrefix.fromString(buf); + const after_prefix = buf[prefix.stringLen()..]; + + const int_part = try p.getIntegerPart(after_prefix, prefix, tok_i); + + const after_int = after_prefix[int_part.len..]; + + const frac = try p.getFracPart(after_int, prefix, tok_i); + const after_frac = after_int[frac.len..]; + + const exponent = try p.getExponent(after_frac, prefix, tok_i); + const suffix_str = after_frac[exponent.len..]; + const is_float = (exponent.len > 0 or frac.len > 0); + const suffix = NumberSuffix.fromString(suffix_str, if (is_float) .float else .int) orelse { + if (is_float) { + try p.errStr(.invalid_float_suffix, tok_i, suffix_str); + } else { + try p.errStr(.invalid_int_suffix, tok_i, suffix_str); + } + return error.ParsingFailed; + }; + if (suffix.isFloat80() and p.comp.float80Type() == null) { + try p.errStr(.invalid_float_suffix, tok_i, suffix_str); + return error.ParsingFailed; + } + + if (is_float) { + assert(prefix == .hex or prefix == .decimal); + if (prefix == .hex and exponent.len == 0) { + try p.errTok(.hex_floating_constant_requires_exponent, tok_i); + return error.ParsingFailed; + } + const number = buf[0 .. buf.len - suffix_str.len]; + return p.parseFloat(number, suffix, tok_i); + } else { + return p.parseInt(prefix, int_part, suffix, tok_i); + } +} + +fn ppNum(p: *Parser) Error!Result { + defer p.tok_i += 1; + var res = try p.parseNumberToken(p.tok_i); + if (p.in_macro) { + if (res.ty.isFloat() or !res.ty.isReal()) { + try p.errTok(.float_literal_in_pp_expr, p.tok_i); + return error.ParsingFailed; + } + res.ty = if (res.ty.isUnsignedInt(p.comp)) p.comp.types.intmax.makeIntegerUnsigned() else p.comp.types.intmax; + } else if (res.val.opt_ref != .none) { + try p.value_map.put(res.node, res.val); + } + return res; +} + +/// Run a parser function but do not evaluate the result +fn parseNoEval(p: *Parser, comptime func: fn (*Parser) Error!Result) Error!Result { + const no_eval = p.no_eval; + defer p.no_eval = no_eval; + p.no_eval = true; + const parsed = try func(p); + try parsed.expect(p); + return parsed; +} + +/// genericSelection : keyword_generic '(' assignExpr ',' genericAssoc (',' genericAssoc)* ')' +/// genericAssoc +/// : typeName ':' assignExpr +/// | keyword_default ':' assignExpr +fn genericSelection(p: *Parser) Error!Result { + const kw_generic = p.tok_i; + p.tok_i += 1; + const l_paren = try p.expectToken(.l_paren); + const controlling_tok = p.tok_i; + const controlling = try p.parseNoEval(assignExpr); + _ = try p.expectToken(.comma); + var controlling_ty = controlling.ty; + if (controlling_ty.isArray()) controlling_ty.decayArray(); + + const list_buf_top = p.list_buf.items.len; + defer p.list_buf.items.len = list_buf_top; + try p.list_buf.append(controlling.node); + + // Use decl_buf to store the token indexes of previous cases + const decl_buf_top = p.decl_buf.items.len; + defer p.decl_buf.items.len = decl_buf_top; + + var default_tok: ?TokenIndex = null; + var default: Result = undefined; + var chosen_tok: TokenIndex = undefined; + var chosen: Result = .{}; + while (true) { + const start = p.tok_i; + if (try p.typeName()) |ty| blk: { + if (ty.isArray()) { + try p.errTok(.generic_array_type, start); + } else if (ty.isFunc()) { + try p.errTok(.generic_func_type, start); + } else if (ty.anyQual()) { + try p.errTok(.generic_qual_type, start); + } + _ = try p.expectToken(.colon); + const node = try p.assignExpr(); + try node.expect(p); + + if (ty.eql(controlling_ty, p.comp, false)) { + if (chosen.node == .none) { + chosen = node; + chosen_tok = start; + break :blk; + } + try p.errStr(.generic_duplicate, start, try p.typeStr(ty)); + try p.errStr(.generic_duplicate_here, chosen_tok, try p.typeStr(ty)); + } + const list_buf = p.list_buf.items[list_buf_top + 1 ..]; + const decl_buf = p.decl_buf.items[decl_buf_top..]; + if (list_buf.len == decl_buf.len) { + // If these do not have the same length, there is already an error + for (list_buf, decl_buf) |item, prev_tok| { + const prev_ty = p.nodes.items(.ty)[@intFromEnum(item)]; + if (prev_ty.eql(ty, p.comp, true)) { + try p.errStr(.generic_duplicate, start, try p.typeStr(ty)); + try p.errStr(.generic_duplicate_here, @intFromEnum(prev_tok), try p.typeStr(ty)); + } + } + } + try p.list_buf.append(try p.addNode(.{ + .tag = .generic_association_expr, + .ty = ty, + .data = .{ .un = node.node }, + .loc = @enumFromInt(start), + })); + try p.decl_buf.append(@enumFromInt(start)); + } else if (p.eatToken(.keyword_default)) |tok| { + if (default_tok) |prev| { + try p.errTok(.generic_duplicate_default, tok); + try p.errTok(.previous_case, prev); + } + default_tok = tok; + _ = try p.expectToken(.colon); + default = try p.assignExpr(); + try default.expect(p); + } else { + if (p.list_buf.items.len == list_buf_top + 1) { + try p.err(.expected_type); + return error.ParsingFailed; + } + break; + } + if (p.eatToken(.comma) == null) break; + } + try p.expectClosing(l_paren, .r_paren); + + if (chosen.node == .none) { + if (default_tok) |tok| { + try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{ + .tag = .generic_default_expr, + .data = .{ .un = default.node }, + .ty = default.ty, + .loc = @enumFromInt(tok), + })); + chosen = default; + } else { + try p.errStr(.generic_no_match, controlling_tok, try p.typeStr(controlling_ty)); + return error.ParsingFailed; + } + } else { + try p.list_buf.insert(list_buf_top + 1, try p.addNode(.{ + .tag = .generic_association_expr, + .data = .{ .un = chosen.node }, + .ty = chosen.ty, + .loc = @enumFromInt(chosen_tok), + })); + if (default_tok) |tok| { + try p.list_buf.append(try p.addNode(.{ + .tag = .generic_default_expr, + .data = .{ .un = default.node }, + .ty = default.ty, + .loc = @enumFromInt(tok), + })); + } + } + + var generic_node: Tree.Node = .{ + .tag = .generic_expr_one, + .ty = chosen.ty, + .data = .{ .two = .{ controlling.node, chosen.node } }, + .loc = @enumFromInt(kw_generic), + }; + const associations = p.list_buf.items[list_buf_top..]; + if (associations.len > 2) { // associations[0] == controlling.node + generic_node.tag = .generic_expr; + generic_node.data = .{ .range = try p.addList(associations) }; + } + chosen.node = try p.addNode(generic_node); + return chosen; +} + +test "Node locations" { + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + + const file = try comp.addSourceFromBuffer("file.c", + \\int foo = 5; + \\int bar = 10; + \\int main(void) {} + \\ + ); + + const builtin_macros = try comp.generateBuiltinMacros(.no_system_defines); + + var pp = Preprocessor.init(&comp); + defer pp.deinit(); + try pp.addBuiltinMacros(); + + _ = try pp.preprocess(builtin_macros); + + const eof = try pp.preprocess(file); + try pp.addToken(eof); + + var tree = try Parser.parse(&pp); + defer tree.deinit(); + + try std.testing.expectEqual(0, comp.diagnostics.list.items.len); + for (tree.root_decls, 0..) |node, i| { + const tok_i = tree.nodeTok(node).?; + const slice = tree.tokSlice(tok_i); + const expected = switch (i) { + 0 => "foo", + 1 => "bar", + 2 => "main", + else => unreachable, + }; + try std.testing.expectEqualStrings(expected, slice); + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Pragma.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Pragma.zig new file mode 100644 index 00000000..279ac5f0 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Pragma.zig @@ -0,0 +1,83 @@ +const std = @import("std"); +const Compilation = @import("Compilation.zig"); +const Preprocessor = @import("Preprocessor.zig"); +const Parser = @import("Parser.zig"); +const TokenIndex = @import("Tree.zig").TokenIndex; + +pub const Error = Compilation.Error || error{ UnknownPragma, StopPreprocessing }; + +const Pragma = @This(); + +/// Called during Preprocessor.init +beforePreprocess: ?*const fn (*Pragma, *Compilation) void = null, + +/// Called at the beginning of Parser.parse +beforeParse: ?*const fn (*Pragma, *Compilation) void = null, + +/// Called at the end of Parser.parse if a Tree was successfully parsed +afterParse: ?*const fn (*Pragma, *Compilation) void = null, + +/// Called during Compilation.deinit +deinit: *const fn (*Pragma, *Compilation) void, + +/// Called whenever the preprocessor encounters this pragma. `start_idx` is the index +/// within `pp.tokens` of the pragma name token. The pragma end is indicated by a +/// .nl token (which may be generated if the source ends with a pragma with no newline) +/// As an example, given the following line: +/// #pragma GCC diagnostic error "-Wnewline-eof" \n +/// Then pp.tokens.get(start_idx) will return the `GCC` token. +/// Return error.UnknownPragma to emit an `unknown_pragma` diagnostic +/// Return error.StopPreprocessing to stop preprocessing the current file (see once.zig) +preprocessorHandler: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) Error!void = null, + +/// Called during token pretty-printing (`-E` option). If this returns true, the pragma will +/// be printed; otherwise it will be omitted. start_idx is the index of the pragma name token +preserveTokens: ?*const fn (*Pragma, *Preprocessor, start_idx: TokenIndex) bool = null, + +/// Same as preprocessorHandler except called during parsing +/// The parser's `p.tok_i` field must not be changed +parserHandler: ?*const fn (*Pragma, *Parser, start_idx: TokenIndex) Compilation.Error!void = null, + +pub fn pasteTokens(pp: *Preprocessor, start_idx: TokenIndex) ![]const u8 { + if (pp.tokens.get(start_idx).id == .nl) return error.ExpectedStringLiteral; + + const char_top = pp.char_buf.items.len; + defer pp.char_buf.items.len = char_top; + var i: usize = 0; + var lparen_count: u32 = 0; + var rparen_count: u32 = 0; + while (true) : (i += 1) { + const tok = pp.tokens.get(start_idx + i); + if (tok.id == .nl) break; + switch (tok.id) { + .l_paren => { + if (lparen_count != i) return error.ExpectedStringLiteral; + lparen_count += 1; + }, + .r_paren => rparen_count += 1, + .string_literal => { + if (rparen_count != 0) return error.ExpectedStringLiteral; + const str = pp.expandedSlice(tok); + try pp.char_buf.appendSlice(str[1 .. str.len - 1]); + }, + else => return error.ExpectedStringLiteral, + } + } + if (lparen_count != rparen_count) return error.ExpectedStringLiteral; + return pp.char_buf.items[char_top..]; +} + +pub fn shouldPreserveTokens(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool { + if (self.preserveTokens) |func| return func(self, pp, start_idx); + return false; +} + +pub fn preprocessorCB(self: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Error!void { + if (self.preprocessorHandler) |func| return func(self, pp, start_idx); +} + +pub fn parserCB(self: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void { + const tok_index = p.tok_i; + defer std.debug.assert(tok_index == p.tok_i); + if (self.parserHandler) |func| return func(self, p, start_idx); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Preprocessor.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Preprocessor.zig new file mode 100644 index 00000000..9f10153d --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Preprocessor.zig @@ -0,0 +1,3649 @@ +const std = @import("std"); +const mem = std.mem; +const Allocator = mem.Allocator; +const assert = std.debug.assert; +const Compilation = @import("Compilation.zig"); +const Error = Compilation.Error; +const Source = @import("Source.zig"); +const Tokenizer = @import("Tokenizer.zig"); +const RawToken = Tokenizer.Token; +const Parser = @import("Parser.zig"); +const Diagnostics = @import("Diagnostics.zig"); +const Tree = @import("Tree.zig"); +const Token = Tree.Token; +const TokenWithExpansionLocs = Tree.TokenWithExpansionLocs; +const Attribute = @import("Attribute.zig"); +const features = @import("features.zig"); +const Hideset = @import("Hideset.zig"); + +const DefineMap = std.StringHashMapUnmanaged(Macro); +const RawTokenList = std.ArrayList(RawToken); +const max_include_depth = 200; + +/// Errors that can be returned when expanding a macro. +/// error.UnknownPragma can occur within Preprocessor.pragma() but +/// it is handled there and doesn't escape that function +const MacroError = Error || error{StopPreprocessing}; + +const Macro = struct { + /// Parameters of the function type macro + params: []const []const u8, + + /// Token constituting the macro body + tokens: []const RawToken, + + /// If the function type macro has variable number of arguments + var_args: bool, + + /// Is a function type macro + is_func: bool, + + /// Is a predefined macro + is_builtin: bool = false, + + /// Location of macro in the source + loc: Source.Location, + + fn eql(a: Macro, b: Macro, pp: *Preprocessor) bool { + if (a.tokens.len != b.tokens.len) return false; + if (a.is_builtin != b.is_builtin) return false; + for (a.tokens, b.tokens) |a_tok, b_tok| if (!tokEql(pp, a_tok, b_tok)) return false; + + if (a.is_func and b.is_func) { + if (a.var_args != b.var_args) return false; + if (a.params.len != b.params.len) return false; + for (a.params, b.params) |a_param, b_param| if (!mem.eql(u8, a_param, b_param)) return false; + } + + return true; + } + + fn tokEql(pp: *Preprocessor, a: RawToken, b: RawToken) bool { + return mem.eql(u8, pp.tokSlice(a), pp.tokSlice(b)); + } +}; + +const Preprocessor = @This(); + +const ExpansionEntry = struct { + idx: Tree.TokenIndex, + locs: [*]Source.Location, +}; + +const TokenState = struct { + tokens_len: usize, + expansion_entries_len: usize, +}; + +comp: *Compilation, +gpa: mem.Allocator, +arena: std.heap.ArenaAllocator, +defines: DefineMap = .{}, +/// Do not directly mutate this; use addToken / addTokenAssumeCapacity / ensureTotalTokenCapacity / ensureUnusedTokenCapacity +tokens: Token.List = .{}, +/// Do not directly mutate this; must be kept in sync with `tokens` +expansion_entries: std.MultiArrayList(ExpansionEntry) = .{}, +token_buf: RawTokenList, +char_buf: std.ArrayList(u8), +/// Counter that is incremented each time preprocess() is called +/// Can be used to distinguish multiple preprocessings of the same file +preprocess_count: u32 = 0, +generated_line: u32 = 1, +add_expansion_nl: u32 = 0, +include_depth: u8 = 0, +counter: u32 = 0, +expansion_source_loc: Source.Location = undefined, +poisoned_identifiers: std.StringHashMap(void), +/// Map from Source.Id to macro name in the `#ifndef` condition which guards the source, if any +include_guards: std.AutoHashMapUnmanaged(Source.Id, []const u8) = .empty, + +/// Store `keyword_define` and `keyword_undef` tokens. +/// Used to implement preprocessor debug dump options +/// Must be false unless in -E mode (parser does not handle those token types) +store_macro_tokens: bool = false, + +/// Memory is retained to avoid allocation on every single token. +top_expansion_buf: ExpandBuf, + +/// Dump current state to stderr. +verbose: bool = false, +preserve_whitespace: bool = false, + +/// linemarker tokens. Must be .none unless in -E mode (parser does not handle linemarkers) +linemarkers: Linemarkers = .none, + +hideset: Hideset, + +pub const parse = Parser.parse; + +pub const Linemarkers = enum { + /// No linemarker tokens. Required setting if parser will run + none, + /// #line "filename" + line_directives, + /// # "filename" flags + numeric_directives, +}; + +pub fn init(comp: *Compilation) Preprocessor { + const pp = Preprocessor{ + .comp = comp, + .gpa = comp.gpa, + .arena = std.heap.ArenaAllocator.init(comp.gpa), + .token_buf = RawTokenList.init(comp.gpa), + .char_buf = std.ArrayList(u8).init(comp.gpa), + .poisoned_identifiers = std.StringHashMap(void).init(comp.gpa), + .top_expansion_buf = ExpandBuf.init(comp.gpa), + .hideset = .{ .comp = comp }, + }; + comp.pragmaEvent(.before_preprocess); + return pp; +} + +/// Initialize Preprocessor with builtin macros. +pub fn initDefault(comp: *Compilation) !Preprocessor { + var pp = init(comp); + errdefer pp.deinit(); + try pp.addBuiltinMacros(); + return pp; +} + +const builtin_macros = struct { + const args = [1][]const u8{"X"}; + + const has_attribute = [1]RawToken{.{ + .id = .macro_param_has_attribute, + .source = .generated, + }}; + const has_c_attribute = [1]RawToken{.{ + .id = .macro_param_has_c_attribute, + .source = .generated, + }}; + const has_declspec_attribute = [1]RawToken{.{ + .id = .macro_param_has_declspec_attribute, + .source = .generated, + }}; + const has_warning = [1]RawToken{.{ + .id = .macro_param_has_warning, + .source = .generated, + }}; + const has_feature = [1]RawToken{.{ + .id = .macro_param_has_feature, + .source = .generated, + }}; + const has_extension = [1]RawToken{.{ + .id = .macro_param_has_extension, + .source = .generated, + }}; + const has_builtin = [1]RawToken{.{ + .id = .macro_param_has_builtin, + .source = .generated, + }}; + const has_include = [1]RawToken{.{ + .id = .macro_param_has_include, + .source = .generated, + }}; + const has_include_next = [1]RawToken{.{ + .id = .macro_param_has_include_next, + .source = .generated, + }}; + const has_embed = [1]RawToken{.{ + .id = .macro_param_has_embed, + .source = .generated, + }}; + + const is_identifier = [1]RawToken{.{ + .id = .macro_param_is_identifier, + .source = .generated, + }}; + + const pragma_operator = [1]RawToken{.{ + .id = .macro_param_pragma_operator, + .source = .generated, + }}; + + const file = [1]RawToken{.{ + .id = .macro_file, + .source = .generated, + }}; + const line = [1]RawToken{.{ + .id = .macro_line, + .source = .generated, + }}; + const counter = [1]RawToken{.{ + .id = .macro_counter, + .source = .generated, + }}; +}; + +fn addBuiltinMacro(pp: *Preprocessor, name: []const u8, is_func: bool, tokens: []const RawToken) !void { + try pp.defines.putNoClobber(pp.gpa, name, .{ + .params = &builtin_macros.args, + .tokens = tokens, + .var_args = false, + .is_func = is_func, + .loc = .{ .id = .generated }, + .is_builtin = true, + }); +} + +pub fn addBuiltinMacros(pp: *Preprocessor) !void { + try pp.addBuiltinMacro("__has_attribute", true, &builtin_macros.has_attribute); + try pp.addBuiltinMacro("__has_c_attribute", true, &builtin_macros.has_c_attribute); + try pp.addBuiltinMacro("__has_declspec_attribute", true, &builtin_macros.has_declspec_attribute); + try pp.addBuiltinMacro("__has_warning", true, &builtin_macros.has_warning); + try pp.addBuiltinMacro("__has_feature", true, &builtin_macros.has_feature); + try pp.addBuiltinMacro("__has_extension", true, &builtin_macros.has_extension); + try pp.addBuiltinMacro("__has_builtin", true, &builtin_macros.has_builtin); + try pp.addBuiltinMacro("__has_include", true, &builtin_macros.has_include); + try pp.addBuiltinMacro("__has_include_next", true, &builtin_macros.has_include_next); + try pp.addBuiltinMacro("__has_embed", true, &builtin_macros.has_embed); + try pp.addBuiltinMacro("__is_identifier", true, &builtin_macros.is_identifier); + try pp.addBuiltinMacro("_Pragma", true, &builtin_macros.pragma_operator); + + try pp.addBuiltinMacro("__FILE__", false, &builtin_macros.file); + try pp.addBuiltinMacro("__LINE__", false, &builtin_macros.line); + try pp.addBuiltinMacro("__COUNTER__", false, &builtin_macros.counter); +} + +pub fn deinit(pp: *Preprocessor) void { + pp.defines.deinit(pp.gpa); + pp.tokens.deinit(pp.gpa); + pp.arena.deinit(); + pp.token_buf.deinit(); + pp.char_buf.deinit(); + pp.poisoned_identifiers.deinit(); + pp.include_guards.deinit(pp.gpa); + pp.top_expansion_buf.deinit(); + pp.hideset.deinit(); + for (pp.expansion_entries.items(.locs)) |locs| TokenWithExpansionLocs.free(locs, pp.gpa); + pp.expansion_entries.deinit(pp.gpa); +} + +/// Free buffers that are not needed after preprocessing +fn clearBuffers(pp: *Preprocessor) void { + pp.token_buf.clearAndFree(); + pp.char_buf.clearAndFree(); + pp.top_expansion_buf.clearAndFree(); + pp.hideset.clearAndFree(); +} + +pub fn expansionSlice(pp: *Preprocessor, tok: Tree.TokenIndex) []Source.Location { + const S = struct { + fn orderTokenIndex(context: Tree.TokenIndex, item: Tree.TokenIndex) std.math.Order { + return std.math.order(context, item); + } + }; + + const indices = pp.expansion_entries.items(.idx); + const idx = std.sort.binarySearch(Tree.TokenIndex, indices, tok, S.orderTokenIndex) orelse return &.{}; + const locs = pp.expansion_entries.items(.locs)[idx]; + var i: usize = 0; + while (locs[i].id != .unused) : (i += 1) {} + return locs[0..i]; +} + +/// Preprocess a compilation unit of sources into a parsable list of tokens. +pub fn preprocessSources(pp: *Preprocessor, sources: []const Source) Error!void { + assert(sources.len > 1); + const first = sources[0]; + try pp.addIncludeStart(first); + for (sources[1..]) |header| { + try pp.addIncludeStart(header); + _ = try pp.preprocess(header); + } + try pp.addIncludeResume(first.id, 0, 1); + const eof = try pp.preprocess(first); + try pp.addToken(eof); + pp.clearBuffers(); +} + +/// Preprocess a source file, returns eof token. +pub fn preprocess(pp: *Preprocessor, source: Source) Error!TokenWithExpansionLocs { + const eof = pp.preprocessExtra(source) catch |er| switch (er) { + // This cannot occur in the main file and is handled in `include`. + error.StopPreprocessing => unreachable, + else => |e| return e, + }; + try eof.checkMsEof(source, pp.comp); + return eof; +} + +/// Tokenize a file without any preprocessing, returns eof token. +pub fn tokenize(pp: *Preprocessor, source: Source) Error!Token { + assert(pp.linemarkers == .none); + assert(pp.preserve_whitespace == false); + var tokenizer = Tokenizer{ + .buf = source.buf, + .comp = pp.comp, + .source = source.id, + }; + + // Estimate how many new tokens this source will contain. + const estimated_token_count = source.buf.len / 8; + try pp.ensureTotalTokenCapacity(pp.tokens.len + estimated_token_count); + + while (true) { + const tok = tokenizer.next(); + if (tok.id == .eof) return tokFromRaw(tok); + try pp.addToken(tokFromRaw(tok)); + } +} + +pub fn addIncludeStart(pp: *Preprocessor, source: Source) !void { + if (pp.linemarkers == .none) return; + try pp.addToken(.{ .id = .include_start, .loc = .{ + .id = source.id, + .byte_offset = std.math.maxInt(u32), + .line = 1, + } }); +} + +pub fn addIncludeResume(pp: *Preprocessor, source: Source.Id, offset: u32, line: u32) !void { + if (pp.linemarkers == .none) return; + try pp.addToken(.{ .id = .include_resume, .loc = .{ + .id = source, + .byte_offset = offset, + .line = line, + } }); +} + +fn invalidTokenDiagnostic(tok_id: Token.Id) Diagnostics.Tag { + return switch (tok_id) { + .unterminated_string_literal => .unterminated_string_literal_warning, + .empty_char_literal => .empty_char_literal_warning, + .unterminated_char_literal => .unterminated_char_literal_warning, + else => unreachable, + }; +} + +/// Return the name of the #ifndef guard macro that starts a source, if any. +fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 { + var tokenizer = Tokenizer{ + .buf = source.buf, + .langopts = pp.comp.langopts, + .source = source.id, + }; + var hash = tokenizer.nextNoWS(); + while (hash.id == .nl) hash = tokenizer.nextNoWS(); + if (hash.id != .hash) return null; + const ifndef = tokenizer.nextNoWS(); + if (ifndef.id != .keyword_ifndef) return null; + const guard = tokenizer.nextNoWS(); + if (guard.id != .identifier) return null; + return pp.tokSlice(guard); +} + +fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!TokenWithExpansionLocs { + var guard_name = pp.findIncludeGuard(source); + + pp.preprocess_count += 1; + var tokenizer = Tokenizer{ + .buf = source.buf, + .langopts = pp.comp.langopts, + .source = source.id, + }; + + // Estimate how many new tokens this source will contain. + const estimated_token_count = source.buf.len / 8; + try pp.ensureTotalTokenCapacity(pp.tokens.len + estimated_token_count); + + var if_level: u8 = 0; + var if_kind: [64]u8 = .{0} ** 64; + const until_else = 0; + const until_endif = 1; + const until_endif_seen_else = 2; + + var start_of_line = true; + while (true) { + var tok = tokenizer.next(); + switch (tok.id) { + .hash => if (!start_of_line) try pp.addToken(tokFromRaw(tok)) else { + const directive = tokenizer.nextNoWS(); + switch (directive.id) { + .keyword_error, .keyword_warning => { + // #error tokens.. + pp.top_expansion_buf.items.len = 0; + const char_top = pp.char_buf.items.len; + defer pp.char_buf.items.len = char_top; + + while (true) { + tok = tokenizer.next(); + if (tok.id == .nl or tok.id == .eof) break; + if (tok.id == .whitespace) tok.id = .macro_ws; + try pp.top_expansion_buf.append(tokFromRaw(tok)); + } + try pp.stringify(pp.top_expansion_buf.items); + const slice = pp.char_buf.items[char_top + 1 .. pp.char_buf.items.len - 2]; + const duped = try pp.comp.diagnostics.arena.allocator().dupe(u8, slice); + + try pp.comp.addDiagnostic(.{ + .tag = if (directive.id == .keyword_error) .error_directive else .warning_directive, + .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line }, + .extra = .{ .str = duped }, + }, &.{}); + }, + .keyword_if => { + const sum, const overflowed = @addWithOverflow(if_level, 1); + if (overflowed != 0) + return pp.fatal(directive, "too many #if nestings", .{}); + if_level = sum; + + if (try pp.expr(&tokenizer)) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_endif); + if (pp.verbose) { + pp.verboseLog(directive, "entering then branch of #if", .{}); + } + } else { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + try pp.skip(&tokenizer, .until_else); + if (pp.verbose) { + pp.verboseLog(directive, "entering else branch of #if", .{}); + } + } + }, + .keyword_ifdef => { + const sum, const overflowed = @addWithOverflow(if_level, 1); + if (overflowed != 0) + return pp.fatal(directive, "too many #if nestings", .{}); + if_level = sum; + + const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue; + try pp.expectNl(&tokenizer); + if (pp.defines.get(macro_name) != null) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_endif); + if (pp.verbose) { + pp.verboseLog(directive, "entering then branch of #ifdef", .{}); + } + } else { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + try pp.skip(&tokenizer, .until_else); + if (pp.verbose) { + pp.verboseLog(directive, "entering else branch of #ifdef", .{}); + } + } + }, + .keyword_ifndef => { + const sum, const overflowed = @addWithOverflow(if_level, 1); + if (overflowed != 0) + return pp.fatal(directive, "too many #if nestings", .{}); + if_level = sum; + + const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue; + try pp.expectNl(&tokenizer); + if (pp.defines.get(macro_name) == null) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_endif); + } else { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + try pp.skip(&tokenizer, .until_else); + } + }, + .keyword_elif => { + if (if_level == 0) { + try pp.err(directive, .elif_without_if); + if_level += 1; + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + } else if (if_level == 1) { + guard_name = null; + } + switch (std.mem.readPackedIntNative(u2, &if_kind, if_level * 2)) { + until_else => if (try pp.expr(&tokenizer)) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_endif); + if (pp.verbose) { + pp.verboseLog(directive, "entering then branch of #elif", .{}); + } + } else { + try pp.skip(&tokenizer, .until_else); + if (pp.verbose) { + pp.verboseLog(directive, "entering else branch of #elif", .{}); + } + }, + until_endif => try pp.skip(&tokenizer, .until_endif), + until_endif_seen_else => { + try pp.err(directive, .elif_after_else); + skipToNl(&tokenizer); + }, + else => unreachable, + } + }, + .keyword_elifdef => { + if (if_level == 0) { + try pp.err(directive, .elifdef_without_if); + if_level += 1; + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + } else if (if_level == 1) { + guard_name = null; + } + switch (std.mem.readPackedIntNative(u2, &if_kind, if_level * 2)) { + until_else => { + const macro_name = try pp.expectMacroName(&tokenizer); + if (macro_name == null) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + try pp.skip(&tokenizer, .until_else); + if (pp.verbose) { + pp.verboseLog(directive, "entering else branch of #elifdef", .{}); + } + } else { + try pp.expectNl(&tokenizer); + if (pp.defines.get(macro_name.?) != null) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_endif); + if (pp.verbose) { + pp.verboseLog(directive, "entering then branch of #elifdef", .{}); + } + } else { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + try pp.skip(&tokenizer, .until_else); + if (pp.verbose) { + pp.verboseLog(directive, "entering else branch of #elifdef", .{}); + } + } + } + }, + until_endif => try pp.skip(&tokenizer, .until_endif), + until_endif_seen_else => { + try pp.err(directive, .elifdef_after_else); + skipToNl(&tokenizer); + }, + else => unreachable, + } + }, + .keyword_elifndef => { + if (if_level == 0) { + try pp.err(directive, .elifdef_without_if); + if_level += 1; + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + } else if (if_level == 1) { + guard_name = null; + } + switch (std.mem.readPackedIntNative(u2, &if_kind, if_level * 2)) { + until_else => { + const macro_name = try pp.expectMacroName(&tokenizer); + if (macro_name == null) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + try pp.skip(&tokenizer, .until_else); + if (pp.verbose) { + pp.verboseLog(directive, "entering else branch of #elifndef", .{}); + } + } else { + try pp.expectNl(&tokenizer); + if (pp.defines.get(macro_name.?) == null) { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_endif); + if (pp.verbose) { + pp.verboseLog(directive, "entering then branch of #elifndef", .{}); + } + } else { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_else); + try pp.skip(&tokenizer, .until_else); + if (pp.verbose) { + pp.verboseLog(directive, "entering else branch of #elifndef", .{}); + } + } + } + }, + until_endif => try pp.skip(&tokenizer, .until_endif), + until_endif_seen_else => { + try pp.err(directive, .elifdef_after_else); + skipToNl(&tokenizer); + }, + else => unreachable, + } + }, + .keyword_else => { + try pp.expectNl(&tokenizer); + if (if_level == 0) { + try pp.err(directive, .else_without_if); + continue; + } else if (if_level == 1) { + guard_name = null; + } + switch (std.mem.readPackedIntNative(u2, &if_kind, if_level * 2)) { + until_else => { + std.mem.writePackedIntNative(u2, &if_kind, if_level * 2, until_endif_seen_else); + if (pp.verbose) { + pp.verboseLog(directive, "#else branch here", .{}); + } + }, + until_endif => try pp.skip(&tokenizer, .until_endif_seen_else), + until_endif_seen_else => { + try pp.err(directive, .else_after_else); + skipToNl(&tokenizer); + }, + else => unreachable, + } + }, + .keyword_endif => { + try pp.expectNl(&tokenizer); + if (if_level == 0) { + guard_name = null; + try pp.err(directive, .endif_without_if); + continue; + } else if (if_level == 1) { + const saved_tokenizer = tokenizer; + defer tokenizer = saved_tokenizer; + + var next = tokenizer.nextNoWS(); + while (next.id == .nl) : (next = tokenizer.nextNoWS()) {} + if (next.id != .eof) guard_name = null; + } + if_level -= 1; + }, + .keyword_define => try pp.define(&tokenizer, directive), + .keyword_undef => { + const macro_name = (try pp.expectMacroName(&tokenizer)) orelse continue; + if (pp.store_macro_tokens) { + try pp.addToken(tokFromRaw(directive)); + } + + _ = pp.defines.remove(macro_name); + try pp.expectNl(&tokenizer); + }, + .keyword_include => { + try pp.include(&tokenizer, .first); + continue; + }, + .keyword_include_next => { + try pp.comp.addDiagnostic(.{ + .tag = .include_next, + .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line }, + }, &.{}); + if (pp.include_depth == 0) { + try pp.comp.addDiagnostic(.{ + .tag = .include_next_outside_header, + .loc = .{ .id = tok.source, .byte_offset = directive.start, .line = directive.line }, + }, &.{}); + try pp.include(&tokenizer, .first); + } else { + try pp.include(&tokenizer, .next); + } + }, + .keyword_embed => try pp.embed(&tokenizer), + .keyword_pragma => { + try pp.pragma(&tokenizer, directive, null, &.{}); + continue; + }, + .keyword_line => { + // #line number "file" + const digits = tokenizer.nextNoWS(); + if (digits.id != .pp_num) try pp.err(digits, .line_simple_digit); + // TODO: validate that the pp_num token is solely digits + + if (digits.id == .eof or digits.id == .nl) continue; + const name = tokenizer.nextNoWS(); + if (name.id == .eof or name.id == .nl) continue; + if (name.id != .string_literal) try pp.err(name, .line_invalid_filename); + try pp.expectNl(&tokenizer); + }, + .pp_num => { + // # number "file" flags + // TODO: validate that the pp_num token is solely digits + // if not, emit `GNU line marker directive requires a simple digit sequence` + const name = tokenizer.nextNoWS(); + if (name.id == .eof or name.id == .nl) continue; + if (name.id != .string_literal) try pp.err(name, .line_invalid_filename); + + const flag_1 = tokenizer.nextNoWS(); + if (flag_1.id == .eof or flag_1.id == .nl) continue; + const flag_2 = tokenizer.nextNoWS(); + if (flag_2.id == .eof or flag_2.id == .nl) continue; + const flag_3 = tokenizer.nextNoWS(); + if (flag_3.id == .eof or flag_3.id == .nl) continue; + const flag_4 = tokenizer.nextNoWS(); + if (flag_4.id == .eof or flag_4.id == .nl) continue; + try pp.expectNl(&tokenizer); + }, + .nl => {}, + .eof => { + if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive); + return tokFromRaw(directive); + }, + else => { + try pp.err(tok, .invalid_preprocessing_directive); + skipToNl(&tokenizer); + }, + } + if (pp.preserve_whitespace) { + tok.id = .nl; + try pp.addToken(tokFromRaw(tok)); + } + }, + .whitespace => if (pp.preserve_whitespace) try pp.addToken(tokFromRaw(tok)), + .nl => { + start_of_line = true; + if (pp.preserve_whitespace) try pp.addToken(tokFromRaw(tok)); + }, + .eof => { + if (if_level != 0) try pp.err(tok, .unterminated_conditional_directive); + // The following check needs to occur here and not at the top of the function + // because a pragma may change the level during preprocessing + if (source.buf.len > 0 and source.buf[source.buf.len - 1] != '\n') { + try pp.err(tok, .newline_eof); + } + if (guard_name) |name| { + if (try pp.include_guards.fetchPut(pp.gpa, source.id, name)) |prev| { + assert(mem.eql(u8, name, prev.value)); + } + } + return tokFromRaw(tok); + }, + .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| { + start_of_line = false; + try pp.err(tok, invalidTokenDiagnostic(tag)); + try pp.expandMacro(&tokenizer, tok); + }, + .unterminated_comment => try pp.err(tok, .unterminated_comment), + else => { + if (tok.id.isMacroIdentifier() and pp.poisoned_identifiers.get(pp.tokSlice(tok)) != null) { + try pp.err(tok, .poisoned_identifier); + } + // Add the token to the buffer doing any necessary expansions. + start_of_line = false; + try pp.expandMacro(&tokenizer, tok); + }, + } + } +} + +/// Get raw token source string. +/// Returned slice is invalidated when comp.generated_buf is updated. +pub fn tokSlice(pp: *Preprocessor, token: anytype) []const u8 { + if (token.id.lexeme()) |some| return some; + const source = pp.comp.getSource(token.source); + return source.buf[token.start..token.end]; +} + +/// Convert a token from the Tokenizer into a token used by the parser. +fn tokFromRaw(raw: RawToken) TokenWithExpansionLocs { + return .{ + .id = raw.id, + .loc = .{ + .id = raw.source, + .byte_offset = raw.start, + .line = raw.line, + }, + }; +} + +fn err(pp: *Preprocessor, raw: RawToken, tag: Diagnostics.Tag) !void { + try pp.comp.addDiagnostic(.{ + .tag = tag, + .loc = .{ + .id = raw.source, + .byte_offset = raw.start, + .line = raw.line, + }, + }, &.{}); +} + +fn errStr(pp: *Preprocessor, tok: TokenWithExpansionLocs, tag: Diagnostics.Tag, str: []const u8) !void { + try pp.comp.addDiagnostic(.{ + .tag = tag, + .loc = tok.loc, + .extra = .{ .str = str }, + }, tok.expansionSlice()); +} + +fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) Compilation.Error { + try pp.comp.diagnostics.list.append(pp.gpa, .{ + .tag = .cli_error, + .kind = .@"fatal error", + .extra = .{ .str = try std.fmt.allocPrint(pp.comp.diagnostics.arena.allocator(), fmt, args) }, + .loc = .{ + .id = raw.source, + .byte_offset = raw.start, + .line = raw.line, + }, + }); + return error.FatalError; +} + +fn fatalNotFound(pp: *Preprocessor, tok: TokenWithExpansionLocs, filename: []const u8) Compilation.Error { + const old = pp.comp.diagnostics.fatal_errors; + pp.comp.diagnostics.fatal_errors = true; + defer pp.comp.diagnostics.fatal_errors = old; + + try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ .tag = .cli_error, .loc = tok.loc, .extra = .{ + .str = try std.fmt.allocPrint(pp.comp.diagnostics.arena.allocator(), "'{s}' not found", .{filename}), + } }, tok.expansionSlice(), false); + unreachable; // addExtra should've returned FatalError +} + +fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void { + const source = pp.comp.getSource(raw.source); + const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start }); + + const stderr = std.io.getStdErr().writer(); + var buf_writer = std.io.bufferedWriter(stderr); + const writer = buf_writer.writer(); + defer buf_writer.flush() catch {}; + writer.print("{s}:{d}:{d}: ", .{ source.path, line_col.line_no, line_col.col }) catch return; + writer.print(fmt, args) catch return; + writer.writeByte('\n') catch return; + writer.writeAll(line_col.line) catch return; + writer.writeByte('\n') catch return; +} + +/// Consume next token, error if it is not an identifier. +fn expectMacroName(pp: *Preprocessor, tokenizer: *Tokenizer) Error!?[]const u8 { + const macro_name = tokenizer.nextNoWS(); + if (!macro_name.id.isMacroIdentifier()) { + try pp.err(macro_name, .macro_name_missing); + skipToNl(tokenizer); + return null; + } + return pp.tokSlice(macro_name); +} + +/// Skip until after a newline, error if extra tokens before it. +fn expectNl(pp: *Preprocessor, tokenizer: *Tokenizer) Error!void { + var sent_err = false; + while (true) { + const tok = tokenizer.next(); + if (tok.id == .nl or tok.id == .eof) return; + if (tok.id == .whitespace or tok.id == .comment) continue; + if (!sent_err) { + sent_err = true; + try pp.err(tok, .extra_tokens_directive_end); + } + } +} + +fn getTokenState(pp: *const Preprocessor) TokenState { + return .{ + .tokens_len = pp.tokens.len, + .expansion_entries_len = pp.expansion_entries.len, + }; +} + +fn restoreTokenState(pp: *Preprocessor, state: TokenState) void { + pp.tokens.len = state.tokens_len; + pp.expansion_entries.len = state.expansion_entries_len; +} + +/// Consume all tokens until a newline and parse the result into a boolean. +fn expr(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!bool { + const token_state = pp.getTokenState(); + defer { + for (pp.top_expansion_buf.items) |tok| TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + pp.restoreTokenState(token_state); + } + + pp.top_expansion_buf.items.len = 0; + const eof = while (true) { + const tok = tokenizer.next(); + switch (tok.id) { + .nl, .eof => break tok, + .whitespace => if (pp.top_expansion_buf.items.len == 0) continue, + else => {}, + } + try pp.top_expansion_buf.append(tokFromRaw(tok)); + } else unreachable; + if (pp.top_expansion_buf.items.len != 0) { + pp.expansion_source_loc = pp.top_expansion_buf.items[0].loc; + pp.hideset.clearRetainingCapacity(); + try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, pp.top_expansion_buf.items.len, false, .expr); + } + for (pp.top_expansion_buf.items) |tok| { + if (tok.id == .macro_ws) continue; + if (!tok.id.validPreprocessorExprStart()) { + try pp.comp.addDiagnostic(.{ + .tag = .invalid_preproc_expr_start, + .loc = tok.loc, + }, tok.expansionSlice()); + return false; + } + break; + } else { + try pp.err(eof, .expected_value_in_expr); + return false; + } + + // validate the tokens in the expression + try pp.ensureUnusedTokenCapacity(pp.top_expansion_buf.items.len); + var i: usize = 0; + const items = pp.top_expansion_buf.items; + while (i < items.len) : (i += 1) { + var tok = items[i]; + switch (tok.id) { + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + => { + try pp.comp.addDiagnostic(.{ + .tag = .string_literal_in_pp_expr, + .loc = tok.loc, + }, tok.expansionSlice()); + return false; + }, + .plus_plus, + .minus_minus, + .plus_equal, + .minus_equal, + .asterisk_equal, + .slash_equal, + .percent_equal, + .angle_bracket_angle_bracket_left_equal, + .angle_bracket_angle_bracket_right_equal, + .ampersand_equal, + .caret_equal, + .pipe_equal, + .l_bracket, + .r_bracket, + .l_brace, + .r_brace, + .ellipsis, + .semicolon, + .hash, + .hash_hash, + .equal, + .arrow, + .period, + => { + try pp.comp.addDiagnostic(.{ + .tag = .invalid_preproc_operator, + .loc = tok.loc, + }, tok.expansionSlice()); + return false; + }, + .macro_ws, .whitespace => continue, + .keyword_false => tok.id = .zero, + .keyword_true => tok.id = .one, + else => if (tok.id.isMacroIdentifier()) { + if (tok.id == .keyword_defined) { + const tokens_consumed = try pp.handleKeywordDefined(&tok, items[i + 1 ..], eof); + i += tokens_consumed; + } else { + try pp.errStr(tok, .undefined_macro, pp.expandedSlice(tok)); + + if (i + 1 < pp.top_expansion_buf.items.len and + pp.top_expansion_buf.items[i + 1].id == .l_paren) + { + try pp.errStr(tok, .fn_macro_undefined, pp.expandedSlice(tok)); + return false; + } + + tok.id = .zero; // undefined macro + } + }, + } + pp.addTokenAssumeCapacity(tok); + } + try pp.addToken(.{ + .id = .eof, + .loc = tokFromRaw(eof).loc, + }); + + // Actually parse it. + var parser = Parser{ + .pp = pp, + .comp = pp.comp, + .gpa = pp.gpa, + .tok_ids = pp.tokens.items(.id), + .tok_i = @intCast(token_state.tokens_len), + .arena = pp.arena.allocator(), + .in_macro = true, + .strings = std.ArrayListAligned(u8, 4).init(pp.comp.gpa), + + .data = undefined, + .value_map = undefined, + .labels = undefined, + .decl_buf = undefined, + .list_buf = undefined, + .param_buf = undefined, + .enum_buf = undefined, + .record_buf = undefined, + .attr_buf = undefined, + .field_attr_buf = undefined, + .string_ids = undefined, + }; + defer parser.strings.deinit(); + return parser.macroExpr(); +} + +/// Turns macro_tok from .keyword_defined into .zero or .one depending on whether the argument is defined +/// Returns the number of tokens consumed +fn handleKeywordDefined(pp: *Preprocessor, macro_tok: *TokenWithExpansionLocs, tokens: []const TokenWithExpansionLocs, eof: RawToken) !usize { + std.debug.assert(macro_tok.id == .keyword_defined); + var it = TokenIterator.init(tokens); + const first = it.nextNoWS() orelse { + try pp.err(eof, .macro_name_missing); + return it.i; + }; + switch (first.id) { + .l_paren => {}, + else => { + if (!first.id.isMacroIdentifier()) { + try pp.errStr(first, .macro_name_must_be_identifier, pp.expandedSlice(first)); + } + macro_tok.id = if (pp.defines.contains(pp.expandedSlice(first))) .one else .zero; + return it.i; + }, + } + const second = it.nextNoWS() orelse { + try pp.err(eof, .macro_name_missing); + return it.i; + }; + if (!second.id.isMacroIdentifier()) { + try pp.comp.addDiagnostic(.{ + .tag = .macro_name_must_be_identifier, + .loc = second.loc, + }, second.expansionSlice()); + return it.i; + } + macro_tok.id = if (pp.defines.contains(pp.expandedSlice(second))) .one else .zero; + + const last = it.nextNoWS(); + if (last == null or last.?.id != .r_paren) { + const tok = last orelse tokFromRaw(eof); + try pp.comp.addDiagnostic(.{ + .tag = .closing_paren, + .loc = tok.loc, + }, tok.expansionSlice()); + try pp.comp.addDiagnostic(.{ + .tag = .to_match_paren, + .loc = first.loc, + }, first.expansionSlice()); + } + + return it.i; +} + +/// Skip until #else #elif #endif, return last directive token id. +/// Also skips nested #if ... #endifs. +fn skip( + pp: *Preprocessor, + tokenizer: *Tokenizer, + cont: enum { until_else, until_endif, until_endif_seen_else }, +) Error!void { + var ifs_seen: u32 = 0; + var line_start = true; + while (tokenizer.index < tokenizer.buf.len) { + if (line_start) { + const saved_tokenizer = tokenizer.*; + const hash = tokenizer.nextNoWS(); + if (hash.id == .nl) continue; + line_start = false; + if (hash.id != .hash) continue; + const directive = tokenizer.nextNoWS(); + switch (directive.id) { + .keyword_else => { + if (ifs_seen != 0) continue; + if (cont == .until_endif_seen_else) { + try pp.err(directive, .else_after_else); + continue; + } + tokenizer.* = saved_tokenizer; + return; + }, + .keyword_elif => { + if (ifs_seen != 0 or cont == .until_endif) continue; + if (cont == .until_endif_seen_else) { + try pp.err(directive, .elif_after_else); + continue; + } + tokenizer.* = saved_tokenizer; + return; + }, + .keyword_elifdef => { + if (ifs_seen != 0 or cont == .until_endif) continue; + if (cont == .until_endif_seen_else) { + try pp.err(directive, .elifdef_after_else); + continue; + } + tokenizer.* = saved_tokenizer; + return; + }, + .keyword_elifndef => { + if (ifs_seen != 0 or cont == .until_endif) continue; + if (cont == .until_endif_seen_else) { + try pp.err(directive, .elifndef_after_else); + continue; + } + tokenizer.* = saved_tokenizer; + return; + }, + .keyword_endif => { + if (ifs_seen == 0) { + tokenizer.* = saved_tokenizer; + return; + } + ifs_seen -= 1; + }, + .keyword_if, .keyword_ifdef, .keyword_ifndef => ifs_seen += 1, + else => {}, + } + } else if (tokenizer.buf[tokenizer.index] == '\n') { + line_start = true; + tokenizer.index += 1; + tokenizer.line += 1; + if (pp.preserve_whitespace) { + try pp.addToken(.{ .id = .nl, .loc = .{ + .id = tokenizer.source, + .line = tokenizer.line, + } }); + } + } else { + line_start = false; + tokenizer.index += 1; + } + } else { + const eof = tokenizer.next(); + return pp.err(eof, .unterminated_conditional_directive); + } +} + +// Skip until newline, ignore other tokens. +fn skipToNl(tokenizer: *Tokenizer) void { + while (true) { + const tok = tokenizer.next(); + if (tok.id == .nl or tok.id == .eof) return; + } +} + +const ExpandBuf = std.ArrayList(TokenWithExpansionLocs); +fn removePlacemarkers(buf: *ExpandBuf) void { + var i: usize = buf.items.len -% 1; + while (i < buf.items.len) : (i -%= 1) { + if (buf.items[i].id == .placemarker) { + const placemarker = buf.orderedRemove(i); + TokenWithExpansionLocs.free(placemarker.expansion_locs, buf.allocator); + } + } +} + +const MacroArguments = std.ArrayList([]const TokenWithExpansionLocs); +fn deinitMacroArguments(allocator: Allocator, args: *const MacroArguments) void { + for (args.items) |item| { + for (item) |tok| TokenWithExpansionLocs.free(tok.expansion_locs, allocator); + allocator.free(item); + } + args.deinit(); +} + +fn expandObjMacro(pp: *Preprocessor, simple_macro: *const Macro) Error!ExpandBuf { + var buf = ExpandBuf.init(pp.gpa); + errdefer buf.deinit(); + if (simple_macro.tokens.len == 0) { + try buf.append(.{ .id = .placemarker, .loc = .{ .id = .generated } }); + return buf; + } + try buf.ensureTotalCapacity(simple_macro.tokens.len); + + // Add all of the simple_macros tokens to the new buffer handling any concats. + var i: usize = 0; + while (i < simple_macro.tokens.len) : (i += 1) { + const raw = simple_macro.tokens[i]; + const tok = tokFromRaw(raw); + switch (raw.id) { + .hash_hash => { + var rhs = tokFromRaw(simple_macro.tokens[i + 1]); + i += 1; + while (true) { + if (rhs.id == .whitespace) { + rhs = tokFromRaw(simple_macro.tokens[i + 1]); + i += 1; + } else if (rhs.id == .comment and !pp.comp.langopts.preserve_comments_in_macros) { + rhs = tokFromRaw(simple_macro.tokens[i + 1]); + i += 1; + } else break; + } + try pp.pasteTokens(&buf, &.{rhs}); + }, + .whitespace => if (pp.preserve_whitespace) buf.appendAssumeCapacity(tok), + .macro_file => { + const start = pp.comp.generated_buf.items.len; + const source = pp.comp.getSource(pp.expansion_source_loc.id); + const w = pp.comp.generated_buf.writer(pp.gpa); + try w.print("\"{s}\"\n", .{source.path}); + + buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .string_literal, tok)); + }, + .macro_line => { + const start = pp.comp.generated_buf.items.len; + const source = pp.comp.getSource(pp.expansion_source_loc.id); + const w = pp.comp.generated_buf.writer(pp.gpa); + try w.print("{d}\n", .{source.physicalLine(pp.expansion_source_loc)}); + + buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok)); + }, + .macro_counter => { + defer pp.counter += 1; + const start = pp.comp.generated_buf.items.len; + const w = pp.comp.generated_buf.writer(pp.gpa); + try w.print("{d}\n", .{pp.counter}); + + buf.appendAssumeCapacity(try pp.makeGeneratedToken(start, .pp_num, tok)); + }, + else => buf.appendAssumeCapacity(tok), + } + } + + return buf; +} + +/// Join a possibly-parenthesized series of string literal tokens into a single string without +/// leading or trailing quotes. The returned slice is invalidated if pp.char_buf changes. +/// Returns error.ExpectedStringLiteral if parentheses are not balanced, a non-string-literal +/// is encountered, or if no string literals are encountered +/// TODO: destringize (replace all '\\' with a single `\` and all '\"' with a '"') +fn pasteStringsUnsafe(pp: *Preprocessor, toks: []const TokenWithExpansionLocs) ![]const u8 { + const char_top = pp.char_buf.items.len; + defer pp.char_buf.items.len = char_top; + var unwrapped = toks; + if (toks.len >= 2 and toks[0].id == .l_paren and toks[toks.len - 1].id == .r_paren) { + unwrapped = toks[1 .. toks.len - 1]; + } + if (unwrapped.len == 0) return error.ExpectedStringLiteral; + + for (unwrapped) |tok| { + if (tok.id == .macro_ws) continue; + if (tok.id != .string_literal) return error.ExpectedStringLiteral; + const str = pp.expandedSlice(tok); + try pp.char_buf.appendSlice(str[1 .. str.len - 1]); + } + return pp.char_buf.items[char_top..]; +} + +/// Handle the _Pragma operator (implemented as a builtin macro) +fn pragmaOperator(pp: *Preprocessor, arg_tok: TokenWithExpansionLocs, operator_loc: Source.Location) !void { + const arg_slice = pp.expandedSlice(arg_tok); + const content = arg_slice[1 .. arg_slice.len - 1]; + const directive = "#pragma "; + + pp.char_buf.clearRetainingCapacity(); + const total_len = directive.len + content.len + 1; // destringify can never grow the string, + 1 for newline + try pp.char_buf.ensureUnusedCapacity(total_len); + pp.char_buf.appendSliceAssumeCapacity(directive); + pp.destringify(content); + pp.char_buf.appendAssumeCapacity('\n'); + + const start = pp.comp.generated_buf.items.len; + try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items); + var tmp_tokenizer = Tokenizer{ + .buf = pp.comp.generated_buf.items, + .langopts = pp.comp.langopts, + .index = @intCast(start), + .source = .generated, + .line = pp.generated_line, + }; + pp.generated_line += 1; + const hash_tok = tmp_tokenizer.next(); + assert(hash_tok.id == .hash); + const pragma_tok = tmp_tokenizer.next(); + assert(pragma_tok.id == .keyword_pragma); + try pp.pragma(&tmp_tokenizer, pragma_tok, operator_loc, arg_tok.expansionSlice()); +} + +/// Inverts the output of the preprocessor stringify (#) operation +/// (except all whitespace is condensed to a single space) +/// writes output to pp.char_buf; assumes capacity is sufficient +/// backslash backslash -> backslash +/// backslash doublequote -> doublequote +/// All other characters remain the same +fn destringify(pp: *Preprocessor, str: []const u8) void { + var state: enum { start, backslash_seen } = .start; + for (str) |c| { + switch (c) { + '\\' => { + if (state == .backslash_seen) pp.char_buf.appendAssumeCapacity(c); + state = if (state == .start) .backslash_seen else .start; + }, + else => { + if (state == .backslash_seen and c != '"') pp.char_buf.appendAssumeCapacity('\\'); + pp.char_buf.appendAssumeCapacity(c); + state = .start; + }, + } + } +} + +/// Stringify `tokens` into pp.char_buf. +/// See https://gcc.gnu.org/onlinedocs/gcc-11.2.0/cpp/Stringizing.html#Stringizing +fn stringify(pp: *Preprocessor, tokens: []const TokenWithExpansionLocs) !void { + try pp.char_buf.append('"'); + var ws_state: enum { start, need, not_needed } = .start; + for (tokens) |tok| { + if (tok.id == .macro_ws) { + if (ws_state == .start) continue; + ws_state = .need; + continue; + } + if (ws_state == .need) try pp.char_buf.append(' '); + ws_state = .not_needed; + + // backslashes not inside strings are not escaped + const is_str = switch (tok.id) { + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + .char_literal, + .char_literal_utf_16, + .char_literal_utf_32, + .char_literal_wide, + => true, + else => false, + }; + + for (pp.expandedSlice(tok)) |c| { + if (c == '"') + try pp.char_buf.appendSlice("\\\"") + else if (c == '\\' and is_str) + try pp.char_buf.appendSlice("\\\\") + else + try pp.char_buf.append(c); + } + } + try pp.char_buf.ensureUnusedCapacity(2); + if (pp.char_buf.items[pp.char_buf.items.len - 1] != '\\') { + pp.char_buf.appendSliceAssumeCapacity("\"\n"); + return; + } + pp.char_buf.appendAssumeCapacity('"'); + var tokenizer: Tokenizer = .{ + .buf = pp.char_buf.items, + .index = 0, + .source = .generated, + .langopts = pp.comp.langopts, + .line = 0, + }; + const item = tokenizer.next(); + if (item.id == .unterminated_string_literal) { + const tok = tokens[tokens.len - 1]; + try pp.comp.addDiagnostic(.{ + .tag = .invalid_pp_stringify_escape, + .loc = tok.loc, + }, tok.expansionSlice()); + pp.char_buf.items.len -= 2; // erase unpaired backslash and appended end quote + pp.char_buf.appendAssumeCapacity('"'); + } + pp.char_buf.appendAssumeCapacity('\n'); +} + +fn reconstructIncludeString(pp: *Preprocessor, param_toks: []const TokenWithExpansionLocs, embed_args: ?*[]const TokenWithExpansionLocs, first: TokenWithExpansionLocs) !?[]const u8 { + if (param_toks.len == 0) { + try pp.comp.addDiagnostic(.{ + .tag = .expected_filename, + .loc = first.loc, + }, first.expansionSlice()); + return null; + } + + const char_top = pp.char_buf.items.len; + defer pp.char_buf.items.len = char_top; + + // Trim leading/trailing whitespace + var begin: usize = 0; + var end: usize = param_toks.len; + while (begin < end and param_toks[begin].id == .macro_ws) : (begin += 1) {} + while (end > begin and param_toks[end - 1].id == .macro_ws) : (end -= 1) {} + const params = param_toks[begin..end]; + + if (params.len == 0) { + try pp.comp.addDiagnostic(.{ + .tag = .expected_filename, + .loc = first.loc, + }, first.expansionSlice()); + return null; + } + // no string pasting + if (embed_args == null and params[0].id == .string_literal and params.len > 1) { + try pp.comp.addDiagnostic(.{ + .tag = .closing_paren, + .loc = params[1].loc, + }, params[1].expansionSlice()); + return null; + } + + for (params, 0..) |tok, i| { + const str = pp.expandedSliceExtra(tok, .preserve_macro_ws); + try pp.char_buf.appendSlice(str); + if (embed_args) |some| { + if ((i == 0 and tok.id == .string_literal) or tok.id == .angle_bracket_right) { + some.* = params[i + 1 ..]; + break; + } + } + } + + const include_str = pp.char_buf.items[char_top..]; + if (include_str.len < 3) { + if (include_str.len == 0) { + try pp.comp.addDiagnostic(.{ + .tag = .expected_filename, + .loc = first.loc, + }, first.expansionSlice()); + return null; + } + try pp.comp.addDiagnostic(.{ + .tag = .empty_filename, + .loc = params[0].loc, + }, params[0].expansionSlice()); + return null; + } + + switch (include_str[0]) { + '<' => { + if (include_str[include_str.len - 1] != '>') { + // Ugly hack to find out where the '>' should go, since we don't have the closing ')' location + const start = params[0].loc; + try pp.comp.addDiagnostic(.{ + .tag = .header_str_closing, + .loc = .{ .id = start.id, .byte_offset = start.byte_offset + @as(u32, @intCast(include_str.len)) + 1, .line = start.line }, + }, params[0].expansionSlice()); + try pp.comp.addDiagnostic(.{ + .tag = .header_str_match, + .loc = params[0].loc, + }, params[0].expansionSlice()); + return null; + } + return include_str; + }, + '"' => return include_str, + else => { + try pp.comp.addDiagnostic(.{ + .tag = .expected_filename, + .loc = params[0].loc, + }, params[0].expansionSlice()); + return null; + }, + } +} + +fn handleBuiltinMacro(pp: *Preprocessor, builtin: RawToken.Id, param_toks: []const TokenWithExpansionLocs, src_loc: Source.Location) Error!bool { + switch (builtin) { + .macro_param_has_attribute, + .macro_param_has_declspec_attribute, + .macro_param_has_feature, + .macro_param_has_extension, + .macro_param_has_builtin, + => { + var invalid: ?TokenWithExpansionLocs = null; + var identifier: ?TokenWithExpansionLocs = null; + for (param_toks) |tok| { + if (tok.id == .macro_ws) continue; + if (tok.id == .comment) continue; + if (!tok.id.isMacroIdentifier()) { + invalid = tok; + break; + } + if (identifier) |_| invalid = tok else identifier = tok; + } + if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc }; + if (invalid) |some| { + try pp.comp.addDiagnostic( + .{ .tag = .feature_check_requires_identifier, .loc = some.loc }, + some.expansionSlice(), + ); + return false; + } + + const ident_str = pp.expandedSlice(identifier.?); + return switch (builtin) { + .macro_param_has_attribute => Attribute.fromString(.gnu, null, ident_str) != null, + .macro_param_has_declspec_attribute => { + return if (pp.comp.langopts.declspec_attrs) + Attribute.fromString(.declspec, null, ident_str) != null + else + false; + }, + .macro_param_has_feature => features.hasFeature(pp.comp, ident_str), + .macro_param_has_extension => features.hasExtension(pp.comp, ident_str), + .macro_param_has_builtin => pp.comp.hasBuiltin(ident_str), + else => unreachable, + }; + }, + .macro_param_has_warning => { + const actual_param = pp.pasteStringsUnsafe(param_toks) catch |er| switch (er) { + error.ExpectedStringLiteral => { + try pp.errStr(param_toks[0], .expected_str_literal_in, "__has_warning"); + return false; + }, + else => |e| return e, + }; + if (!mem.startsWith(u8, actual_param, "-W")) { + try pp.errStr(param_toks[0], .malformed_warning_check, "__has_warning"); + return false; + } + const warning_name = actual_param[2..]; + return Diagnostics.warningExists(warning_name); + }, + .macro_param_is_identifier => { + var invalid: ?TokenWithExpansionLocs = null; + var identifier: ?TokenWithExpansionLocs = null; + for (param_toks) |tok| switch (tok.id) { + .macro_ws => continue, + .comment => continue, + else => { + if (identifier) |_| invalid = tok else identifier = tok; + }, + }; + if (identifier == null and invalid == null) invalid = .{ .id = .eof, .loc = src_loc }; + if (invalid) |some| { + try pp.comp.addDiagnostic(.{ + .tag = .missing_tok_builtin, + .loc = some.loc, + .extra = .{ .tok_id_expected = .r_paren }, + }, some.expansionSlice()); + return false; + } + + const id = identifier.?.id; + return id == .identifier or id == .extended_identifier; + }, + .macro_param_has_include, .macro_param_has_include_next => { + const include_str = (try pp.reconstructIncludeString(param_toks, null, param_toks[0])) orelse return false; + const include_type: Compilation.IncludeType = switch (include_str[0]) { + '"' => .quotes, + '<' => .angle_brackets, + else => unreachable, + }; + const filename = include_str[1 .. include_str.len - 1]; + if (builtin == .macro_param_has_include or pp.include_depth == 0) { + if (builtin == .macro_param_has_include_next) { + try pp.comp.addDiagnostic(.{ + .tag = .include_next_outside_header, + .loc = src_loc, + }, &.{}); + } + return pp.comp.hasInclude(filename, src_loc.id, include_type, .first); + } + return pp.comp.hasInclude(filename, src_loc.id, include_type, .next); + }, + else => unreachable, + } +} + +/// Treat whitespace-only paste arguments as empty +fn getPasteArgs(args: []const TokenWithExpansionLocs) []const TokenWithExpansionLocs { + for (args) |tok| { + if (tok.id != .macro_ws) return args; + } + return &[1]TokenWithExpansionLocs{.{ + .id = .placemarker, + .loc = .{ .id = .generated, .byte_offset = 0, .line = 0 }, + }}; +} + +fn expandFuncMacro( + pp: *Preprocessor, + macro_tok: TokenWithExpansionLocs, + func_macro: *const Macro, + args: *const MacroArguments, + expanded_args: *const MacroArguments, + hideset_arg: Hideset.Index, +) MacroError!ExpandBuf { + var hideset = hideset_arg; + var buf = ExpandBuf.init(pp.gpa); + try buf.ensureTotalCapacity(func_macro.tokens.len); + errdefer buf.deinit(); + + var expanded_variable_arguments = ExpandBuf.init(pp.gpa); + defer expanded_variable_arguments.deinit(); + var variable_arguments = ExpandBuf.init(pp.gpa); + defer variable_arguments.deinit(); + + if (func_macro.var_args) { + var i: usize = func_macro.params.len; + while (i < expanded_args.items.len) : (i += 1) { + try variable_arguments.appendSlice(args.items[i]); + try expanded_variable_arguments.appendSlice(expanded_args.items[i]); + if (i != expanded_args.items.len - 1) { + const comma = TokenWithExpansionLocs{ .id = .comma, .loc = .{ .id = .generated } }; + try variable_arguments.append(comma); + try expanded_variable_arguments.append(comma); + } + } + } + + // token concatenation and expansion phase + var tok_i: usize = 0; + while (tok_i < func_macro.tokens.len) : (tok_i += 1) { + const raw = func_macro.tokens[tok_i]; + switch (raw.id) { + .hash_hash => while (tok_i + 1 < func_macro.tokens.len) { + const raw_next = func_macro.tokens[tok_i + 1]; + tok_i += 1; + + var va_opt_buf = ExpandBuf.init(pp.gpa); + defer va_opt_buf.deinit(); + + const next = switch (raw_next.id) { + .macro_ws => continue, + .hash_hash => continue, + .comment => if (!pp.comp.langopts.preserve_comments_in_macros) + continue + else + &[1]TokenWithExpansionLocs{tokFromRaw(raw_next)}, + .macro_param, .macro_param_no_expand => getPasteArgs(args.items[raw_next.end]), + .keyword_va_args => variable_arguments.items, + .keyword_va_opt => blk: { + try pp.expandVaOpt(&va_opt_buf, raw_next, variable_arguments.items.len != 0); + if (va_opt_buf.items.len == 0) break; + break :blk va_opt_buf.items; + }, + else => &[1]TokenWithExpansionLocs{tokFromRaw(raw_next)}, + }; + try pp.pasteTokens(&buf, next); + if (next.len != 0) break; + }, + .macro_param_no_expand => { + if (tok_i + 1 < func_macro.tokens.len and func_macro.tokens[tok_i + 1].id == .hash_hash) { + hideset = pp.hideset.get(tokFromRaw(func_macro.tokens[tok_i + 1]).loc); + } + const slice = getPasteArgs(args.items[raw.end]); + const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line }; + try bufCopyTokens(&buf, slice, &.{raw_loc}); + }, + .macro_param => { + if (tok_i + 1 < func_macro.tokens.len and func_macro.tokens[tok_i + 1].id == .hash_hash) { + hideset = pp.hideset.get(tokFromRaw(func_macro.tokens[tok_i + 1]).loc); + } + const arg = expanded_args.items[raw.end]; + const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line }; + try bufCopyTokens(&buf, arg, &.{raw_loc}); + }, + .keyword_va_args => { + const raw_loc = Source.Location{ .id = raw.source, .byte_offset = raw.start, .line = raw.line }; + try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc}); + }, + .keyword_va_opt => { + try pp.expandVaOpt(&buf, raw, variable_arguments.items.len != 0); + }, + .stringify_param, .stringify_va_args => { + const arg = if (raw.id == .stringify_va_args) + variable_arguments.items + else + args.items[raw.end]; + + pp.char_buf.clearRetainingCapacity(); + try pp.stringify(arg); + + const start = pp.comp.generated_buf.items.len; + try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items); + + try buf.append(try pp.makeGeneratedToken(start, .string_literal, tokFromRaw(raw))); + }, + .macro_param_has_attribute, + .macro_param_has_declspec_attribute, + .macro_param_has_warning, + .macro_param_has_feature, + .macro_param_has_extension, + .macro_param_has_builtin, + .macro_param_has_include, + .macro_param_has_include_next, + .macro_param_is_identifier, + => { + const arg = expanded_args.items[0]; + const result = if (arg.len == 0) blk: { + const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } }; + try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = macro_tok.loc, .extra = extra }, &.{}); + break :blk false; + } else try pp.handleBuiltinMacro(raw.id, arg, macro_tok.loc); + const start = pp.comp.generated_buf.items.len; + const w = pp.comp.generated_buf.writer(pp.gpa); + try w.print("{}\n", .{@intFromBool(result)}); + try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw))); + }, + .macro_param_has_c_attribute => { + const arg = expanded_args.items[0]; + const not_found = "0\n"; + const result = if (arg.len == 0) blk: { + const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } }; + try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = macro_tok.loc, .extra = extra }, &.{}); + break :blk not_found; + } else res: { + var invalid: ?TokenWithExpansionLocs = null; + var vendor_ident: ?TokenWithExpansionLocs = null; + var colon_colon: ?TokenWithExpansionLocs = null; + var attr_ident: ?TokenWithExpansionLocs = null; + for (arg) |tok| { + if (tok.id == .macro_ws) continue; + if (tok.id == .comment) continue; + if (tok.id == .colon_colon) { + if (colon_colon != null or attr_ident == null) { + invalid = tok; + break; + } + vendor_ident = attr_ident; + attr_ident = null; + colon_colon = tok; + continue; + } + if (!tok.id.isMacroIdentifier()) { + invalid = tok; + break; + } + if (attr_ident) |_| { + invalid = tok; + break; + } else attr_ident = tok; + } + if (vendor_ident != null and attr_ident == null) { + invalid = vendor_ident; + } else if (attr_ident == null and invalid == null) { + invalid = .{ .id = .eof, .loc = macro_tok.loc }; + } + if (invalid) |some| { + try pp.comp.addDiagnostic( + .{ .tag = .feature_check_requires_identifier, .loc = some.loc }, + some.expansionSlice(), + ); + break :res not_found; + } + if (vendor_ident) |some| { + const vendor_str = pp.expandedSlice(some); + const attr_str = pp.expandedSlice(attr_ident.?); + const exists = Attribute.fromString(.gnu, vendor_str, attr_str) != null; + + const start = pp.comp.generated_buf.items.len; + try pp.comp.generated_buf.appendSlice(pp.gpa, if (exists) "1\n" else "0\n"); + try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw))); + continue; + } + if (!pp.comp.langopts.standard.atLeast(.c23)) break :res not_found; + + const attrs = std.StaticStringMap([]const u8).initComptime(.{ + .{ "deprecated", "201904L\n" }, + .{ "fallthrough", "201904L\n" }, + .{ "maybe_unused", "201904L\n" }, + .{ "nodiscard", "202003L\n" }, + .{ "noreturn", "202202L\n" }, + .{ "_Noreturn", "202202L\n" }, + .{ "unsequenced", "202207L\n" }, + .{ "reproducible", "202207L\n" }, + }); + + const attr_str = Attribute.normalize(pp.expandedSlice(attr_ident.?)); + break :res attrs.get(attr_str) orelse not_found; + }; + const start = pp.comp.generated_buf.items.len; + try pp.comp.generated_buf.appendSlice(pp.gpa, result); + try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw))); + }, + .macro_param_has_embed => { + const arg = expanded_args.items[0]; + const not_found = "0\n"; + const result = if (arg.len == 0) blk: { + const extra = Diagnostics.Message.Extra{ .arguments = .{ .expected = 1, .actual = 0 } }; + try pp.comp.addDiagnostic(.{ .tag = .expected_arguments, .loc = macro_tok.loc, .extra = extra }, &.{}); + break :blk not_found; + } else res: { + var embed_args: []const TokenWithExpansionLocs = &.{}; + const include_str = (try pp.reconstructIncludeString(arg, &embed_args, arg[0])) orelse + break :res not_found; + + var prev = tokFromRaw(raw); + prev.id = .eof; + var it: struct { + i: u32 = 0, + slice: []const TokenWithExpansionLocs, + prev: TokenWithExpansionLocs, + fn next(it: *@This()) TokenWithExpansionLocs { + while (it.i < it.slice.len) switch (it.slice[it.i].id) { + .macro_ws, .whitespace => it.i += 1, + else => break, + } else return it.prev; + defer it.i += 1; + it.prev = it.slice[it.i]; + it.prev.id = .eof; + return it.slice[it.i]; + } + } = .{ .slice = embed_args, .prev = prev }; + + while (true) { + const param_first = it.next(); + if (param_first.id == .eof) break; + if (param_first.id != .identifier) { + try pp.comp.addDiagnostic( + .{ .tag = .malformed_embed_param, .loc = param_first.loc }, + param_first.expansionSlice(), + ); + continue; + } + + const char_top = pp.char_buf.items.len; + defer pp.char_buf.items.len = char_top; + + const maybe_colon = it.next(); + const param = switch (maybe_colon.id) { + .colon_colon => blk: { + // vendor::param + const param = it.next(); + if (param.id != .identifier) { + try pp.comp.addDiagnostic( + .{ .tag = .malformed_embed_param, .loc = param.loc }, + param.expansionSlice(), + ); + continue; + } + const l_paren = it.next(); + if (l_paren.id != .l_paren) { + try pp.comp.addDiagnostic( + .{ .tag = .malformed_embed_param, .loc = l_paren.loc }, + l_paren.expansionSlice(), + ); + continue; + } + break :blk "doesn't exist"; + }, + .l_paren => Attribute.normalize(pp.expandedSlice(param_first)), + else => { + try pp.comp.addDiagnostic( + .{ .tag = .malformed_embed_param, .loc = maybe_colon.loc }, + maybe_colon.expansionSlice(), + ); + continue; + }, + }; + + var arg_count: u32 = 0; + var first_arg: TokenWithExpansionLocs = undefined; + while (true) { + const next = it.next(); + if (next.id == .eof) { + try pp.comp.addDiagnostic( + .{ .tag = .malformed_embed_limit, .loc = param_first.loc }, + param_first.expansionSlice(), + ); + break; + } + if (next.id == .r_paren) break; + arg_count += 1; + if (arg_count == 1) first_arg = next; + } + + if (std.mem.eql(u8, param, "limit")) { + if (arg_count != 1) { + try pp.comp.addDiagnostic( + .{ .tag = .malformed_embed_limit, .loc = param_first.loc }, + param_first.expansionSlice(), + ); + continue; + } + if (first_arg.id != .pp_num) { + try pp.comp.addDiagnostic( + .{ .tag = .malformed_embed_limit, .loc = param_first.loc }, + param_first.expansionSlice(), + ); + continue; + } + _ = std.fmt.parseInt(u32, pp.expandedSlice(first_arg), 10) catch { + break :res not_found; + }; + } else if (!std.mem.eql(u8, param, "prefix") and !std.mem.eql(u8, param, "suffix") and + !std.mem.eql(u8, param, "if_empty")) + { + break :res not_found; + } + } + + const include_type: Compilation.IncludeType = switch (include_str[0]) { + '"' => .quotes, + '<' => .angle_brackets, + else => unreachable, + }; + const filename = include_str[1 .. include_str.len - 1]; + const contents = (try pp.comp.findEmbed(filename, arg[0].loc.id, include_type, 1)) orelse + break :res not_found; + + defer pp.comp.gpa.free(contents); + break :res if (contents.len != 0) "1\n" else "2\n"; + }; + const start = pp.comp.generated_buf.items.len; + try pp.comp.generated_buf.appendSlice(pp.comp.gpa, result); + try buf.append(try pp.makeGeneratedToken(start, .pp_num, tokFromRaw(raw))); + }, + .macro_param_pragma_operator => { + const param_toks = expanded_args.items[0]; + // Clang and GCC require exactly one token (so, no parentheses or string pasting) + // even though their error messages indicate otherwise. Ours is slightly more + // descriptive. + var invalid: ?TokenWithExpansionLocs = null; + var string: ?TokenWithExpansionLocs = null; + for (param_toks) |tok| switch (tok.id) { + .string_literal => { + if (string) |_| invalid = tok else string = tok; + }, + .macro_ws => continue, + .comment => continue, + else => { + invalid = tok; + break; + }, + }; + if (string == null and invalid == null) invalid = .{ .loc = macro_tok.loc, .id = .eof }; + if (invalid) |some| try pp.comp.addDiagnostic( + .{ .tag = .pragma_operator_string_literal, .loc = some.loc }, + some.expansionSlice(), + ) else try pp.pragmaOperator(string.?, macro_tok.loc); + }, + .comma => { + if (tok_i + 2 < func_macro.tokens.len and func_macro.tokens[tok_i + 1].id == .hash_hash) { + const hash_hash = func_macro.tokens[tok_i + 1]; + var maybe_va_args = func_macro.tokens[tok_i + 2]; + var consumed: usize = 2; + if (maybe_va_args.id == .macro_ws and tok_i + 3 < func_macro.tokens.len) { + consumed = 3; + maybe_va_args = func_macro.tokens[tok_i + 3]; + } + if (maybe_va_args.id == .keyword_va_args) { + // GNU extension: `, ##__VA_ARGS__` deletes the comma if __VA_ARGS__ is empty + tok_i += consumed; + if (func_macro.params.len == expanded_args.items.len) { + // Empty __VA_ARGS__, drop the comma + try pp.err(hash_hash, .comma_deletion_va_args); + } else if (func_macro.params.len == 0 and expanded_args.items.len == 1 and expanded_args.items[0].len == 0) { + // Ambiguous whether this is "empty __VA_ARGS__" or "__VA_ARGS__ omitted" + if (pp.comp.langopts.standard.isGNU()) { + // GNU standard, drop the comma + try pp.err(hash_hash, .comma_deletion_va_args); + } else { + // C standard, retain the comma + try buf.append(tokFromRaw(raw)); + } + } else { + try buf.append(tokFromRaw(raw)); + if (expanded_variable_arguments.items.len > 0 or variable_arguments.items.len == func_macro.params.len) { + try pp.err(hash_hash, .comma_deletion_va_args); + } + const raw_loc = Source.Location{ + .id = maybe_va_args.source, + .byte_offset = maybe_va_args.start, + .line = maybe_va_args.line, + }; + try bufCopyTokens(&buf, expanded_variable_arguments.items, &.{raw_loc}); + } + continue; + } + } + // Regular comma, no token pasting with __VA_ARGS__ + try buf.append(tokFromRaw(raw)); + }, + else => try buf.append(tokFromRaw(raw)), + } + } + removePlacemarkers(&buf); + + const macro_expansion_locs = macro_tok.expansionSlice(); + for (buf.items) |*tok| { + try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc}); + try tok.addExpansionLocation(pp.gpa, macro_expansion_locs); + const tok_hidelist = pp.hideset.get(tok.loc); + const new_hidelist = try pp.hideset.@"union"(tok_hidelist, hideset); + try pp.hideset.put(tok.loc, new_hidelist); + } + + return buf; +} + +fn expandVaOpt( + pp: *Preprocessor, + buf: *ExpandBuf, + raw: RawToken, + should_expand: bool, +) !void { + if (!should_expand) return; + + const source = pp.comp.getSource(raw.source); + var tokenizer: Tokenizer = .{ + .buf = source.buf, + .index = raw.start, + .source = raw.source, + .langopts = pp.comp.langopts, + .line = raw.line, + }; + while (tokenizer.index < raw.end) { + const tok = tokenizer.next(); + try buf.append(tokFromRaw(tok)); + } +} + +fn bufCopyTokens(buf: *ExpandBuf, tokens: []const TokenWithExpansionLocs, src: []const Source.Location) !void { + try buf.ensureUnusedCapacity(tokens.len); + for (tokens) |tok| { + var copy = try tok.dupe(buf.allocator); + errdefer TokenWithExpansionLocs.free(copy.expansion_locs, buf.allocator); + try copy.addExpansionLocation(buf.allocator, src); + buf.appendAssumeCapacity(copy); + } +} + +fn nextBufToken( + pp: *Preprocessor, + tokenizer: *Tokenizer, + buf: *ExpandBuf, + start_idx: *usize, + end_idx: *usize, + extend_buf: bool, +) Error!TokenWithExpansionLocs { + start_idx.* += 1; + if (start_idx.* == buf.items.len and start_idx.* >= end_idx.*) { + if (extend_buf) { + const raw_tok = tokenizer.next(); + if (raw_tok.id.isMacroIdentifier() and + pp.poisoned_identifiers.get(pp.tokSlice(raw_tok)) != null) + try pp.err(raw_tok, .poisoned_identifier); + + if (raw_tok.id == .nl) pp.add_expansion_nl += 1; + + const new_tok = tokFromRaw(raw_tok); + end_idx.* += 1; + try buf.append(new_tok); + return new_tok; + } else { + return TokenWithExpansionLocs{ .id = .eof, .loc = .{ .id = .generated } }; + } + } else { + return buf.items[start_idx.*]; + } +} + +fn collectMacroFuncArguments( + pp: *Preprocessor, + tokenizer: *Tokenizer, + buf: *ExpandBuf, + start_idx: *usize, + end_idx: *usize, + extend_buf: bool, + is_builtin: bool, + r_paren: *TokenWithExpansionLocs, +) !MacroArguments { + const name_tok = buf.items[start_idx.*]; + const saved_tokenizer = tokenizer.*; + const old_end = end_idx.*; + + while (true) { + const tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf); + switch (tok.id) { + .nl, .whitespace, .macro_ws => {}, + .l_paren => break, + else => { + if (is_builtin) { + try pp.errStr(name_tok, .missing_lparen_after_builtin, pp.expandedSlice(name_tok)); + } + // Not a macro function call, go over normal identifier, rewind + tokenizer.* = saved_tokenizer; + end_idx.* = old_end; + return error.MissingLParen; + }, + } + } + + // collect the arguments. + var parens: u32 = 0; + var args = MacroArguments.init(pp.gpa); + errdefer deinitMacroArguments(pp.gpa, &args); + var curArgument = std.ArrayList(TokenWithExpansionLocs).init(pp.gpa); + defer curArgument.deinit(); + while (true) { + var tok = try nextBufToken(pp, tokenizer, buf, start_idx, end_idx, extend_buf); + tok.flags.is_macro_arg = true; + switch (tok.id) { + .comma => { + if (parens == 0) { + const owned = try curArgument.toOwnedSlice(); + errdefer pp.gpa.free(owned); + try args.append(owned); + } else { + const duped = try tok.dupe(pp.gpa); + errdefer TokenWithExpansionLocs.free(duped.expansion_locs, pp.gpa); + try curArgument.append(duped); + } + }, + .l_paren => { + const duped = try tok.dupe(pp.gpa); + errdefer TokenWithExpansionLocs.free(duped.expansion_locs, pp.gpa); + try curArgument.append(duped); + parens += 1; + }, + .r_paren => { + if (parens == 0) { + const owned = try curArgument.toOwnedSlice(); + errdefer pp.gpa.free(owned); + try args.append(owned); + r_paren.* = tok; + break; + } else { + const duped = try tok.dupe(pp.gpa); + errdefer TokenWithExpansionLocs.free(duped.expansion_locs, pp.gpa); + try curArgument.append(duped); + parens -= 1; + } + }, + .eof => { + { + const owned = try curArgument.toOwnedSlice(); + errdefer pp.gpa.free(owned); + try args.append(owned); + } + tokenizer.* = saved_tokenizer; + try pp.comp.addDiagnostic( + .{ .tag = .unterminated_macro_arg_list, .loc = name_tok.loc }, + name_tok.expansionSlice(), + ); + return error.Unterminated; + }, + .nl, .whitespace => { + try curArgument.append(.{ .id = .macro_ws, .loc = tok.loc }); + }, + else => { + const duped = try tok.dupe(pp.gpa); + errdefer TokenWithExpansionLocs.free(duped.expansion_locs, pp.gpa); + try curArgument.append(duped); + }, + } + } + + return args; +} + +fn removeExpandedTokens(pp: *Preprocessor, buf: *ExpandBuf, start: usize, len: usize, moving_end_idx: *usize) !void { + for (buf.items[start .. start + len]) |tok| TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + try buf.replaceRange(start, len, &.{}); + moving_end_idx.* -|= len; +} + +/// The behavior of `defined` depends on whether we are in a preprocessor +/// expression context (#if or #elif) or not. +/// In a non-expression context it's just an identifier. Within a preprocessor +/// expression it is a unary operator or one-argument function. +const EvalContext = enum { + expr, + non_expr, +}; + +/// Helper for safely iterating over a slice of tokens while skipping whitespace +const TokenIterator = struct { + toks: []const TokenWithExpansionLocs, + i: usize, + + fn init(toks: []const TokenWithExpansionLocs) TokenIterator { + return .{ .toks = toks, .i = 0 }; + } + + fn nextNoWS(self: *TokenIterator) ?TokenWithExpansionLocs { + while (self.i < self.toks.len) : (self.i += 1) { + const tok = self.toks[self.i]; + if (tok.id == .whitespace or tok.id == .macro_ws) continue; + + self.i += 1; + return tok; + } + return null; + } +}; + +fn expandMacroExhaustive( + pp: *Preprocessor, + tokenizer: *Tokenizer, + buf: *ExpandBuf, + start_idx: usize, + end_idx: usize, + extend_buf: bool, + eval_ctx: EvalContext, +) MacroError!void { + var moving_end_idx = end_idx; + var advance_index: usize = 0; + // rescan loop + var do_rescan = true; + while (do_rescan) { + do_rescan = false; + // expansion loop + var idx: usize = start_idx + advance_index; + while (idx < moving_end_idx) { + const macro_tok = buf.items[idx]; + if (macro_tok.id == .keyword_defined and eval_ctx == .expr) { + idx += 1; + var it = TokenIterator.init(buf.items[idx..moving_end_idx]); + if (it.nextNoWS()) |tok| { + switch (tok.id) { + .l_paren => { + _ = it.nextNoWS(); // eat (what should be) identifier + _ = it.nextNoWS(); // eat (what should be) r paren + }, + .identifier, .extended_identifier => {}, + else => {}, + } + } + idx += it.i; + continue; + } + if (!macro_tok.id.isMacroIdentifier() or macro_tok.flags.expansion_disabled) { + idx += 1; + continue; + } + const expanded = pp.expandedSlice(macro_tok); + const macro = pp.defines.getPtr(expanded) orelse { + idx += 1; + continue; + }; + const macro_hidelist = pp.hideset.get(macro_tok.loc); + if (pp.hideset.contains(macro_hidelist, expanded)) { + idx += 1; + continue; + } + + macro_handler: { + if (macro.is_func) { + var r_paren: TokenWithExpansionLocs = undefined; + var macro_scan_idx = idx; + // to be saved in case this doesn't turn out to be a call + const args = pp.collectMacroFuncArguments( + tokenizer, + buf, + ¯o_scan_idx, + &moving_end_idx, + extend_buf, + macro.is_builtin, + &r_paren, + ) catch |er| switch (er) { + error.MissingLParen => { + if (!buf.items[idx].flags.is_macro_arg) buf.items[idx].flags.expansion_disabled = true; + idx += 1; + break :macro_handler; + }, + error.Unterminated => { + if (pp.comp.langopts.emulate == .gcc) idx += 1; + try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx, &moving_end_idx); + break :macro_handler; + }, + else => |e| return e, + }; + assert(r_paren.id == .r_paren); + var free_arg_expansion_locs = false; + defer { + for (args.items) |item| { + if (free_arg_expansion_locs) for (item) |tok| TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + pp.gpa.free(item); + } + args.deinit(); + } + const r_paren_hidelist = pp.hideset.get(r_paren.loc); + var hs = try pp.hideset.intersection(macro_hidelist, r_paren_hidelist); + hs = try pp.hideset.prepend(macro_tok.loc, hs); + + var args_count: u32 = @intCast(args.items.len); + // if the macro has zero arguments g() args_count is still 1 + // an empty token list g() and a whitespace-only token list g( ) + // counts as zero arguments for the purposes of argument-count validation + if (args_count == 1 and macro.params.len == 0) { + for (args.items[0]) |tok| { + if (tok.id != .macro_ws) break; + } else { + args_count = 0; + } + } + + // Validate argument count. + const extra = Diagnostics.Message.Extra{ + .arguments = .{ .expected = @intCast(macro.params.len), .actual = args_count }, + }; + if (macro.var_args and args_count < macro.params.len) { + free_arg_expansion_locs = true; + try pp.comp.addDiagnostic( + .{ .tag = .expected_at_least_arguments, .loc = buf.items[idx].loc, .extra = extra }, + buf.items[idx].expansionSlice(), + ); + idx += 1; + try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx); + continue; + } + if (!macro.var_args and args_count != macro.params.len) { + free_arg_expansion_locs = true; + try pp.comp.addDiagnostic( + .{ .tag = .expected_arguments, .loc = buf.items[idx].loc, .extra = extra }, + buf.items[idx].expansionSlice(), + ); + idx += 1; + try pp.removeExpandedTokens(buf, idx, macro_scan_idx - idx + 1, &moving_end_idx); + continue; + } + var expanded_args = MacroArguments.init(pp.gpa); + defer deinitMacroArguments(pp.gpa, &expanded_args); + try expanded_args.ensureTotalCapacity(args.items.len); + for (args.items) |arg| { + var expand_buf = ExpandBuf.init(pp.gpa); + errdefer expand_buf.deinit(); + try expand_buf.appendSlice(arg); + + try pp.expandMacroExhaustive(tokenizer, &expand_buf, 0, expand_buf.items.len, false, eval_ctx); + + expanded_args.appendAssumeCapacity(try expand_buf.toOwnedSlice()); + } + + var res = try pp.expandFuncMacro(macro_tok, macro, &args, &expanded_args, hs); + defer res.deinit(); + const tokens_added = res.items.len; + const tokens_removed = macro_scan_idx - idx + 1; + for (buf.items[idx .. idx + tokens_removed]) |tok| TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + try buf.replaceRange(idx, tokens_removed, res.items); + + moving_end_idx += tokens_added; + // Overflow here means that we encountered an unterminated argument list + // while expanding the body of this macro. + moving_end_idx -|= tokens_removed; + idx += tokens_added; + do_rescan = true; + } else { + const res = try pp.expandObjMacro(macro); + defer res.deinit(); + + const hs = try pp.hideset.prepend(macro_tok.loc, macro_hidelist); + + const macro_expansion_locs = macro_tok.expansionSlice(); + var increment_idx_by = res.items.len; + for (res.items, 0..) |*tok, i| { + tok.flags.is_macro_arg = macro_tok.flags.is_macro_arg; + try tok.addExpansionLocation(pp.gpa, &.{macro_tok.loc}); + try tok.addExpansionLocation(pp.gpa, macro_expansion_locs); + + const tok_hidelist = pp.hideset.get(tok.loc); + const new_hidelist = try pp.hideset.@"union"(tok_hidelist, hs); + try pp.hideset.put(tok.loc, new_hidelist); + + if (tok.id == .keyword_defined and eval_ctx == .expr) { + try pp.comp.addDiagnostic(.{ + .tag = .expansion_to_defined, + .loc = tok.loc, + }, tok.expansionSlice()); + } + + if (i < increment_idx_by and (tok.id == .keyword_defined or pp.defines.contains(pp.expandedSlice(tok.*)))) { + increment_idx_by = i; + } + } + + TokenWithExpansionLocs.free(buf.items[idx].expansion_locs, pp.gpa); + try buf.replaceRange(idx, 1, res.items); + idx += increment_idx_by; + moving_end_idx = moving_end_idx + res.items.len - 1; + do_rescan = true; + } + } + if (idx - start_idx == advance_index + 1 and !do_rescan) { + advance_index += 1; + } + } // end of replacement phase + } + // end of scanning phase + + // trim excess buffer + for (buf.items[moving_end_idx..]) |item| { + TokenWithExpansionLocs.free(item.expansion_locs, pp.gpa); + } + buf.items.len = moving_end_idx; +} + +/// Try to expand a macro after a possible candidate has been read from the `tokenizer` +/// into the `raw` token passed as argument +fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroError!void { + var source_tok = tokFromRaw(raw); + if (!raw.id.isMacroIdentifier()) { + source_tok.id.simplifyMacroKeyword(); + return pp.addToken(source_tok); + } + pp.top_expansion_buf.items.len = 0; + try pp.top_expansion_buf.append(source_tok); + pp.expansion_source_loc = source_tok.loc; + + pp.hideset.clearRetainingCapacity(); + try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr); + try pp.ensureUnusedTokenCapacity(pp.top_expansion_buf.items.len); + for (pp.top_expansion_buf.items) |*tok| { + if (tok.id == .macro_ws and !pp.preserve_whitespace) { + TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + continue; + } + if (tok.id == .comment and !pp.comp.langopts.preserve_comments_in_macros) { + TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + continue; + } + if (tok.id == .placemarker) { + TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + continue; + } + tok.id.simplifyMacroKeywordExtra(true); + pp.addTokenAssumeCapacity(tok.*); + } + if (pp.preserve_whitespace) { + try pp.ensureUnusedTokenCapacity(pp.add_expansion_nl); + while (pp.add_expansion_nl > 0) : (pp.add_expansion_nl -= 1) { + pp.addTokenAssumeCapacity(.{ .id = .nl, .loc = .{ + .id = tokenizer.source, + .line = tokenizer.line, + } }); + } + } +} + +fn expandedSliceExtra(pp: *const Preprocessor, tok: anytype, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 { + if (tok.id.lexeme()) |some| { + if (!tok.id.allowsDigraphs(pp.comp.langopts) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some; + } + var tmp_tokenizer = Tokenizer{ + .buf = pp.comp.getSource(tok.loc.id).buf, + .langopts = pp.comp.langopts, + .index = tok.loc.byte_offset, + .source = .generated, + }; + if (tok.id == .macro_string) { + while (true) : (tmp_tokenizer.index += 1) { + if (tmp_tokenizer.buf[tmp_tokenizer.index] == '>') break; + } + return tmp_tokenizer.buf[tok.loc.byte_offset .. tmp_tokenizer.index + 1]; + } + const res = tmp_tokenizer.next(); + return tmp_tokenizer.buf[res.start..res.end]; +} + +/// Get expanded token source string. +pub fn expandedSlice(pp: *const Preprocessor, tok: anytype) []const u8 { + return pp.expandedSliceExtra(tok, .single_macro_ws); +} + +/// Concat two tokens and add the result to pp.generated +fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const TokenWithExpansionLocs) Error!void { + const lhs = while (lhs_toks.pop()) |lhs| { + if ((pp.comp.langopts.preserve_comments_in_macros and lhs.id == .comment) or + (lhs.id != .macro_ws and lhs.id != .comment)) + break lhs; + + TokenWithExpansionLocs.free(lhs.expansion_locs, pp.gpa); + } else { + return bufCopyTokens(lhs_toks, rhs_toks, &.{}); + }; + + var rhs_rest: u32 = 1; + const rhs = for (rhs_toks) |rhs| { + if ((pp.comp.langopts.preserve_comments_in_macros and rhs.id == .comment) or + (rhs.id != .macro_ws and rhs.id != .comment)) + break rhs; + + rhs_rest += 1; + } else { + return lhs_toks.appendAssumeCapacity(lhs); + }; + defer TokenWithExpansionLocs.free(lhs.expansion_locs, pp.gpa); + + const start = pp.comp.generated_buf.items.len; + const end = start + pp.expandedSlice(lhs).len + pp.expandedSlice(rhs).len; + try pp.comp.generated_buf.ensureTotalCapacity(pp.gpa, end + 1); // +1 for a newline + // We cannot use the same slices here since they might be invalidated by `ensureCapacity` + pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(lhs)); + pp.comp.generated_buf.appendSliceAssumeCapacity(pp.expandedSlice(rhs)); + pp.comp.generated_buf.appendAssumeCapacity('\n'); + + // Try to tokenize the result. + var tmp_tokenizer = Tokenizer{ + .buf = pp.comp.generated_buf.items, + .langopts = pp.comp.langopts, + .index = @intCast(start), + .source = .generated, + }; + const pasted_token = tmp_tokenizer.nextNoWSComments(); + const next = tmp_tokenizer.nextNoWSComments(); + const pasted_id = if (lhs.id == .placemarker and rhs.id == .placemarker) + .placemarker + else + pasted_token.id; + try lhs_toks.append(try pp.makeGeneratedToken(start, pasted_id, lhs)); + + if (next.id != .nl and next.id != .eof) { + try pp.errStr( + lhs, + .pasting_formed_invalid, + try pp.comp.diagnostics.arena.allocator().dupe(u8, pp.comp.generated_buf.items[start..end]), + ); + try lhs_toks.append(tokFromRaw(next)); + } + + try bufCopyTokens(lhs_toks, rhs_toks[rhs_rest..], &.{}); +} + +fn makeGeneratedToken(pp: *Preprocessor, start: usize, id: Token.Id, source: TokenWithExpansionLocs) !TokenWithExpansionLocs { + var pasted_token = TokenWithExpansionLocs{ .id = id, .loc = .{ + .id = .generated, + .byte_offset = @intCast(start), + .line = pp.generated_line, + } }; + pp.generated_line += 1; + try pasted_token.addExpansionLocation(pp.gpa, &.{source.loc}); + try pasted_token.addExpansionLocation(pp.gpa, source.expansionSlice()); + return pasted_token; +} + +/// Defines a new macro and warns if it is a duplicate +fn defineMacro(pp: *Preprocessor, define_tok: RawToken, name_tok: RawToken, macro: Macro) Error!void { + const name_str = pp.tokSlice(name_tok); + const gop = try pp.defines.getOrPut(pp.gpa, name_str); + if (gop.found_existing and !gop.value_ptr.eql(macro, pp)) { + const tag: Diagnostics.Tag = if (gop.value_ptr.is_builtin) .builtin_macro_redefined else .macro_redefined; + const start = pp.comp.diagnostics.list.items.len; + try pp.comp.addDiagnostic(.{ + .tag = tag, + .loc = .{ .id = name_tok.source, .byte_offset = name_tok.start, .line = name_tok.line }, + .extra = .{ .str = name_str }, + }, &.{}); + if (!gop.value_ptr.is_builtin and pp.comp.diagnostics.list.items.len != start) { + try pp.comp.addDiagnostic(.{ + .tag = .previous_definition, + .loc = gop.value_ptr.loc, + }, &.{}); + } + } + if (pp.verbose) { + pp.verboseLog(name_tok, "macro {s} defined", .{name_str}); + } + if (pp.store_macro_tokens) { + try pp.addToken(tokFromRaw(define_tok)); + } + gop.value_ptr.* = macro; +} + +/// Handle a #define directive. +fn define(pp: *Preprocessor, tokenizer: *Tokenizer, define_tok: RawToken) Error!void { + // Get macro name and validate it. + const macro_name = tokenizer.nextNoWS(); + if (macro_name.id == .keyword_defined) { + try pp.err(macro_name, .defined_as_macro_name); + return skipToNl(tokenizer); + } + if (!macro_name.id.isMacroIdentifier()) { + try pp.err(macro_name, .macro_name_must_be_identifier); + return skipToNl(tokenizer); + } + var macro_name_token_id = macro_name.id; + macro_name_token_id.simplifyMacroKeyword(); + switch (macro_name_token_id) { + .identifier, .extended_identifier => {}, + else => if (macro_name_token_id.isMacroIdentifier()) { + try pp.err(macro_name, .keyword_macro); + }, + } + + // Check for function macros and empty defines. + var first = tokenizer.next(); + switch (first.id) { + .nl, .eof => return pp.defineMacro(define_tok, macro_name, .{ + .params = &.{}, + .tokens = &.{}, + .var_args = false, + .loc = tokFromRaw(macro_name).loc, + .is_func = false, + }), + .whitespace => first = tokenizer.next(), + .l_paren => return pp.defineFn(tokenizer, define_tok, macro_name, first), + else => try pp.err(first, .whitespace_after_macro_name), + } + if (first.id == .hash_hash) { + try pp.err(first, .hash_hash_at_start); + return skipToNl(tokenizer); + } + first.id.simplifyMacroKeyword(); + + pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time. + + var need_ws = false; + // Collect the token body and validate any ## found. + var tok = first; + while (true) { + tok.id.simplifyMacroKeyword(); + switch (tok.id) { + .hash_hash => { + const next = tokenizer.nextNoWSComments(); + switch (next.id) { + .nl, .eof => { + try pp.err(tok, .hash_hash_at_end); + return; + }, + .hash_hash => { + try pp.err(next, .hash_hash_at_end); + return; + }, + else => {}, + } + try pp.token_buf.append(tok); + try pp.token_buf.append(next); + }, + .nl, .eof => break, + .comment => if (pp.comp.langopts.preserve_comments_in_macros) { + if (need_ws) { + need_ws = false; + try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated }); + } + try pp.token_buf.append(tok); + }, + .whitespace => need_ws = true, + .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| { + try pp.err(tok, invalidTokenDiagnostic(tag)); + try pp.token_buf.append(tok); + }, + .unterminated_comment => try pp.err(tok, .unterminated_comment), + else => { + if (tok.id != .whitespace and need_ws) { + need_ws = false; + try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated }); + } + try pp.token_buf.append(tok); + }, + } + tok = tokenizer.next(); + } + + const list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items); + try pp.defineMacro(define_tok, macro_name, .{ + .loc = tokFromRaw(macro_name).loc, + .tokens = list, + .params = undefined, + .is_func = false, + .var_args = false, + }); +} + +/// Handle a function like #define directive. +fn defineFn(pp: *Preprocessor, tokenizer: *Tokenizer, define_tok: RawToken, macro_name: RawToken, l_paren: RawToken) Error!void { + assert(macro_name.id.isMacroIdentifier()); + var params = std.ArrayList([]const u8).init(pp.gpa); + defer params.deinit(); + + // Parse the parameter list. + var gnu_var_args: []const u8 = ""; + var var_args = false; + while (true) { + var tok = tokenizer.nextNoWS(); + if (tok.id == .r_paren) break; + if (tok.id == .eof) return pp.err(tok, .unterminated_macro_param_list); + if (tok.id == .ellipsis) { + var_args = true; + const r_paren = tokenizer.nextNoWS(); + if (r_paren.id != .r_paren) { + try pp.err(r_paren, .missing_paren_param_list); + try pp.err(l_paren, .to_match_paren); + return skipToNl(tokenizer); + } + break; + } + if (!tok.id.isMacroIdentifier()) { + try pp.err(tok, .invalid_token_param_list); + return skipToNl(tokenizer); + } + + try params.append(pp.tokSlice(tok)); + + tok = tokenizer.nextNoWS(); + if (tok.id == .ellipsis) { + try pp.err(tok, .gnu_va_macro); + gnu_var_args = params.pop().?; + const r_paren = tokenizer.nextNoWS(); + if (r_paren.id != .r_paren) { + try pp.err(r_paren, .missing_paren_param_list); + try pp.err(l_paren, .to_match_paren); + return skipToNl(tokenizer); + } + break; + } else if (tok.id == .r_paren) { + break; + } else if (tok.id != .comma) { + try pp.err(tok, .expected_comma_param_list); + return skipToNl(tokenizer); + } + } + + var need_ws = false; + // Collect the body tokens and validate # and ##'s found. + pp.token_buf.items.len = 0; // Safe to use since we can only be in one directive at a time. + tok_loop: while (true) { + var tok = tokenizer.next(); + switch (tok.id) { + .nl, .eof => break, + .whitespace => need_ws = pp.token_buf.items.len != 0, + .comment => if (!pp.comp.langopts.preserve_comments_in_macros) continue else { + if (need_ws) { + need_ws = false; + try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated }); + } + try pp.token_buf.append(tok); + }, + .hash => { + if (tok.id != .whitespace and need_ws) { + need_ws = false; + try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated }); + } + const param = tokenizer.nextNoWS(); + blk: { + if (var_args and param.id == .keyword_va_args) { + tok.id = .stringify_va_args; + try pp.token_buf.append(tok); + continue :tok_loop; + } + if (!param.id.isMacroIdentifier()) break :blk; + const s = pp.tokSlice(param); + if (mem.eql(u8, s, gnu_var_args)) { + tok.id = .stringify_va_args; + try pp.token_buf.append(tok); + continue :tok_loop; + } + for (params.items, 0..) |p, i| { + if (mem.eql(u8, p, s)) { + tok.id = .stringify_param; + tok.end = @intCast(i); + try pp.token_buf.append(tok); + continue :tok_loop; + } + } + } + try pp.err(param, .hash_not_followed_param); + return skipToNl(tokenizer); + }, + .hash_hash => { + need_ws = false; + // if ## appears at the beginning, the token buf is still empty + // in this case, error out + if (pp.token_buf.items.len == 0) { + try pp.err(tok, .hash_hash_at_start); + return skipToNl(tokenizer); + } + const saved_tokenizer = tokenizer.*; + const next = tokenizer.nextNoWSComments(); + if (next.id == .nl or next.id == .eof) { + try pp.err(tok, .hash_hash_at_end); + return; + } + tokenizer.* = saved_tokenizer; + // convert the previous token to .macro_param_no_expand if it was .macro_param + if (pp.token_buf.items[pp.token_buf.items.len - 1].id == .macro_param) { + pp.token_buf.items[pp.token_buf.items.len - 1].id = .macro_param_no_expand; + } + try pp.token_buf.append(tok); + }, + .unterminated_string_literal, .unterminated_char_literal, .empty_char_literal => |tag| { + try pp.err(tok, invalidTokenDiagnostic(tag)); + try pp.token_buf.append(tok); + }, + .unterminated_comment => try pp.err(tok, .unterminated_comment), + else => { + if (tok.id != .whitespace and need_ws) { + need_ws = false; + try pp.token_buf.append(.{ .id = .macro_ws, .source = .generated }); + } + if (var_args and tok.id == .keyword_va_args) { + // do nothing + } else if (var_args and tok.id == .keyword_va_opt) { + const opt_l_paren = tokenizer.next(); + if (opt_l_paren.id != .l_paren) { + try pp.err(opt_l_paren, .va_opt_lparen); + return skipToNl(tokenizer); + } + tok.start = opt_l_paren.end; + + var parens: u32 = 0; + while (true) { + const opt_tok = tokenizer.next(); + switch (opt_tok.id) { + .l_paren => parens += 1, + .r_paren => if (parens == 0) { + break; + } else { + parens -= 1; + }, + .nl, .eof => { + try pp.err(opt_tok, .va_opt_rparen); + try pp.err(opt_l_paren, .to_match_paren); + return skipToNl(tokenizer); + }, + .whitespace => {}, + else => tok.end = opt_tok.end, + } + } + } else if (tok.id.isMacroIdentifier()) { + tok.id.simplifyMacroKeyword(); + const s = pp.tokSlice(tok); + if (mem.eql(u8, gnu_var_args, s)) { + tok.id = .keyword_va_args; + } else for (params.items, 0..) |param, i| { + if (mem.eql(u8, param, s)) { + // NOTE: it doesn't matter to assign .macro_param_no_expand + // here in case a ## was the previous token, because + // ## processing will eat this token with the same semantics + tok.id = .macro_param; + tok.end = @intCast(i); + break; + } + } + } + try pp.token_buf.append(tok); + }, + } + } + + const param_list = try pp.arena.allocator().dupe([]const u8, params.items); + const token_list = try pp.arena.allocator().dupe(RawToken, pp.token_buf.items); + try pp.defineMacro(define_tok, macro_name, .{ + .is_func = true, + .params = param_list, + .var_args = var_args or gnu_var_args.len != 0, + .tokens = token_list, + .loc = tokFromRaw(macro_name).loc, + }); +} + +/// Handle an #embed directive +/// embedDirective : ("FILENAME" | ) embedParam* +/// embedParam : IDENTIFIER (:: IDENTIFIER)? '(' ')' +fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void { + const first = tokenizer.nextNoWS(); + const filename_tok = pp.findIncludeFilenameToken(first, tokenizer, .ignore_trailing_tokens) catch |er| switch (er) { + error.InvalidInclude => return, + else => |e| return e, + }; + defer TokenWithExpansionLocs.free(filename_tok.expansion_locs, pp.gpa); + + // Check for empty filename. + const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws); + if (tok_slice.len < 3) { + try pp.err(first, .empty_filename); + return; + } + const filename = tok_slice[1 .. tok_slice.len - 1]; + const include_type: Compilation.IncludeType = switch (filename_tok.id) { + .string_literal => .quotes, + .macro_string => .angle_brackets, + else => unreachable, + }; + + // Index into `token_buf` + const Range = struct { + start: u32, + end: u32, + + fn expand(opt_range: ?@This(), pp_: *Preprocessor, tokenizer_: *Tokenizer) !void { + const range = opt_range orelse return; + const slice = pp_.token_buf.items[range.start..range.end]; + for (slice) |tok| { + try pp_.expandMacro(tokenizer_, tok); + } + } + }; + pp.token_buf.items.len = 0; + + var limit: ?u32 = null; + var prefix: ?Range = null; + var suffix: ?Range = null; + var if_empty: ?Range = null; + while (true) { + const param_first = tokenizer.nextNoWS(); + switch (param_first.id) { + .nl, .eof => break, + .identifier => {}, + else => { + try pp.err(param_first, .malformed_embed_param); + continue; + }, + } + + const char_top = pp.char_buf.items.len; + defer pp.char_buf.items.len = char_top; + + const maybe_colon = tokenizer.colonColon(); + const param = switch (maybe_colon.id) { + .colon_colon => blk: { + // vendor::param + const param = tokenizer.nextNoWS(); + if (param.id != .identifier) { + try pp.err(param, .malformed_embed_param); + continue; + } + const l_paren = tokenizer.nextNoWS(); + if (l_paren.id != .l_paren) { + try pp.err(l_paren, .malformed_embed_param); + continue; + } + try pp.char_buf.appendSlice(Attribute.normalize(pp.tokSlice(param_first))); + try pp.char_buf.appendSlice("::"); + try pp.char_buf.appendSlice(Attribute.normalize(pp.tokSlice(param))); + break :blk pp.char_buf.items; + }, + .l_paren => Attribute.normalize(pp.tokSlice(param_first)), + else => { + try pp.err(maybe_colon, .malformed_embed_param); + continue; + }, + }; + + const start: u32 = @intCast(pp.token_buf.items.len); + while (true) { + const next = tokenizer.nextNoWS(); + if (next.id == .r_paren) break; + if (next.id == .eof) { + try pp.err(maybe_colon, .malformed_embed_param); + break; + } + try pp.token_buf.append(next); + } + const end: u32 = @intCast(pp.token_buf.items.len); + + if (std.mem.eql(u8, param, "limit")) { + if (limit != null) { + try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "limit"); + continue; + } + if (start + 1 != end) { + try pp.err(param_first, .malformed_embed_limit); + continue; + } + const limit_tok = pp.token_buf.items[start]; + if (limit_tok.id != .pp_num) { + try pp.err(param_first, .malformed_embed_limit); + continue; + } + limit = std.fmt.parseInt(u32, pp.tokSlice(limit_tok), 10) catch { + try pp.err(limit_tok, .malformed_embed_limit); + continue; + }; + pp.token_buf.items.len = start; + } else if (std.mem.eql(u8, param, "prefix")) { + if (prefix != null) { + try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "prefix"); + continue; + } + prefix = .{ .start = start, .end = end }; + } else if (std.mem.eql(u8, param, "suffix")) { + if (suffix != null) { + try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "suffix"); + continue; + } + suffix = .{ .start = start, .end = end }; + } else if (std.mem.eql(u8, param, "if_empty")) { + if (if_empty != null) { + try pp.errStr(tokFromRaw(param_first), .duplicate_embed_param, "if_empty"); + continue; + } + if_empty = .{ .start = start, .end = end }; + } else { + try pp.errStr( + tokFromRaw(param_first), + .unsupported_embed_param, + try pp.comp.diagnostics.arena.allocator().dupe(u8, param), + ); + pp.token_buf.items.len = start; + } + } + + const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type, limit)) orelse + return pp.fatalNotFound(filename_tok, filename); + defer pp.comp.gpa.free(embed_bytes); + + try Range.expand(prefix, pp, tokenizer); + + if (embed_bytes.len == 0) { + try Range.expand(if_empty, pp, tokenizer); + try Range.expand(suffix, pp, tokenizer); + return; + } + + try pp.ensureUnusedTokenCapacity(2 * embed_bytes.len - 1); // N bytes and N-1 commas + + // TODO: We currently only support systems with CHAR_BIT == 8 + // If the target's CHAR_BIT is not 8, we need to write out correctly-sized embed_bytes + // and correctly account for the target's endianness + const writer = pp.comp.generated_buf.writer(pp.gpa); + + { + const byte = embed_bytes[0]; + const start = pp.comp.generated_buf.items.len; + try writer.print("{d}", .{byte}); + pp.addTokenAssumeCapacity(try pp.makeGeneratedToken(start, .embed_byte, filename_tok)); + } + + for (embed_bytes[1..]) |byte| { + const start = pp.comp.generated_buf.items.len; + try writer.print(",{d}", .{byte}); + pp.addTokenAssumeCapacity(.{ .id = .comma, .loc = .{ .id = .generated, .byte_offset = @intCast(start) } }); + pp.addTokenAssumeCapacity(try pp.makeGeneratedToken(start + 1, .embed_byte, filename_tok)); + } + try pp.comp.generated_buf.append(pp.gpa, '\n'); + + try Range.expand(suffix, pp, tokenizer); +} + +// Handle a #include directive. +fn include(pp: *Preprocessor, tokenizer: *Tokenizer, which: Compilation.WhichInclude) MacroError!void { + const first = tokenizer.nextNoWS(); + const new_source = findIncludeSource(pp, tokenizer, first, which) catch |er| switch (er) { + error.InvalidInclude => return, + else => |e| return e, + }; + + // Prevent stack overflow + pp.include_depth += 1; + defer pp.include_depth -= 1; + if (pp.include_depth > max_include_depth) { + try pp.comp.addDiagnostic(.{ + .tag = .too_many_includes, + .loc = .{ .id = first.source, .byte_offset = first.start, .line = first.line }, + }, &.{}); + return error.StopPreprocessing; + } + + if (pp.include_guards.get(new_source.id)) |guard| { + if (pp.defines.contains(guard)) return; + } + + if (pp.verbose) { + pp.verboseLog(first, "include file {s}", .{new_source.path}); + } + + const token_state = pp.getTokenState(); + try pp.addIncludeStart(new_source); + const eof = pp.preprocessExtra(new_source) catch |er| switch (er) { + error.StopPreprocessing => { + for (pp.expansion_entries.items(.locs)[token_state.expansion_entries_len..]) |loc| TokenWithExpansionLocs.free(loc, pp.gpa); + pp.restoreTokenState(token_state); + return; + }, + else => |e| return e, + }; + try eof.checkMsEof(new_source, pp.comp); + if (pp.preserve_whitespace and pp.tokens.items(.id)[pp.tokens.len - 1] != .nl) { + try pp.addToken(.{ .id = .nl, .loc = .{ + .id = tokenizer.source, + .line = tokenizer.line, + } }); + } + if (pp.linemarkers == .none) return; + var next = first; + while (true) { + var tmp = tokenizer.*; + next = tmp.nextNoWS(); + if (next.id != .nl) break; + tokenizer.* = tmp; + } + try pp.addIncludeResume(next.source, next.end, next.line); +} + +/// tokens that are part of a pragma directive can happen in 3 ways: +/// 1. directly in the text via `#pragma ...` +/// 2. Via a string literal argument to `_Pragma` +/// 3. Via a stringified macro argument which is used as an argument to `_Pragma` +/// operator_loc: Location of `_Pragma`; null if this is from #pragma +/// arg_locs: expansion locations of the argument to _Pragma. empty if #pragma or a raw string literal was used +fn makePragmaToken(pp: *Preprocessor, raw: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !TokenWithExpansionLocs { + var tok = tokFromRaw(raw); + if (operator_loc) |loc| { + try tok.addExpansionLocation(pp.gpa, &.{loc}); + } + try tok.addExpansionLocation(pp.gpa, arg_locs); + return tok; +} + +pub fn addToken(pp: *Preprocessor, tok: TokenWithExpansionLocs) !void { + if (tok.expansion_locs) |expansion_locs| { + try pp.expansion_entries.append(pp.gpa, .{ .idx = @intCast(pp.tokens.len), .locs = expansion_locs }); + } + try pp.tokens.append(pp.gpa, .{ .id = tok.id, .loc = tok.loc }); +} + +pub fn addTokenAssumeCapacity(pp: *Preprocessor, tok: TokenWithExpansionLocs) void { + if (tok.expansion_locs) |expansion_locs| { + pp.expansion_entries.appendAssumeCapacity(.{ .idx = @intCast(pp.tokens.len), .locs = expansion_locs }); + } + pp.tokens.appendAssumeCapacity(.{ .id = tok.id, .loc = tok.loc }); +} + +pub fn ensureTotalTokenCapacity(pp: *Preprocessor, capacity: usize) !void { + try pp.tokens.ensureTotalCapacity(pp.gpa, capacity); + try pp.expansion_entries.ensureTotalCapacity(pp.gpa, capacity); +} + +pub fn ensureUnusedTokenCapacity(pp: *Preprocessor, capacity: usize) !void { + try pp.tokens.ensureUnusedCapacity(pp.gpa, capacity); + try pp.expansion_entries.ensureUnusedCapacity(pp.gpa, capacity); +} + +/// Handle a pragma directive +fn pragma(pp: *Preprocessor, tokenizer: *Tokenizer, pragma_tok: RawToken, operator_loc: ?Source.Location, arg_locs: []const Source.Location) !void { + const name_tok = tokenizer.nextNoWS(); + if (name_tok.id == .nl or name_tok.id == .eof) return; + + const name = pp.tokSlice(name_tok); + try pp.addToken(try pp.makePragmaToken(pragma_tok, operator_loc, arg_locs)); + const pragma_start: u32 = @intCast(pp.tokens.len); + + const pragma_name_tok = try pp.makePragmaToken(name_tok, operator_loc, arg_locs); + try pp.addToken(pragma_name_tok); + while (true) { + const next_tok = tokenizer.next(); + if (next_tok.id == .whitespace) continue; + if (next_tok.id == .eof) { + try pp.addToken(.{ + .id = .nl, + .loc = .{ .id = .generated }, + }); + break; + } + try pp.addToken(try pp.makePragmaToken(next_tok, operator_loc, arg_locs)); + if (next_tok.id == .nl) break; + } + if (pp.comp.getPragma(name)) |prag| unknown: { + return prag.preprocessorCB(pp, pragma_start) catch |er| switch (er) { + error.UnknownPragma => break :unknown, + else => |e| return e, + }; + } + return pp.comp.addDiagnostic(.{ + .tag = .unknown_pragma, + .loc = pragma_name_tok.loc, + }, pragma_name_tok.expansionSlice()); +} + +fn findIncludeFilenameToken( + pp: *Preprocessor, + first_token: RawToken, + tokenizer: *Tokenizer, + trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof }, +) !TokenWithExpansionLocs { + var first = first_token; + + if (first.id == .angle_bracket_left) to_end: { + // The tokenizer does not handle include strings so do it here. + while (tokenizer.index < tokenizer.buf.len) : (tokenizer.index += 1) { + switch (tokenizer.buf[tokenizer.index]) { + '>' => { + tokenizer.index += 1; + first.end = tokenizer.index; + first.id = .macro_string; + break :to_end; + }, + '\n' => break, + else => {}, + } + } + try pp.comp.addDiagnostic(.{ + .tag = .header_str_closing, + .loc = .{ .id = first.source, .byte_offset = tokenizer.index, .line = first.line }, + }, &.{}); + try pp.err(first, .header_str_match); + } + + const source_tok = tokFromRaw(first); + const filename_tok, const expanded_trailing = switch (source_tok.id) { + .string_literal, .macro_string => .{ source_tok, false }, + else => expanded: { + // Try to expand if the argument is a macro. + pp.top_expansion_buf.items.len = 0; + defer for (pp.top_expansion_buf.items) |tok| TokenWithExpansionLocs.free(tok.expansion_locs, pp.gpa); + try pp.top_expansion_buf.append(source_tok); + pp.expansion_source_loc = source_tok.loc; + + try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr); + var trailing_toks: []const TokenWithExpansionLocs = &.{}; + const include_str = (try pp.reconstructIncludeString(pp.top_expansion_buf.items, &trailing_toks, tokFromRaw(first))) orelse { + try pp.expectNl(tokenizer); + return error.InvalidInclude; + }; + const start = pp.comp.generated_buf.items.len; + try pp.comp.generated_buf.appendSlice(pp.gpa, include_str); + + break :expanded .{ try pp.makeGeneratedToken(start, switch (include_str[0]) { + '"' => .string_literal, + '<' => .macro_string, + else => unreachable, + }, pp.top_expansion_buf.items[0]), trailing_toks.len != 0 }; + }, + }; + + switch (trailing_token_behavior) { + .expect_nl_eof => { + // Error on extra tokens. + const nl = tokenizer.nextNoWS(); + if ((nl.id != .nl and nl.id != .eof) or expanded_trailing) { + skipToNl(tokenizer); + try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ + .tag = .extra_tokens_directive_end, + .loc = filename_tok.loc, + }, filename_tok.expansionSlice(), false); + } + }, + .ignore_trailing_tokens => if (expanded_trailing) { + try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ + .tag = .extra_tokens_directive_end, + .loc = filename_tok.loc, + }, filename_tok.expansionSlice(), false); + }, + } + return filename_tok; +} + +fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source { + const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof); + defer TokenWithExpansionLocs.free(filename_tok.expansion_locs, pp.gpa); + + // Check for empty filename. + const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws); + if (tok_slice.len < 3) { + try pp.err(first, .empty_filename); + return error.InvalidInclude; + } + + // Find the file. + const filename = tok_slice[1 .. tok_slice.len - 1]; + const include_type: Compilation.IncludeType = switch (filename_tok.id) { + .string_literal => .quotes, + .macro_string => .angle_brackets, + else => unreachable, + }; + + return (try pp.comp.findInclude(filename, first, include_type, which)) orelse + return pp.fatalNotFound(filename_tok, filename); +} + +fn printLinemarker( + pp: *Preprocessor, + w: anytype, + line_no: u32, + source: Source, + start_resume: enum(u8) { start, @"resume", none }, +) !void { + try w.writeByte('#'); + if (pp.linemarkers == .line_directives) try w.writeAll("line"); + try w.print(" {d} \"", .{line_no}); + for (source.path) |byte| switch (byte) { + '\n' => try w.writeAll("\\n"), + '\r' => try w.writeAll("\\r"), + '\t' => try w.writeAll("\\t"), + '\\' => try w.writeAll("\\\\"), + '"' => try w.writeAll("\\\""), + ' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte), + // Use hex escapes for any non-ASCII/unprintable characters. + // This ensures that the parsed version of this string will end up + // containing the same bytes as the input regardless of encoding. + else => { + try w.writeAll("\\x"); + try std.fmt.formatInt(byte, 16, .lower, .{ .width = 2, .fill = '0' }, w); + }, + }; + try w.writeByte('"'); + if (pp.linemarkers == .numeric_directives) { + switch (start_resume) { + .none => {}, + .start => try w.writeAll(" 1"), + .@"resume" => try w.writeAll(" 2"), + } + switch (source.kind) { + .user => {}, + .system => try w.writeAll(" 3"), + .extern_c_system => try w.writeAll(" 3 4"), + } + } + try w.writeByte('\n'); +} + +// After how many empty lines are needed to replace them with linemarkers. +const collapse_newlines = 8; + +pub const DumpMode = enum { + /// Standard preprocessor output; no macros + result_only, + /// Output only #define directives for all the macros defined during the execution of the preprocessor + /// Only macros which are still defined at the end of preprocessing are printed. + /// Only the most recent definition is printed + /// Defines are printed in arbitrary order + macros_only, + /// Standard preprocessor output; but additionally output #define's and #undef's for macros as they are encountered + macros_and_result, + /// Same as macros_and_result, except only the macro name is printed for #define's + macro_names_and_result, +}; + +/// Pretty-print the macro define or undef at location `loc`. +/// We re-tokenize the directive because we are printing a macro that may have the same name as one in +/// `pp.defines` but a different definition (due to being #undef'ed and then redefined) +fn prettyPrintMacro(pp: *Preprocessor, w: anytype, loc: Source.Location, parts: enum { name_only, name_and_body }) !void { + const source = pp.comp.getSource(loc.id); + var tokenizer: Tokenizer = .{ + .buf = source.buf, + .langopts = pp.comp.langopts, + .source = source.id, + .index = loc.byte_offset, + }; + var prev_ws = false; // avoid printing multiple whitespace if /* */ comments are within the macro def + var saw_name = false; // do not print comments before the name token is seen. + while (true) { + const tok = tokenizer.next(); + switch (tok.id) { + .comment => { + if (saw_name) { + prev_ws = false; + try w.print("{s}", .{pp.tokSlice(tok)}); + } + }, + .nl, .eof => break, + .whitespace => { + if (!prev_ws) { + try w.writeByte(' '); + prev_ws = true; + } + }, + else => { + prev_ws = false; + try w.print("{s}", .{pp.tokSlice(tok)}); + }, + } + if (tok.id == .identifier or tok.id == .extended_identifier) { + if (parts == .name_only) break; + saw_name = true; + } + } +} + +fn prettyPrintMacrosOnly(pp: *Preprocessor, w: anytype) !void { + var it = pp.defines.valueIterator(); + while (it.next()) |macro| { + if (macro.is_builtin) continue; + + try w.writeAll("#define "); + try pp.prettyPrintMacro(w, macro.loc, .name_and_body); + try w.writeByte('\n'); + } +} + +/// Pretty print tokens and try to preserve whitespace. +pub fn prettyPrintTokens(pp: *Preprocessor, w: anytype, macro_dump_mode: DumpMode) !void { + if (macro_dump_mode == .macros_only) { + return pp.prettyPrintMacrosOnly(w); + } + + const tok_ids = pp.tokens.items(.id); + + var i: u32 = 0; + var last_nl = true; + outer: while (true) : (i += 1) { + var cur: Token = pp.tokens.get(i); + switch (cur.id) { + .eof => { + if (!last_nl) try w.writeByte('\n'); + return; + }, + .nl => { + var newlines: u32 = 0; + for (tok_ids[i..], i..) |id, j| { + if (id == .nl) { + newlines += 1; + } else if (id == .eof) { + if (!last_nl) try w.writeByte('\n'); + return; + } else if (id != .whitespace) { + if (pp.linemarkers == .none) { + if (newlines < 2) break; + } else if (newlines < collapse_newlines) { + break; + } + + i = @intCast((j - 1) - @intFromBool(tok_ids[j - 1] == .whitespace)); + if (!last_nl) try w.writeAll("\n"); + if (pp.linemarkers != .none) { + const next = pp.tokens.get(i); + const source = pp.comp.getSource(next.loc.id); + const line_col = source.lineCol(next.loc); + try pp.printLinemarker(w, line_col.line_no, source, .none); + last_nl = true; + } + continue :outer; + } + } + last_nl = true; + try w.writeAll("\n"); + }, + .keyword_pragma => { + const pragma_name = pp.expandedSlice(pp.tokens.get(i + 1)); + const end_idx = mem.indexOfScalarPos(Token.Id, tok_ids, i, .nl) orelse i + 1; + const pragma_len = @as(u32, @intCast(end_idx)) - i; + + if (pp.comp.getPragma(pragma_name)) |prag| { + if (!prag.shouldPreserveTokens(pp, i + 1)) { + try w.writeByte('\n'); + i += pragma_len; + cur = pp.tokens.get(i); + continue; + } + } + try w.writeAll("#pragma"); + i += 1; + while (true) : (i += 1) { + cur = pp.tokens.get(i); + if (cur.id == .nl) { + try w.writeByte('\n'); + last_nl = true; + break; + } + try w.writeByte(' '); + const slice = pp.expandedSlice(cur); + try w.writeAll(slice); + } + }, + .whitespace => { + var slice = pp.expandedSlice(cur); + while (mem.indexOfScalar(u8, slice, '\n')) |some| { + if (pp.linemarkers != .none) try w.writeByte('\n'); + slice = slice[some + 1 ..]; + } + for (slice) |_| try w.writeByte(' '); + last_nl = false; + }, + .include_start => { + const source = pp.comp.getSource(cur.loc.id); + + try pp.printLinemarker(w, 1, source, .start); + last_nl = true; + }, + .include_resume => { + const source = pp.comp.getSource(cur.loc.id); + const line_col = source.lineCol(cur.loc); + if (!last_nl) try w.writeAll("\n"); + + try pp.printLinemarker(w, line_col.line_no, source, .@"resume"); + last_nl = true; + }, + .keyword_define, .keyword_undef => { + switch (macro_dump_mode) { + .macros_and_result, .macro_names_and_result => { + try w.writeByte('#'); + try pp.prettyPrintMacro(w, cur.loc, if (macro_dump_mode == .macros_and_result) .name_and_body else .name_only); + last_nl = false; + }, + .result_only => unreachable, // `pp.store_macro_tokens` should be false for standard preprocessor output + .macros_only => unreachable, // handled by prettyPrintMacrosOnly + } + }, + else => { + const slice = pp.expandedSlice(cur); + try w.writeAll(slice); + last_nl = false; + }, + } + } +} + +test "Preserve pragma tokens sometimes" { + const allocator = std.testing.allocator; + const Test = struct { + fn runPreprocessor(source_text: []const u8) ![]const u8 { + var buf = std.ArrayList(u8).init(allocator); + defer buf.deinit(); + + var comp = Compilation.init(allocator, std.fs.cwd()); + defer comp.deinit(); + + try comp.addDefaultPragmaHandlers(); + + var pp = Preprocessor.init(&comp); + defer pp.deinit(); + + pp.preserve_whitespace = true; + assert(pp.linemarkers == .none); + + const test_runner_macros = try comp.addSourceFromBuffer("", source_text); + const eof = try pp.preprocess(test_runner_macros); + try pp.addToken(eof); + try pp.prettyPrintTokens(buf.writer(), .result_only); + return allocator.dupe(u8, buf.items); + } + + fn check(source_text: []const u8, expected: []const u8) !void { + const output = try runPreprocessor(source_text); + defer allocator.free(output); + + try std.testing.expectEqualStrings(expected, output); + } + }; + const preserve_gcc_diagnostic = + \\#pragma GCC diagnostic error "-Wnewline-eof" + \\#pragma GCC warning error "-Wnewline-eof" + \\int x; + \\#pragma GCC ignored error "-Wnewline-eof" + \\ + ; + try Test.check(preserve_gcc_diagnostic, preserve_gcc_diagnostic); + + const omit_once = + \\#pragma once + \\int x; + \\#pragma once + \\ + ; + // TODO should only be one newline afterwards when emulating clang + try Test.check(omit_once, "\nint x;\n\n"); + + const omit_poison = + \\#pragma GCC poison foobar + \\ + ; + try Test.check(omit_poison, "\n"); +} + +test "destringify" { + const allocator = std.testing.allocator; + const Test = struct { + fn testDestringify(pp: *Preprocessor, stringified: []const u8, destringified: []const u8) !void { + pp.char_buf.clearRetainingCapacity(); + try pp.char_buf.ensureUnusedCapacity(stringified.len); + pp.destringify(stringified); + try std.testing.expectEqualStrings(destringified, pp.char_buf.items); + } + }; + var comp = Compilation.init(allocator, std.fs.cwd()); + defer comp.deinit(); + var pp = Preprocessor.init(&comp); + defer pp.deinit(); + + try Test.testDestringify(&pp, "hello\tworld\n", "hello\tworld\n"); + try Test.testDestringify(&pp, + \\ \"FOO BAR BAZ\" + , + \\ "FOO BAR BAZ" + ); + try Test.testDestringify(&pp, + \\ \\t\\n + \\ + , + \\ \t\n + \\ + ); +} + +test "Include guards" { + const Test = struct { + /// This is here so that when #elifdef / #elifndef are added we don't forget + /// to test that they don't accidentally break include guard detection + fn pairsWithIfndef(tok_id: RawToken.Id) bool { + return switch (tok_id) { + .keyword_elif, + .keyword_elifdef, + .keyword_elifndef, + .keyword_else, + => true, + + .keyword_include, + .keyword_include_next, + .keyword_embed, + .keyword_define, + .keyword_defined, + .keyword_undef, + .keyword_ifdef, + .keyword_ifndef, + .keyword_error, + .keyword_warning, + .keyword_pragma, + .keyword_line, + .keyword_endif, + => false, + else => unreachable, + }; + } + + fn skippable(tok_id: RawToken.Id) bool { + return switch (tok_id) { + .keyword_defined, .keyword_va_args, .keyword_va_opt, .keyword_endif => true, + else => false, + }; + } + + fn testIncludeGuard(allocator: std.mem.Allocator, comptime template: []const u8, tok_id: RawToken.Id, expected_guards: u32) !void { + var comp = Compilation.init(allocator, std.fs.cwd()); + defer comp.deinit(); + var pp = Preprocessor.init(&comp); + defer pp.deinit(); + + const path = try std.fs.path.join(allocator, &.{ ".", "bar.h" }); + defer allocator.free(path); + + _ = try comp.addSourceFromBuffer(path, "int bar = 5;\n"); + + var buf = std.ArrayList(u8).init(allocator); + defer buf.deinit(); + + var writer = buf.writer(); + switch (tok_id) { + .keyword_include, .keyword_include_next => try writer.print(template, .{ tok_id.lexeme().?, " \"bar.h\"" }), + .keyword_define, .keyword_undef => try writer.print(template, .{ tok_id.lexeme().?, " BAR" }), + .keyword_ifndef, + .keyword_ifdef, + .keyword_elifdef, + .keyword_elifndef, + => try writer.print(template, .{ tok_id.lexeme().?, " BAR\n#endif" }), + else => try writer.print(template, .{ tok_id.lexeme().?, "" }), + } + const source = try comp.addSourceFromBuffer("test.h", buf.items); + _ = try pp.preprocess(source); + + try std.testing.expectEqual(expected_guards, pp.include_guards.count()); + } + }; + const tags = std.meta.tags(RawToken.Id); + for (tags) |tag| { + if (Test.skippable(tag)) continue; + var copy = tag; + copy.simplifyMacroKeyword(); + if (copy != tag or tag == .keyword_else) { + const inside_ifndef_template = + \\//Leading comment (should be ignored) + \\ + \\#ifndef FOO + \\#{s}{s} + \\#endif + ; + const expected_guards: u32 = if (Test.pairsWithIfndef(tag)) 0 else 1; + try Test.testIncludeGuard(std.testing.allocator, inside_ifndef_template, tag, expected_guards); + + const outside_ifndef_template = + \\#ifndef FOO + \\#endif + \\#{s}{s} + ; + try Test.testIncludeGuard(std.testing.allocator, outside_ifndef_template, tag, 0); + } + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Source.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Source.zig new file mode 100644 index 00000000..20788af2 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Source.zig @@ -0,0 +1,137 @@ +const std = @import("std"); + +pub const Id = enum(u32) { + unused = 0, + generated = 1, + _, +}; + +/// Classifies the file for line marker output in -E mode +pub const Kind = enum { + /// regular file + user, + /// Included from a system include directory + system, + /// Included from an "implicit extern C" directory + extern_c_system, +}; + +pub const Location = struct { + id: Id = .unused, + byte_offset: u32 = 0, + line: u32 = 0, + + pub fn eql(a: Location, b: Location) bool { + return a.id == b.id and a.byte_offset == b.byte_offset and a.line == b.line; + } +}; + +const Source = @This(); + +path: []const u8, +buf: []const u8, +id: Id, +/// each entry represents a byte position within `buf` where a backslash+newline was deleted +/// from the original raw buffer. The same position can appear multiple times if multiple +/// consecutive splices happened. Guaranteed to be non-decreasing +splice_locs: []const u32, +kind: Kind, + +/// Todo: binary search instead of scanning entire `splice_locs`. +pub fn numSplicesBefore(source: Source, byte_offset: u32) u32 { + for (source.splice_locs, 0..) |splice_offset, i| { + if (splice_offset > byte_offset) return @intCast(i); + } + return @intCast(source.splice_locs.len); +} + +/// Returns the actual line number (before newline splicing) of a Location +/// This corresponds to what the user would actually see in their text editor +pub fn physicalLine(source: Source, loc: Location) u32 { + return loc.line + source.numSplicesBefore(loc.byte_offset); +} + +const LineCol = struct { line: []const u8, line_no: u32, col: u32, width: u32, end_with_splice: bool }; + +pub fn lineCol(source: Source, loc: Location) LineCol { + var start: usize = 0; + // find the start of the line which is either a newline or a splice + if (std.mem.lastIndexOfScalar(u8, source.buf[0..loc.byte_offset], '\n')) |some| start = some + 1; + const splice_index: u32 = for (source.splice_locs, 0..) |splice_offset, i| { + if (splice_offset > start) { + if (splice_offset < loc.byte_offset) { + start = splice_offset; + break @as(u32, @intCast(i)) + 1; + } + break @intCast(i); + } + } else @intCast(source.splice_locs.len); + var i: usize = start; + var col: u32 = 1; + var width: u32 = 0; + + while (i < loc.byte_offset) : (col += 1) { // TODO this is still incorrect, but better + const len = std.unicode.utf8ByteSequenceLength(source.buf[i]) catch { + i += 1; + continue; + }; + const slice = source.buf[i..]; + if (len > slice.len) { + break; + } + const cp = switch (len) { + 1 => slice[0], + 2 => std.unicode.utf8Decode2(slice[0..2].*), + 3 => std.unicode.utf8Decode3(slice[0..3].*), + 4 => std.unicode.utf8Decode4(slice[0..4].*), + else => unreachable, + } catch { + i += 1; + continue; + }; + width += codepointWidth(cp); + i += len; + } + + // find the end of the line which is either a newline, EOF or a splice + var nl = source.buf.len; + var end_with_splice = false; + if (std.mem.indexOfScalar(u8, source.buf[start..], '\n')) |some| nl = some + start; + if (source.splice_locs.len > splice_index and nl > source.splice_locs[splice_index] and source.splice_locs[splice_index] > start) { + end_with_splice = true; + nl = source.splice_locs[splice_index]; + } + return .{ + .line = source.buf[start..nl], + .line_no = loc.line + splice_index, + .col = col, + .width = width, + .end_with_splice = end_with_splice, + }; +} + +fn codepointWidth(cp: u32) u32 { + return switch (cp) { + 0x1100...0x115F, + 0x2329, + 0x232A, + 0x2E80...0x303F, + 0x3040...0x3247, + 0x3250...0x4DBF, + 0x4E00...0xA4C6, + 0xA960...0xA97C, + 0xAC00...0xD7A3, + 0xF900...0xFAFF, + 0xFE10...0xFE19, + 0xFE30...0xFE6B, + 0xFF01...0xFF60, + 0xFFE0...0xFFE6, + 0x1B000...0x1B001, + 0x1F200...0x1F251, + 0x20000...0x3FFFD, + 0x1F300...0x1F5FF, + 0x1F900...0x1F9FF, + => 2, + else => 1, + }; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/StringInterner.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/StringInterner.zig new file mode 100644 index 00000000..b6e0cd79 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/StringInterner.zig @@ -0,0 +1,83 @@ +const std = @import("std"); +const mem = std.mem; +const Compilation = @import("Compilation.zig"); + +const StringToIdMap = std.StringHashMapUnmanaged(StringId); + +pub const StringId = enum(u32) { + empty, + _, +}; + +pub const TypeMapper = struct { + const LookupSpeed = enum { + fast, + slow, + }; + + data: union(LookupSpeed) { + fast: []const []const u8, + slow: *const StringToIdMap, + }, + + pub fn lookup(self: TypeMapper, string_id: StringInterner.StringId) []const u8 { + if (string_id == .empty) return ""; + switch (self.data) { + .fast => |arr| return arr[@intFromEnum(string_id)], + .slow => |map| { + var it = map.iterator(); + while (it.next()) |entry| { + if (entry.value_ptr.* == string_id) return entry.key_ptr.*; + } + unreachable; + }, + } + } + + pub fn deinit(self: TypeMapper, allocator: mem.Allocator) void { + switch (self.data) { + .slow => {}, + .fast => |arr| allocator.free(arr), + } + } +}; + +const StringInterner = @This(); + +string_table: StringToIdMap = .{}, +next_id: StringId = @enumFromInt(@intFromEnum(StringId.empty) + 1), + +pub fn deinit(self: *StringInterner, allocator: mem.Allocator) void { + self.string_table.deinit(allocator); +} + +pub fn intern(comp: *Compilation, str: []const u8) !StringId { + return comp.string_interner.internExtra(comp.gpa, str); +} + +pub fn internExtra(self: *StringInterner, allocator: mem.Allocator, str: []const u8) !StringId { + if (str.len == 0) return .empty; + + const gop = try self.string_table.getOrPut(allocator, str); + if (gop.found_existing) return gop.value_ptr.*; + + defer self.next_id = @enumFromInt(@intFromEnum(self.next_id) + 1); + gop.value_ptr.* = self.next_id; + return self.next_id; +} + +/// deinit for the returned TypeMapper is a no-op and does not need to be called +pub fn getSlowTypeMapper(self: *const StringInterner) TypeMapper { + return TypeMapper{ .data = .{ .slow = &self.string_table } }; +} + +/// Caller must call `deinit` on the returned TypeMapper +pub fn getFastTypeMapper(self: *const StringInterner, allocator: mem.Allocator) !TypeMapper { + var strings = try allocator.alloc([]const u8, @intFromEnum(self.next_id)); + var it = self.string_table.iterator(); + strings[0] = ""; + while (it.next()) |entry| { + strings[@intFromEnum(entry.value_ptr.*)] = entry.key_ptr.*; + } + return TypeMapper{ .data = .{ .fast = strings } }; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/SymbolStack.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/SymbolStack.zig new file mode 100644 index 00000000..4c01e3d3 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/SymbolStack.zig @@ -0,0 +1,399 @@ +const std = @import("std"); +const mem = std.mem; +const Allocator = mem.Allocator; +const assert = std.debug.assert; +const Tree = @import("Tree.zig"); +const Token = Tree.Token; +const TokenIndex = Tree.TokenIndex; +const NodeIndex = Tree.NodeIndex; +const Type = @import("Type.zig"); +const Parser = @import("Parser.zig"); +const Value = @import("Value.zig"); +const StringId = @import("StringInterner.zig").StringId; + +const SymbolStack = @This(); + +pub const Symbol = struct { + name: StringId, + ty: Type, + tok: TokenIndex, + node: NodeIndex = .none, + kind: Kind, + val: Value, +}; + +pub const Kind = enum { + typedef, + @"struct", + @"union", + @"enum", + decl, + def, + enumeration, + constexpr, +}; + +scopes: std.ArrayListUnmanaged(Scope) = .empty, +/// allocations from nested scopes are retained after popping; `active_len` is the number +/// of currently-active items in `scopes`. +active_len: usize = 0, + +const Scope = struct { + vars: std.AutoHashMapUnmanaged(StringId, Symbol) = .empty, + tags: std.AutoHashMapUnmanaged(StringId, Symbol) = .empty, + + fn deinit(self: *Scope, allocator: Allocator) void { + self.vars.deinit(allocator); + self.tags.deinit(allocator); + } + + fn clearRetainingCapacity(self: *Scope) void { + self.vars.clearRetainingCapacity(); + self.tags.clearRetainingCapacity(); + } +}; + +pub fn deinit(s: *SymbolStack, gpa: Allocator) void { + std.debug.assert(s.active_len == 0); // all scopes should have been popped + for (s.scopes.items) |*scope| { + scope.deinit(gpa); + } + s.scopes.deinit(gpa); + s.* = undefined; +} + +pub fn pushScope(s: *SymbolStack, p: *Parser) !void { + if (s.active_len + 1 > s.scopes.items.len) { + try s.scopes.append(p.gpa, .{}); + s.active_len = s.scopes.items.len; + } else { + s.scopes.items[s.active_len].clearRetainingCapacity(); + s.active_len += 1; + } +} + +pub fn popScope(s: *SymbolStack) void { + s.active_len -= 1; +} + +pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol { + const prev = s.lookup(name, .vars) orelse s.lookup(name, .tags) orelse return null; + switch (prev.kind) { + .typedef => return prev, + .@"struct" => { + if (no_type_yet) return null; + try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok)); + return prev; + }, + .@"union" => { + if (no_type_yet) return null; + try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok)); + return prev; + }, + .@"enum" => { + if (no_type_yet) return null; + try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok)); + return prev; + }, + else => return null, + } +} + +pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol { + return s.lookup(name, .vars); +} + +pub fn findTag( + s: *SymbolStack, + p: *Parser, + name: StringId, + kind: Token.Id, + name_tok: TokenIndex, + next_tok_id: Token.Id, +) !?Symbol { + // `tag Name;` should always result in a new type if in a new scope. + const prev = (if (next_tok_id == .semicolon) s.get(name, .tags) else s.lookup(name, .tags)) orelse return null; + switch (prev.kind) { + .@"enum" => if (kind == .keyword_enum) return prev, + .@"struct" => if (kind == .keyword_struct) return prev, + .@"union" => if (kind == .keyword_union) return prev, + else => unreachable, + } + if (s.get(name, .tags) == null) return null; + try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok)); + try p.errTok(.previous_definition, prev.tok); + return null; +} + +const ScopeKind = enum { + /// structs, enums, unions + tags, + /// everything else + vars, +}; + +/// Return the Symbol for `name` (or null if not found) in the innermost scope +pub fn get(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol { + return switch (kind) { + .vars => s.scopes.items[s.active_len - 1].vars.get(name), + .tags => s.scopes.items[s.active_len - 1].tags.get(name), + }; +} + +/// Return the Symbol for `name` (or null if not found) in the nearest active scope, +/// starting at the innermost. +fn lookup(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol { + var i = s.active_len; + while (i > 0) { + i -= 1; + switch (kind) { + .vars => if (s.scopes.items[i].vars.get(name)) |sym| return sym, + .tags => if (s.scopes.items[i].tags.get(name)) |sym| return sym, + } + } + return null; +} + +/// Define a symbol in the innermost scope. Does not issue diagnostics or check correctness +/// with regard to the C standard. +pub fn define(s: *SymbolStack, allocator: Allocator, symbol: Symbol) !void { + switch (symbol.kind) { + .constexpr, .def, .decl, .enumeration, .typedef => { + try s.scopes.items[s.active_len - 1].vars.put(allocator, symbol.name, symbol); + }, + .@"struct", .@"union", .@"enum" => { + try s.scopes.items[s.active_len - 1].tags.put(allocator, symbol.name, symbol); + }, + } +} + +pub fn defineTypedef( + s: *SymbolStack, + p: *Parser, + name: StringId, + ty: Type, + tok: TokenIndex, + node: NodeIndex, +) !void { + if (s.get(name, .vars)) |prev| { + switch (prev.kind) { + .typedef => { + if (!prev.ty.is(.invalid)) { + if (!ty.eql(prev.ty, p.comp, true)) { + try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev.ty)); + if (prev.tok != 0) try p.errTok(.previous_definition, prev.tok); + } + } + }, + .enumeration, .decl, .def, .constexpr => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + else => unreachable, + } + } + try s.define(p.gpa, .{ + .kind = .typedef, + .name = name, + .tok = tok, + .ty = .{ + .name = name, + .specifier = ty.specifier, + .qual = ty.qual, + .data = ty.data, + }, + .node = node, + .val = .{}, + }); +} + +pub fn defineSymbol( + s: *SymbolStack, + p: *Parser, + name: StringId, + ty: Type, + tok: TokenIndex, + node: NodeIndex, + val: Value, + constexpr: bool, +) !void { + if (s.get(name, .vars)) |prev| { + switch (prev.kind) { + .enumeration => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + .decl => { + if (!ty.eql(prev.ty, p.comp, true)) { + try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + } + }, + .def, .constexpr => { + try p.errStr(.redefinition, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + .typedef => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + else => unreachable, + } + } + + try s.define(p.gpa, .{ + .kind = if (constexpr) .constexpr else .def, + .name = name, + .tok = tok, + .ty = ty, + .node = node, + .val = val, + }); +} + +/// Get a pointer to the named symbol in the innermost scope. +/// Asserts that a symbol with the name exists. +pub fn getPtr(s: *SymbolStack, name: StringId, kind: ScopeKind) *Symbol { + return switch (kind) { + .tags => s.scopes.items[s.active_len - 1].tags.getPtr(name).?, + .vars => s.scopes.items[s.active_len - 1].vars.getPtr(name).?, + }; +} + +pub fn declareSymbol( + s: *SymbolStack, + p: *Parser, + name: StringId, + ty: Type, + tok: TokenIndex, + node: NodeIndex, +) !void { + if (s.get(name, .vars)) |prev| { + switch (prev.kind) { + .enumeration => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + .decl => { + if (!ty.eql(prev.ty, p.comp, true)) { + try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + } + }, + .def, .constexpr => { + if (!ty.eql(prev.ty, p.comp, true)) { + try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + } else { + return; + } + }, + .typedef => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + else => unreachable, + } + } + try s.define(p.gpa, .{ + .kind = .decl, + .name = name, + .tok = tok, + .ty = ty, + .node = node, + .val = .{}, + }); +} + +pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void { + if (s.get(name, .vars)) |prev| { + switch (prev.kind) { + .enumeration, .decl, .def, .constexpr => { + try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + .typedef => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + else => unreachable, + } + } + if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) { + try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters"); + } + try s.define(p.gpa, .{ + .kind = .def, + .name = name, + .tok = tok, + .ty = ty, + .val = .{}, + }); +} + +pub fn defineTag( + s: *SymbolStack, + p: *Parser, + name: StringId, + kind: Token.Id, + tok: TokenIndex, +) !?Symbol { + const prev = s.get(name, .tags) orelse return null; + switch (prev.kind) { + .@"enum" => { + if (kind == .keyword_enum) return prev; + try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + return null; + }, + .@"struct" => { + if (kind == .keyword_struct) return prev; + try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + return null; + }, + .@"union" => { + if (kind == .keyword_union) return prev; + try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + return null; + }, + else => unreachable, + } +} + +pub fn defineEnumeration( + s: *SymbolStack, + p: *Parser, + name: StringId, + ty: Type, + tok: TokenIndex, + val: Value, +) !void { + if (s.get(name, .vars)) |prev| { + switch (prev.kind) { + .enumeration => { + try p.errStr(.redefinition, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + return; + }, + .decl, .def, .constexpr => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + return; + }, + .typedef => { + try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); + try p.errTok(.previous_definition, prev.tok); + }, + else => unreachable, + } + } + try s.define(p.gpa, .{ + .kind = .enumeration, + .name = name, + .tok = tok, + .ty = ty, + .val = val, + }); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tokenizer.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tokenizer.zig new file mode 100644 index 00000000..f703940f --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tokenizer.zig @@ -0,0 +1,2204 @@ +const std = @import("std"); +const assert = std.debug.assert; +const Compilation = @import("Compilation.zig"); +const Source = @import("Source.zig"); +const LangOpts = @import("LangOpts.zig"); + +pub const Token = struct { + id: Id, + source: Source.Id, + start: u32 = 0, + end: u32 = 0, + line: u32 = 0, + + pub const Id = enum(u8) { + invalid, + nl, + whitespace, + eof, + /// identifier containing solely basic character set characters + identifier, + /// identifier with at least one extended character + extended_identifier, + + // string literals with prefixes + string_literal, + string_literal_utf_16, + string_literal_utf_8, + string_literal_utf_32, + string_literal_wide, + + /// Any string literal with an embedded newline or EOF + /// Always a parser error; by default just a warning from preprocessor + unterminated_string_literal, + + // only generated by preprocessor + macro_string, + + // char literals with prefixes + char_literal, + char_literal_utf_8, + char_literal_utf_16, + char_literal_utf_32, + char_literal_wide, + + /// Any character literal with nothing inside the quotes + /// Always a parser error; by default just a warning from preprocessor + empty_char_literal, + + /// Any character literal with an embedded newline or EOF + /// Always a parser error; by default just a warning from preprocessor + unterminated_char_literal, + + /// `/* */` style comment without a closing `*/` before EOF + unterminated_comment, + + /// Integer literal tokens generated by preprocessor. + one, + zero, + + bang, + bang_equal, + pipe, + pipe_pipe, + pipe_equal, + equal, + equal_equal, + l_paren, + r_paren, + l_brace, + r_brace, + l_bracket, + r_bracket, + period, + ellipsis, + caret, + caret_equal, + plus, + plus_plus, + plus_equal, + minus, + minus_minus, + minus_equal, + asterisk, + asterisk_equal, + percent, + percent_equal, + arrow, + colon, + colon_colon, + semicolon, + slash, + slash_equal, + comma, + ampersand, + ampersand_ampersand, + ampersand_equal, + question_mark, + angle_bracket_left, + angle_bracket_left_equal, + angle_bracket_angle_bracket_left, + angle_bracket_angle_bracket_left_equal, + angle_bracket_right, + angle_bracket_right_equal, + angle_bracket_angle_bracket_right, + angle_bracket_angle_bracket_right_equal, + tilde, + hash, + hash_hash, + + /// Special token to speed up preprocessing, `loc.end` will be an index to the param list. + macro_param, + /// Special token to signal that the argument must be replaced without expansion (e.g. in concatenation) + macro_param_no_expand, + /// Special token to speed up preprocessing, `loc.end` will be an index to the param list. + stringify_param, + /// Same as stringify_param, but for var args + stringify_va_args, + /// Special macro whitespace, always equal to a single space + macro_ws, + /// Special token for implementing __has_attribute + macro_param_has_attribute, + /// Special token for implementing __has_c_attribute + macro_param_has_c_attribute, + /// Special token for implementing __has_declspec_attribute + macro_param_has_declspec_attribute, + /// Special token for implementing __has_warning + macro_param_has_warning, + /// Special token for implementing __has_feature + macro_param_has_feature, + /// Special token for implementing __has_extension + macro_param_has_extension, + /// Special token for implementing __has_builtin + macro_param_has_builtin, + /// Special token for implementing __has_include + macro_param_has_include, + /// Special token for implementing __has_include_next + macro_param_has_include_next, + /// Special token for implementing __has_embed + macro_param_has_embed, + /// Special token for implementing __is_identifier + macro_param_is_identifier, + /// Special token for implementing __FILE__ + macro_file, + /// Special token for implementing __LINE__ + macro_line, + /// Special token for implementing __COUNTER__ + macro_counter, + /// Special token for implementing _Pragma + macro_param_pragma_operator, + + /// Special identifier for implementing __func__ + macro_func, + /// Special identifier for implementing __FUNCTION__ + macro_function, + /// Special identifier for implementing __PRETTY_FUNCTION__ + macro_pretty_func, + + keyword_auto, + keyword_auto_type, + keyword_break, + keyword_case, + keyword_char, + keyword_const, + keyword_continue, + keyword_default, + keyword_do, + keyword_double, + keyword_else, + keyword_enum, + keyword_extern, + keyword_float, + keyword_for, + keyword_goto, + keyword_if, + keyword_int, + keyword_long, + keyword_register, + keyword_return, + keyword_short, + keyword_signed, + keyword_signed1, + keyword_signed2, + keyword_sizeof, + keyword_static, + keyword_struct, + keyword_switch, + keyword_typedef, + keyword_typeof1, + keyword_typeof2, + keyword_union, + keyword_unsigned, + keyword_void, + keyword_volatile, + keyword_while, + + // ISO C99 + keyword_bool, + keyword_complex, + keyword_imaginary, + keyword_inline, + keyword_restrict, + + // ISO C11 + keyword_alignas, + keyword_alignof, + keyword_atomic, + keyword_generic, + keyword_noreturn, + keyword_static_assert, + keyword_thread_local, + + // ISO C23 + keyword_bit_int, + keyword_c23_alignas, + keyword_c23_alignof, + keyword_c23_bool, + keyword_c23_static_assert, + keyword_c23_thread_local, + keyword_constexpr, + keyword_true, + keyword_false, + keyword_nullptr, + keyword_typeof_unqual, + + // Preprocessor directives + keyword_include, + keyword_include_next, + keyword_embed, + keyword_define, + keyword_defined, + keyword_undef, + keyword_ifdef, + keyword_ifndef, + keyword_elif, + keyword_elifdef, + keyword_elifndef, + keyword_endif, + keyword_error, + keyword_warning, + keyword_pragma, + keyword_line, + keyword_va_args, + keyword_va_opt, + + // gcc keywords + keyword_const1, + keyword_const2, + keyword_inline1, + keyword_inline2, + keyword_volatile1, + keyword_volatile2, + keyword_restrict1, + keyword_restrict2, + keyword_alignof1, + keyword_alignof2, + keyword_typeof, + keyword_attribute1, + keyword_attribute2, + keyword_extension, + keyword_asm, + keyword_asm1, + keyword_asm2, + /// _Float128 + keyword_float128_1, + /// __float128 + keyword_float128_2, + keyword_int128, + keyword_imag1, + keyword_imag2, + keyword_real1, + keyword_real2, + keyword_float16, + + // clang keywords + keyword_fp16, + + // ms keywords + keyword_declspec, + keyword_int64, + keyword_int64_2, + keyword_int32, + keyword_int32_2, + keyword_int16, + keyword_int16_2, + keyword_int8, + keyword_int8_2, + keyword_stdcall, + keyword_stdcall2, + keyword_thiscall, + keyword_thiscall2, + keyword_vectorcall, + keyword_vectorcall2, + + // builtins that require special parsing + builtin_choose_expr, + builtin_va_arg, + builtin_offsetof, + builtin_bitoffsetof, + builtin_types_compatible_p, + + /// Generated by #embed directive + /// Decimal value with no prefix or suffix + embed_byte, + + /// preprocessor number + /// An optional period, followed by a digit 0-9, followed by any number of letters + /// digits, underscores, periods, and exponents (e+, e-, E+, E-, p+, p-, P+, P-) + pp_num, + + /// preprocessor placemarker token + /// generated if `##` is used with a zero-token argument + /// removed after substitution, so the parser should never see this + /// See C99 6.10.3.3.2 + placemarker, + + /// Virtual linemarker token output from preprocessor to indicate start of a new include + include_start, + + /// Virtual linemarker token output from preprocessor to indicate resuming a file after + /// completion of the preceding #include + include_resume, + + /// A comment token if asked to preserve comments. + comment, + + /// Return true if token is identifier or keyword. + pub fn isMacroIdentifier(id: Id) bool { + switch (id) { + .keyword_include, + .keyword_include_next, + .keyword_embed, + .keyword_define, + .keyword_defined, + .keyword_undef, + .keyword_ifdef, + .keyword_ifndef, + .keyword_elif, + .keyword_elifdef, + .keyword_elifndef, + .keyword_endif, + .keyword_error, + .keyword_warning, + .keyword_pragma, + .keyword_line, + .keyword_va_args, + .keyword_va_opt, + .macro_func, + .macro_function, + .macro_pretty_func, + .keyword_auto, + .keyword_auto_type, + .keyword_break, + .keyword_case, + .keyword_char, + .keyword_const, + .keyword_continue, + .keyword_default, + .keyword_do, + .keyword_double, + .keyword_else, + .keyword_enum, + .keyword_extern, + .keyword_float, + .keyword_for, + .keyword_goto, + .keyword_if, + .keyword_int, + .keyword_long, + .keyword_register, + .keyword_return, + .keyword_short, + .keyword_signed, + .keyword_signed1, + .keyword_signed2, + .keyword_sizeof, + .keyword_static, + .keyword_struct, + .keyword_switch, + .keyword_typedef, + .keyword_union, + .keyword_unsigned, + .keyword_void, + .keyword_volatile, + .keyword_while, + .keyword_bool, + .keyword_complex, + .keyword_imaginary, + .keyword_inline, + .keyword_restrict, + .keyword_alignas, + .keyword_alignof, + .keyword_atomic, + .keyword_generic, + .keyword_noreturn, + .keyword_static_assert, + .keyword_thread_local, + .identifier, + .extended_identifier, + .keyword_typeof, + .keyword_typeof1, + .keyword_typeof2, + .keyword_const1, + .keyword_const2, + .keyword_inline1, + .keyword_inline2, + .keyword_volatile1, + .keyword_volatile2, + .keyword_restrict1, + .keyword_restrict2, + .keyword_alignof1, + .keyword_alignof2, + .builtin_choose_expr, + .builtin_va_arg, + .builtin_offsetof, + .builtin_bitoffsetof, + .builtin_types_compatible_p, + .keyword_attribute1, + .keyword_attribute2, + .keyword_extension, + .keyword_asm, + .keyword_asm1, + .keyword_asm2, + .keyword_float128_1, + .keyword_float128_2, + .keyword_int128, + .keyword_imag1, + .keyword_imag2, + .keyword_real1, + .keyword_real2, + .keyword_float16, + .keyword_fp16, + .keyword_declspec, + .keyword_int64, + .keyword_int64_2, + .keyword_int32, + .keyword_int32_2, + .keyword_int16, + .keyword_int16_2, + .keyword_int8, + .keyword_int8_2, + .keyword_stdcall, + .keyword_stdcall2, + .keyword_thiscall, + .keyword_thiscall2, + .keyword_vectorcall, + .keyword_vectorcall2, + .keyword_bit_int, + .keyword_c23_alignas, + .keyword_c23_alignof, + .keyword_c23_bool, + .keyword_c23_static_assert, + .keyword_c23_thread_local, + .keyword_constexpr, + .keyword_true, + .keyword_false, + .keyword_nullptr, + .keyword_typeof_unqual, + => return true, + else => return false, + } + } + + /// Turn macro keywords into identifiers. + /// `keyword_defined` is special since it should only turn into an identifier if + /// we are *not* in an #if or #elif expression + pub fn simplifyMacroKeywordExtra(id: *Id, defined_to_identifier: bool) void { + switch (id.*) { + .keyword_include, + .keyword_include_next, + .keyword_embed, + .keyword_define, + .keyword_undef, + .keyword_ifdef, + .keyword_ifndef, + .keyword_elif, + .keyword_elifdef, + .keyword_elifndef, + .keyword_endif, + .keyword_error, + .keyword_warning, + .keyword_pragma, + .keyword_line, + .keyword_va_args, + .keyword_va_opt, + => id.* = .identifier, + .keyword_defined => if (defined_to_identifier) { + id.* = .identifier; + }, + else => {}, + } + } + + pub fn simplifyMacroKeyword(id: *Id) void { + simplifyMacroKeywordExtra(id, false); + } + + pub fn lexeme(id: Id) ?[]const u8 { + return switch (id) { + .include_start, + .include_resume, + => unreachable, + + .unterminated_comment, + .invalid, + .identifier, + .extended_identifier, + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + .unterminated_string_literal, + .unterminated_char_literal, + .empty_char_literal, + .char_literal, + .char_literal_utf_8, + .char_literal_utf_16, + .char_literal_utf_32, + .char_literal_wide, + .macro_string, + .whitespace, + .pp_num, + .embed_byte, + .comment, + => null, + + .zero => "0", + .one => "1", + + .nl, + .eof, + .macro_param, + .macro_param_no_expand, + .stringify_param, + .stringify_va_args, + .macro_param_has_attribute, + .macro_param_has_c_attribute, + .macro_param_has_declspec_attribute, + .macro_param_has_warning, + .macro_param_has_feature, + .macro_param_has_extension, + .macro_param_has_builtin, + .macro_param_has_include, + .macro_param_has_include_next, + .macro_param_has_embed, + .macro_param_is_identifier, + .macro_file, + .macro_line, + .macro_counter, + .macro_param_pragma_operator, + .placemarker, + => "", + .macro_ws => " ", + + .macro_func => "__func__", + .macro_function => "__FUNCTION__", + .macro_pretty_func => "__PRETTY_FUNCTION__", + + .bang => "!", + .bang_equal => "!=", + .pipe => "|", + .pipe_pipe => "||", + .pipe_equal => "|=", + .equal => "=", + .equal_equal => "==", + .l_paren => "(", + .r_paren => ")", + .l_brace => "{", + .r_brace => "}", + .l_bracket => "[", + .r_bracket => "]", + .period => ".", + .ellipsis => "...", + .caret => "^", + .caret_equal => "^=", + .plus => "+", + .plus_plus => "++", + .plus_equal => "+=", + .minus => "-", + .minus_minus => "--", + .minus_equal => "-=", + .asterisk => "*", + .asterisk_equal => "*=", + .percent => "%", + .percent_equal => "%=", + .arrow => "->", + .colon => ":", + .colon_colon => "::", + .semicolon => ";", + .slash => "/", + .slash_equal => "/=", + .comma => ",", + .ampersand => "&", + .ampersand_ampersand => "&&", + .ampersand_equal => "&=", + .question_mark => "?", + .angle_bracket_left => "<", + .angle_bracket_left_equal => "<=", + .angle_bracket_angle_bracket_left => "<<", + .angle_bracket_angle_bracket_left_equal => "<<=", + .angle_bracket_right => ">", + .angle_bracket_right_equal => ">=", + .angle_bracket_angle_bracket_right => ">>", + .angle_bracket_angle_bracket_right_equal => ">>=", + .tilde => "~", + .hash => "#", + .hash_hash => "##", + + .keyword_auto => "auto", + .keyword_auto_type => "__auto_type", + .keyword_break => "break", + .keyword_case => "case", + .keyword_char => "char", + .keyword_const => "const", + .keyword_continue => "continue", + .keyword_default => "default", + .keyword_do => "do", + .keyword_double => "double", + .keyword_else => "else", + .keyword_enum => "enum", + .keyword_extern => "extern", + .keyword_float => "float", + .keyword_for => "for", + .keyword_goto => "goto", + .keyword_if => "if", + .keyword_int => "int", + .keyword_long => "long", + .keyword_register => "register", + .keyword_return => "return", + .keyword_short => "short", + .keyword_signed => "signed", + .keyword_signed1 => "__signed", + .keyword_signed2 => "__signed__", + .keyword_sizeof => "sizeof", + .keyword_static => "static", + .keyword_struct => "struct", + .keyword_switch => "switch", + .keyword_typedef => "typedef", + .keyword_typeof => "typeof", + .keyword_union => "union", + .keyword_unsigned => "unsigned", + .keyword_void => "void", + .keyword_volatile => "volatile", + .keyword_while => "while", + .keyword_bool => "_Bool", + .keyword_complex => "_Complex", + .keyword_imaginary => "_Imaginary", + .keyword_inline => "inline", + .keyword_restrict => "restrict", + .keyword_alignas => "_Alignas", + .keyword_alignof => "_Alignof", + .keyword_atomic => "_Atomic", + .keyword_generic => "_Generic", + .keyword_noreturn => "_Noreturn", + .keyword_static_assert => "_Static_assert", + .keyword_thread_local => "_Thread_local", + .keyword_bit_int => "_BitInt", + .keyword_c23_alignas => "alignas", + .keyword_c23_alignof => "alignof", + .keyword_c23_bool => "bool", + .keyword_c23_static_assert => "static_assert", + .keyword_c23_thread_local => "thread_local", + .keyword_constexpr => "constexpr", + .keyword_true => "true", + .keyword_false => "false", + .keyword_nullptr => "nullptr", + .keyword_typeof_unqual => "typeof_unqual", + .keyword_include => "include", + .keyword_include_next => "include_next", + .keyword_embed => "embed", + .keyword_define => "define", + .keyword_defined => "defined", + .keyword_undef => "undef", + .keyword_ifdef => "ifdef", + .keyword_ifndef => "ifndef", + .keyword_elif => "elif", + .keyword_elifdef => "elifdef", + .keyword_elifndef => "elifndef", + .keyword_endif => "endif", + .keyword_error => "error", + .keyword_warning => "warning", + .keyword_pragma => "pragma", + .keyword_line => "line", + .keyword_va_args => "__VA_ARGS__", + .keyword_va_opt => "__VA_OPT__", + .keyword_const1 => "__const", + .keyword_const2 => "__const__", + .keyword_inline1 => "__inline", + .keyword_inline2 => "__inline__", + .keyword_volatile1 => "__volatile", + .keyword_volatile2 => "__volatile__", + .keyword_restrict1 => "__restrict", + .keyword_restrict2 => "__restrict__", + .keyword_alignof1 => "__alignof", + .keyword_alignof2 => "__alignof__", + .keyword_typeof1 => "__typeof", + .keyword_typeof2 => "__typeof__", + .builtin_choose_expr => "__builtin_choose_expr", + .builtin_va_arg => "__builtin_va_arg", + .builtin_offsetof => "__builtin_offsetof", + .builtin_bitoffsetof => "__builtin_bitoffsetof", + .builtin_types_compatible_p => "__builtin_types_compatible_p", + .keyword_attribute1 => "__attribute", + .keyword_attribute2 => "__attribute__", + .keyword_extension => "__extension__", + .keyword_asm => "asm", + .keyword_asm1 => "__asm", + .keyword_asm2 => "__asm__", + .keyword_float128_1 => "_Float128", + .keyword_float128_2 => "__float128", + .keyword_int128 => "__int128", + .keyword_imag1 => "__imag", + .keyword_imag2 => "__imag__", + .keyword_real1 => "__real", + .keyword_real2 => "__real__", + .keyword_float16 => "_Float16", + .keyword_fp16 => "__fp16", + .keyword_declspec => "__declspec", + .keyword_int64 => "__int64", + .keyword_int64_2 => "_int64", + .keyword_int32 => "__int32", + .keyword_int32_2 => "_int32", + .keyword_int16 => "__int16", + .keyword_int16_2 => "_int16", + .keyword_int8 => "__int8", + .keyword_int8_2 => "_int8", + .keyword_stdcall => "__stdcall", + .keyword_stdcall2 => "_stdcall", + .keyword_thiscall => "__thiscall", + .keyword_thiscall2 => "_thiscall", + .keyword_vectorcall => "__vectorcall", + .keyword_vectorcall2 => "_vectorcall", + }; + } + + pub fn symbol(id: Id) []const u8 { + return switch (id) { + .macro_string => unreachable, + .invalid => "invalid bytes", + .identifier, + .extended_identifier, + .macro_func, + .macro_function, + .macro_pretty_func, + .builtin_choose_expr, + .builtin_va_arg, + .builtin_offsetof, + .builtin_bitoffsetof, + .builtin_types_compatible_p, + => "an identifier", + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + .unterminated_string_literal, + => "a string literal", + .char_literal, + .char_literal_utf_8, + .char_literal_utf_16, + .char_literal_utf_32, + .char_literal_wide, + .unterminated_char_literal, + .empty_char_literal, + => "a character literal", + .pp_num, .embed_byte => "A number", + else => id.lexeme().?, + }; + } + + /// tokens that can start an expression parsed by Preprocessor.expr + /// Note that eof, r_paren, and string literals cannot actually start a + /// preprocessor expression, but we include them here so that a nicer + /// error message can be generated by the parser. + pub fn validPreprocessorExprStart(id: Id) bool { + return switch (id) { + .eof, + .r_paren, + .string_literal, + .string_literal_utf_16, + .string_literal_utf_8, + .string_literal_utf_32, + .string_literal_wide, + + .char_literal, + .char_literal_utf_8, + .char_literal_utf_16, + .char_literal_utf_32, + .char_literal_wide, + .l_paren, + .plus, + .minus, + .tilde, + .bang, + .identifier, + .extended_identifier, + .keyword_defined, + .one, + .zero, + .pp_num, + .keyword_true, + .keyword_false, + => true, + else => false, + }; + } + + pub fn allowsDigraphs(id: Id, langopts: LangOpts) bool { + return switch (id) { + .l_bracket, + .r_bracket, + .l_brace, + .r_brace, + .hash, + .hash_hash, + => langopts.hasDigraphs(), + else => false, + }; + } + + pub fn canOpenGCCAsmStmt(id: Id) bool { + return switch (id) { + .keyword_volatile, .keyword_volatile1, .keyword_volatile2, .keyword_inline, .keyword_inline1, .keyword_inline2, .keyword_goto, .l_paren => true, + else => false, + }; + } + + pub fn isStringLiteral(id: Id) bool { + return switch (id) { + .string_literal, .string_literal_utf_16, .string_literal_utf_8, .string_literal_utf_32, .string_literal_wide => true, + else => false, + }; + } + }; + + /// double underscore and underscore + capital letter identifiers + /// belong to the implementation namespace, so we always convert them + /// to keywords. + pub fn getTokenId(langopts: LangOpts, str: []const u8) Token.Id { + const kw = all_kws.get(str) orelse return .identifier; + const standard = langopts.standard; + return switch (kw) { + .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier, + .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier, + .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c23)) kw else .identifier, + .keyword_asm => if (standard.isGNU()) kw else .identifier, + .keyword_declspec => if (langopts.declspec_attrs) kw else .identifier, + + .keyword_c23_alignas, + .keyword_c23_alignof, + .keyword_c23_bool, + .keyword_c23_static_assert, + .keyword_c23_thread_local, + .keyword_constexpr, + .keyword_true, + .keyword_false, + .keyword_nullptr, + .keyword_typeof_unqual, + .keyword_elifdef, + .keyword_elifndef, + => if (standard.atLeast(.c23)) kw else .identifier, + + .keyword_int64, + .keyword_int64_2, + .keyword_int32, + .keyword_int32_2, + .keyword_int16, + .keyword_int16_2, + .keyword_int8, + .keyword_int8_2, + .keyword_stdcall2, + .keyword_thiscall2, + .keyword_vectorcall2, + => if (langopts.ms_extensions) kw else .identifier, + else => kw, + }; + } + + const all_kws = std.StaticStringMap(Id).initComptime(.{ + .{ "auto", .keyword_auto }, + .{ "break", .keyword_break }, + .{ "case", .keyword_case }, + .{ "char", .keyword_char }, + .{ "const", .keyword_const }, + .{ "continue", .keyword_continue }, + .{ "default", .keyword_default }, + .{ "do", .keyword_do }, + .{ "double", .keyword_double }, + .{ "else", .keyword_else }, + .{ "enum", .keyword_enum }, + .{ "extern", .keyword_extern }, + .{ "float", .keyword_float }, + .{ "for", .keyword_for }, + .{ "goto", .keyword_goto }, + .{ "if", .keyword_if }, + .{ "int", .keyword_int }, + .{ "long", .keyword_long }, + .{ "register", .keyword_register }, + .{ "return", .keyword_return }, + .{ "short", .keyword_short }, + .{ "signed", .keyword_signed }, + .{ "__signed", .keyword_signed1 }, + .{ "__signed__", .keyword_signed2 }, + .{ "sizeof", .keyword_sizeof }, + .{ "static", .keyword_static }, + .{ "struct", .keyword_struct }, + .{ "switch", .keyword_switch }, + .{ "typedef", .keyword_typedef }, + .{ "union", .keyword_union }, + .{ "unsigned", .keyword_unsigned }, + .{ "void", .keyword_void }, + .{ "volatile", .keyword_volatile }, + .{ "while", .keyword_while }, + .{ "__typeof__", .keyword_typeof2 }, + .{ "__typeof", .keyword_typeof1 }, + + // ISO C99 + .{ "_Bool", .keyword_bool }, + .{ "_Complex", .keyword_complex }, + .{ "_Imaginary", .keyword_imaginary }, + .{ "inline", .keyword_inline }, + .{ "restrict", .keyword_restrict }, + + // ISO C11 + .{ "_Alignas", .keyword_alignas }, + .{ "_Alignof", .keyword_alignof }, + .{ "_Atomic", .keyword_atomic }, + .{ "_Generic", .keyword_generic }, + .{ "_Noreturn", .keyword_noreturn }, + .{ "_Static_assert", .keyword_static_assert }, + .{ "_Thread_local", .keyword_thread_local }, + + // ISO C23 + .{ "_BitInt", .keyword_bit_int }, + .{ "alignas", .keyword_c23_alignas }, + .{ "alignof", .keyword_c23_alignof }, + .{ "bool", .keyword_c23_bool }, + .{ "static_assert", .keyword_c23_static_assert }, + .{ "thread_local", .keyword_c23_thread_local }, + .{ "constexpr", .keyword_constexpr }, + .{ "true", .keyword_true }, + .{ "false", .keyword_false }, + .{ "nullptr", .keyword_nullptr }, + .{ "typeof_unqual", .keyword_typeof_unqual }, + + // Preprocessor directives + .{ "include", .keyword_include }, + .{ "include_next", .keyword_include_next }, + .{ "embed", .keyword_embed }, + .{ "define", .keyword_define }, + .{ "defined", .keyword_defined }, + .{ "undef", .keyword_undef }, + .{ "ifdef", .keyword_ifdef }, + .{ "ifndef", .keyword_ifndef }, + .{ "elif", .keyword_elif }, + .{ "elifdef", .keyword_elifdef }, + .{ "elifndef", .keyword_elifndef }, + .{ "endif", .keyword_endif }, + .{ "error", .keyword_error }, + .{ "warning", .keyword_warning }, + .{ "pragma", .keyword_pragma }, + .{ "line", .keyword_line }, + .{ "__VA_ARGS__", .keyword_va_args }, + .{ "__VA_OPT__", .keyword_va_opt }, + .{ "__func__", .macro_func }, + .{ "__FUNCTION__", .macro_function }, + .{ "__PRETTY_FUNCTION__", .macro_pretty_func }, + + // gcc keywords + .{ "__auto_type", .keyword_auto_type }, + .{ "__const", .keyword_const1 }, + .{ "__const__", .keyword_const2 }, + .{ "__inline", .keyword_inline1 }, + .{ "__inline__", .keyword_inline2 }, + .{ "__volatile", .keyword_volatile1 }, + .{ "__volatile__", .keyword_volatile2 }, + .{ "__restrict", .keyword_restrict1 }, + .{ "__restrict__", .keyword_restrict2 }, + .{ "__alignof", .keyword_alignof1 }, + .{ "__alignof__", .keyword_alignof2 }, + .{ "typeof", .keyword_typeof }, + .{ "__attribute", .keyword_attribute1 }, + .{ "__attribute__", .keyword_attribute2 }, + .{ "__extension__", .keyword_extension }, + .{ "asm", .keyword_asm }, + .{ "__asm", .keyword_asm1 }, + .{ "__asm__", .keyword_asm2 }, + .{ "_Float128", .keyword_float128_1 }, + .{ "__float128", .keyword_float128_2 }, + .{ "__int128", .keyword_int128 }, + .{ "__imag", .keyword_imag1 }, + .{ "__imag__", .keyword_imag2 }, + .{ "__real", .keyword_real1 }, + .{ "__real__", .keyword_real2 }, + .{ "_Float16", .keyword_float16 }, + + // clang keywords + .{ "__fp16", .keyword_fp16 }, + + // ms keywords + .{ "__declspec", .keyword_declspec }, + .{ "__int64", .keyword_int64 }, + .{ "_int64", .keyword_int64_2 }, + .{ "__int32", .keyword_int32 }, + .{ "_int32", .keyword_int32_2 }, + .{ "__int16", .keyword_int16 }, + .{ "_int16", .keyword_int16_2 }, + .{ "__int8", .keyword_int8 }, + .{ "_int8", .keyword_int8_2 }, + .{ "__stdcall", .keyword_stdcall }, + .{ "_stdcall", .keyword_stdcall2 }, + .{ "__thiscall", .keyword_thiscall }, + .{ "_thiscall", .keyword_thiscall2 }, + .{ "__vectorcall", .keyword_vectorcall }, + .{ "_vectorcall", .keyword_vectorcall2 }, + + // builtins that require special parsing + .{ "__builtin_choose_expr", .builtin_choose_expr }, + .{ "__builtin_va_arg", .builtin_va_arg }, + .{ "__builtin_offsetof", .builtin_offsetof }, + .{ "__builtin_bitoffsetof", .builtin_bitoffsetof }, + .{ "__builtin_types_compatible_p", .builtin_types_compatible_p }, + }); +}; + +const Tokenizer = @This(); + +buf: []const u8, +index: u32 = 0, +source: Source.Id, +langopts: LangOpts, +line: u32 = 1, + +pub fn next(self: *Tokenizer) Token { + var state: enum { + start, + whitespace, + u, + u8, + U, + L, + string_literal, + char_literal_start, + char_literal, + char_escape_sequence, + string_escape_sequence, + identifier, + extended_identifier, + equal, + bang, + pipe, + colon, + percent, + asterisk, + plus, + angle_bracket_left, + angle_bracket_angle_bracket_left, + angle_bracket_right, + angle_bracket_angle_bracket_right, + caret, + period, + period2, + minus, + slash, + ampersand, + hash, + hash_digraph, + hash_hash_digraph_partial, + line_comment, + multi_line_comment, + multi_line_comment_asterisk, + multi_line_comment_done, + pp_num, + pp_num_exponent, + pp_num_digit_separator, + } = .start; + + var start = self.index; + var id: Token.Id = .eof; + + while (self.index < self.buf.len) : (self.index += 1) { + const c = self.buf[self.index]; + switch (state) { + .start => switch (c) { + '\n' => { + id = .nl; + self.index += 1; + self.line += 1; + break; + }, + '"' => { + id = .string_literal; + state = .string_literal; + }, + '\'' => { + id = .char_literal; + state = .char_literal_start; + }, + 'u' => state = .u, + 'U' => state = .U, + 'L' => state = .L, + 'a'...'t', 'v'...'z', 'A'...'K', 'M'...'T', 'V'...'Z', '_' => state = .identifier, + '=' => state = .equal, + '!' => state = .bang, + '|' => state = .pipe, + '(' => { + id = .l_paren; + self.index += 1; + break; + }, + ')' => { + id = .r_paren; + self.index += 1; + break; + }, + '[' => { + id = .l_bracket; + self.index += 1; + break; + }, + ']' => { + id = .r_bracket; + self.index += 1; + break; + }, + ';' => { + id = .semicolon; + self.index += 1; + break; + }, + ',' => { + id = .comma; + self.index += 1; + break; + }, + '?' => { + id = .question_mark; + self.index += 1; + break; + }, + ':' => state = .colon, + '%' => state = .percent, + '*' => state = .asterisk, + '+' => state = .plus, + '<' => state = .angle_bracket_left, + '>' => state = .angle_bracket_right, + '^' => state = .caret, + '{' => { + id = .l_brace; + self.index += 1; + break; + }, + '}' => { + id = .r_brace; + self.index += 1; + break; + }, + '~' => { + id = .tilde; + self.index += 1; + break; + }, + '.' => state = .period, + '-' => state = .minus, + '/' => state = .slash, + '&' => state = .ampersand, + '#' => state = .hash, + '0'...'9' => state = .pp_num, + '\t', '\x0B', '\x0C', ' ' => state = .whitespace, + '$' => if (self.langopts.dollars_in_identifiers) { + state = .extended_identifier; + } else { + id = .invalid; + self.index += 1; + break; + }, + 0x1A => if (self.langopts.ms_extensions) { + id = .eof; + break; + } else { + id = .invalid; + self.index += 1; + break; + }, + 0x80...0xFF => state = .extended_identifier, + else => { + id = .invalid; + self.index += 1; + break; + }, + }, + .whitespace => switch (c) { + '\t', '\x0B', '\x0C', ' ' => {}, + else => { + id = .whitespace; + break; + }, + }, + .u => switch (c) { + '8' => { + state = .u8; + }, + '\'' => { + id = .char_literal_utf_16; + state = .char_literal_start; + }, + '\"' => { + id = .string_literal_utf_16; + state = .string_literal; + }, + else => { + self.index -= 1; + state = .identifier; + }, + }, + .u8 => switch (c) { + '\"' => { + id = .string_literal_utf_8; + state = .string_literal; + }, + '\'' => { + id = .char_literal_utf_8; + state = .char_literal_start; + }, + else => { + self.index -= 1; + state = .identifier; + }, + }, + .U => switch (c) { + '\'' => { + id = .char_literal_utf_32; + state = .char_literal_start; + }, + '\"' => { + id = .string_literal_utf_32; + state = .string_literal; + }, + else => { + self.index -= 1; + state = .identifier; + }, + }, + .L => switch (c) { + '\'' => { + id = .char_literal_wide; + state = .char_literal_start; + }, + '\"' => { + id = .string_literal_wide; + state = .string_literal; + }, + else => { + self.index -= 1; + state = .identifier; + }, + }, + .string_literal => switch (c) { + '\\' => { + state = .string_escape_sequence; + }, + '"' => { + self.index += 1; + break; + }, + '\n' => { + id = .unterminated_string_literal; + break; + }, + '\r' => unreachable, + else => {}, + }, + .char_literal_start => switch (c) { + '\\' => { + state = .char_escape_sequence; + }, + '\'' => { + id = .empty_char_literal; + self.index += 1; + break; + }, + '\n' => { + id = .unterminated_char_literal; + break; + }, + else => { + state = .char_literal; + }, + }, + .char_literal => switch (c) { + '\\' => { + state = .char_escape_sequence; + }, + '\'' => { + self.index += 1; + break; + }, + '\n' => { + id = .unterminated_char_literal; + break; + }, + else => {}, + }, + .char_escape_sequence => switch (c) { + '\r', '\n' => { + id = .unterminated_char_literal; + break; + }, + else => state = .char_literal, + }, + .string_escape_sequence => switch (c) { + '\r', '\n' => { + id = .unterminated_string_literal; + break; + }, + else => state = .string_literal, + }, + .identifier, .extended_identifier => switch (c) { + 'a'...'z', 'A'...'Z', '_', '0'...'9' => {}, + '$' => if (self.langopts.dollars_in_identifiers) { + state = .extended_identifier; + } else { + id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier; + break; + }, + 0x80...0xFF => state = .extended_identifier, + else => { + id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier; + break; + }, + }, + .equal => switch (c) { + '=' => { + id = .equal_equal; + self.index += 1; + break; + }, + else => { + id = .equal; + break; + }, + }, + .bang => switch (c) { + '=' => { + id = .bang_equal; + self.index += 1; + break; + }, + else => { + id = .bang; + break; + }, + }, + .pipe => switch (c) { + '=' => { + id = .pipe_equal; + self.index += 1; + break; + }, + '|' => { + id = .pipe_pipe; + self.index += 1; + break; + }, + else => { + id = .pipe; + break; + }, + }, + .colon => switch (c) { + '>' => { + if (self.langopts.hasDigraphs()) { + id = .r_bracket; + self.index += 1; + } else { + id = .colon; + } + break; + }, + ':' => { + if (self.langopts.standard.atLeast(.c23)) { + id = .colon_colon; + self.index += 1; + break; + } else { + id = .colon; + break; + } + }, + else => { + id = .colon; + break; + }, + }, + .percent => switch (c) { + '=' => { + id = .percent_equal; + self.index += 1; + break; + }, + '>' => { + if (self.langopts.hasDigraphs()) { + id = .r_brace; + self.index += 1; + } else { + id = .percent; + } + break; + }, + ':' => { + if (self.langopts.hasDigraphs()) { + state = .hash_digraph; + } else { + id = .percent; + break; + } + }, + else => { + id = .percent; + break; + }, + }, + .asterisk => switch (c) { + '=' => { + id = .asterisk_equal; + self.index += 1; + break; + }, + else => { + id = .asterisk; + break; + }, + }, + .plus => switch (c) { + '=' => { + id = .plus_equal; + self.index += 1; + break; + }, + '+' => { + id = .plus_plus; + self.index += 1; + break; + }, + else => { + id = .plus; + break; + }, + }, + .angle_bracket_left => switch (c) { + '<' => state = .angle_bracket_angle_bracket_left, + '=' => { + id = .angle_bracket_left_equal; + self.index += 1; + break; + }, + ':' => { + if (self.langopts.hasDigraphs()) { + id = .l_bracket; + self.index += 1; + } else { + id = .angle_bracket_left; + } + break; + }, + '%' => { + if (self.langopts.hasDigraphs()) { + id = .l_brace; + self.index += 1; + } else { + id = .angle_bracket_left; + } + break; + }, + else => { + id = .angle_bracket_left; + break; + }, + }, + .angle_bracket_angle_bracket_left => switch (c) { + '=' => { + id = .angle_bracket_angle_bracket_left_equal; + self.index += 1; + break; + }, + else => { + id = .angle_bracket_angle_bracket_left; + break; + }, + }, + .angle_bracket_right => switch (c) { + '>' => state = .angle_bracket_angle_bracket_right, + '=' => { + id = .angle_bracket_right_equal; + self.index += 1; + break; + }, + else => { + id = .angle_bracket_right; + break; + }, + }, + .angle_bracket_angle_bracket_right => switch (c) { + '=' => { + id = .angle_bracket_angle_bracket_right_equal; + self.index += 1; + break; + }, + else => { + id = .angle_bracket_angle_bracket_right; + break; + }, + }, + .caret => switch (c) { + '=' => { + id = .caret_equal; + self.index += 1; + break; + }, + else => { + id = .caret; + break; + }, + }, + .period => switch (c) { + '.' => state = .period2, + '0'...'9' => state = .pp_num, + else => { + id = .period; + break; + }, + }, + .period2 => switch (c) { + '.' => { + id = .ellipsis; + self.index += 1; + break; + }, + else => { + id = .period; + self.index -= 1; + break; + }, + }, + .minus => switch (c) { + '>' => { + id = .arrow; + self.index += 1; + break; + }, + '=' => { + id = .minus_equal; + self.index += 1; + break; + }, + '-' => { + id = .minus_minus; + self.index += 1; + break; + }, + else => { + id = .minus; + break; + }, + }, + .ampersand => switch (c) { + '&' => { + id = .ampersand_ampersand; + self.index += 1; + break; + }, + '=' => { + id = .ampersand_equal; + self.index += 1; + break; + }, + else => { + id = .ampersand; + break; + }, + }, + .hash => switch (c) { + '#' => { + id = .hash_hash; + self.index += 1; + break; + }, + else => { + id = .hash; + break; + }, + }, + .hash_digraph => switch (c) { + '%' => state = .hash_hash_digraph_partial, + else => { + id = .hash; + break; + }, + }, + .hash_hash_digraph_partial => switch (c) { + ':' => { + id = .hash_hash; + self.index += 1; + break; + }, + else => { + id = .hash; + self.index -= 1; // re-tokenize the percent + break; + }, + }, + .slash => switch (c) { + '/' => state = .line_comment, + '*' => state = .multi_line_comment, + '=' => { + id = .slash_equal; + self.index += 1; + break; + }, + else => { + id = .slash; + break; + }, + }, + .line_comment => switch (c) { + '\n' => { + if (self.langopts.preserve_comments) { + id = .comment; + break; + } + self.index -= 1; + state = .start; + }, + else => {}, + }, + .multi_line_comment => switch (c) { + '*' => state = .multi_line_comment_asterisk, + '\n' => self.line += 1, + else => {}, + }, + .multi_line_comment_asterisk => switch (c) { + '/' => { + if (self.langopts.preserve_comments) { + self.index += 1; + id = .comment; + break; + } + state = .multi_line_comment_done; + }, + '\n' => { + self.line += 1; + state = .multi_line_comment; + }, + '*' => {}, + else => state = .multi_line_comment, + }, + .multi_line_comment_done => switch (c) { + '\n' => { + start = self.index; + id = .nl; + self.index += 1; + self.line += 1; + break; + }, + '\r' => unreachable, + '\t', '\x0B', '\x0C', ' ' => { + start = self.index; + state = .whitespace; + }, + else => { + id = .whitespace; + break; + }, + }, + .pp_num => switch (c) { + 'a'...'d', + 'A'...'D', + 'f'...'o', + 'F'...'O', + 'q'...'z', + 'Q'...'Z', + '0'...'9', + '_', + '.', + => {}, + 'e', 'E', 'p', 'P' => state = .pp_num_exponent, + '\'' => if (self.langopts.standard.atLeast(.c23)) { + state = .pp_num_digit_separator; + } else { + id = .pp_num; + break; + }, + else => { + id = .pp_num; + break; + }, + }, + .pp_num_digit_separator => switch (c) { + 'a'...'d', + 'A'...'D', + 'f'...'o', + 'F'...'O', + 'q'...'z', + 'Q'...'Z', + '0'...'9', + '_', + => state = .pp_num, + else => { + self.index -= 1; + id = .pp_num; + break; + }, + }, + .pp_num_exponent => switch (c) { + 'a'...'o', + 'q'...'z', + 'A'...'O', + 'Q'...'Z', + '0'...'9', + '_', + '.', + '+', + '-', + => state = .pp_num, + 'p', 'P' => {}, + else => { + id = .pp_num; + break; + }, + }, + } + } else if (self.index == self.buf.len) { + switch (state) { + .start, .line_comment => {}, + .u, .u8, .U, .L, .identifier => id = Token.getTokenId(self.langopts, self.buf[start..self.index]), + .extended_identifier => id = .extended_identifier, + + .period2 => { + self.index -= 1; + id = .period; + }, + + .multi_line_comment, + .multi_line_comment_asterisk, + => id = .unterminated_comment, + + .char_escape_sequence, .char_literal, .char_literal_start => id = .unterminated_char_literal, + .string_escape_sequence, .string_literal => id = .unterminated_string_literal, + + .whitespace => id = .whitespace, + .multi_line_comment_done => id = .whitespace, + + .equal => id = .equal, + .bang => id = .bang, + .minus => id = .minus, + .slash => id = .slash, + .ampersand => id = .ampersand, + .hash => id = .hash, + .period => id = .period, + .pipe => id = .pipe, + .angle_bracket_angle_bracket_right => id = .angle_bracket_angle_bracket_right, + .angle_bracket_right => id = .angle_bracket_right, + .angle_bracket_angle_bracket_left => id = .angle_bracket_angle_bracket_left, + .angle_bracket_left => id = .angle_bracket_left, + .plus => id = .plus, + .colon => id = .colon, + .percent => id = .percent, + .caret => id = .caret, + .asterisk => id = .asterisk, + .hash_digraph => id = .hash, + .hash_hash_digraph_partial => { + id = .hash; + self.index -= 1; // re-tokenize the percent + }, + .pp_num, .pp_num_exponent, .pp_num_digit_separator => id = .pp_num, + } + } + + return .{ + .id = id, + .start = start, + .end = self.index, + .line = self.line, + .source = self.source, + }; +} + +pub fn nextNoWS(self: *Tokenizer) Token { + var tok = self.next(); + while (tok.id == .whitespace or tok.id == .comment) tok = self.next(); + return tok; +} + +pub fn nextNoWSComments(self: *Tokenizer) Token { + var tok = self.next(); + while (tok.id == .whitespace) tok = self.next(); + return tok; +} + +/// Try to tokenize a '::' even if not supported by the current language standard. +pub fn colonColon(self: *Tokenizer) Token { + var tok = self.nextNoWS(); + if (tok.id == .colon and self.index < self.buf.len and self.buf[self.index] == ':') { + self.index += 1; + tok.id = .colon_colon; + } + return tok; +} + +test "operators" { + try expectTokens( + \\ ! != | || |= = == + \\ ( ) { } [ ] . .. ... + \\ ^ ^= + ++ += - -- -= + \\ * *= % %= -> : ; / /= + \\ , & && &= ? < <= << + \\ <<= > >= >> >>= ~ # ## + \\ + , &.{ + .bang, + .bang_equal, + .pipe, + .pipe_pipe, + .pipe_equal, + .equal, + .equal_equal, + .nl, + .l_paren, + .r_paren, + .l_brace, + .r_brace, + .l_bracket, + .r_bracket, + .period, + .period, + .period, + .ellipsis, + .nl, + .caret, + .caret_equal, + .plus, + .plus_plus, + .plus_equal, + .minus, + .minus_minus, + .minus_equal, + .nl, + .asterisk, + .asterisk_equal, + .percent, + .percent_equal, + .arrow, + .colon, + .semicolon, + .slash, + .slash_equal, + .nl, + .comma, + .ampersand, + .ampersand_ampersand, + .ampersand_equal, + .question_mark, + .angle_bracket_left, + .angle_bracket_left_equal, + .angle_bracket_angle_bracket_left, + .nl, + .angle_bracket_angle_bracket_left_equal, + .angle_bracket_right, + .angle_bracket_right_equal, + .angle_bracket_angle_bracket_right, + .angle_bracket_angle_bracket_right_equal, + .tilde, + .hash, + .hash_hash, + .nl, + }); +} + +test "keywords" { + try expectTokens( + \\auto __auto_type break case char const continue default do + \\double else enum extern float for goto if int + \\long register return short signed sizeof static + \\struct switch typedef union unsigned void volatile + \\while _Bool _Complex _Imaginary inline restrict _Alignas + \\_Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local + \\__attribute __attribute__ + \\ + , &.{ + .keyword_auto, + .keyword_auto_type, + .keyword_break, + .keyword_case, + .keyword_char, + .keyword_const, + .keyword_continue, + .keyword_default, + .keyword_do, + .nl, + .keyword_double, + .keyword_else, + .keyword_enum, + .keyword_extern, + .keyword_float, + .keyword_for, + .keyword_goto, + .keyword_if, + .keyword_int, + .nl, + .keyword_long, + .keyword_register, + .keyword_return, + .keyword_short, + .keyword_signed, + .keyword_sizeof, + .keyword_static, + .nl, + .keyword_struct, + .keyword_switch, + .keyword_typedef, + .keyword_union, + .keyword_unsigned, + .keyword_void, + .keyword_volatile, + .nl, + .keyword_while, + .keyword_bool, + .keyword_complex, + .keyword_imaginary, + .keyword_inline, + .keyword_restrict, + .keyword_alignas, + .nl, + .keyword_alignof, + .keyword_atomic, + .keyword_generic, + .keyword_noreturn, + .keyword_static_assert, + .keyword_thread_local, + .nl, + .keyword_attribute1, + .keyword_attribute2, + .nl, + }); +} + +test "preprocessor keywords" { + try expectTokens( + \\#include + \\#include_next + \\#embed + \\#define + \\#ifdef + \\#ifndef + \\#error + \\#pragma + \\ + , &.{ + .hash, + .keyword_include, + .nl, + .hash, + .keyword_include_next, + .nl, + .hash, + .keyword_embed, + .nl, + .hash, + .keyword_define, + .nl, + .hash, + .keyword_ifdef, + .nl, + .hash, + .keyword_ifndef, + .nl, + .hash, + .keyword_error, + .nl, + .hash, + .keyword_pragma, + .nl, + }); +} + +test "line continuation" { + try expectTokens( + \\#define foo \ + \\ bar + \\"foo\ + \\ bar" + \\#define "foo" + \\ "bar" + \\#define "foo" \ + \\ "bar" + , &.{ + .hash, + .keyword_define, + .identifier, + .identifier, + .nl, + .string_literal, + .nl, + .hash, + .keyword_define, + .string_literal, + .nl, + .string_literal, + .nl, + .hash, + .keyword_define, + .string_literal, + .string_literal, + }); +} + +test "string prefix" { + try expectTokens( + \\"foo" + \\u"foo" + \\u8"foo" + \\U"foo" + \\L"foo" + \\'foo' + \\u8'A' + \\u'foo' + \\U'foo' + \\L'foo' + \\ + , &.{ + .string_literal, + .nl, + .string_literal_utf_16, + .nl, + .string_literal_utf_8, + .nl, + .string_literal_utf_32, + .nl, + .string_literal_wide, + .nl, + .char_literal, + .nl, + .char_literal_utf_8, + .nl, + .char_literal_utf_16, + .nl, + .char_literal_utf_32, + .nl, + .char_literal_wide, + .nl, + }); +} + +test "num suffixes" { + try expectTokens( + \\ 1.0f 1.0L 1.0 .0 1. 0x1p0f 0X1p0 + \\ 0l 0lu 0ll 0llu 0 + \\ 1u 1ul 1ull 1 + \\ 1.0i 1.0I + \\ 1.0if 1.0If 1.0fi 1.0fI + \\ 1.0il 1.0Il 1.0li 1.0lI + \\ + , &.{ + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .nl, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .nl, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .nl, + .pp_num, + .pp_num, + .nl, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .nl, + .pp_num, + .pp_num, + .pp_num, + .pp_num, + .nl, + }); +} + +test "comments" { + try expectTokens( + \\//foo + \\#foo + , &.{ + .nl, + .hash, + .identifier, + }); +} + +test "extended identifiers" { + try expectTokens("𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier}); + try expectTokens("u𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier}); + try expectTokens("u8𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier}); + try expectTokens("U𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier}); + try expectTokens("L𝓪𝓻𝓸𝓬𝓬", &.{.extended_identifier}); + try expectTokens("1™", &.{ .pp_num, .extended_identifier }); + try expectTokens("1.™", &.{ .pp_num, .extended_identifier }); + try expectTokens("..™", &.{ .period, .period, .extended_identifier }); + try expectTokens("0™", &.{ .pp_num, .extended_identifier }); + try expectTokens("0b\u{E0000}", &.{ .pp_num, .extended_identifier }); + try expectTokens("0b0\u{E0000}", &.{ .pp_num, .extended_identifier }); + try expectTokens("01\u{E0000}", &.{ .pp_num, .extended_identifier }); + try expectTokens("010\u{E0000}", &.{ .pp_num, .extended_identifier }); + try expectTokens("0x\u{E0000}", &.{ .pp_num, .extended_identifier }); + try expectTokens("0x0\u{E0000}", &.{ .pp_num, .extended_identifier }); + try expectTokens("\"\\0\u{E0000}\"", &.{.string_literal}); + try expectTokens("\"\\x\u{E0000}\"", &.{.string_literal}); + try expectTokens("\"\\u\u{E0000}\"", &.{.string_literal}); + try expectTokens("1e\u{E0000}", &.{ .pp_num, .extended_identifier }); + try expectTokens("1e1\u{E0000}", &.{ .pp_num, .extended_identifier }); +} + +test "digraphs" { + try expectTokens("%:<::><%%>%:%:", &.{ .hash, .l_bracket, .r_bracket, .l_brace, .r_brace, .hash_hash }); + try expectTokens("\"%:<::><%%>%:%:\"", &.{.string_literal}); + try expectTokens("%:%42 %:%", &.{ .hash, .percent, .pp_num, .hash, .percent }); +} + +test "C23 keywords" { + try expectTokensExtra("true false alignas alignof bool static_assert thread_local nullptr typeof_unqual", &.{ + .keyword_true, + .keyword_false, + .keyword_c23_alignas, + .keyword_c23_alignof, + .keyword_c23_bool, + .keyword_c23_static_assert, + .keyword_c23_thread_local, + .keyword_nullptr, + .keyword_typeof_unqual, + }, .c23); +} + +test "Tokenizer fuzz test" { + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + + const input_bytes = std.testing.fuzzInput(.{}); + if (input_bytes.len == 0) return; + + const source = try comp.addSourceFromBuffer("fuzz.c", input_bytes); + + var tokenizer: Tokenizer = .{ + .buf = source.buf, + .source = source.id, + .langopts = comp.langopts, + }; + while (true) { + const prev_index = tokenizer.index; + const tok = tokenizer.next(); + if (tok.id == .eof) break; + try std.testing.expect(prev_index < tokenizer.index); // ensure that the tokenizer always makes progress + } +} + +fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, standard: ?LangOpts.Standard) !void { + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + if (standard) |provided| { + comp.langopts.standard = provided; + } + const source = try comp.addSourceFromBuffer("path", contents); + var tokenizer = Tokenizer{ + .buf = source.buf, + .source = source.id, + .langopts = comp.langopts, + }; + var i: usize = 0; + while (i < expected_tokens.len) { + const token = tokenizer.next(); + if (token.id == .whitespace) continue; + const expected_token_id = expected_tokens[i]; + i += 1; + if (!std.meta.eql(token.id, expected_token_id)) { + std.debug.print("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.id) }); + return error.TokensDoNotEqual; + } + } + const last_token = tokenizer.next(); + try std.testing.expect(last_token.id == .eof); +} + +fn expectTokens(contents: []const u8, expected_tokens: []const Token.Id) !void { + return expectTokensExtra(contents, expected_tokens, null); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Toolchain.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Toolchain.zig new file mode 100644 index 00000000..c3d43f05 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Toolchain.zig @@ -0,0 +1,508 @@ +const std = @import("std"); +const Driver = @import("Driver.zig"); +const Compilation = @import("Compilation.zig"); +const mem = std.mem; +const system_defaults = @import("system_defaults"); +const target_util = @import("target.zig"); +const Linux = @import("toolchains/Linux.zig"); +const Multilib = @import("Driver/Multilib.zig"); +const Filesystem = @import("Driver/Filesystem.zig").Filesystem; + +pub const PathList = std.ArrayListUnmanaged([]const u8); + +pub const RuntimeLibKind = enum { + compiler_rt, + libgcc, +}; + +pub const FileKind = enum { + object, + static, + shared, +}; + +pub const LibGCCKind = enum { + unspecified, + static, + shared, +}; + +pub const UnwindLibKind = enum { + none, + compiler_rt, + libgcc, +}; + +const Inner = union(enum) { + uninitialized, + linux: Linux, + unknown: void, + + fn deinit(self: *Inner, allocator: mem.Allocator) void { + switch (self.*) { + .linux => |*linux| linux.deinit(allocator), + .uninitialized, .unknown => {}, + } + } +}; + +const Toolchain = @This(); + +filesystem: Filesystem = .{ .real = {} }, +driver: *Driver, +arena: mem.Allocator, + +/// The list of toolchain specific path prefixes to search for libraries. +library_paths: PathList = .{}, + +/// The list of toolchain specific path prefixes to search for files. +file_paths: PathList = .{}, + +/// The list of toolchain specific path prefixes to search for programs. +program_paths: PathList = .{}, + +selected_multilib: Multilib = .{}, + +inner: Inner = .{ .uninitialized = {} }, + +pub fn getTarget(tc: *const Toolchain) std.Target { + return tc.driver.comp.target; +} + +fn getDefaultLinker(tc: *const Toolchain) []const u8 { + return switch (tc.inner) { + .uninitialized => unreachable, + .linux => |linux| linux.getDefaultLinker(tc.getTarget()), + .unknown => "ld", + }; +} + +/// Call this after driver has finished parsing command line arguments to find the toolchain +pub fn discover(tc: *Toolchain) !void { + if (tc.inner != .uninitialized) return; + + const target = tc.getTarget(); + tc.inner = switch (target.os.tag) { + .elfiamcu, + .linux, + => if (target.cpu.arch == .hexagon) + .{ .unknown = {} } // TODO + else if (target.cpu.arch.isMIPS()) + .{ .unknown = {} } // TODO + else if (target.cpu.arch.isPowerPC()) + .{ .unknown = {} } // TODO + else if (target.cpu.arch == .ve) + .{ .unknown = {} } // TODO + else + .{ .linux = .{} }, + else => .{ .unknown = {} }, // TODO + }; + return switch (tc.inner) { + .uninitialized => unreachable, + .linux => |*linux| linux.discover(tc), + .unknown => {}, + }; +} + +pub fn deinit(tc: *Toolchain) void { + const gpa = tc.driver.comp.gpa; + tc.inner.deinit(gpa); + + tc.library_paths.deinit(gpa); + tc.file_paths.deinit(gpa); + tc.program_paths.deinit(gpa); +} + +/// Write linker path to `buf` and return a slice of it +pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 { + // --ld-path= takes precedence over -fuse-ld= and specifies the executable + // name. -B, COMPILER_PATH and PATH are consulted if the value does not + // contain a path component separator. + // -fuse-ld=lld can be used with --ld-path= to indicate that the binary + // that --ld-path= points to is lld. + const use_linker = tc.driver.use_linker orelse system_defaults.linker; + + if (tc.driver.linker_path) |ld_path| { + var path = ld_path; + if (path.len > 0) { + if (std.fs.path.dirname(path) == null) { + path = tc.getProgramPath(path, buf); + } + if (tc.filesystem.canExecute(path)) { + return path; + } + } + return tc.driver.fatal( + "invalid linker name in argument '--ld-path={s}'", + .{path}, + ); + } + + // If we're passed -fuse-ld= with no argument, or with the argument ld, + // then use whatever the default system linker is. + if (use_linker.len == 0 or mem.eql(u8, use_linker, "ld")) { + const default = tc.getDefaultLinker(); + if (std.fs.path.isAbsolute(default)) return default; + return tc.getProgramPath(default, buf); + } + + // Extending -fuse-ld= to an absolute or relative path is unexpected. Checking + // for the linker flavor is brittle. In addition, prepending "ld." or "ld64." + // to a relative path is surprising. This is more complex due to priorities + // among -B, COMPILER_PATH and PATH. --ld-path= should be used instead. + if (mem.indexOfScalar(u8, use_linker, '/') != null) { + try tc.driver.comp.addDiagnostic(.{ .tag = .fuse_ld_path }, &.{}); + } + + if (std.fs.path.isAbsolute(use_linker)) { + if (tc.filesystem.canExecute(use_linker)) { + return use_linker; + } + } else { + var linker_name = try std.ArrayList(u8).initCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker + defer linker_name.deinit(); + if (tc.getTarget().os.tag.isDarwin()) { + linker_name.appendSliceAssumeCapacity("ld64."); + } else { + linker_name.appendSliceAssumeCapacity("ld."); + } + linker_name.appendSliceAssumeCapacity(use_linker); + const linker_path = tc.getProgramPath(linker_name.items, buf); + if (tc.filesystem.canExecute(linker_path)) { + return linker_path; + } + } + + if (tc.driver.use_linker) |linker| { + return tc.driver.fatal( + "invalid linker name in argument '-fuse-ld={s}'", + .{linker}, + ); + } + const default_linker = tc.getDefaultLinker(); + return tc.getProgramPath(default_linker, buf); +} + +/// If an explicit target is provided, also check the prefixed tool-specific name +/// TODO: this isn't exactly right since our target names don't necessarily match up +/// with GCC's. +/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools +fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, buf: *[64]u8) std.BoundedArray([]const u8, 2) { + var possible_names: std.BoundedArray([]const u8, 2) = .{}; + if (raw_triple) |triple| { + if (std.fmt.bufPrint(buf, "{s}-{s}", .{ triple, name })) |res| { + possible_names.appendAssumeCapacity(res); + } else |_| {} + } + possible_names.appendAssumeCapacity(name); + + return possible_names; +} + +/// Add toolchain `file_paths` to argv as `-L` arguments +pub fn addFilePathLibArgs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void { + try argv.ensureUnusedCapacity(tc.file_paths.items.len); + + var bytes_needed: usize = 0; + for (tc.file_paths.items) |path| { + bytes_needed += path.len + 2; // +2 for `-L` + } + var bytes = try tc.arena.alloc(u8, bytes_needed); + var index: usize = 0; + for (tc.file_paths.items) |path| { + @memcpy(bytes[index..][0..2], "-L"); + @memcpy(bytes[index + 2 ..][0..path.len], path); + argv.appendAssumeCapacity(bytes[index..][0 .. path.len + 2]); + index += path.len + 2; + } +} + +/// Search for an executable called `name` or `{triple}-{name} in program_paths and the $PATH environment variable +/// If not found there, just use `name` +/// Writes the result to `buf` and returns a slice of it +fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8 { + var path_buf: [std.fs.max_path_bytes]u8 = undefined; + var fib = std.heap.FixedBufferAllocator.init(&path_buf); + + var tool_specific_buf: [64]u8 = undefined; + const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf); + + for (possible_names.constSlice()) |tool_name| { + for (tc.program_paths.items) |program_path| { + defer fib.reset(); + + const candidate = std.fs.path.join(fib.allocator(), &.{ program_path, tool_name }) catch continue; + + if (tc.filesystem.canExecute(candidate) and candidate.len <= buf.len) { + @memcpy(buf[0..candidate.len], candidate); + return buf[0..candidate.len]; + } + } + return tc.filesystem.findProgramByName(tc.driver.comp.gpa, name, tc.driver.comp.environment.path, buf) orelse continue; + } + @memcpy(buf[0..name.len], name); + return buf[0..name.len]; +} + +pub fn getSysroot(tc: *const Toolchain) []const u8 { + return tc.driver.sysroot orelse system_defaults.sysroot; +} + +/// Search for `name` in a variety of places +/// TODO: cache results based on `name` so we're not repeatedly allocating the same strings? +pub fn getFilePath(tc: *const Toolchain, name: []const u8) ![]const u8 { + var path_buf: [std.fs.max_path_bytes]u8 = undefined; + var fib = std.heap.FixedBufferAllocator.init(&path_buf); + const allocator = fib.allocator(); + + const sysroot = tc.getSysroot(); + + // todo check resource dir + // todo check compiler RT path + const aro_dir = std.fs.path.dirname(tc.driver.aro_name) orelse ""; + const candidate = try std.fs.path.join(allocator, &.{ aro_dir, "..", name }); + if (tc.filesystem.exists(candidate)) { + return tc.arena.dupe(u8, candidate); + } + + if (tc.searchPaths(&fib, sysroot, tc.library_paths.items, name)) |path| { + return tc.arena.dupe(u8, path); + } + + if (tc.searchPaths(&fib, sysroot, tc.file_paths.items, name)) |path| { + return try tc.arena.dupe(u8, path); + } + + return name; +} + +/// Search a list of `path_prefixes` for the existence `name` +/// Assumes that `fba` is a fixed-buffer allocator, so does not free joined path candidates +fn searchPaths(tc: *const Toolchain, fib: *std.heap.FixedBufferAllocator, sysroot: []const u8, path_prefixes: []const []const u8, name: []const u8) ?[]const u8 { + for (path_prefixes) |path| { + fib.reset(); + if (path.len == 0) continue; + + const candidate = if (path[0] == '=') + std.fs.path.join(fib.allocator(), &.{ sysroot, path[1..], name }) catch continue + else + std.fs.path.join(fib.allocator(), &.{ path, name }) catch continue; + + if (tc.filesystem.exists(candidate)) { + return candidate; + } + } + return null; +} + +const PathKind = enum { + library, + file, + program, +}; + +/// Join `components` into a path. If the path exists, dupe it into the toolchain arena and +/// add it to the specified path list. +pub fn addPathIfExists(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void { + var path_buf: [std.fs.max_path_bytes]u8 = undefined; + var fib = std.heap.FixedBufferAllocator.init(&path_buf); + + const candidate = try std.fs.path.join(fib.allocator(), components); + + if (tc.filesystem.exists(candidate)) { + const duped = try tc.arena.dupe(u8, candidate); + const dest = switch (dest_kind) { + .library => &tc.library_paths, + .file => &tc.file_paths, + .program => &tc.program_paths, + }; + try dest.append(tc.driver.comp.gpa, duped); + } +} + +/// Join `components` using the toolchain arena and add the resulting path to `dest_kind`. Does not check +/// whether the path actually exists +pub fn addPathFromComponents(tc: *Toolchain, components: []const []const u8, dest_kind: PathKind) !void { + const full_path = try std.fs.path.join(tc.arena, components); + const dest = switch (dest_kind) { + .library => &tc.library_paths, + .file => &tc.file_paths, + .program => &tc.program_paths, + }; + try dest.append(tc.driver.comp.gpa, full_path); +} + +/// Add linker args to `argv`. Does not add path to linker executable as first item; that must be handled separately +/// Items added to `argv` will be string literals or owned by `tc.arena` so they must not be individually freed +pub fn buildLinkerArgs(tc: *Toolchain, argv: *std.ArrayList([]const u8)) !void { + return switch (tc.inner) { + .uninitialized => unreachable, + .linux => |*linux| linux.buildLinkerArgs(tc, argv), + .unknown => @panic("This toolchain does not support linking yet"), + }; +} + +fn getDefaultRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind { + if (tc.getTarget().abi.isAndroid()) { + return .compiler_rt; + } + return .libgcc; +} + +pub fn getRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind { + const libname = tc.driver.rtlib orelse system_defaults.rtlib; + if (mem.eql(u8, libname, "compiler-rt")) + return .compiler_rt + else if (mem.eql(u8, libname, "libgcc")) + return .libgcc + else + return tc.getDefaultRuntimeLibKind(); +} + +/// TODO +pub fn getCompilerRt(tc: *const Toolchain, component: []const u8, file_kind: FileKind) ![]const u8 { + _ = file_kind; + _ = component; + _ = tc; + return ""; +} + +fn getLibGCCKind(tc: *const Toolchain) LibGCCKind { + const target = tc.getTarget(); + if (tc.driver.static_libgcc or tc.driver.static or tc.driver.static_pie or target.abi.isAndroid()) { + return .static; + } + if (tc.driver.shared_libgcc) { + return .shared; + } + return .unspecified; +} + +fn getUnwindLibKind(tc: *const Toolchain) !UnwindLibKind { + const libname = tc.driver.unwindlib orelse system_defaults.unwindlib; + if (libname.len == 0 or mem.eql(u8, libname, "platform")) { + switch (tc.getRuntimeLibKind()) { + .compiler_rt => { + const target = tc.getTarget(); + if (target.abi.isAndroid() or target.os.tag == .aix) { + return .compiler_rt; + } else { + return .none; + } + }, + .libgcc => return .libgcc, + } + } else if (mem.eql(u8, libname, "none")) { + return .none; + } else if (mem.eql(u8, libname, "libgcc")) { + return .libgcc; + } else if (mem.eql(u8, libname, "libunwind")) { + if (tc.getRuntimeLibKind() == .libgcc) { + try tc.driver.comp.addDiagnostic(.{ .tag = .incompatible_unwindlib }, &.{}); + } + return .compiler_rt; + } else { + unreachable; + } +} + +fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 { + if (is_solaris) { + return if (needed) "-zignore" else "-zrecord"; + } else { + return if (needed) "--as-needed" else "--no-as-needed"; + } +} + +fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void { + const unw = try tc.getUnwindLibKind(); + const target = tc.getTarget(); + if ((target.abi.isAndroid() and unw == .libgcc) or + target.os.tag == .elfiamcu or + target.ofmt == .wasm or + target_util.isWindowsMSVCEnvironment(target) or + unw == .none) return; + + const lgk = tc.getLibGCCKind(); + const as_needed = lgk == .unspecified and !target.abi.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix; + if (as_needed) { + try argv.append(getAsNeededOption(target.os.tag == .solaris, true)); + } + switch (unw) { + .none => return, + .libgcc => if (lgk == .static) try argv.append("-lgcc_eh") else try argv.append("-lgcc_s"), + .compiler_rt => if (target.os.tag == .aix) { + if (lgk != .static) { + try argv.append("-lunwind"); + } + } else if (lgk == .static) { + try argv.append("-l:libunwind.a"); + } else if (lgk == .shared) { + if (target_util.isCygwinMinGW(target)) { + try argv.append("-l:libunwind.dll.a"); + } else { + try argv.append("-l:libunwind.so"); + } + } else { + try argv.append("-lunwind"); + }, + } + + if (as_needed) { + try argv.append(getAsNeededOption(target.os.tag == .solaris, false)); + } +} + +fn addLibGCC(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void { + const libgcc_kind = tc.getLibGCCKind(); + if (libgcc_kind == .static or libgcc_kind == .unspecified) { + try argv.append("-lgcc"); + } + try tc.addUnwindLibrary(argv); + if (libgcc_kind == .shared) { + try argv.append("-lgcc"); + } +} + +pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void { + const target = tc.getTarget(); + const rlt = tc.getRuntimeLibKind(); + switch (rlt) { + .compiler_rt => { + // TODO + }, + .libgcc => { + if (target_util.isKnownWindowsMSVCEnvironment(target)) { + const rtlib_str = tc.driver.rtlib orelse system_defaults.rtlib; + if (!mem.eql(u8, rtlib_str, "platform")) { + try tc.driver.comp.addDiagnostic(.{ .tag = .unsupported_rtlib_gcc, .extra = .{ .str = "MSVC" } }, &.{}); + } + } else { + try tc.addLibGCC(argv); + } + }, + } + + if (target.abi.isAndroid() and !tc.driver.static and !tc.driver.static_pie) { + try argv.append("-ldl"); + } +} + +pub fn defineSystemIncludes(tc: *Toolchain) !void { + return switch (tc.inner) { + .uninitialized => unreachable, + .linux => |*linux| linux.defineSystemIncludes(tc), + .unknown => { + if (tc.driver.nostdinc) return; + + const comp = tc.driver.comp; + if (!tc.driver.nobuiltininc) { + try comp.addBuiltinIncludeDir(tc.driver.aro_name); + } + + if (!tc.driver.nostdlibinc) { + try comp.addSystemIncludeDir("/usr/include"); + } + }, + }; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tree.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tree.zig new file mode 100644 index 00000000..a1b15bd6 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tree.zig @@ -0,0 +1,1435 @@ +const std = @import("std"); +const Interner = @import("../backend.zig").Interner; +const Attribute = @import("Attribute.zig"); +const CodeGen = @import("CodeGen.zig"); +const Compilation = @import("Compilation.zig"); +const number_affixes = @import("Tree/number_affixes.zig"); +const Source = @import("Source.zig"); +const Tokenizer = @import("Tokenizer.zig"); +const Type = @import("Type.zig"); +const Value = @import("Value.zig"); +const StringInterner = @import("StringInterner.zig"); + +pub const Token = struct { + id: Id, + loc: Source.Location, + + pub const List = std.MultiArrayList(Token); + pub const Id = Tokenizer.Token.Id; + pub const NumberPrefix = number_affixes.Prefix; + pub const NumberSuffix = number_affixes.Suffix; +}; + +pub const TokenWithExpansionLocs = struct { + id: Token.Id, + flags: packed struct { + expansion_disabled: bool = false, + is_macro_arg: bool = false, + } = .{}, + /// This location contains the actual token slice which might be generated. + /// If it is generated then there is guaranteed to be at least one + /// expansion location. + loc: Source.Location, + expansion_locs: ?[*]Source.Location = null, + + pub fn expansionSlice(tok: TokenWithExpansionLocs) []const Source.Location { + const locs = tok.expansion_locs orelse return &[0]Source.Location{}; + var i: usize = 0; + while (locs[i].id != .unused) : (i += 1) {} + return locs[0..i]; + } + + pub fn addExpansionLocation(tok: *TokenWithExpansionLocs, gpa: std.mem.Allocator, new: []const Source.Location) !void { + if (new.len == 0 or tok.id == .whitespace or tok.id == .macro_ws or tok.id == .placemarker) return; + var list = std.ArrayList(Source.Location).init(gpa); + defer { + @memset(list.items.ptr[list.items.len..list.capacity], .{}); + // Add a sentinel to indicate the end of the list since + // the ArrayList's capacity isn't guaranteed to be exactly + // what we ask for. + if (list.capacity > 0) { + list.items.ptr[list.capacity - 1].byte_offset = 1; + } + tok.expansion_locs = list.items.ptr; + } + + if (tok.expansion_locs) |locs| { + var i: usize = 0; + while (locs[i].id != .unused) : (i += 1) {} + list.items = locs[0..i]; + while (locs[i].byte_offset != 1) : (i += 1) {} + list.capacity = i + 1; + } + + const min_len = @max(list.items.len + new.len + 1, 4); + const wanted_len = std.math.ceilPowerOfTwo(usize, min_len) catch + return error.OutOfMemory; + try list.ensureTotalCapacity(wanted_len); + + for (new) |new_loc| { + if (new_loc.id == .generated) continue; + list.appendAssumeCapacity(new_loc); + } + } + + pub fn free(expansion_locs: ?[*]Source.Location, gpa: std.mem.Allocator) void { + const locs = expansion_locs orelse return; + var i: usize = 0; + while (locs[i].id != .unused) : (i += 1) {} + while (locs[i].byte_offset != 1) : (i += 1) {} + gpa.free(locs[0 .. i + 1]); + } + + pub fn dupe(tok: TokenWithExpansionLocs, gpa: std.mem.Allocator) !TokenWithExpansionLocs { + var copy = tok; + copy.expansion_locs = null; + try copy.addExpansionLocation(gpa, tok.expansionSlice()); + return copy; + } + + pub fn checkMsEof(tok: TokenWithExpansionLocs, source: Source, comp: *Compilation) !void { + std.debug.assert(tok.id == .eof); + if (source.buf.len > tok.loc.byte_offset and source.buf[tok.loc.byte_offset] == 0x1A) { + try comp.addDiagnostic(.{ + .tag = .ctrl_z_eof, + .loc = .{ + .id = source.id, + .byte_offset = tok.loc.byte_offset, + .line = tok.loc.line, + }, + }, &.{}); + } + } +}; + +pub const TokenIndex = u32; +pub const NodeIndex = enum(u32) { none, _ }; +pub const ValueMap = std.AutoHashMap(NodeIndex, Value); + +const Tree = @This(); + +comp: *Compilation, +arena: std.heap.ArenaAllocator, +generated: []const u8, +tokens: Token.List.Slice, +nodes: Node.List.Slice, +data: []const NodeIndex, +root_decls: []const NodeIndex, +value_map: ValueMap, + +pub const genIr = CodeGen.genIr; + +pub fn deinit(tree: *Tree) void { + tree.comp.gpa.free(tree.root_decls); + tree.comp.gpa.free(tree.data); + tree.nodes.deinit(tree.comp.gpa); + tree.arena.deinit(); + tree.value_map.deinit(); +} + +pub const GNUAssemblyQualifiers = struct { + @"volatile": bool = false, + @"inline": bool = false, + goto: bool = false, +}; + +pub const Node = struct { + tag: Tag, + ty: Type = .{ .specifier = .void }, + data: Data, + loc: Loc = .none, + + pub const Range = struct { start: u32, end: u32 }; + + pub const Loc = enum(u32) { + none = std.math.maxInt(u32), + _, + }; + + pub const Data = union { + decl: struct { + name: TokenIndex, + node: NodeIndex = .none, + }, + decl_ref: TokenIndex, + two: [2]NodeIndex, + range: Range, + if3: struct { + cond: NodeIndex, + body: u32, + }, + un: NodeIndex, + bin: struct { + lhs: NodeIndex, + rhs: NodeIndex, + }, + member: struct { + lhs: NodeIndex, + index: u32, + }, + union_init: struct { + field_index: u32, + node: NodeIndex, + }, + cast: struct { + operand: NodeIndex, + kind: CastKind, + }, + int: u64, + return_zero: bool, + + pub fn forDecl(data: Data, tree: *const Tree) struct { + decls: []const NodeIndex, + cond: NodeIndex, + incr: NodeIndex, + body: NodeIndex, + } { + const items = tree.data[data.range.start..data.range.end]; + const decls = items[0 .. items.len - 3]; + + return .{ + .decls = decls, + .cond = items[items.len - 3], + .incr = items[items.len - 2], + .body = items[items.len - 1], + }; + } + + pub fn forStmt(data: Data, tree: *const Tree) struct { + init: NodeIndex, + cond: NodeIndex, + incr: NodeIndex, + body: NodeIndex, + } { + const items = tree.data[data.if3.body..]; + + return .{ + .init = items[0], + .cond = items[1], + .incr = items[2], + .body = data.if3.cond, + }; + } + }; + + pub const List = std.MultiArrayList(Node); +}; + +pub const CastKind = enum(u8) { + /// Does nothing except possibly add qualifiers + no_op, + /// Interpret one bit pattern as another. Used for operands which have the same + /// size and unrelated types, e.g. casting one pointer type to another + bitcast, + /// Convert T[] to T * + array_to_pointer, + /// Converts an lvalue to an rvalue + lval_to_rval, + /// Convert a function type to a pointer to a function + function_to_pointer, + /// Convert a pointer type to a _Bool + pointer_to_bool, + /// Convert a pointer type to an integer type + pointer_to_int, + /// Convert _Bool to an integer type + bool_to_int, + /// Convert _Bool to a floating type + bool_to_float, + /// Convert a _Bool to a pointer; will cause a warning + bool_to_pointer, + /// Convert an integer type to _Bool + int_to_bool, + /// Convert an integer to a floating type + int_to_float, + /// Convert a complex integer to a complex floating type + complex_int_to_complex_float, + /// Convert an integer type to a pointer type + int_to_pointer, + /// Convert a floating type to a _Bool + float_to_bool, + /// Convert a floating type to an integer + float_to_int, + /// Convert a complex floating type to a complex integer + complex_float_to_complex_int, + /// Convert one integer type to another + int_cast, + /// Convert one complex integer type to another + complex_int_cast, + /// Convert real part of complex integer to a integer + complex_int_to_real, + /// Create a complex integer type using operand as the real part + real_to_complex_int, + /// Convert one floating type to another + float_cast, + /// Convert one complex floating type to another + complex_float_cast, + /// Convert real part of complex float to a float + complex_float_to_real, + /// Create a complex floating type using operand as the real part + real_to_complex_float, + /// Convert type to void + to_void, + /// Convert a literal 0 to a null pointer + null_to_pointer, + /// GNU cast-to-union extension + union_cast, + /// Create vector where each value is same as the input scalar. + vector_splat, +}; + +pub const Tag = enum(u8) { + /// Must appear at index 0. Also used as the tag for __builtin_types_compatible_p arguments, since the arguments are types + /// Reaching it is always the result of a bug. + invalid, + + // ====== Decl ====== + + /// _Static_assert + /// loc is token index of _Static_assert + static_assert, + + // function prototype + fn_proto, + static_fn_proto, + inline_fn_proto, + inline_static_fn_proto, + + // function definition + fn_def, + static_fn_def, + inline_fn_def, + inline_static_fn_def, + + // variable declaration + @"var", + extern_var, + static_var, + // same as static_var, used for __func__, __FUNCTION__ and __PRETTY_FUNCTION__ + implicit_static_var, + threadlocal_var, + threadlocal_extern_var, + threadlocal_static_var, + + /// __asm__("...") at file scope + /// loc is token index of __asm__ keyword + file_scope_asm, + + // typedef declaration + typedef, + + // container declarations + /// { two[0]; two[1]; } + struct_decl_two, + /// { two[0]; two[1]; } + union_decl_two, + /// { two[0], two[1], } + enum_decl_two, + /// { range } + struct_decl, + /// { range } + union_decl, + /// { range } + enum_decl, + /// struct decl_ref; + struct_forward_decl, + /// union decl_ref; + union_forward_decl, + /// enum decl_ref; + enum_forward_decl, + + /// name = node + enum_field_decl, + /// ty name : node + /// name == 0 means unnamed + record_field_decl, + /// Used when a record has an unnamed record as a field + indirect_record_field_decl, + + // ====== Stmt ====== + + labeled_stmt, + /// { two[0]; two[1]; } first and second may be null + compound_stmt_two, + /// { data } + compound_stmt, + /// if (first) data[second] else data[second+1]; + if_then_else_stmt, + /// if (first) second; second may be null + if_then_stmt, + /// switch (first) second + switch_stmt, + /// case first: second + case_stmt, + /// case data[body]...data[body+1]: cond + case_range_stmt, + /// default: first + default_stmt, + /// while (first) second + while_stmt, + /// do second while(first); + do_while_stmt, + /// for (data[..]; data[len-3]; data[len-2]) data[len-1] + for_decl_stmt, + /// for (;;;) first + forever_stmt, + /// for (data[first]; data[first+1]; data[first+2]) second + for_stmt, + /// goto first; + goto_stmt, + /// goto *un; + computed_goto_stmt, + // continue; first and second unused + continue_stmt, + // break; first and second unused + break_stmt, + // null statement (just a semicolon); first and second unused + null_stmt, + /// return first; first may be null + return_stmt, + /// Assembly statement of the form __asm__("string literal") + gnu_asm_simple, + + // ====== Expr ====== + + /// lhs , rhs + comma_expr, + /// lhs ? data[0] : data[1] + binary_cond_expr, + /// Used as the base for casts of the lhs in `binary_cond_expr`. + cond_dummy_expr, + /// lhs ? data[0] : data[1] + cond_expr, + /// lhs = rhs + assign_expr, + /// lhs *= rhs + mul_assign_expr, + /// lhs /= rhs + div_assign_expr, + /// lhs %= rhs + mod_assign_expr, + /// lhs += rhs + add_assign_expr, + /// lhs -= rhs + sub_assign_expr, + /// lhs <<= rhs + shl_assign_expr, + /// lhs >>= rhs + shr_assign_expr, + /// lhs &= rhs + bit_and_assign_expr, + /// lhs ^= rhs + bit_xor_assign_expr, + /// lhs |= rhs + bit_or_assign_expr, + /// lhs || rhs + bool_or_expr, + /// lhs && rhs + bool_and_expr, + /// lhs | rhs + bit_or_expr, + /// lhs ^ rhs + bit_xor_expr, + /// lhs & rhs + bit_and_expr, + /// lhs == rhs + equal_expr, + /// lhs != rhs + not_equal_expr, + /// lhs < rhs + less_than_expr, + /// lhs <= rhs + less_than_equal_expr, + /// lhs > rhs + greater_than_expr, + /// lhs >= rhs + greater_than_equal_expr, + /// lhs << rhs + shl_expr, + /// lhs >> rhs + shr_expr, + /// lhs + rhs + add_expr, + /// lhs - rhs + sub_expr, + /// lhs * rhs + mul_expr, + /// lhs / rhs + div_expr, + /// lhs % rhs + mod_expr, + /// Explicit: (type) cast + explicit_cast, + /// Implicit: cast + implicit_cast, + /// &un + addr_of_expr, + /// &&decl_ref + addr_of_label, + /// *un + deref_expr, + /// +un + plus_expr, + /// -un + negate_expr, + /// ~un + bit_not_expr, + /// !un + bool_not_expr, + /// ++un + pre_inc_expr, + /// --un + pre_dec_expr, + /// __imag un + imag_expr, + /// __real un + real_expr, + /// lhs[rhs] lhs is pointer/array type, rhs is integer type + array_access_expr, + /// two[0](two[1]) two[1] may be 0 + call_expr_one, + /// data[0](data[1..]) + call_expr, + /// decl + builtin_call_expr_one, + builtin_call_expr, + /// lhs.member + member_access_expr, + /// lhs->member + member_access_ptr_expr, + /// un++ + post_inc_expr, + /// un-- + post_dec_expr, + /// (un) + paren_expr, + /// decl_ref + decl_ref_expr, + /// decl_ref + enumeration_ref, + /// C23 bool literal `true` / `false` + bool_literal, + /// C23 nullptr literal + nullptr_literal, + /// integer literal, always unsigned + int_literal, + /// Same as int_literal, but originates from a char literal + char_literal, + /// a floating point literal + float_literal, + /// wraps a float or double literal: un + imaginary_literal, + /// tree.str[index..][0..len] + string_literal_expr, + /// sizeof(un?) + sizeof_expr, + /// _Alignof(un?) + alignof_expr, + /// _Generic(controlling two[0], chosen two[1]) + generic_expr_one, + /// _Generic(controlling range[0], chosen range[1], rest range[2..]) + generic_expr, + /// ty: un + generic_association_expr, + // default: un + generic_default_expr, + /// __builtin_choose_expr(lhs, data[0], data[1]) + builtin_choose_expr, + /// __builtin_types_compatible_p(lhs, rhs) + builtin_types_compatible_p, + /// decl - special builtins require custom parsing + special_builtin_call_one, + /// ({ un }) + stmt_expr, + + // ====== Initializer expressions ====== + + /// { two[0], two[1] } + array_init_expr_two, + /// { range } + array_init_expr, + /// { two[0], two[1] } + struct_init_expr_two, + /// { range } + struct_init_expr, + /// { union_init } + union_init_expr, + + /// (ty){ un } + /// loc is token index of l_paren + compound_literal_expr, + /// (static ty){ un } + /// loc is token index of l_paren + static_compound_literal_expr, + /// (thread_local ty){ un } + /// loc is token index of l_paren + thread_local_compound_literal_expr, + /// (static thread_local ty){ un } + /// loc is token index of l_paren + static_thread_local_compound_literal_expr, + + /// Inserted at the end of a function body if no return stmt is found. + /// ty is the functions return type + /// data is return_zero which is true if the function is called "main" and ty is compatible with int + /// loc is token index of closing r_brace of function + implicit_return, + + /// Inserted in array_init_expr to represent unspecified elements. + /// data.int contains the amount of elements. + array_filler_expr, + /// Inserted in record and scalar initializers for unspecified elements. + default_init_expr, + + pub fn isImplicit(tag: Tag) bool { + return switch (tag) { + .implicit_cast, + .implicit_return, + .array_filler_expr, + .default_init_expr, + .implicit_static_var, + .cond_dummy_expr, + => true, + else => false, + }; + } +}; + +pub fn isBitfield(tree: *const Tree, node: NodeIndex) bool { + return tree.bitfieldWidth(node, false) != null; +} + +/// Returns null if node is not a bitfield. If inspect_lval is true, this function will +/// recurse into implicit lval_to_rval casts (useful for arithmetic conversions) +pub fn bitfieldWidth(tree: *const Tree, node: NodeIndex, inspect_lval: bool) ?u32 { + if (node == .none) return null; + switch (tree.nodes.items(.tag)[@intFromEnum(node)]) { + .member_access_expr, .member_access_ptr_expr => { + const member = tree.nodes.items(.data)[@intFromEnum(node)].member; + var ty = tree.nodes.items(.ty)[@intFromEnum(member.lhs)]; + if (ty.isPtr()) ty = ty.elemType(); + const record_ty = ty.get(.@"struct") orelse ty.get(.@"union") orelse return null; + const field = record_ty.data.record.fields[member.index]; + return field.bit_width; + }, + .implicit_cast => { + if (!inspect_lval) return null; + + const data = tree.nodes.items(.data)[@intFromEnum(node)]; + return switch (data.cast.kind) { + .lval_to_rval => tree.bitfieldWidth(data.cast.operand, false), + else => null, + }; + }, + else => return null, + } +} + +const CallableResultUsage = struct { + /// name token of the thing being called, for diagnostics + tok: TokenIndex, + /// true if `nodiscard` attribute present + nodiscard: bool, + /// true if `warn_unused_result` attribute present + warn_unused_result: bool, +}; + +pub fn callableResultUsage(tree: *const Tree, node: NodeIndex) ?CallableResultUsage { + const data = tree.nodes.items(.data); + + var cur_node = node; + while (true) switch (tree.nodes.items(.tag)[@intFromEnum(cur_node)]) { + .decl_ref_expr => { + const tok = data[@intFromEnum(cur_node)].decl_ref; + const fn_ty = tree.nodes.items(.ty)[@intFromEnum(node)].elemType(); + return .{ + .tok = tok, + .nodiscard = fn_ty.hasAttribute(.nodiscard), + .warn_unused_result = fn_ty.hasAttribute(.warn_unused_result), + }; + }, + .paren_expr => cur_node = data[@intFromEnum(cur_node)].un, + .comma_expr => cur_node = data[@intFromEnum(cur_node)].bin.rhs, + + .explicit_cast, .implicit_cast => cur_node = data[@intFromEnum(cur_node)].cast.operand, + .addr_of_expr, .deref_expr => cur_node = data[@intFromEnum(cur_node)].un, + .call_expr_one => cur_node = data[@intFromEnum(cur_node)].two[0], + .call_expr => cur_node = tree.data[data[@intFromEnum(cur_node)].range.start], + .member_access_expr, .member_access_ptr_expr => { + const member = data[@intFromEnum(cur_node)].member; + var ty = tree.nodes.items(.ty)[@intFromEnum(member.lhs)]; + if (ty.isPtr()) ty = ty.elemType(); + const record = ty.getRecord().?; + const field = record.fields[member.index]; + const attributes = if (record.field_attributes) |attrs| attrs[member.index] else &.{}; + return .{ + .tok = field.name_tok, + .nodiscard = for (attributes) |attr| { + if (attr.tag == .nodiscard) break true; + } else false, + .warn_unused_result = for (attributes) |attr| { + if (attr.tag == .warn_unused_result) break true; + } else false, + }; + }, + else => return null, + }; +} + +pub fn isLval(tree: *const Tree, node: NodeIndex) bool { + var is_const: bool = undefined; + return tree.isLvalExtra(node, &is_const); +} + +pub fn isLvalExtra(tree: *const Tree, node: NodeIndex, is_const: *bool) bool { + is_const.* = false; + switch (tree.nodes.items(.tag)[@intFromEnum(node)]) { + .compound_literal_expr, + .static_compound_literal_expr, + .thread_local_compound_literal_expr, + .static_thread_local_compound_literal_expr, + => { + is_const.* = tree.nodes.items(.ty)[@intFromEnum(node)].isConst(); + return true; + }, + .string_literal_expr => return true, + .member_access_ptr_expr => { + const lhs_expr = tree.nodes.items(.data)[@intFromEnum(node)].member.lhs; + const ptr_ty = tree.nodes.items(.ty)[@intFromEnum(lhs_expr)]; + if (ptr_ty.isPtr()) is_const.* = ptr_ty.elemType().isConst(); + return true; + }, + .array_access_expr => { + const lhs_expr = tree.nodes.items(.data)[@intFromEnum(node)].bin.lhs; + if (lhs_expr != .none) { + const array_ty = tree.nodes.items(.ty)[@intFromEnum(lhs_expr)]; + if (array_ty.isPtr() or array_ty.isArray()) is_const.* = array_ty.elemType().isConst(); + } + return true; + }, + .decl_ref_expr => { + const decl_ty = tree.nodes.items(.ty)[@intFromEnum(node)]; + is_const.* = decl_ty.isConst(); + return true; + }, + .deref_expr => { + const data = tree.nodes.items(.data)[@intFromEnum(node)]; + const operand_ty = tree.nodes.items(.ty)[@intFromEnum(data.un)]; + if (operand_ty.isFunc()) return false; + if (operand_ty.isPtr() or operand_ty.isArray()) is_const.* = operand_ty.elemType().isConst(); + return true; + }, + .member_access_expr => { + const data = tree.nodes.items(.data)[@intFromEnum(node)]; + return tree.isLvalExtra(data.member.lhs, is_const); + }, + .paren_expr => { + const data = tree.nodes.items(.data)[@intFromEnum(node)]; + return tree.isLvalExtra(data.un, is_const); + }, + .builtin_choose_expr => { + const data = tree.nodes.items(.data)[@intFromEnum(node)]; + + if (tree.value_map.get(data.if3.cond)) |val| { + const offset = @intFromBool(val.isZero(tree.comp)); + return tree.isLvalExtra(tree.data[data.if3.body + offset], is_const); + } + return false; + }, + else => return false, + } +} + +/// This should only be used for node tags that represent AST nodes which have an arbitrary number of children +/// It particular it should *not* be used for nodes with .un or .bin data types +/// +/// For call expressions, child_nodes[0] is the function pointer being called and child_nodes[1..] +/// are the arguments +/// +/// For generic selection expressions, child_nodes[0] is the controlling expression, +/// child_nodes[1] is the chosen expression (it is a syntax error for there to be no chosen expression), +/// and child_nodes[2..] are the remaining expressions. +pub fn childNodes(tree: *const Tree, node: NodeIndex) []const NodeIndex { + const tags = tree.nodes.items(.tag); + const data = tree.nodes.items(.data); + switch (tags[@intFromEnum(node)]) { + .compound_stmt_two, + .array_init_expr_two, + .struct_init_expr_two, + .enum_decl_two, + .struct_decl_two, + .union_decl_two, + .call_expr_one, + .generic_expr_one, + => { + const index: u32 = @intFromEnum(node); + const end = std.mem.indexOfScalar(NodeIndex, &data[index].two, .none) orelse 2; + return data[index].two[0..end]; + }, + .compound_stmt, + .array_init_expr, + .struct_init_expr, + .enum_decl, + .struct_decl, + .union_decl, + .call_expr, + .generic_expr, + => { + const range = data[@intFromEnum(node)].range; + return tree.data[range.start..range.end]; + }, + else => unreachable, + } +} + +pub fn tokSlice(tree: *const Tree, tok_i: TokenIndex) []const u8 { + if (tree.tokens.items(.id)[tok_i].lexeme()) |some| return some; + const loc = tree.tokens.items(.loc)[tok_i]; + return tree.comp.locSlice(loc); +} + +pub fn nodeTok(tree: *const Tree, node: NodeIndex) ?TokenIndex { + std.debug.assert(node != .none); + const loc = tree.nodes.items(.loc)[@intFromEnum(node)]; + return switch (loc) { + .none => null, + else => |tok_i| @intFromEnum(tok_i), + }; +} + +pub fn nodeLoc(tree: *const Tree, node: NodeIndex) ?Source.Location { + const tok_i = tree.nodeTok(node) orelse return null; + return tree.tokens.items(.loc)[@intFromEnum(tok_i)]; +} + +pub fn dump(tree: *const Tree, config: std.io.tty.Config, writer: anytype) !void { + const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper(); + defer mapper.deinit(tree.comp.gpa); + + for (tree.root_decls) |i| { + try tree.dumpNode(i, 0, mapper, config, writer); + try writer.writeByte('\n'); + } +} + +fn dumpFieldAttributes(tree: *const Tree, attributes: []const Attribute, level: u32, writer: anytype) !void { + for (attributes) |attr| { + try writer.writeByteNTimes(' ', level); + try writer.print("field attr: {s}", .{@tagName(attr.tag)}); + try tree.dumpAttribute(attr, writer); + } +} + +fn dumpAttribute(tree: *const Tree, attr: Attribute, writer: anytype) !void { + switch (attr.tag) { + inline else => |tag| { + const args = @field(attr.args, @tagName(tag)); + const fields = @typeInfo(@TypeOf(args)).@"struct".fields; + if (fields.len == 0) { + try writer.writeByte('\n'); + return; + } + try writer.writeByte(' '); + inline for (fields, 0..) |f, i| { + if (comptime std.mem.eql(u8, f.name, "__name_tok")) continue; + if (i != 0) { + try writer.writeAll(", "); + } + try writer.writeAll(f.name); + try writer.writeAll(": "); + switch (f.type) { + Interner.Ref => try writer.print("\"{s}\"", .{tree.interner.get(@field(args, f.name)).bytes}), + ?Interner.Ref => try writer.print("\"{?s}\"", .{if (@field(args, f.name)) |str| tree.interner.get(str).bytes else null}), + else => switch (@typeInfo(f.type)) { + .@"enum" => try writer.writeAll(@tagName(@field(args, f.name))), + else => try writer.print("{any}", .{@field(args, f.name)}), + }, + } + } + try writer.writeByte('\n'); + return; + }, + } +} + +fn dumpNode( + tree: *const Tree, + node: NodeIndex, + level: u32, + mapper: StringInterner.TypeMapper, + config: std.io.tty.Config, + w: anytype, +) !void { + const delta = 2; + const half = delta / 2; + const TYPE = std.io.tty.Color.bright_magenta; + const TAG = std.io.tty.Color.bright_cyan; + const IMPLICIT = std.io.tty.Color.bright_blue; + const NAME = std.io.tty.Color.bright_red; + const LITERAL = std.io.tty.Color.bright_green; + const ATTRIBUTE = std.io.tty.Color.bright_yellow; + std.debug.assert(node != .none); + + const tag = tree.nodes.items(.tag)[@intFromEnum(node)]; + const data = tree.nodes.items(.data)[@intFromEnum(node)]; + const ty = tree.nodes.items(.ty)[@intFromEnum(node)]; + try w.writeByteNTimes(' ', level); + + try config.setColor(w, if (tag.isImplicit()) IMPLICIT else TAG); + try w.print("{s}: ", .{@tagName(tag)}); + if (tag == .implicit_cast or tag == .explicit_cast) { + try config.setColor(w, .white); + try w.print("({s}) ", .{@tagName(data.cast.kind)}); + } + try config.setColor(w, TYPE); + try w.writeByte('\''); + const name = ty.getName(); + if (name != .empty) { + try w.print("{s}': '", .{mapper.lookup(name)}); + } + try ty.dump(mapper, tree.comp.langopts, w); + try w.writeByte('\''); + + if (tree.isLval(node)) { + try config.setColor(w, ATTRIBUTE); + try w.writeAll(" lvalue"); + } + if (tree.isBitfield(node)) { + try config.setColor(w, ATTRIBUTE); + try w.writeAll(" bitfield"); + } + if (tree.value_map.get(node)) |val| { + try config.setColor(w, LITERAL); + try w.writeAll(" (value: "); + try val.print(ty, tree.comp, w); + try w.writeByte(')'); + } + if (tag == .implicit_return and data.return_zero) { + try config.setColor(w, IMPLICIT); + try w.writeAll(" (value: 0)"); + try config.setColor(w, .reset); + } + + try w.writeAll("\n"); + try config.setColor(w, .reset); + + if (ty.specifier == .attributed) { + try config.setColor(w, ATTRIBUTE); + var it = Attribute.Iterator.initType(ty); + while (it.next()) |item| { + const attr, _ = item; + try w.writeByteNTimes(' ', level + half); + try w.print("attr: {s}", .{@tagName(attr.tag)}); + try tree.dumpAttribute(attr, w); + } + try config.setColor(w, .reset); + } + + switch (tag) { + .invalid => unreachable, + .file_scope_asm => { + try w.writeByteNTimes(' ', level + 1); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + }, + .gnu_asm_simple => { + try w.writeByteNTimes(' ', level); + try tree.dumpNode(data.un, level, mapper, config, w); + }, + .static_assert => { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("condition:\n"); + try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w); + if (data.bin.rhs != .none) { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("diagnostic:\n"); + try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w); + } + }, + .fn_proto, + .static_fn_proto, + .inline_fn_proto, + .inline_static_fn_proto, + => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + }, + .fn_def, + .static_fn_def, + .inline_fn_def, + .inline_static_fn_def, + => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + try w.writeByteNTimes(' ', level + half); + try w.writeAll("body:\n"); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + }, + .typedef, + .@"var", + .extern_var, + .static_var, + .implicit_static_var, + .threadlocal_var, + .threadlocal_extern_var, + .threadlocal_static_var, + => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + if (data.decl.node != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("init:\n"); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + } + }, + .enum_field_decl => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + if (data.decl.node != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("value:\n"); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + } + }, + .record_field_decl => { + if (data.decl.name != 0) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + } + if (data.decl.node != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("bits:\n"); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + } + }, + .indirect_record_field_decl => {}, + .compound_stmt, + .array_init_expr, + .struct_init_expr, + .enum_decl, + .struct_decl, + .union_decl, + .compound_stmt_two, + .array_init_expr_two, + .struct_init_expr_two, + .enum_decl_two, + .struct_decl_two, + .union_decl_two, + => { + const child_nodes = tree.childNodes(node); + const maybe_field_attributes = if (ty.getRecord()) |record| record.field_attributes else null; + for (child_nodes, 0..) |stmt, i| { + if (i != 0) try w.writeByte('\n'); + try tree.dumpNode(stmt, level + delta, mapper, config, w); + if (maybe_field_attributes) |field_attributes| { + if (field_attributes[i].len == 0) continue; + + try config.setColor(w, ATTRIBUTE); + try tree.dumpFieldAttributes(field_attributes[i], level + delta + half, w); + try config.setColor(w, .reset); + } + } + }, + .union_init_expr => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("field index: "); + try config.setColor(w, LITERAL); + try w.print("{d}\n", .{data.union_init.field_index}); + try config.setColor(w, .reset); + if (data.union_init.node != .none) { + try tree.dumpNode(data.union_init.node, level + delta, mapper, config, w); + } + }, + .compound_literal_expr, + .static_compound_literal_expr, + .thread_local_compound_literal_expr, + .static_thread_local_compound_literal_expr, + => { + try tree.dumpNode(data.un, level + half, mapper, config, w); + }, + .labeled_stmt => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("label: "); + try config.setColor(w, LITERAL); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + if (data.decl.node != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("stmt:\n"); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + } + }, + .case_stmt => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("value:\n"); + try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w); + if (data.bin.rhs != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("stmt:\n"); + try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w); + } + }, + .case_range_stmt => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("range start:\n"); + try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, config, w); + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("range end:\n"); + try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, config, w); + + if (data.if3.cond != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("stmt:\n"); + try tree.dumpNode(data.if3.cond, level + delta, mapper, config, w); + } + }, + .default_stmt => { + if (data.un != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("stmt:\n"); + try tree.dumpNode(data.un, level + delta, mapper, config, w); + } + }, + .binary_cond_expr, .cond_expr, .if_then_else_stmt, .builtin_choose_expr => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("cond:\n"); + try tree.dumpNode(data.if3.cond, level + delta, mapper, config, w); + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("then:\n"); + try tree.dumpNode(tree.data[data.if3.body], level + delta, mapper, config, w); + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("else:\n"); + try tree.dumpNode(tree.data[data.if3.body + 1], level + delta, mapper, config, w); + }, + .builtin_types_compatible_p => { + std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.lhs)] == .invalid); + std.debug.assert(tree.nodes.items(.tag)[@intFromEnum(data.bin.rhs)] == .invalid); + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("lhs: "); + + const lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.lhs)]; + try config.setColor(w, TYPE); + try lhs_ty.dump(mapper, tree.comp.langopts, w); + try config.setColor(w, .reset); + try w.writeByte('\n'); + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("rhs: "); + + const rhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.bin.rhs)]; + try config.setColor(w, TYPE); + try rhs_ty.dump(mapper, tree.comp.langopts, w); + try config.setColor(w, .reset); + try w.writeByte('\n'); + }, + .if_then_stmt => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("cond:\n"); + try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w); + + if (data.bin.rhs != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("then:\n"); + try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w); + } + }, + .switch_stmt, .while_stmt, .do_while_stmt => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("cond:\n"); + try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w); + + if (data.bin.rhs != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("body:\n"); + try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w); + } + }, + .for_decl_stmt => { + const for_decl = data.forDecl(tree); + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("decl:\n"); + for (for_decl.decls) |decl| { + try tree.dumpNode(decl, level + delta, mapper, config, w); + try w.writeByte('\n'); + } + if (for_decl.cond != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("cond:\n"); + try tree.dumpNode(for_decl.cond, level + delta, mapper, config, w); + } + if (for_decl.incr != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("incr:\n"); + try tree.dumpNode(for_decl.incr, level + delta, mapper, config, w); + } + if (for_decl.body != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("body:\n"); + try tree.dumpNode(for_decl.body, level + delta, mapper, config, w); + } + }, + .forever_stmt => { + if (data.un != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("body:\n"); + try tree.dumpNode(data.un, level + delta, mapper, config, w); + } + }, + .for_stmt => { + const for_stmt = data.forStmt(tree); + + if (for_stmt.init != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("init:\n"); + try tree.dumpNode(for_stmt.init, level + delta, mapper, config, w); + } + if (for_stmt.cond != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("cond:\n"); + try tree.dumpNode(for_stmt.cond, level + delta, mapper, config, w); + } + if (for_stmt.incr != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("incr:\n"); + try tree.dumpNode(for_stmt.incr, level + delta, mapper, config, w); + } + if (for_stmt.body != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("body:\n"); + try tree.dumpNode(for_stmt.body, level + delta, mapper, config, w); + } + }, + .goto_stmt, .addr_of_label => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("label: "); + try config.setColor(w, LITERAL); + try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)}); + try config.setColor(w, .reset); + }, + .continue_stmt, .break_stmt, .implicit_return, .null_stmt => {}, + .return_stmt => { + if (data.un != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("expr:\n"); + try tree.dumpNode(data.un, level + delta, mapper, config, w); + } + }, + .call_expr, .call_expr_one => { + const child_nodes = tree.childNodes(node); + const fn_ptr = child_nodes[0]; + const args = child_nodes[1..]; + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("lhs:\n"); + try tree.dumpNode(fn_ptr, level + delta, mapper, config, w); + + if (args.len > 0) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("args:\n"); + for (args) |arg| { + try tree.dumpNode(arg, level + delta, mapper, config, w); + } + } + }, + .builtin_call_expr => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(@intFromEnum(tree.data[data.range.start]))}); + try config.setColor(w, .reset); + + try w.writeByteNTimes(' ', level + half); + try w.writeAll("args:\n"); + for (tree.data[data.range.start + 1 .. data.range.end]) |arg| try tree.dumpNode(arg, level + delta, mapper, config, w); + }, + .builtin_call_expr_one => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + if (data.decl.node != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("arg:\n"); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + } + }, + .special_builtin_call_one => { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl.name)}); + try config.setColor(w, .reset); + if (data.decl.node != .none) { + try w.writeByteNTimes(' ', level + half); + try w.writeAll("arg:\n"); + try tree.dumpNode(data.decl.node, level + delta, mapper, config, w); + } + }, + .comma_expr, + .assign_expr, + .mul_assign_expr, + .div_assign_expr, + .mod_assign_expr, + .add_assign_expr, + .sub_assign_expr, + .shl_assign_expr, + .shr_assign_expr, + .bit_and_assign_expr, + .bit_xor_assign_expr, + .bit_or_assign_expr, + .bool_or_expr, + .bool_and_expr, + .bit_or_expr, + .bit_xor_expr, + .bit_and_expr, + .equal_expr, + .not_equal_expr, + .less_than_expr, + .less_than_equal_expr, + .greater_than_expr, + .greater_than_equal_expr, + .shl_expr, + .shr_expr, + .add_expr, + .sub_expr, + .mul_expr, + .div_expr, + .mod_expr, + => { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("lhs:\n"); + try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w); + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("rhs:\n"); + try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w); + }, + .explicit_cast, .implicit_cast => try tree.dumpNode(data.cast.operand, level + delta, mapper, config, w), + .addr_of_expr, + .computed_goto_stmt, + .deref_expr, + .plus_expr, + .negate_expr, + .bit_not_expr, + .bool_not_expr, + .pre_inc_expr, + .pre_dec_expr, + .imag_expr, + .real_expr, + .post_inc_expr, + .post_dec_expr, + .paren_expr, + => { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("operand:\n"); + try tree.dumpNode(data.un, level + delta, mapper, config, w); + }, + .decl_ref_expr => { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)}); + try config.setColor(w, .reset); + }, + .enumeration_ref => { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{tree.tokSlice(data.decl_ref)}); + try config.setColor(w, .reset); + }, + .bool_literal, + .nullptr_literal, + .int_literal, + .char_literal, + .float_literal, + .string_literal_expr, + => {}, + .member_access_expr, .member_access_ptr_expr => { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("lhs:\n"); + try tree.dumpNode(data.member.lhs, level + delta, mapper, config, w); + + var lhs_ty = tree.nodes.items(.ty)[@intFromEnum(data.member.lhs)]; + if (lhs_ty.isPtr()) lhs_ty = lhs_ty.elemType(); + lhs_ty = lhs_ty.canonicalize(.standard); + + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("name: "); + try config.setColor(w, NAME); + try w.print("{s}\n", .{mapper.lookup(lhs_ty.data.record.fields[data.member.index].name)}); + try config.setColor(w, .reset); + }, + .array_access_expr => { + if (data.bin.lhs != .none) { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("lhs:\n"); + try tree.dumpNode(data.bin.lhs, level + delta, mapper, config, w); + } + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("index:\n"); + try tree.dumpNode(data.bin.rhs, level + delta, mapper, config, w); + }, + .sizeof_expr, .alignof_expr => { + if (data.un != .none) { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("expr:\n"); + try tree.dumpNode(data.un, level + delta, mapper, config, w); + } + }, + .generic_expr, .generic_expr_one => { + const child_nodes = tree.childNodes(node); + const controlling = child_nodes[0]; + const chosen = child_nodes[1]; + const rest = child_nodes[2..]; + + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("controlling:\n"); + try tree.dumpNode(controlling, level + delta, mapper, config, w); + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("chosen:\n"); + try tree.dumpNode(chosen, level + delta, mapper, config, w); + + if (rest.len > 0) { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("rest:\n"); + for (rest) |expr| { + try tree.dumpNode(expr, level + delta, mapper, config, w); + } + } + }, + .generic_association_expr, .generic_default_expr, .stmt_expr, .imaginary_literal => { + try tree.dumpNode(data.un, level + delta, mapper, config, w); + }, + .array_filler_expr => { + try w.writeByteNTimes(' ', level + 1); + try w.writeAll("count: "); + try config.setColor(w, LITERAL); + try w.print("{d}\n", .{data.int}); + try config.setColor(w, .reset); + }, + .struct_forward_decl, + .union_forward_decl, + .enum_forward_decl, + .default_init_expr, + .cond_dummy_expr, + => {}, + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tree/number_affixes.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tree/number_affixes.zig new file mode 100644 index 00000000..38ef6b8a --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Tree/number_affixes.zig @@ -0,0 +1,192 @@ +const std = @import("std"); +const mem = std.mem; + +pub const Prefix = enum(u8) { + binary = 2, + octal = 8, + decimal = 10, + hex = 16, + + pub fn digitAllowed(prefix: Prefix, c: u8) bool { + return switch (c) { + '0', '1' => true, + '2'...'7' => prefix != .binary, + '8'...'9' => prefix == .decimal or prefix == .hex, + 'a'...'f', 'A'...'F' => prefix == .hex, + else => false, + }; + } + + pub fn fromString(buf: []const u8) Prefix { + if (buf.len == 1) return .decimal; + // tokenizer enforces that first byte is a decimal digit or period + switch (buf[0]) { + '.', '1'...'9' => return .decimal, + '0' => {}, + else => unreachable, + } + switch (buf[1]) { + 'x', 'X' => return if (buf.len == 2) .decimal else .hex, + 'b', 'B' => return if (buf.len == 2) .decimal else .binary, + else => { + if (mem.indexOfAny(u8, buf, "eE.")) |_| { + // This is a decimal floating point number that happens to start with zero + return .decimal; + } else if (Suffix.fromString(buf[1..], .int)) |_| { + // This is `0` with a valid suffix + return .decimal; + } else { + return .octal; + } + }, + } + } + + /// Length of this prefix as a string + pub fn stringLen(prefix: Prefix) usize { + return switch (prefix) { + .binary => 2, + .octal => 1, + .decimal => 0, + .hex => 2, + }; + } +}; + +pub const Suffix = enum { + // zig fmt: off + + // int and imaginary int + None, I, + + // unsigned real integers + U, UL, ULL, + + // unsigned imaginary integers + IU, IUL, IULL, + + // long or long double, real and imaginary + L, IL, + + // long long and imaginary long long + LL, ILL, + + // float and imaginary float + F, IF, + + // _Float16 and imaginary _Float16 + F16, IF16, + + // __float80 + W, + + // Imaginary __float80 + IW, + + // _Float128 + Q, F128, + + // Imaginary _Float128 + IQ, IF128, + + // Imaginary _Bitint + IWB, IUWB, + + // _Bitint + WB, UWB, + + // zig fmt: on + + const Tuple = struct { Suffix, []const []const u8 }; + + const IntSuffixes = &[_]Tuple{ + .{ .U, &.{"U"} }, + .{ .L, &.{"L"} }, + .{ .WB, &.{"WB"} }, + .{ .UL, &.{ "U", "L" } }, + .{ .UWB, &.{ "U", "WB" } }, + .{ .LL, &.{"LL"} }, + .{ .ULL, &.{ "U", "LL" } }, + + .{ .I, &.{"I"} }, + + .{ .IWB, &.{ "I", "WB" } }, + .{ .IU, &.{ "I", "U" } }, + .{ .IL, &.{ "I", "L" } }, + .{ .IUL, &.{ "I", "U", "L" } }, + .{ .IUWB, &.{ "I", "U", "WB" } }, + .{ .ILL, &.{ "I", "LL" } }, + .{ .IULL, &.{ "I", "U", "LL" } }, + }; + + const FloatSuffixes = &[_]Tuple{ + .{ .F16, &.{"F16"} }, + .{ .F, &.{"F"} }, + .{ .L, &.{"L"} }, + .{ .W, &.{"W"} }, + .{ .F128, &.{"F128"} }, + .{ .Q, &.{"Q"} }, + + .{ .I, &.{"I"} }, + .{ .IL, &.{ "I", "L" } }, + .{ .IF16, &.{ "I", "F16" } }, + .{ .IF, &.{ "I", "F" } }, + .{ .IW, &.{ "I", "W" } }, + .{ .IF128, &.{ "I", "F128" } }, + .{ .IQ, &.{ "I", "Q" } }, + }; + + pub fn fromString(buf: []const u8, suffix_kind: enum { int, float }) ?Suffix { + if (buf.len == 0) return .None; + + const suffixes = switch (suffix_kind) { + .float => FloatSuffixes, + .int => IntSuffixes, + }; + var scratch: [4]u8 = undefined; + top: for (suffixes) |candidate| { + const tag = candidate[0]; + const parts = candidate[1]; + var len: usize = 0; + for (parts) |part| len += part.len; + if (len != buf.len) continue; + + for (parts) |part| { + const lower = std.ascii.lowerString(&scratch, part); + if (mem.indexOf(u8, buf, part) == null and mem.indexOf(u8, buf, lower) == null) continue :top; + } + return tag; + } + return null; + } + + pub fn isImaginary(suffix: Suffix) bool { + return switch (suffix) { + .I, .IL, .IF, .IU, .IUL, .ILL, .IULL, .IWB, .IUWB, .IF128, .IQ, .IW, .IF16 => true, + .None, .L, .F16, .F, .U, .UL, .LL, .ULL, .WB, .UWB, .F128, .Q, .W => false, + }; + } + + pub fn isSignedInteger(suffix: Suffix) bool { + return switch (suffix) { + .None, .L, .LL, .I, .IL, .ILL, .WB, .IWB => true, + .U, .UL, .ULL, .IU, .IUL, .IULL, .UWB, .IUWB => false, + .F, .IF, .F16, .F128, .IF128, .Q, .IQ, .W, .IW, .IF16 => unreachable, + }; + } + + pub fn signedness(suffix: Suffix) std.builtin.Signedness { + return if (suffix.isSignedInteger()) .signed else .unsigned; + } + + pub fn isBitInt(suffix: Suffix) bool { + return switch (suffix) { + .WB, .UWB, .IWB, .IUWB => true, + else => false, + }; + } + + pub fn isFloat80(suffix: Suffix) bool { + return suffix == .W or suffix == .IW; + } +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Type.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Type.zig new file mode 100644 index 00000000..6bec686a --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Type.zig @@ -0,0 +1,2675 @@ +const std = @import("std"); +const Tree = @import("Tree.zig"); +const TokenIndex = Tree.TokenIndex; +const NodeIndex = Tree.NodeIndex; +const Parser = @import("Parser.zig"); +const Compilation = @import("Compilation.zig"); +const Attribute = @import("Attribute.zig"); +const StringInterner = @import("StringInterner.zig"); +const StringId = StringInterner.StringId; +const target_util = @import("target.zig"); +const LangOpts = @import("LangOpts.zig"); + +pub const Qualifiers = packed struct { + @"const": bool = false, + atomic: bool = false, + @"volatile": bool = false, + restrict: bool = false, + + // for function parameters only, stored here since it fits in the padding + register: bool = false, + + pub fn any(quals: Qualifiers) bool { + return quals.@"const" or quals.restrict or quals.@"volatile" or quals.atomic; + } + + pub fn dump(quals: Qualifiers, w: anytype) !void { + if (quals.@"const") try w.writeAll("const "); + if (quals.atomic) try w.writeAll("_Atomic "); + if (quals.@"volatile") try w.writeAll("volatile "); + if (quals.restrict) try w.writeAll("restrict "); + if (quals.register) try w.writeAll("register "); + } + + /// Merge the const/volatile qualifiers, used by type resolution + /// of the conditional operator + pub fn mergeCV(a: Qualifiers, b: Qualifiers) Qualifiers { + return .{ + .@"const" = a.@"const" or b.@"const", + .@"volatile" = a.@"volatile" or b.@"volatile", + }; + } + + /// Merge all qualifiers, used by typeof() + fn mergeAll(a: Qualifiers, b: Qualifiers) Qualifiers { + return .{ + .@"const" = a.@"const" or b.@"const", + .atomic = a.atomic or b.atomic, + .@"volatile" = a.@"volatile" or b.@"volatile", + .restrict = a.restrict or b.restrict, + .register = a.register or b.register, + }; + } + + /// Checks if a has all the qualifiers of b + pub fn hasQuals(a: Qualifiers, b: Qualifiers) bool { + if (b.@"const" and !a.@"const") return false; + if (b.@"volatile" and !a.@"volatile") return false; + if (b.atomic and !a.atomic) return false; + return true; + } + + /// register is a storage class and not actually a qualifier + /// so it is not preserved by typeof() + pub fn inheritFromTypeof(quals: Qualifiers) Qualifiers { + var res = quals; + res.register = false; + return res; + } + + pub const Builder = struct { + @"const": ?TokenIndex = null, + atomic: ?TokenIndex = null, + @"volatile": ?TokenIndex = null, + restrict: ?TokenIndex = null, + + pub fn finish(b: Qualifiers.Builder, p: *Parser, ty: *Type) !void { + if (ty.specifier != .pointer and b.restrict != null) { + try p.errStr(.restrict_non_pointer, b.restrict.?, try p.typeStr(ty.*)); + } + if (b.atomic) |some| { + if (ty.isArray()) try p.errStr(.atomic_array, some, try p.typeStr(ty.*)); + if (ty.isFunc()) try p.errStr(.atomic_func, some, try p.typeStr(ty.*)); + if (ty.hasIncompleteSize()) try p.errStr(.atomic_incomplete, some, try p.typeStr(ty.*)); + } + + if (b.@"const" != null) ty.qual.@"const" = true; + if (b.atomic != null) ty.qual.atomic = true; + if (b.@"volatile" != null) ty.qual.@"volatile" = true; + if (b.restrict != null) ty.qual.restrict = true; + } + }; +}; + +// TODO improve memory usage +pub const Func = struct { + return_type: Type, + params: []Param, + + pub const Param = struct { + ty: Type, + name: StringId, + name_tok: TokenIndex, + }; + + fn eql(a: *const Func, b: *const Func, a_spec: Specifier, b_spec: Specifier, comp: *const Compilation) bool { + // return type cannot have qualifiers + if (!a.return_type.eql(b.return_type, comp, false)) return false; + if (a.params.len == 0 and b.params.len == 0) return true; + + if (a.params.len != b.params.len) { + if (a_spec == .old_style_func or b_spec == .old_style_func) { + const maybe_has_params = if (a_spec == .old_style_func) b else a; + for (maybe_has_params.params) |param| { + if (param.ty.undergoesDefaultArgPromotion(comp)) return false; + } + return true; + } + return false; + } + if ((a_spec == .func) != (b_spec == .func)) return false; + // TODO validate this + for (a.params, b.params) |param, b_qual| { + var a_unqual = param.ty; + a_unqual.qual.@"const" = false; + a_unqual.qual.@"volatile" = false; + var b_unqual = b_qual.ty; + b_unqual.qual.@"const" = false; + b_unqual.qual.@"volatile" = false; + if (!a_unqual.eql(b_unqual, comp, true)) return false; + } + return true; + } +}; + +pub const Array = struct { + len: u64, + elem: Type, +}; + +pub const Expr = struct { + node: NodeIndex, + ty: Type, +}; + +pub const Attributed = struct { + attributes: []Attribute, + base: Type, + + pub fn create(allocator: std.mem.Allocator, base_ty: Type, attributes: []const Attribute) !*Attributed { + const attributed_type = try allocator.create(Attributed); + errdefer allocator.destroy(attributed_type); + const duped = try allocator.dupe(Attribute, attributes); + + attributed_type.* = .{ + .attributes = duped, + .base = base_ty, + }; + return attributed_type; + } +}; + +// TODO improve memory usage +pub const Enum = struct { + fields: []Field, + tag_ty: Type, + name: StringId, + fixed: bool, + + pub const Field = struct { + ty: Type, + name: StringId, + name_tok: TokenIndex, + node: NodeIndex, + }; + + pub fn isIncomplete(e: Enum) bool { + return e.fields.len == std.math.maxInt(usize); + } + + pub fn create(allocator: std.mem.Allocator, name: StringId, fixed_ty: ?Type) !*Enum { + var e = try allocator.create(Enum); + e.name = name; + e.fields.len = std.math.maxInt(usize); + if (fixed_ty) |some| e.tag_ty = some; + e.fixed = fixed_ty != null; + return e; + } +}; + +pub const TypeLayout = struct { + /// The size of the type in bits. + /// + /// This is the value returned by `sizeof` in C + /// (but in bits instead of bytes). This is a multiple of `pointer_alignment_bits`. + size_bits: u64, + /// The alignment of the type, in bits, when used as a field in a record. + /// + /// This is usually the value returned by `_Alignof` in C, but there are some edge + /// cases in GCC where `_Alignof` returns a smaller value. + field_alignment_bits: u32, + /// The alignment, in bits, of valid pointers to this type. + /// `size_bits` is a multiple of this value. + pointer_alignment_bits: u32, + /// The required alignment of the type in bits. + /// + /// This value is only used by MSVC targets. It is 8 on all other + /// targets. On MSVC targets, this value restricts the effects of `#pragma pack` except + /// in some cases involving bit-fields. + required_alignment_bits: u32, +}; + +pub const FieldLayout = struct { + /// `offset_bits` and `size_bits` should both be INVALID if and only if the field + /// is an unnamed bitfield. There is no way to reference an unnamed bitfield in C, so + /// there should be no way to observe these values. If it is used, this value will + /// maximize the chance that a safety-checked overflow will occur. + const INVALID = std.math.maxInt(u64); + + /// The offset of the field, in bits, from the start of the struct. + offset_bits: u64 = INVALID, + /// The size, in bits, of the field. + /// + /// For bit-fields, this is the width of the field. + size_bits: u64 = INVALID, + + pub fn isUnnamed(self: FieldLayout) bool { + return self.offset_bits == INVALID and self.size_bits == INVALID; + } +}; + +// TODO improve memory usage +pub const Record = struct { + fields: []Field, + type_layout: TypeLayout, + /// If this is null, none of the fields have attributes + /// Otherwise, it's a pointer to N items (where N == number of fields) + /// and the item at index i is the attributes for the field at index i + field_attributes: ?[*][]const Attribute, + name: StringId, + + pub const Field = struct { + ty: Type, + name: StringId, + /// zero for anonymous fields + name_tok: TokenIndex = 0, + bit_width: ?u32 = null, + layout: FieldLayout = .{ + .offset_bits = 0, + .size_bits = 0, + }, + + pub fn isNamed(f: *const Field) bool { + return f.name_tok != 0; + } + + pub fn isAnonymousRecord(f: Field) bool { + return !f.isNamed() and f.ty.isRecord(); + } + + /// false for bitfields + pub fn isRegularField(f: *const Field) bool { + return f.bit_width == null; + } + + /// bit width as specified in the C source. Asserts that `f` is a bitfield. + pub fn specifiedBitWidth(f: *const Field) u32 { + return f.bit_width.?; + } + }; + + pub fn isIncomplete(r: Record) bool { + return r.fields.len == std.math.maxInt(usize); + } + + pub fn create(allocator: std.mem.Allocator, name: StringId) !*Record { + var r = try allocator.create(Record); + r.name = name; + r.fields.len = std.math.maxInt(usize); + r.field_attributes = null; + r.type_layout = .{ + .size_bits = 8, + .field_alignment_bits = 8, + .pointer_alignment_bits = 8, + .required_alignment_bits = 8, + }; + return r; + } + + pub fn hasFieldOfType(self: *const Record, ty: Type, comp: *const Compilation) bool { + if (self.isIncomplete()) return false; + for (self.fields) |f| { + if (ty.eql(f.ty, comp, false)) return true; + } + return false; + } + + pub fn hasField(self: *const Record, name: StringId) bool { + std.debug.assert(!self.isIncomplete()); + for (self.fields) |f| { + if (f.isAnonymousRecord() and f.ty.getRecord().?.hasField(name)) return true; + if (name == f.name) return true; + } + return false; + } +}; + +pub const Specifier = enum { + /// A NaN-like poison value + invalid, + + /// GNU auto type + /// This is a placeholder specifier - it must be replaced by the actual type specifier (determined by the initializer) + auto_type, + /// C23 auto, behaves like auto_type + c23_auto, + + void, + bool, + + // integers + char, + schar, + uchar, + short, + ushort, + int, + uint, + long, + ulong, + long_long, + ulong_long, + int128, + uint128, + complex_char, + complex_schar, + complex_uchar, + complex_short, + complex_ushort, + complex_int, + complex_uint, + complex_long, + complex_ulong, + complex_long_long, + complex_ulong_long, + complex_int128, + complex_uint128, + + // data.int + bit_int, + complex_bit_int, + + // floating point numbers + fp16, + float16, + float, + double, + long_double, + float128, + complex_float16, + complex_float, + complex_double, + complex_long_double, + complex_float128, + + // data.sub_type + pointer, + unspecified_variable_len_array, + // data.func + /// int foo(int bar, char baz) and int (void) + func, + /// int foo(int bar, char baz, ...) + var_args_func, + /// int foo(bar, baz) and int foo() + /// is also var args, but we can give warnings about incorrect amounts of parameters + old_style_func, + + // data.array + array, + static_array, + incomplete_array, + vector, + // data.expr + variable_len_array, + + // data.record + @"struct", + @"union", + + // data.enum + @"enum", + + /// typeof(type-name) + typeof_type, + + /// typeof(expression) + typeof_expr, + + /// data.attributed + attributed, + + /// C23 nullptr_t + nullptr_t, +}; + +const Type = @This(); + +/// All fields of Type except data may be mutated +data: union { + sub_type: *Type, + func: *Func, + array: *Array, + expr: *Expr, + @"enum": *Enum, + record: *Record, + attributed: *Attributed, + none: void, + int: struct { + bits: u16, + signedness: std.builtin.Signedness, + }, +} = .{ .none = {} }, +specifier: Specifier, +qual: Qualifiers = .{}, +decayed: bool = false, +/// typedef name, if any +name: StringId = .empty, + +pub const int = Type{ .specifier = .int }; +pub const invalid = Type{ .specifier = .invalid }; + +/// Determine if type matches the given specifier, recursing into typeof +/// types if necessary. +pub fn is(ty: Type, specifier: Specifier) bool { + std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr); + return ty.get(specifier) != null; +} + +pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type { + if (attributes.len == 0) return self; + const attributed_type = try Type.Attributed.create(allocator, self, attributes); + return .{ .specifier = .attributed, .data = .{ .attributed = attributed_type }, .decayed = self.decayed }; +} + +pub fn isCallable(ty: Type) ?Type { + return switch (ty.specifier) { + .func, .var_args_func, .old_style_func => ty, + .pointer => if (ty.data.sub_type.isFunc()) ty.data.sub_type.* else null, + .typeof_type => ty.data.sub_type.isCallable(), + .typeof_expr => ty.data.expr.ty.isCallable(), + .attributed => ty.data.attributed.base.isCallable(), + else => null, + }; +} + +pub fn isFunc(ty: Type) bool { + return switch (ty.specifier) { + .func, .var_args_func, .old_style_func => true, + .typeof_type => ty.data.sub_type.isFunc(), + .typeof_expr => ty.data.expr.ty.isFunc(), + .attributed => ty.data.attributed.base.isFunc(), + else => false, + }; +} + +pub fn isArray(ty: Type) bool { + return switch (ty.specifier) { + .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => !ty.isDecayed(), + .typeof_type => !ty.isDecayed() and ty.data.sub_type.isArray(), + .typeof_expr => !ty.isDecayed() and ty.data.expr.ty.isArray(), + .attributed => !ty.isDecayed() and ty.data.attributed.base.isArray(), + else => false, + }; +} + +/// Must only be used to set the length of an incomplete array as determined by its initializer +pub fn setIncompleteArrayLen(ty: *Type, len: u64) void { + switch (ty.specifier) { + .incomplete_array => { + // Modifying .data is exceptionally allowed for .incomplete_array. + ty.data.array.len = len; + ty.specifier = .array; + }, + + .typeof_type => ty.data.sub_type.setIncompleteArrayLen(len), + .typeof_expr => ty.data.expr.ty.setIncompleteArrayLen(len), + .attributed => ty.data.attributed.base.setIncompleteArrayLen(len), + + else => unreachable, + } +} + +/// Whether the type is promoted if used as a variadic argument or as an argument to a function with no prototype +fn undergoesDefaultArgPromotion(ty: Type, comp: *const Compilation) bool { + return switch (ty.specifier) { + .bool => true, + .char, .uchar, .schar => true, + .short, .ushort => true, + .@"enum" => if (comp.langopts.emulate == .clang) ty.data.@"enum".isIncomplete() else false, + .float => true, + + .typeof_type => ty.data.sub_type.undergoesDefaultArgPromotion(comp), + .typeof_expr => ty.data.expr.ty.undergoesDefaultArgPromotion(comp), + .attributed => ty.data.attributed.base.undergoesDefaultArgPromotion(comp), + else => false, + }; +} + +pub fn isScalar(ty: Type) bool { + return ty.isInt() or ty.isScalarNonInt(); +} + +/// To avoid calling isInt() twice for allowable loop/if controlling expressions +pub fn isScalarNonInt(ty: Type) bool { + return ty.isFloat() or ty.isPtr() or ty.is(.nullptr_t); +} + +pub fn isDecayed(ty: Type) bool { + return ty.decayed; +} + +pub fn isPtr(ty: Type) bool { + return switch (ty.specifier) { + .pointer => true, + + .array, + .static_array, + .incomplete_array, + .variable_len_array, + .unspecified_variable_len_array, + => ty.isDecayed(), + .typeof_type => ty.isDecayed() or ty.data.sub_type.isPtr(), + .typeof_expr => ty.isDecayed() or ty.data.expr.ty.isPtr(), + .attributed => ty.isDecayed() or ty.data.attributed.base.isPtr(), + else => false, + }; +} + +pub fn isInt(ty: Type) bool { + return switch (ty.specifier) { + // zig fmt: off + .@"enum", .bool, .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong, + .long_long, .ulong_long, .int128, .uint128, .complex_char, .complex_schar, .complex_uchar, + .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, + .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128, + .bit_int, .complex_bit_int => true, + // zig fmt: on + .typeof_type => ty.data.sub_type.isInt(), + .typeof_expr => ty.data.expr.ty.isInt(), + .attributed => ty.data.attributed.base.isInt(), + else => false, + }; +} + +pub fn isFloat(ty: Type) bool { + return switch (ty.specifier) { + // zig fmt: off + .float, .double, .long_double, .complex_float, .complex_double, .complex_long_double, + .fp16, .float16, .float128, .complex_float128, .complex_float16 => true, + // zig fmt: on + .typeof_type => ty.data.sub_type.isFloat(), + .typeof_expr => ty.data.expr.ty.isFloat(), + .attributed => ty.data.attributed.base.isFloat(), + else => false, + }; +} + +pub fn isReal(ty: Type) bool { + return switch (ty.specifier) { + // zig fmt: off + .complex_float, .complex_double, .complex_long_double, + .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short, + .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, + .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128, + .complex_bit_int, .complex_float16 => false, + // zig fmt: on + .typeof_type => ty.data.sub_type.isReal(), + .typeof_expr => ty.data.expr.ty.isReal(), + .attributed => ty.data.attributed.base.isReal(), + else => true, + }; +} + +pub fn isComplex(ty: Type) bool { + return switch (ty.specifier) { + // zig fmt: off + .complex_float, .complex_double, .complex_long_double, + .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short, + .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, + .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128, + .complex_bit_int, .complex_float16 => true, + // zig fmt: on + .typeof_type => ty.data.sub_type.isComplex(), + .typeof_expr => ty.data.expr.ty.isComplex(), + .attributed => ty.data.attributed.base.isComplex(), + else => false, + }; +} + +pub fn isVoidStar(ty: Type) bool { + return switch (ty.specifier) { + .pointer => ty.data.sub_type.specifier == .void, + .typeof_type => ty.data.sub_type.isVoidStar(), + .typeof_expr => ty.data.expr.ty.isVoidStar(), + .attributed => ty.data.attributed.base.isVoidStar(), + else => false, + }; +} + +pub fn isTypeof(ty: Type) bool { + return switch (ty.specifier) { + .typeof_type, .typeof_expr => true, + else => false, + }; +} + +pub fn isConst(ty: Type) bool { + return switch (ty.specifier) { + .typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(), + .typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(), + .attributed => ty.data.attributed.base.isConst(), + else => ty.qual.@"const", + }; +} + +pub fn isUnsignedInt(ty: Type, comp: *const Compilation) bool { + return ty.signedness(comp) == .unsigned; +} + +pub fn signedness(ty: Type, comp: *const Compilation) std.builtin.Signedness { + return switch (ty.specifier) { + // zig fmt: off + .char, .complex_char => return comp.getCharSignedness(), + .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128, .bool, .complex_uchar, .complex_ushort, + .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => .unsigned, + // zig fmt: on + .bit_int, .complex_bit_int => ty.data.int.signedness, + .typeof_type => ty.data.sub_type.signedness(comp), + .typeof_expr => ty.data.expr.ty.signedness(comp), + .attributed => ty.data.attributed.base.signedness(comp), + else => .signed, + }; +} + +pub fn isEnumOrRecord(ty: Type) bool { + return switch (ty.specifier) { + .@"enum", .@"struct", .@"union" => true, + .typeof_type => ty.data.sub_type.isEnumOrRecord(), + .typeof_expr => ty.data.expr.ty.isEnumOrRecord(), + .attributed => ty.data.attributed.base.isEnumOrRecord(), + else => false, + }; +} + +pub fn isRecord(ty: Type) bool { + return switch (ty.specifier) { + .@"struct", .@"union" => true, + .typeof_type => ty.data.sub_type.isRecord(), + .typeof_expr => ty.data.expr.ty.isRecord(), + .attributed => ty.data.attributed.base.isRecord(), + else => false, + }; +} + +pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool { + return switch (ty.specifier) { + // anonymous records can be recognized by their names which are in + // the format "(anonymous TAG at path:line:col)". + .@"struct", .@"union" => { + const mapper = comp.string_interner.getSlowTypeMapper(); + return mapper.lookup(ty.data.record.name)[0] == '('; + }, + .typeof_type => ty.data.sub_type.isAnonymousRecord(comp), + .typeof_expr => ty.data.expr.ty.isAnonymousRecord(comp), + .attributed => ty.data.attributed.base.isAnonymousRecord(comp), + else => false, + }; +} + +pub fn elemType(ty: Type) Type { + return switch (ty.specifier) { + .pointer, .unspecified_variable_len_array => ty.data.sub_type.*, + .array, .static_array, .incomplete_array, .vector => ty.data.array.elem, + .variable_len_array => ty.data.expr.ty, + .typeof_type, .typeof_expr => { + const unwrapped = ty.canonicalize(.preserve_quals); + var elem = unwrapped.elemType(); + elem.qual = elem.qual.mergeAll(unwrapped.qual); + return elem; + }, + .attributed => ty.data.attributed.base.elemType(), + .invalid => Type.invalid, + // zig fmt: off + .complex_float, .complex_double, .complex_long_double, + .complex_float128, .complex_char, .complex_schar, .complex_uchar, .complex_short, + .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, + .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128, + .complex_bit_int, .complex_float16 => ty.makeReal(), + // zig fmt: on + else => unreachable, + }; +} + +pub fn returnType(ty: Type) Type { + return switch (ty.specifier) { + .func, .var_args_func, .old_style_func => ty.data.func.return_type, + .typeof_type => ty.data.sub_type.returnType(), + .typeof_expr => ty.data.expr.ty.returnType(), + .attributed => ty.data.attributed.base.returnType(), + .invalid => Type.invalid, + else => unreachable, + }; +} + +pub fn params(ty: Type) []Func.Param { + return switch (ty.specifier) { + .func, .var_args_func, .old_style_func => ty.data.func.params, + .typeof_type => ty.data.sub_type.params(), + .typeof_expr => ty.data.expr.ty.params(), + .attributed => ty.data.attributed.base.params(), + .invalid => &.{}, + else => unreachable, + }; +} + +/// Returns true if the return value or any param of `ty` is `.invalid` +/// Asserts that ty is a function type +pub fn isInvalidFunc(ty: Type) bool { + if (ty.returnType().is(.invalid)) return true; + for (ty.params()) |param| { + if (param.ty.is(.invalid)) return true; + } + return false; +} + +pub fn arrayLen(ty: Type) ?u64 { + return switch (ty.specifier) { + .array, .static_array => ty.data.array.len, + .typeof_type => ty.data.sub_type.arrayLen(), + .typeof_expr => ty.data.expr.ty.arrayLen(), + .attributed => ty.data.attributed.base.arrayLen(), + else => null, + }; +} + +/// Complex numbers are scalars but they can be initialized with a 2-element initList +pub fn expectedInitListSize(ty: Type) ?u64 { + return if (ty.isComplex()) 2 else ty.arrayLen(); +} + +pub fn anyQual(ty: Type) bool { + return switch (ty.specifier) { + .typeof_type => ty.qual.any() or ty.data.sub_type.anyQual(), + .typeof_expr => ty.qual.any() or ty.data.expr.ty.anyQual(), + else => ty.qual.any(), + }; +} + +pub fn getRecord(ty: Type) ?*const Type.Record { + return switch (ty.specifier) { + .attributed => ty.data.attributed.base.getRecord(), + .typeof_type => ty.data.sub_type.getRecord(), + .typeof_expr => ty.data.expr.ty.getRecord(), + .@"struct", .@"union" => ty.data.record, + else => null, + }; +} + +pub fn compareIntegerRanks(a: Type, b: Type, comp: *const Compilation) std.math.Order { + std.debug.assert(a.isInt() and b.isInt()); + if (a.eql(b, comp, false)) return .eq; + + const a_unsigned = a.isUnsignedInt(comp); + const b_unsigned = b.isUnsignedInt(comp); + + const a_rank = a.integerRank(comp); + const b_rank = b.integerRank(comp); + if (a_unsigned == b_unsigned) { + return std.math.order(a_rank, b_rank); + } + if (a_unsigned) { + if (a_rank >= b_rank) return .gt; + return .lt; + } + std.debug.assert(b_unsigned); + if (b_rank >= a_rank) return .lt; + return .gt; +} + +fn realIntegerConversion(a: Type, b: Type, comp: *const Compilation) Type { + std.debug.assert(a.isReal() and b.isReal()); + const type_order = a.compareIntegerRanks(b, comp); + const a_signed = !a.isUnsignedInt(comp); + const b_signed = !b.isUnsignedInt(comp); + if (a_signed == b_signed) { + // If both have the same sign, use higher-rank type. + return switch (type_order) { + .lt => b, + .eq, .gt => a, + }; + } else if (type_order != if (a_signed) std.math.Order.gt else std.math.Order.lt) { + // Only one is signed; and the unsigned type has rank >= the signed type + // Use the unsigned type + return if (b_signed) a else b; + } else if (a.bitSizeof(comp).? != b.bitSizeof(comp).?) { + // Signed type is higher rank and sizes are not equal + // Use the signed type + return if (a_signed) a else b; + } else { + // Signed type is higher rank but same size as unsigned type + // e.g. `long` and `unsigned` on x86-linux-gnu + // Use unsigned version of the signed type + return if (a_signed) a.makeIntegerUnsigned() else b.makeIntegerUnsigned(); + } +} + +pub fn makeIntegerUnsigned(ty: Type) Type { + // TODO discards attributed/typeof + var base_ty = ty.canonicalize(.standard); + switch (base_ty.specifier) { + // zig fmt: off + .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128, + .complex_uchar, .complex_ushort, .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128, + => return ty, + // zig fmt: on + + .char, .complex_char => { + base_ty.specifier = @enumFromInt(@intFromEnum(base_ty.specifier) + 2); + return base_ty; + }, + + // zig fmt: off + .schar, .short, .int, .long, .long_long, .int128, + .complex_schar, .complex_short, .complex_int, .complex_long, .complex_long_long, .complex_int128 => { + base_ty.specifier = @enumFromInt(@intFromEnum(base_ty.specifier) + 1); + return base_ty; + }, + // zig fmt: on + + .bit_int, .complex_bit_int => { + base_ty.data.int.signedness = .unsigned; + return base_ty; + }, + else => unreachable, + } +} + +/// Find the common type of a and b for binary operations +pub fn integerConversion(a: Type, b: Type, comp: *const Compilation) Type { + const a_real = a.isReal(); + const b_real = b.isReal(); + const target_ty = a.makeReal().realIntegerConversion(b.makeReal(), comp); + return if (a_real and b_real) target_ty else target_ty.makeComplex(); +} + +pub fn integerPromotion(ty: Type, comp: *Compilation) Type { + var specifier = ty.specifier; + switch (specifier) { + .@"enum" => { + if (ty.hasIncompleteSize()) return .{ .specifier = .int }; + if (ty.data.@"enum".fixed) return ty.data.@"enum".tag_ty.integerPromotion(comp); + + specifier = ty.data.@"enum".tag_ty.specifier; + }, + .bit_int, .complex_bit_int => return .{ .specifier = specifier, .data = ty.data }, + else => {}, + } + return switch (specifier) { + else => .{ + .specifier = switch (specifier) { + // zig fmt: off + .bool, .char, .schar, .uchar, .short => .int, + .ushort => if (ty.sizeof(comp).? == sizeof(.{ .specifier = .int }, comp)) Specifier.uint else .int, + .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128, .complex_char, + .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, + .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, + .complex_int128, .complex_uint128 => specifier, + // zig fmt: on + .typeof_type => return ty.data.sub_type.integerPromotion(comp), + .typeof_expr => return ty.data.expr.ty.integerPromotion(comp), + .attributed => return ty.data.attributed.base.integerPromotion(comp), + .invalid => .invalid, + else => unreachable, // _BitInt, or not an integer type + }, + }, + }; +} + +/// Promote a bitfield. If `int` can hold all the values of the underlying field, +/// promote to int. Otherwise, promote to unsigned int +/// Returns null if no promotion is necessary +pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type { + const type_size_bits = ty.bitSizeof(comp).?; + + // Note: GCC and clang will promote `long: 3` to int even though the C standard does not allow this + if (width < type_size_bits) { + return int; + } + + if (width == type_size_bits) { + return if (ty.isUnsignedInt(comp)) .{ .specifier = .uint } else int; + } + + return null; +} + +pub fn hasIncompleteSize(ty: Type) bool { + if (ty.isDecayed()) return false; + return switch (ty.specifier) { + .void, .incomplete_array => true, + .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed, + .@"struct", .@"union" => ty.data.record.isIncomplete(), + .array, .static_array => ty.data.array.elem.hasIncompleteSize(), + .typeof_type => ty.data.sub_type.hasIncompleteSize(), + .typeof_expr, .variable_len_array => ty.data.expr.ty.hasIncompleteSize(), + .unspecified_variable_len_array => ty.data.sub_type.hasIncompleteSize(), + .attributed => ty.data.attributed.base.hasIncompleteSize(), + else => false, + }; +} + +pub fn hasUnboundVLA(ty: Type) bool { + var cur = ty; + while (true) { + switch (cur.specifier) { + .unspecified_variable_len_array => return true, + .array, + .static_array, + .incomplete_array, + .variable_len_array, + => cur = cur.elemType(), + .typeof_type => cur = cur.data.sub_type.*, + .typeof_expr => cur = cur.data.expr.ty, + .attributed => cur = cur.data.attributed.base, + else => return false, + } + } +} + +pub fn hasField(ty: Type, name: StringId) bool { + return ty.getRecord().?.hasField(name); +} + +const TypeSizeOrder = enum { + lt, + gt, + eq, + indeterminate, +}; + +pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder { + const a_size = a.sizeof(comp) orelse return .indeterminate; + const b_size = b.sizeof(comp) orelse return .indeterminate; + return switch (std.math.order(a_size, b_size)) { + .lt => .lt, + .gt => .gt, + .eq => .eq, + }; +} + +/// Size of type as reported by sizeof +pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 { + if (ty.isPtr()) return comp.target.ptrBitWidth() / 8; + + return switch (ty.specifier) { + .auto_type, .c23_auto => unreachable, + .variable_len_array, .unspecified_variable_len_array => null, + .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null, + .func, .var_args_func, .old_style_func, .void, .bool => 1, + .char, .schar, .uchar => 1, + .short => comp.target.cTypeByteSize(.short), + .ushort => comp.target.cTypeByteSize(.ushort), + .int => comp.target.cTypeByteSize(.int), + .uint => comp.target.cTypeByteSize(.uint), + .long => comp.target.cTypeByteSize(.long), + .ulong => comp.target.cTypeByteSize(.ulong), + .long_long => comp.target.cTypeByteSize(.longlong), + .ulong_long => comp.target.cTypeByteSize(.ulonglong), + .long_double => comp.target.cTypeByteSize(.longdouble), + .int128, .uint128 => 16, + .fp16, .float16 => 2, + .float => comp.target.cTypeByteSize(.float), + .double => comp.target.cTypeByteSize(.double), + .float128 => 16, + .bit_int => { + return std.mem.alignForward(u64, (@as(u32, ty.data.int.bits) + 7) / 8, ty.alignof(comp)); + }, + // zig fmt: off + .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, + .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, + .complex_int128, .complex_uint128, .complex_float, .complex_double, + .complex_long_double, .complex_float128, .complex_bit_int, .complex_float16, + => return 2 * ty.makeReal().sizeof(comp).?, + // zig fmt: on + .pointer => unreachable, + .static_array, + .nullptr_t, + => comp.target.ptrBitWidth() / 8, + .array, .vector => { + const size = ty.data.array.elem.sizeof(comp) orelse return null; + const arr_size = size * ty.data.array.len; + if (comp.langopts.emulate == .msvc) { + // msvc ignores array type alignment. + // Since the size might not be a multiple of the field + // alignment, the address of the second element might not be properly aligned + // for the field alignment. A flexible array has size 0. See test case 0018. + return arr_size; + } else { + return std.mem.alignForward(u64, arr_size, ty.alignof(comp)); + } + }, + .@"struct", .@"union" => if (ty.data.record.isIncomplete()) null else @as(u64, ty.data.record.type_layout.size_bits / 8), + .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) null else ty.data.@"enum".tag_ty.sizeof(comp), + .typeof_type => ty.data.sub_type.sizeof(comp), + .typeof_expr => ty.data.expr.ty.sizeof(comp), + .attributed => ty.data.attributed.base.sizeof(comp), + .invalid => return null, + }; +} + +pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 { + return switch (ty.specifier) { + .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1, + .typeof_type => ty.data.sub_type.bitSizeof(comp), + .typeof_expr => ty.data.expr.ty.bitSizeof(comp), + .attributed => ty.data.attributed.base.bitSizeof(comp), + .bit_int => return ty.data.int.bits, + .long_double => comp.target.cTypeBitSize(.longdouble), + else => 8 * (ty.sizeof(comp) orelse return null), + }; +} + +pub fn alignable(ty: Type) bool { + return (ty.isArray() or !ty.hasIncompleteSize() or ty.is(.void)) and !ty.is(.invalid); +} + +/// Get the alignment of a type +pub fn alignof(ty: Type, comp: *const Compilation) u29 { + // don't return the attribute for records + // layout has already accounted for requested alignment + if (ty.requestedAlignment(comp)) |requested| { + // gcc does not respect alignment on enums + if (ty.get(.@"enum")) |ty_enum| { + if (comp.langopts.emulate == .gcc) { + return ty_enum.alignof(comp); + } + } else if (ty.getRecord()) |rec| { + if (ty.hasIncompleteSize()) return 0; + const computed: u29 = @intCast(@divExact(rec.type_layout.field_alignment_bits, 8)); + return @max(requested, computed); + } else if (comp.langopts.emulate == .msvc) { + const type_align = ty.data.attributed.base.alignof(comp); + return @max(requested, type_align); + } + return requested; + } + + return switch (ty.specifier) { + .invalid => unreachable, + .auto_type, .c23_auto => unreachable, + + .variable_len_array, + .incomplete_array, + .unspecified_variable_len_array, + .array, + .vector, + => if (ty.isPtr()) switch (comp.target.cpu.arch) { + .avr => 1, + else => comp.target.ptrBitWidth() / 8, + } else ty.elemType().alignof(comp), + .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target), + .char, .schar, .uchar, .void, .bool => 1, + + // zig fmt: off + .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, + .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, + .complex_int128, .complex_uint128, .complex_float, .complex_double, + .complex_long_double, .complex_float128, .complex_bit_int, .complex_float16, + => return ty.makeReal().alignof(comp), + // zig fmt: on + + .short => comp.target.cTypeAlignment(.short), + .ushort => comp.target.cTypeAlignment(.ushort), + .int => comp.target.cTypeAlignment(.int), + .uint => comp.target.cTypeAlignment(.uint), + + .long => comp.target.cTypeAlignment(.long), + .ulong => comp.target.cTypeAlignment(.ulong), + .long_long => comp.target.cTypeAlignment(.longlong), + .ulong_long => comp.target.cTypeAlignment(.ulonglong), + + .bit_int => { + // https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2709.pdf + // _BitInt(N) types align with existing calling conventions. They have the same size and alignment as the + // smallest basic type that can contain them. Types that are larger than __int64_t are conceptually treated + // as struct of register size chunks. The number of chunks is the smallest number that can contain the type. + if (ty.data.int.bits > 64) return 8; + const basic_type = comp.intLeastN(ty.data.int.bits, ty.data.int.signedness); + return basic_type.alignof(comp); + }, + + .float => comp.target.cTypeAlignment(.float), + .double => comp.target.cTypeAlignment(.double), + .long_double => comp.target.cTypeAlignment(.longdouble), + + .int128, .uint128 => if (comp.target.cpu.arch == .s390x and comp.target.os.tag == .linux and comp.target.abi.isGnu()) 8 else 16, + .fp16, .float16 => 2, + + .float128 => 16, + .pointer, + .static_array, + .nullptr_t, + => switch (comp.target.cpu.arch) { + .avr => 1, + else => comp.target.ptrBitWidth() / 8, + }, + .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8), + .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp), + .typeof_type => ty.data.sub_type.alignof(comp), + .typeof_expr => ty.data.expr.ty.alignof(comp), + .attributed => ty.data.attributed.base.alignof(comp), + }; +} + +// This enum should be kept public because it is used by the downstream zig translate-c +pub const QualHandling = enum { + standard, + preserve_quals, +}; + +/// Canonicalize a possibly-typeof() type. If the type is not a typeof() type, simply +/// return it. Otherwise, determine the actual qualified type. +/// The `qual_handling` parameter can be used to return the full set of qualifiers +/// added by typeof() operations, which is useful when determining the elemType of +/// arrays and pointers. +pub fn canonicalize(ty: Type, qual_handling: QualHandling) Type { + var cur = ty; + var qual = cur.qual; + while (true) { + switch (cur.specifier) { + .typeof_type => cur = cur.data.sub_type.*, + .typeof_expr => cur = cur.data.expr.ty, + .attributed => cur = cur.data.attributed.base, + else => break, + } + qual = qual.mergeAll(cur.qual); + } + if ((cur.isArray() or cur.isPtr()) and qual_handling == .standard) { + cur.qual = .{}; + } else { + cur.qual = qual; + } + cur.decayed = ty.decayed; + return cur; +} + +pub fn get(ty: *const Type, specifier: Specifier) ?*const Type { + std.debug.assert(specifier != .typeof_type and specifier != .typeof_expr); + return switch (ty.specifier) { + .typeof_type => ty.data.sub_type.get(specifier), + .typeof_expr => ty.data.expr.ty.get(specifier), + .attributed => ty.data.attributed.base.get(specifier), + else => if (ty.specifier == specifier) ty else null, + }; +} + +pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 { + return switch (ty.specifier) { + .typeof_type => ty.data.sub_type.requestedAlignment(comp), + .typeof_expr => ty.data.expr.ty.requestedAlignment(comp), + .attributed => annotationAlignment(comp, Attribute.Iterator.initType(ty)), + else => null, + }; +} + +pub fn enumIsPacked(ty: Type, comp: *const Compilation) bool { + std.debug.assert(ty.is(.@"enum")); + return comp.langopts.short_enums or target_util.packAllEnums(comp.target) or ty.hasAttribute(.@"packed"); +} + +pub fn getName(ty: Type) StringId { + return switch (ty.specifier) { + .typeof_type => if (ty.name == .empty) ty.data.sub_type.getName() else ty.name, + .typeof_expr => if (ty.name == .empty) ty.data.expr.ty.getName() else ty.name, + .attributed => if (ty.name == .empty) ty.data.attributed.base.getName() else ty.name, + else => ty.name, + }; +} + +pub fn annotationAlignment(comp: *const Compilation, attrs: Attribute.Iterator) ?u29 { + var it = attrs; + var max_requested: ?u29 = null; + var last_aligned_index: ?usize = null; + while (it.next()) |item| { + const attribute, const index = item; + if (attribute.tag != .aligned) continue; + if (last_aligned_index) |aligned_index| { + // once we recurse into a new type, after an `aligned` attribute was found, we're done + if (index <= aligned_index) break; + } + last_aligned_index = index; + const requested = if (attribute.args.aligned.alignment) |alignment| alignment.requested else target_util.defaultAlignment(comp.target); + if (max_requested == null or max_requested.? < requested) { + max_requested = requested; + } + } + return max_requested; +} + +pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifiers: bool) bool { + const a = a_param.canonicalize(.standard); + const b = b_param.canonicalize(.standard); + + if (a.specifier == .invalid or b.specifier == .invalid) return false; + if (a.alignof(comp) != b.alignof(comp)) return false; + if (a.isPtr()) { + if (!b.isPtr()) return false; + } else if (a.isFunc()) { + if (!b.isFunc()) return false; + } else if (a.isArray()) { + if (!b.isArray()) return false; + } else if (a.specifier == .@"enum" and b.specifier != .@"enum") { + return a.data.@"enum".tag_ty.eql(b, comp, check_qualifiers); + } else if (b.specifier == .@"enum" and a.specifier != .@"enum") { + return a.eql(b.data.@"enum".tag_ty, comp, check_qualifiers); + } else if (a.specifier != b.specifier) return false; + + if (a.qual.atomic != b.qual.atomic) return false; + if (check_qualifiers) { + if (a.qual.@"const" != b.qual.@"const") return false; + if (a.qual.@"volatile" != b.qual.@"volatile") return false; + } + + if (a.isPtr()) { + return a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers); + } + switch (a.specifier) { + .pointer => unreachable, + + .func, + .var_args_func, + .old_style_func, + => if (!a.data.func.eql(b.data.func, a.specifier, b.specifier, comp)) return false, + + .array, + .static_array, + .incomplete_array, + .vector, + => { + const a_len = a.arrayLen(); + const b_len = b.arrayLen(); + if (a_len == null or b_len == null) { + // At least one array is incomplete; only check child type for equality + } else if (a_len.? != b_len.?) { + return false; + } + if (!a.elemType().eql(b.elemType(), comp, false)) return false; + }, + .variable_len_array => { + if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false; + }, + .@"struct", .@"union" => if (a.data.record != b.data.record) return false, + .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false, + .bit_int, .complex_bit_int => return a.data.int.bits == b.data.int.bits and a.data.int.signedness == b.data.int.signedness, + + else => {}, + } + return true; +} + +/// Decays an array to a pointer +pub fn decayArray(ty: *Type) void { + std.debug.assert(ty.isArray()); + ty.decayed = true; +} + +pub fn originalTypeOfDecayedArray(ty: Type) Type { + std.debug.assert(ty.isDecayed()); + var copy = ty; + copy.decayed = false; + return copy; +} + +/// Rank for floating point conversions, ignoring domain (complex vs real) +/// Asserts that ty is a floating point type +pub fn floatRank(ty: Type) usize { + const real = ty.makeReal(); + return switch (real.specifier) { + // TODO: bfloat16 => 0 + .float16 => 1, + .fp16 => 2, + .float => 3, + .double => 4, + .long_double => 5, + .float128 => 6, + // TODO: ibm128 => 7 + else => unreachable, + }; +} + +/// Rank for integer conversions, ignoring domain (complex vs real) +/// Asserts that ty is an integer type +pub fn integerRank(ty: Type, comp: *const Compilation) usize { + const real = ty.makeReal(); + return @intCast(switch (real.specifier) { + .bit_int => @as(u64, real.data.int.bits) << 3, + + .bool => 1 + (ty.bitSizeof(comp).? << 3), + .char, .schar, .uchar => 2 + (ty.bitSizeof(comp).? << 3), + .short, .ushort => 3 + (ty.bitSizeof(comp).? << 3), + .int, .uint => 4 + (ty.bitSizeof(comp).? << 3), + .long, .ulong => 5 + (ty.bitSizeof(comp).? << 3), + .long_long, .ulong_long => 6 + (ty.bitSizeof(comp).? << 3), + .int128, .uint128 => 7 + (ty.bitSizeof(comp).? << 3), + + .typeof_type => ty.data.sub_type.integerRank(comp), + .typeof_expr => ty.data.expr.ty.integerRank(comp), + .attributed => ty.data.attributed.base.integerRank(comp), + + .@"enum" => real.data.@"enum".tag_ty.integerRank(comp), + + else => unreachable, + }); +} + +/// Returns true if `a` and `b` are integer types that differ only in sign +pub fn sameRankDifferentSign(a: Type, b: Type, comp: *const Compilation) bool { + if (!a.isInt() or !b.isInt()) return false; + if (a.hasIncompleteSize() or b.hasIncompleteSize()) return false; + if (a.integerRank(comp) != b.integerRank(comp)) return false; + return a.isUnsignedInt(comp) != b.isUnsignedInt(comp); +} + +pub fn makeReal(ty: Type) Type { + // TODO discards attributed/typeof + var base_ty = ty.canonicalize(.standard); + switch (base_ty.specifier) { + .complex_float16, .complex_float, .complex_double, .complex_long_double, .complex_float128 => { + base_ty.specifier = @enumFromInt(@intFromEnum(base_ty.specifier) - 5); + return base_ty; + }, + .complex_char, .complex_schar, .complex_uchar, .complex_short, .complex_ushort, .complex_int, .complex_uint, .complex_long, .complex_ulong, .complex_long_long, .complex_ulong_long, .complex_int128, .complex_uint128 => { + base_ty.specifier = @enumFromInt(@intFromEnum(base_ty.specifier) - 13); + return base_ty; + }, + .complex_bit_int => { + base_ty.specifier = .bit_int; + return base_ty; + }, + else => return ty, + } +} + +pub fn makeComplex(ty: Type) Type { + // TODO discards attributed/typeof + var base_ty = ty.canonicalize(.standard); + switch (base_ty.specifier) { + .float, .double, .long_double, .float128 => { + base_ty.specifier = @enumFromInt(@intFromEnum(base_ty.specifier) + 5); + return base_ty; + }, + .char, .schar, .uchar, .short, .ushort, .int, .uint, .long, .ulong, .long_long, .ulong_long, .int128, .uint128 => { + base_ty.specifier = @enumFromInt(@intFromEnum(base_ty.specifier) + 13); + return base_ty; + }, + .bit_int => { + base_ty.specifier = .complex_bit_int; + return base_ty; + }, + else => return ty, + } +} + +/// Combines types recursively in the order they were parsed, uses `.void` specifier as a sentinel value. +pub fn combine(inner: *Type, outer: Type) Parser.Error!void { + switch (inner.specifier) { + .pointer => return inner.data.sub_type.combine(outer), + .unspecified_variable_len_array => { + std.debug.assert(!inner.isDecayed()); + try inner.data.sub_type.combine(outer); + }, + .variable_len_array => { + std.debug.assert(!inner.isDecayed()); + try inner.data.expr.ty.combine(outer); + }, + .array, .static_array, .incomplete_array => { + std.debug.assert(!inner.isDecayed()); + try inner.data.array.elem.combine(outer); + }, + .func, .var_args_func, .old_style_func => { + try inner.data.func.return_type.combine(outer); + }, + .typeof_type, + .typeof_expr, + => std.debug.assert(!inner.isDecayed()), + .void, .invalid => inner.* = outer, + else => unreachable, + } +} + +pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser.Error!void { + switch (ty.specifier) { + .pointer => return ty.data.sub_type.validateCombinedType(p, source_tok), + .unspecified_variable_len_array, + .variable_len_array, + .array, + .static_array, + .incomplete_array, + => { + const elem_ty = ty.elemType(); + if (elem_ty.hasIncompleteSize()) { + try p.errStr(.array_incomplete_elem, source_tok, try p.typeStr(elem_ty)); + return error.ParsingFailed; + } + if (elem_ty.isFunc()) { + try p.errTok(.array_func_elem, source_tok); + return error.ParsingFailed; + } + if (elem_ty.specifier == .static_array and elem_ty.isArray()) { + try p.errTok(.static_non_outermost_array, source_tok); + } + if (elem_ty.anyQual() and elem_ty.isArray()) { + try p.errTok(.qualifier_non_outermost_array, source_tok); + } + }, + .func, .var_args_func, .old_style_func => { + const ret_ty = &ty.data.func.return_type; + if (ret_ty.isArray()) try p.errTok(.func_cannot_return_array, source_tok); + if (ret_ty.isFunc()) try p.errTok(.func_cannot_return_func, source_tok); + if (ret_ty.qual.@"const") { + try p.errStr(.qual_on_ret_type, source_tok, "const"); + ret_ty.qual.@"const" = false; + } + if (ret_ty.qual.@"volatile") { + try p.errStr(.qual_on_ret_type, source_tok, "volatile"); + ret_ty.qual.@"volatile" = false; + } + if (ret_ty.qual.atomic) { + try p.errStr(.qual_on_ret_type, source_tok, "atomic"); + ret_ty.qual.atomic = false; + } + if (ret_ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) { + try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value"); + } + }, + .typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok), + .typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok), + .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok), + else => {}, + } +} + +/// An unfinished Type +pub const Builder = struct { + complex_tok: ?TokenIndex = null, + bit_int_tok: ?TokenIndex = null, + auto_type_tok: ?TokenIndex = null, + typedef: ?struct { + tok: TokenIndex, + ty: Type, + } = null, + specifier: Builder.Specifier = .none, + qual: Qualifiers.Builder = .{}, + typeof: ?Type = null, + /// When true an error is returned instead of adding a diagnostic message. + /// Used for trying to combine typedef types. + error_on_invalid: bool = false, + + pub const Specifier = union(enum) { + none, + void, + /// GNU __auto_type extension + auto_type, + /// C23 auto + c23_auto, + nullptr_t, + bool, + char, + schar, + uchar, + complex_char, + complex_schar, + complex_uchar, + + unsigned, + signed, + short, + sshort, + ushort, + short_int, + sshort_int, + ushort_int, + int, + sint, + uint, + long, + slong, + ulong, + long_int, + slong_int, + ulong_int, + long_long, + slong_long, + ulong_long, + long_long_int, + slong_long_int, + ulong_long_int, + int128, + sint128, + uint128, + complex_unsigned, + complex_signed, + complex_short, + complex_sshort, + complex_ushort, + complex_short_int, + complex_sshort_int, + complex_ushort_int, + complex_int, + complex_sint, + complex_uint, + complex_long, + complex_slong, + complex_ulong, + complex_long_int, + complex_slong_int, + complex_ulong_int, + complex_long_long, + complex_slong_long, + complex_ulong_long, + complex_long_long_int, + complex_slong_long_int, + complex_ulong_long_int, + complex_int128, + complex_sint128, + complex_uint128, + bit_int: u64, + sbit_int: u64, + ubit_int: u64, + complex_bit_int: u64, + complex_sbit_int: u64, + complex_ubit_int: u64, + + fp16, + float16, + float, + double, + long_double, + float128, + complex, + complex_float16, + complex_float, + complex_double, + complex_long_double, + complex_float128, + + pointer: *Type, + unspecified_variable_len_array: *Type, + decayed_unspecified_variable_len_array: *Type, + func: *Func, + var_args_func: *Func, + old_style_func: *Func, + array: *Array, + decayed_array: *Array, + static_array: *Array, + decayed_static_array: *Array, + incomplete_array: *Array, + decayed_incomplete_array: *Array, + vector: *Array, + variable_len_array: *Expr, + decayed_variable_len_array: *Expr, + @"struct": *Record, + @"union": *Record, + @"enum": *Enum, + typeof_type: *Type, + decayed_typeof_type: *Type, + typeof_expr: *Expr, + decayed_typeof_expr: *Expr, + + attributed: *Attributed, + decayed_attributed: *Attributed, + + pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 { + return switch (spec) { + .none => unreachable, + .void => "void", + .auto_type => "__auto_type", + .c23_auto => "auto", + .nullptr_t => "nullptr_t", + .bool => if (langopts.standard.atLeast(.c23)) "bool" else "_Bool", + .char => "char", + .schar => "signed char", + .uchar => "unsigned char", + .unsigned => "unsigned", + .signed => "signed", + .short => "short", + .ushort => "unsigned short", + .sshort => "signed short", + .short_int => "short int", + .sshort_int => "signed short int", + .ushort_int => "unsigned short int", + .int => "int", + .sint => "signed int", + .uint => "unsigned int", + .long => "long", + .slong => "signed long", + .ulong => "unsigned long", + .long_int => "long int", + .slong_int => "signed long int", + .ulong_int => "unsigned long int", + .long_long => "long long", + .slong_long => "signed long long", + .ulong_long => "unsigned long long", + .long_long_int => "long long int", + .slong_long_int => "signed long long int", + .ulong_long_int => "unsigned long long int", + .int128 => "__int128", + .sint128 => "signed __int128", + .uint128 => "unsigned __int128", + .complex_char => "_Complex char", + .complex_schar => "_Complex signed char", + .complex_uchar => "_Complex unsigned char", + .complex_unsigned => "_Complex unsigned", + .complex_signed => "_Complex signed", + .complex_short => "_Complex short", + .complex_ushort => "_Complex unsigned short", + .complex_sshort => "_Complex signed short", + .complex_short_int => "_Complex short int", + .complex_sshort_int => "_Complex signed short int", + .complex_ushort_int => "_Complex unsigned short int", + .complex_int => "_Complex int", + .complex_sint => "_Complex signed int", + .complex_uint => "_Complex unsigned int", + .complex_long => "_Complex long", + .complex_slong => "_Complex signed long", + .complex_ulong => "_Complex unsigned long", + .complex_long_int => "_Complex long int", + .complex_slong_int => "_Complex signed long int", + .complex_ulong_int => "_Complex unsigned long int", + .complex_long_long => "_Complex long long", + .complex_slong_long => "_Complex signed long long", + .complex_ulong_long => "_Complex unsigned long long", + .complex_long_long_int => "_Complex long long int", + .complex_slong_long_int => "_Complex signed long long int", + .complex_ulong_long_int => "_Complex unsigned long long int", + .complex_int128 => "_Complex __int128", + .complex_sint128 => "_Complex signed __int128", + .complex_uint128 => "_Complex unsigned __int128", + + .fp16 => "__fp16", + .float16 => "_Float16", + .float => "float", + .double => "double", + .long_double => "long double", + .float128 => "__float128", + .complex => "_Complex", + .complex_float16 => "_Complex _Float16", + .complex_float => "_Complex float", + .complex_double => "_Complex double", + .complex_long_double => "_Complex long double", + .complex_float128 => "_Complex __float128", + + .attributed => |attributed| Builder.fromType(attributed.base).str(langopts), + + else => null, + }; + } + }; + + pub fn finish(b: Builder, p: *Parser) Parser.Error!Type { + var ty: Type = .{ .specifier = undefined }; + if (b.typedef) |typedef| { + ty = typedef.ty; + if (ty.isArray()) { + var elem = ty.elemType(); + try b.qual.finish(p, &elem); + // TODO this really should be easier + switch (ty.specifier) { + .array, .static_array, .incomplete_array => { + const old = ty.data.array; + ty.data.array = try p.arena.create(Array); + ty.data.array.* = .{ + .len = old.len, + .elem = elem, + }; + }, + .variable_len_array, .unspecified_variable_len_array => { + const old = ty.data.expr; + ty.data.expr = try p.arena.create(Expr); + ty.data.expr.* = .{ + .node = old.node, + .ty = elem, + }; + }, + .typeof_type => {}, // TODO handle + .typeof_expr => {}, // TODO handle + .attributed => {}, // TODO handle + else => unreachable, + } + + return ty; + } + try b.qual.finish(p, &ty); + return ty; + } + switch (b.specifier) { + .none => { + if (b.typeof) |typeof| { + ty = typeof; + } else { + ty.specifier = .int; + if (p.comp.langopts.standard.atLeast(.c23)) { + try p.err(.missing_type_specifier_c23); + } else { + try p.err(.missing_type_specifier); + } + } + }, + .void => ty.specifier = .void, + .auto_type => ty.specifier = .auto_type, + .c23_auto => ty.specifier = .c23_auto, + .nullptr_t => unreachable, // nullptr_t can only be accessed via typeof(nullptr) + .bool => ty.specifier = .bool, + .char => ty.specifier = .char, + .schar => ty.specifier = .schar, + .uchar => ty.specifier = .uchar, + .complex_char => ty.specifier = .complex_char, + .complex_schar => ty.specifier = .complex_schar, + .complex_uchar => ty.specifier = .complex_uchar, + + .unsigned => ty.specifier = .uint, + .signed => ty.specifier = .int, + .short_int, .sshort_int, .short, .sshort => ty.specifier = .short, + .ushort, .ushort_int => ty.specifier = .ushort, + .int, .sint => ty.specifier = .int, + .uint => ty.specifier = .uint, + .long, .slong, .long_int, .slong_int => ty.specifier = .long, + .ulong, .ulong_int => ty.specifier = .ulong, + .long_long, .slong_long, .long_long_int, .slong_long_int => ty.specifier = .long_long, + .ulong_long, .ulong_long_int => ty.specifier = .ulong_long, + .int128, .sint128 => ty.specifier = .int128, + .uint128 => ty.specifier = .uint128, + .complex_unsigned => ty.specifier = .complex_uint, + .complex_signed => ty.specifier = .complex_int, + .complex_short_int, .complex_sshort_int, .complex_short, .complex_sshort => ty.specifier = .complex_short, + .complex_ushort, .complex_ushort_int => ty.specifier = .complex_ushort, + .complex_int, .complex_sint => ty.specifier = .complex_int, + .complex_uint => ty.specifier = .complex_uint, + .complex_long, .complex_slong, .complex_long_int, .complex_slong_int => ty.specifier = .complex_long, + .complex_ulong, .complex_ulong_int => ty.specifier = .complex_ulong, + .complex_long_long, .complex_slong_long, .complex_long_long_int, .complex_slong_long_int => ty.specifier = .complex_long_long, + .complex_ulong_long, .complex_ulong_long_int => ty.specifier = .complex_ulong_long, + .complex_int128, .complex_sint128 => ty.specifier = .complex_int128, + .complex_uint128 => ty.specifier = .complex_uint128, + .bit_int, .sbit_int, .ubit_int, .complex_bit_int, .complex_ubit_int, .complex_sbit_int => |bits| { + const unsigned = b.specifier == .ubit_int or b.specifier == .complex_ubit_int; + const complex_str = if (b.complex_tok != null) "_Complex " else ""; + if (unsigned) { + if (bits < 1) { + try p.errStr(.unsigned_bit_int_too_small, b.bit_int_tok.?, complex_str); + return Type.invalid; + } + } else { + if (bits < 2) { + try p.errStr(.signed_bit_int_too_small, b.bit_int_tok.?, complex_str); + return Type.invalid; + } + } + if (bits > Compilation.bit_int_max_bits) { + try p.errStr(if (unsigned) .unsigned_bit_int_too_big else .signed_bit_int_too_big, b.bit_int_tok.?, complex_str); + return Type.invalid; + } + ty.specifier = if (b.complex_tok != null) .complex_bit_int else .bit_int; + ty.data = .{ .int = .{ + .signedness = if (unsigned) .unsigned else .signed, + .bits = @intCast(bits), + } }; + }, + + .fp16 => ty.specifier = .fp16, + .float16 => ty.specifier = .float16, + .float => ty.specifier = .float, + .double => ty.specifier = .double, + .long_double => ty.specifier = .long_double, + .float128 => ty.specifier = .float128, + .complex_float16 => ty.specifier = .complex_float16, + .complex_float => ty.specifier = .complex_float, + .complex_double => ty.specifier = .complex_double, + .complex_long_double => ty.specifier = .complex_long_double, + .complex_float128 => ty.specifier = .complex_float128, + .complex => { + try p.errTok(.plain_complex, p.tok_i - 1); + ty.specifier = .complex_double; + }, + + .pointer => |data| { + ty.specifier = .pointer; + ty.data = .{ .sub_type = data }; + }, + .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => |data| { + ty.specifier = .unspecified_variable_len_array; + ty.data = .{ .sub_type = data }; + ty.decayed = b.specifier == .decayed_unspecified_variable_len_array; + }, + .func => |data| { + ty.specifier = .func; + ty.data = .{ .func = data }; + }, + .var_args_func => |data| { + ty.specifier = .var_args_func; + ty.data = .{ .func = data }; + }, + .old_style_func => |data| { + ty.specifier = .old_style_func; + ty.data = .{ .func = data }; + }, + .array, .decayed_array => |data| { + ty.specifier = .array; + ty.data = .{ .array = data }; + ty.decayed = b.specifier == .decayed_array; + }, + .static_array, .decayed_static_array => |data| { + ty.specifier = .static_array; + ty.data = .{ .array = data }; + ty.decayed = b.specifier == .decayed_static_array; + }, + .incomplete_array, .decayed_incomplete_array => |data| { + ty.specifier = .incomplete_array; + ty.data = .{ .array = data }; + ty.decayed = b.specifier == .decayed_incomplete_array; + }, + .vector => |data| { + ty.specifier = .vector; + ty.data = .{ .array = data }; + }, + .variable_len_array, .decayed_variable_len_array => |data| { + ty.specifier = .variable_len_array; + ty.data = .{ .expr = data }; + ty.decayed = b.specifier == .decayed_variable_len_array; + }, + .@"struct" => |data| { + ty.specifier = .@"struct"; + ty.data = .{ .record = data }; + }, + .@"union" => |data| { + ty.specifier = .@"union"; + ty.data = .{ .record = data }; + }, + .@"enum" => |data| { + ty.specifier = .@"enum"; + ty.data = .{ .@"enum" = data }; + }, + .typeof_type, .decayed_typeof_type => |data| { + ty.specifier = .typeof_type; + ty.data = .{ .sub_type = data }; + ty.decayed = b.specifier == .decayed_typeof_type; + }, + .typeof_expr, .decayed_typeof_expr => |data| { + ty.specifier = .typeof_expr; + ty.data = .{ .expr = data }; + ty.decayed = b.specifier == .decayed_typeof_expr; + }, + .attributed, .decayed_attributed => |data| { + ty.specifier = .attributed; + ty.data = .{ .attributed = data }; + ty.decayed = b.specifier == .decayed_attributed; + }, + } + if (!ty.isReal() and ty.isInt()) { + if (b.complex_tok) |tok| try p.errTok(.complex_int, tok); + } + try b.qual.finish(p, &ty); + return ty; + } + + fn cannotCombine(b: Builder, p: *Parser, source_tok: TokenIndex) !void { + if (b.error_on_invalid) return error.CannotCombine; + const ty_str = b.specifier.str(p.comp.langopts) orelse try p.typeStr(try b.finish(p)); + try p.errExtra(.cannot_combine_spec, source_tok, .{ .str = ty_str }); + if (b.typedef) |some| try p.errStr(.spec_from_typedef, some.tok, try p.typeStr(some.ty)); + } + + fn duplicateSpec(b: *Builder, p: *Parser, source_tok: TokenIndex, spec: []const u8) !void { + if (b.error_on_invalid) return error.CannotCombine; + if (p.comp.langopts.emulate != .clang) return b.cannotCombine(p, source_tok); + try p.errStr(.duplicate_decl_spec, p.tok_i, spec); + } + + pub fn combineFromTypeof(b: *Builder, p: *Parser, new: Type, source_tok: TokenIndex) Compilation.Error!void { + if (b.typeof != null) return p.errStr(.cannot_combine_spec, source_tok, "typeof"); + if (b.specifier != .none) return p.errStr(.invalid_typeof, source_tok, @tagName(b.specifier)); + const inner = switch (new.specifier) { + .typeof_type => new.data.sub_type.*, + .typeof_expr => new.data.expr.ty, + .nullptr_t => new, // typeof(nullptr) is special-cased to be an unwrapped typeof-expr + else => unreachable, + }; + + b.typeof = switch (inner.specifier) { + .attributed => inner.data.attributed.base, + else => new, + }; + } + + /// Try to combine type from typedef, returns true if successful. + pub fn combineTypedef(b: *Builder, p: *Parser, typedef_ty: Type, name_tok: TokenIndex) bool { + if (typedef_ty.is(.invalid)) return false; + b.error_on_invalid = true; + defer b.error_on_invalid = false; + + const new_spec = fromType(typedef_ty); + b.combineExtra(p, new_spec, 0) catch |err| switch (err) { + error.FatalError => unreachable, // we do not add any diagnostics + error.OutOfMemory => unreachable, // we do not add any diagnostics + error.ParsingFailed => unreachable, // we do not add any diagnostics + error.CannotCombine => return false, + }; + b.typedef = .{ .tok = name_tok, .ty = typedef_ty }; + return true; + } + + pub fn combine(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void { + b.combineExtra(p, new, source_tok) catch |err| switch (err) { + error.CannotCombine => unreachable, + else => |e| return e, + }; + } + + fn combineExtra(b: *Builder, p: *Parser, new: Builder.Specifier, source_tok: TokenIndex) !void { + if (b.typeof != null) { + if (b.error_on_invalid) return error.CannotCombine; + try p.errStr(.invalid_typeof, source_tok, @tagName(new)); + } + + switch (new) { + .complex => b.complex_tok = source_tok, + .bit_int => b.bit_int_tok = source_tok, + .auto_type => b.auto_type_tok = source_tok, + else => {}, + } + + if (new == .int128 and !target_util.hasInt128(p.comp.target)) { + try p.errStr(.type_not_supported_on_target, source_tok, "__int128"); + } + + switch (new) { + else => switch (b.specifier) { + .none => b.specifier = new, + else => return b.cannotCombine(p, source_tok), + }, + .signed => b.specifier = switch (b.specifier) { + .none => .signed, + .char => .schar, + .short => .sshort, + .short_int => .sshort_int, + .int => .sint, + .long => .slong, + .long_int => .slong_int, + .long_long => .slong_long, + .long_long_int => .slong_long_int, + .int128 => .sint128, + .bit_int => |bits| .{ .sbit_int = bits }, + .complex => .complex_signed, + .complex_char => .complex_schar, + .complex_short => .complex_sshort, + .complex_short_int => .complex_sshort_int, + .complex_int => .complex_sint, + .complex_long => .complex_slong, + .complex_long_int => .complex_slong_int, + .complex_long_long => .complex_slong_long, + .complex_long_long_int => .complex_slong_long_int, + .complex_int128 => .complex_sint128, + .complex_bit_int => |bits| .{ .complex_sbit_int = bits }, + .signed, + .sshort, + .sshort_int, + .sint, + .slong, + .slong_int, + .slong_long, + .slong_long_int, + .sint128, + .sbit_int, + .complex_schar, + .complex_signed, + .complex_sshort, + .complex_sshort_int, + .complex_sint, + .complex_slong, + .complex_slong_int, + .complex_slong_long, + .complex_slong_long_int, + .complex_sint128, + .complex_sbit_int, + => return b.duplicateSpec(p, source_tok, "signed"), + else => return b.cannotCombine(p, source_tok), + }, + .unsigned => b.specifier = switch (b.specifier) { + .none => .unsigned, + .char => .uchar, + .short => .ushort, + .short_int => .ushort_int, + .int => .uint, + .long => .ulong, + .long_int => .ulong_int, + .long_long => .ulong_long, + .long_long_int => .ulong_long_int, + .int128 => .uint128, + .bit_int => |bits| .{ .ubit_int = bits }, + .complex => .complex_unsigned, + .complex_char => .complex_uchar, + .complex_short => .complex_ushort, + .complex_short_int => .complex_ushort_int, + .complex_int => .complex_uint, + .complex_long => .complex_ulong, + .complex_long_int => .complex_ulong_int, + .complex_long_long => .complex_ulong_long, + .complex_long_long_int => .complex_ulong_long_int, + .complex_int128 => .complex_uint128, + .complex_bit_int => |bits| .{ .complex_ubit_int = bits }, + .unsigned, + .ushort, + .ushort_int, + .uint, + .ulong, + .ulong_int, + .ulong_long, + .ulong_long_int, + .uint128, + .ubit_int, + .complex_uchar, + .complex_unsigned, + .complex_ushort, + .complex_ushort_int, + .complex_uint, + .complex_ulong, + .complex_ulong_int, + .complex_ulong_long, + .complex_ulong_long_int, + .complex_uint128, + .complex_ubit_int, + => return b.duplicateSpec(p, source_tok, "unsigned"), + else => return b.cannotCombine(p, source_tok), + }, + .char => b.specifier = switch (b.specifier) { + .none => .char, + .unsigned => .uchar, + .signed => .schar, + .complex => .complex_char, + .complex_signed => .complex_schar, + .complex_unsigned => .complex_uchar, + else => return b.cannotCombine(p, source_tok), + }, + .short => b.specifier = switch (b.specifier) { + .none => .short, + .unsigned => .ushort, + .signed => .sshort, + .int => .short_int, + .sint => .sshort_int, + .uint => .ushort_int, + .complex => .complex_short, + .complex_signed => .complex_sshort, + .complex_unsigned => .complex_ushort, + else => return b.cannotCombine(p, source_tok), + }, + .int => b.specifier = switch (b.specifier) { + .none => .int, + .signed => .sint, + .unsigned => .uint, + .short => .short_int, + .sshort => .sshort_int, + .ushort => .ushort_int, + .long => .long_int, + .slong => .slong_int, + .ulong => .ulong_int, + .long_long => .long_long_int, + .slong_long => .slong_long_int, + .ulong_long => .ulong_long_int, + .complex => .complex_int, + .complex_signed => .complex_sint, + .complex_unsigned => .complex_uint, + .complex_short => .complex_short_int, + .complex_sshort => .complex_sshort_int, + .complex_ushort => .complex_ushort_int, + .complex_long => .complex_long_int, + .complex_slong => .complex_slong_int, + .complex_ulong => .complex_ulong_int, + .complex_long_long => .complex_long_long_int, + .complex_slong_long => .complex_slong_long_int, + .complex_ulong_long => .complex_ulong_long_int, + else => return b.cannotCombine(p, source_tok), + }, + .long => b.specifier = switch (b.specifier) { + .none => .long, + .double => .long_double, + .long => .long_long, + .unsigned => .ulong, + .signed => .long, + .int => .long_int, + .sint => .slong_int, + .ulong => .ulong_long, + .complex => .complex_long, + .complex_signed => .complex_slong, + .complex_unsigned => .complex_ulong, + .complex_long => .complex_long_long, + .complex_slong => .complex_slong_long, + .complex_ulong => .complex_ulong_long, + .complex_double => .complex_long_double, + else => return b.cannotCombine(p, source_tok), + }, + .int128 => b.specifier = switch (b.specifier) { + .none => .int128, + .unsigned => .uint128, + .signed => .sint128, + .complex => .complex_int128, + .complex_signed => .complex_sint128, + .complex_unsigned => .complex_uint128, + else => return b.cannotCombine(p, source_tok), + }, + .bit_int => b.specifier = switch (b.specifier) { + .none => .{ .bit_int = new.bit_int }, + .unsigned => .{ .ubit_int = new.bit_int }, + .signed => .{ .sbit_int = new.bit_int }, + .complex => .{ .complex_bit_int = new.bit_int }, + .complex_signed => .{ .complex_sbit_int = new.bit_int }, + .complex_unsigned => .{ .complex_ubit_int = new.bit_int }, + else => return b.cannotCombine(p, source_tok), + }, + .auto_type => b.specifier = switch (b.specifier) { + .none => .auto_type, + else => return b.cannotCombine(p, source_tok), + }, + .c23_auto => b.specifier = switch (b.specifier) { + .none => .c23_auto, + else => return b.cannotCombine(p, source_tok), + }, + .fp16 => b.specifier = switch (b.specifier) { + .none => .fp16, + else => return b.cannotCombine(p, source_tok), + }, + .float16 => b.specifier = switch (b.specifier) { + .none => .float16, + .complex => .complex_float16, + else => return b.cannotCombine(p, source_tok), + }, + .float => b.specifier = switch (b.specifier) { + .none => .float, + .complex => .complex_float, + else => return b.cannotCombine(p, source_tok), + }, + .double => b.specifier = switch (b.specifier) { + .none => .double, + .long => .long_double, + .complex_long => .complex_long_double, + .complex => .complex_double, + else => return b.cannotCombine(p, source_tok), + }, + .float128 => b.specifier = switch (b.specifier) { + .none => .float128, + .complex => .complex_float128, + else => return b.cannotCombine(p, source_tok), + }, + .complex => b.specifier = switch (b.specifier) { + .none => .complex, + .float16 => .complex_float16, + .float => .complex_float, + .double => .complex_double, + .long_double => .complex_long_double, + .float128 => .complex_float128, + .char => .complex_char, + .schar => .complex_schar, + .uchar => .complex_uchar, + .unsigned => .complex_unsigned, + .signed => .complex_signed, + .short => .complex_short, + .sshort => .complex_sshort, + .ushort => .complex_ushort, + .short_int => .complex_short_int, + .sshort_int => .complex_sshort_int, + .ushort_int => .complex_ushort_int, + .int => .complex_int, + .sint => .complex_sint, + .uint => .complex_uint, + .long => .complex_long, + .slong => .complex_slong, + .ulong => .complex_ulong, + .long_int => .complex_long_int, + .slong_int => .complex_slong_int, + .ulong_int => .complex_ulong_int, + .long_long => .complex_long_long, + .slong_long => .complex_slong_long, + .ulong_long => .complex_ulong_long, + .long_long_int => .complex_long_long_int, + .slong_long_int => .complex_slong_long_int, + .ulong_long_int => .complex_ulong_long_int, + .int128 => .complex_int128, + .sint128 => .complex_sint128, + .uint128 => .complex_uint128, + .bit_int => |bits| .{ .complex_bit_int = bits }, + .sbit_int => |bits| .{ .complex_sbit_int = bits }, + .ubit_int => |bits| .{ .complex_ubit_int = bits }, + .complex, + .complex_float, + .complex_double, + .complex_long_double, + .complex_float128, + .complex_char, + .complex_schar, + .complex_uchar, + .complex_unsigned, + .complex_signed, + .complex_short, + .complex_sshort, + .complex_ushort, + .complex_short_int, + .complex_sshort_int, + .complex_ushort_int, + .complex_int, + .complex_sint, + .complex_uint, + .complex_long, + .complex_slong, + .complex_ulong, + .complex_long_int, + .complex_slong_int, + .complex_ulong_int, + .complex_long_long, + .complex_slong_long, + .complex_ulong_long, + .complex_long_long_int, + .complex_slong_long_int, + .complex_ulong_long_int, + .complex_int128, + .complex_sint128, + .complex_uint128, + .complex_bit_int, + .complex_sbit_int, + .complex_ubit_int, + => return b.duplicateSpec(p, source_tok, "_Complex"), + else => return b.cannotCombine(p, source_tok), + }, + } + } + + pub fn fromType(ty: Type) Builder.Specifier { + return switch (ty.specifier) { + .void => .void, + .auto_type => .auto_type, + .c23_auto => .c23_auto, + .nullptr_t => .nullptr_t, + .bool => .bool, + .char => .char, + .schar => .schar, + .uchar => .uchar, + .short => .short, + .ushort => .ushort, + .int => .int, + .uint => .uint, + .long => .long, + .ulong => .ulong, + .long_long => .long_long, + .ulong_long => .ulong_long, + .int128 => .int128, + .uint128 => .uint128, + .bit_int => if (ty.data.int.signedness == .unsigned) { + return .{ .ubit_int = ty.data.int.bits }; + } else { + return .{ .bit_int = ty.data.int.bits }; + }, + .complex_char => .complex_char, + .complex_schar => .complex_schar, + .complex_uchar => .complex_uchar, + .complex_short => .complex_short, + .complex_ushort => .complex_ushort, + .complex_int => .complex_int, + .complex_uint => .complex_uint, + .complex_long => .complex_long, + .complex_ulong => .complex_ulong, + .complex_long_long => .complex_long_long, + .complex_ulong_long => .complex_ulong_long, + .complex_int128 => .complex_int128, + .complex_uint128 => .complex_uint128, + .complex_bit_int => if (ty.data.int.signedness == .unsigned) { + return .{ .complex_ubit_int = ty.data.int.bits }; + } else { + return .{ .complex_bit_int = ty.data.int.bits }; + }, + .fp16 => .fp16, + .float16 => .float16, + .float => .float, + .double => .double, + .float128 => .float128, + .long_double => .long_double, + .complex_float16 => .complex_float16, + .complex_float => .complex_float, + .complex_double => .complex_double, + .complex_long_double => .complex_long_double, + .complex_float128 => .complex_float128, + + .pointer => .{ .pointer = ty.data.sub_type }, + .unspecified_variable_len_array => if (ty.isDecayed()) + .{ .decayed_unspecified_variable_len_array = ty.data.sub_type } + else + .{ .unspecified_variable_len_array = ty.data.sub_type }, + .func => .{ .func = ty.data.func }, + .var_args_func => .{ .var_args_func = ty.data.func }, + .old_style_func => .{ .old_style_func = ty.data.func }, + .array => if (ty.isDecayed()) + .{ .decayed_array = ty.data.array } + else + .{ .array = ty.data.array }, + .static_array => if (ty.isDecayed()) + .{ .decayed_static_array = ty.data.array } + else + .{ .static_array = ty.data.array }, + .incomplete_array => if (ty.isDecayed()) + .{ .decayed_incomplete_array = ty.data.array } + else + .{ .incomplete_array = ty.data.array }, + .vector => .{ .vector = ty.data.array }, + .variable_len_array => if (ty.isDecayed()) + .{ .decayed_variable_len_array = ty.data.expr } + else + .{ .variable_len_array = ty.data.expr }, + .@"struct" => .{ .@"struct" = ty.data.record }, + .@"union" => .{ .@"union" = ty.data.record }, + .@"enum" => .{ .@"enum" = ty.data.@"enum" }, + + .typeof_type => if (ty.isDecayed()) + .{ .decayed_typeof_type = ty.data.sub_type } + else + .{ .typeof_type = ty.data.sub_type }, + .typeof_expr => if (ty.isDecayed()) + .{ .decayed_typeof_expr = ty.data.expr } + else + .{ .typeof_expr = ty.data.expr }, + + .attributed => if (ty.isDecayed()) + .{ .decayed_attributed = ty.data.attributed } + else + .{ .attributed = ty.data.attributed }, + else => unreachable, + }; + } +}; + +/// Use with caution +pub fn base(ty: *Type) *Type { + return switch (ty.specifier) { + .typeof_type => ty.data.sub_type.base(), + .typeof_expr => ty.data.expr.ty.base(), + .attributed => ty.data.attributed.base.base(), + else => ty, + }; +} + +pub fn getAttribute(ty: Type, comptime tag: Attribute.Tag) ?Attribute.ArgumentsForTag(tag) { + if (tag == .aligned) @compileError("use requestedAlignment"); + var it = Attribute.Iterator.initType(ty); + while (it.next()) |item| { + const attribute, _ = item; + if (attribute.tag == tag) return @field(attribute.args, @tagName(tag)); + } + return null; +} + +pub fn hasAttribute(ty: Type, tag: Attribute.Tag) bool { + var it = Attribute.Iterator.initType(ty); + while (it.next()) |item| { + const attr, _ = item; + if (attr.tag == tag) return true; + } + return false; +} + +/// printf format modifier +pub fn formatModifier(ty: Type) []const u8 { + return switch (ty.specifier) { + .schar, .uchar => "hh", + .short, .ushort => "h", + .int, .uint => "", + .long, .ulong => "l", + .long_long, .ulong_long => "ll", + else => unreachable, + }; +} + +/// Suffix for integer values of this type +pub fn intValueSuffix(ty: Type, comp: *const Compilation) []const u8 { + return switch (ty.specifier) { + .schar, .short, .int => "", + .long => "L", + .long_long => "LL", + .uchar, .char => { + if (ty.specifier == .char and comp.getCharSignedness() == .signed) return ""; + // Only 8-bit char supported currently; + // TODO: handle platforms with 16-bit int + 16-bit char + std.debug.assert(ty.sizeof(comp).? == 1); + return ""; + }, + .ushort => { + if (ty.sizeof(comp).? < int.sizeof(comp).?) { + return ""; + } + return "U"; + }, + .uint => "U", + .ulong => "UL", + .ulong_long => "ULL", + else => unreachable, // not integer + }; +} + +/// Print type in C style +pub fn print(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void { + _ = try ty.printPrologue(mapper, langopts, w); + try ty.printEpilogue(mapper, langopts, w); +} + +pub fn printNamed(ty: Type, name: []const u8, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void { + const simple = try ty.printPrologue(mapper, langopts, w); + if (simple) try w.writeByte(' '); + try w.writeAll(name); + try ty.printEpilogue(mapper, langopts, w); +} + +const StringGetter = fn (TokenIndex) []const u8; + +/// return true if `ty` is simple +fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!bool { + if (ty.qual.atomic) { + var non_atomic_ty = ty; + non_atomic_ty.qual.atomic = false; + try w.writeAll("_Atomic("); + try non_atomic_ty.print(mapper, langopts, w); + try w.writeAll(")"); + return true; + } + if (ty.isPtr()) { + const elem_ty = ty.elemType(); + const simple = try elem_ty.printPrologue(mapper, langopts, w); + if (simple) try w.writeByte(' '); + if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('('); + try w.writeByte('*'); + try ty.qual.dump(w); + return false; + } + switch (ty.specifier) { + .pointer => unreachable, + .func, .var_args_func, .old_style_func => { + const ret_ty = ty.data.func.return_type; + const simple = try ret_ty.printPrologue(mapper, langopts, w); + if (simple) try w.writeByte(' '); + return false; + }, + .array, .static_array, .incomplete_array, .unspecified_variable_len_array, .variable_len_array => { + const elem_ty = ty.elemType(); + const simple = try elem_ty.printPrologue(mapper, langopts, w); + if (simple) try w.writeByte(' '); + return false; + }, + .typeof_type, .typeof_expr => { + const actual = ty.canonicalize(.standard); + return actual.printPrologue(mapper, langopts, w); + }, + .attributed => { + const actual = ty.canonicalize(.standard); + return actual.printPrologue(mapper, langopts, w); + }, + else => {}, + } + try ty.qual.dump(w); + + switch (ty.specifier) { + .@"enum" => if (ty.data.@"enum".fixed) { + try w.print("enum {s}: ", .{mapper.lookup(ty.data.@"enum".name)}); + try ty.data.@"enum".tag_ty.dump(mapper, langopts, w); + } else { + try w.print("enum {s}", .{mapper.lookup(ty.data.@"enum".name)}); + }, + .@"struct" => try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)}), + .@"union" => try w.print("union {s}", .{mapper.lookup(ty.data.record.name)}), + .vector => { + const len = ty.data.array.len; + const elem_ty = ty.data.array.elem; + try w.print("__attribute__((__vector_size__({d} * sizeof(", .{len}); + _ = try elem_ty.printPrologue(mapper, langopts, w); + try w.writeAll(")))) "); + _ = try elem_ty.printPrologue(mapper, langopts, w); + try w.print(" (vector of {d} '", .{len}); + _ = try elem_ty.printPrologue(mapper, langopts, w); + try w.writeAll("' values)"); + }, + .bit_int => try w.print("{s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }), + .complex_bit_int => try w.print("_Complex {s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }), + else => try w.writeAll(Builder.fromType(ty).str(langopts).?), + } + return true; +} + +fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void { + if (ty.qual.atomic) return; + if (ty.isPtr()) { + const elem_ty = ty.elemType(); + if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')'); + try elem_ty.printEpilogue(mapper, langopts, w); + return; + } + switch (ty.specifier) { + .pointer => unreachable, // handled above + .func, .var_args_func, .old_style_func => { + try w.writeByte('('); + for (ty.data.func.params, 0..) |param, i| { + if (i != 0) try w.writeAll(", "); + _ = try param.ty.printPrologue(mapper, langopts, w); + try param.ty.printEpilogue(mapper, langopts, w); + } + if (ty.specifier != .func) { + if (ty.data.func.params.len != 0) try w.writeAll(", "); + try w.writeAll("..."); + } else if (ty.data.func.params.len == 0) { + try w.writeAll("void"); + } + try w.writeByte(')'); + try ty.data.func.return_type.printEpilogue(mapper, langopts, w); + }, + .array, .static_array => { + try w.writeByte('['); + if (ty.specifier == .static_array) try w.writeAll("static "); + try ty.qual.dump(w); + try w.print("{d}]", .{ty.data.array.len}); + try ty.data.array.elem.printEpilogue(mapper, langopts, w); + }, + .incomplete_array => { + try w.writeByte('['); + try ty.qual.dump(w); + try w.writeByte(']'); + try ty.data.array.elem.printEpilogue(mapper, langopts, w); + }, + .unspecified_variable_len_array => { + try w.writeByte('['); + try ty.qual.dump(w); + try w.writeAll("*]"); + try ty.data.sub_type.printEpilogue(mapper, langopts, w); + }, + .variable_len_array => { + try w.writeByte('['); + try ty.qual.dump(w); + try w.writeAll("]"); + try ty.data.expr.ty.printEpilogue(mapper, langopts, w); + }, + .typeof_type, .typeof_expr => { + const actual = ty.canonicalize(.standard); + try actual.printEpilogue(mapper, langopts, w); + }, + .attributed => { + const actual = ty.canonicalize(.standard); + try actual.printEpilogue(mapper, langopts, w); + }, + else => {}, + } +} + +/// Useful for debugging, too noisy to be enabled by default. +const dump_detailed_containers = false; + +// Print as Zig types since those are actually readable +pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void { + try ty.qual.dump(w); + switch (ty.specifier) { + .invalid => try w.writeAll("invalid"), + .pointer => { + try w.writeAll("*"); + try ty.data.sub_type.dump(mapper, langopts, w); + }, + .func, .var_args_func, .old_style_func => { + if (ty.specifier == .old_style_func) + try w.writeAll("kr (") + else + try w.writeAll("fn ("); + for (ty.data.func.params, 0..) |param, i| { + if (i != 0) try w.writeAll(", "); + if (param.name != .empty) try w.print("{s}: ", .{mapper.lookup(param.name)}); + try param.ty.dump(mapper, langopts, w); + } + if (ty.specifier != .func) { + if (ty.data.func.params.len != 0) try w.writeAll(", "); + try w.writeAll("..."); + } + try w.writeAll(") "); + try ty.data.func.return_type.dump(mapper, langopts, w); + }, + .array, .static_array => { + if (ty.isDecayed()) try w.writeAll("*d"); + try w.writeByte('['); + if (ty.specifier == .static_array) try w.writeAll("static "); + try w.print("{d}]", .{ty.data.array.len}); + try ty.data.array.elem.dump(mapper, langopts, w); + }, + .vector => { + try w.print("vector({d}, ", .{ty.data.array.len}); + try ty.data.array.elem.dump(mapper, langopts, w); + try w.writeAll(")"); + }, + .incomplete_array => { + if (ty.isDecayed()) try w.writeAll("*d"); + try w.writeAll("[]"); + try ty.data.array.elem.dump(mapper, langopts, w); + }, + .@"enum" => { + const enum_ty = ty.data.@"enum"; + if (enum_ty.isIncomplete() and !enum_ty.fixed) { + try w.print("enum {s}", .{mapper.lookup(enum_ty.name)}); + } else { + try w.print("enum {s}: ", .{mapper.lookup(enum_ty.name)}); + try enum_ty.tag_ty.dump(mapper, langopts, w); + } + if (dump_detailed_containers) try dumpEnum(enum_ty, mapper, w); + }, + .@"struct" => { + try w.print("struct {s}", .{mapper.lookup(ty.data.record.name)}); + if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w); + }, + .@"union" => { + try w.print("union {s}", .{mapper.lookup(ty.data.record.name)}); + if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w); + }, + .unspecified_variable_len_array => { + if (ty.isDecayed()) try w.writeAll("*d"); + try w.writeAll("[*]"); + try ty.data.sub_type.dump(mapper, langopts, w); + }, + .variable_len_array => { + if (ty.isDecayed()) try w.writeAll("*d"); + try w.writeAll("[]"); + try ty.data.expr.ty.dump(mapper, langopts, w); + }, + .typeof_type => { + try w.writeAll("typeof("); + try ty.data.sub_type.dump(mapper, langopts, w); + try w.writeAll(")"); + }, + .typeof_expr => { + try w.writeAll("typeof(: "); + try ty.data.expr.ty.dump(mapper, langopts, w); + try w.writeAll(")"); + }, + .attributed => { + if (ty.isDecayed()) try w.writeAll("*d:"); + try w.writeAll("attributed("); + try ty.data.attributed.base.canonicalize(.standard).dump(mapper, langopts, w); + try w.writeAll(")"); + }, + .bit_int => try w.print("{s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }), + .complex_bit_int => try w.print("_Complex {s} _BitInt({d})", .{ @tagName(ty.data.int.signedness), ty.data.int.bits }), + else => try w.writeAll(Builder.fromType(ty).str(langopts).?), + } +} + +fn dumpEnum(@"enum": *Enum, mapper: StringInterner.TypeMapper, w: anytype) @TypeOf(w).Error!void { + try w.writeAll(" {"); + for (@"enum".fields) |field| { + try w.print(" {s} = {d},", .{ mapper.lookup(field.name), field.value }); + } + try w.writeAll(" }"); +} + +fn dumpRecord(record: *Record, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void { + try w.writeAll(" {"); + for (record.fields) |field| { + try w.writeByte(' '); + try field.ty.dump(mapper, langopts, w); + try w.print(" {s}: {d};", .{ mapper.lookup(field.name), field.bit_width }); + } + try w.writeAll(" }"); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Value.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Value.zig new file mode 100644 index 00000000..f736d63a --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/Value.zig @@ -0,0 +1,1033 @@ +const std = @import("std"); +const assert = std.debug.assert; +const BigIntConst = std.math.big.int.Const; +const BigIntMutable = std.math.big.int.Mutable; +const backend = @import("../backend.zig"); +const Interner = backend.Interner; +const BigIntSpace = Interner.Tag.Int.BigIntSpace; +const Compilation = @import("Compilation.zig"); +const Type = @import("Type.zig"); +const target_util = @import("target.zig"); +const annex_g = @import("annex_g.zig"); + +const Value = @This(); + +opt_ref: Interner.OptRef = .none, + +pub const zero = Value{ .opt_ref = .zero }; +pub const one = Value{ .opt_ref = .one }; +pub const @"null" = Value{ .opt_ref = .null }; + +pub fn intern(comp: *Compilation, k: Interner.Key) !Value { + const r = try comp.interner.put(comp.gpa, k); + return .{ .opt_ref = @enumFromInt(@intFromEnum(r)) }; +} + +pub fn int(i: anytype, comp: *Compilation) !Value { + const info = @typeInfo(@TypeOf(i)); + if (info == .comptime_int or info.int.signedness == .unsigned) { + return intern(comp, .{ .int = .{ .u64 = i } }); + } else { + return intern(comp, .{ .int = .{ .i64 = i } }); + } +} + +pub fn ref(v: Value) Interner.Ref { + std.debug.assert(v.opt_ref != .none); + return @enumFromInt(@intFromEnum(v.opt_ref)); +} + +pub fn is(v: Value, tag: std.meta.Tag(Interner.Key), comp: *const Compilation) bool { + if (v.opt_ref == .none) return false; + return comp.interner.get(v.ref()) == tag; +} + +pub fn isArithmetic(v: Value, comp: *const Compilation) bool { + if (v.opt_ref == .none) return false; + return switch (comp.interner.get(v.ref())) { + .int, .float, .complex => true, + else => false, + }; +} + +/// Number of bits needed to hold `v`. +/// Asserts that `v` is not negative +pub fn minUnsignedBits(v: Value, comp: *const Compilation) usize { + var space: BigIntSpace = undefined; + const big = v.toBigInt(&space, comp); + assert(big.positive); + return big.bitCountAbs(); +} + +test "minUnsignedBits" { + const Test = struct { + fn checkIntBits(comp: *Compilation, v: u64, expected: usize) !void { + const val = try intern(comp, .{ .int = .{ .u64 = v } }); + try std.testing.expectEqual(expected, val.minUnsignedBits(comp)); + } + }; + + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + const target_query = try std.Target.Query.parse(.{ .arch_os_abi = "x86_64-linux-gnu" }); + comp.target = try std.zig.system.resolveTargetQuery(target_query); + + try Test.checkIntBits(&comp, 0, 0); + try Test.checkIntBits(&comp, 1, 1); + try Test.checkIntBits(&comp, 2, 2); + try Test.checkIntBits(&comp, std.math.maxInt(i8), 7); + try Test.checkIntBits(&comp, std.math.maxInt(u8), 8); + try Test.checkIntBits(&comp, std.math.maxInt(i16), 15); + try Test.checkIntBits(&comp, std.math.maxInt(u16), 16); + try Test.checkIntBits(&comp, std.math.maxInt(i32), 31); + try Test.checkIntBits(&comp, std.math.maxInt(u32), 32); + try Test.checkIntBits(&comp, std.math.maxInt(i64), 63); + try Test.checkIntBits(&comp, std.math.maxInt(u64), 64); +} + +/// Minimum number of bits needed to represent `v` in 2's complement notation +/// Asserts that `v` is negative. +pub fn minSignedBits(v: Value, comp: *const Compilation) usize { + var space: BigIntSpace = undefined; + const big = v.toBigInt(&space, comp); + assert(!big.positive); + return big.bitCountTwosComp(); +} + +test "minSignedBits" { + const Test = struct { + fn checkIntBits(comp: *Compilation, v: i64, expected: usize) !void { + const val = try intern(comp, .{ .int = .{ .i64 = v } }); + try std.testing.expectEqual(expected, val.minSignedBits(comp)); + } + }; + + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + const target_query = try std.Target.Query.parse(.{ .arch_os_abi = "x86_64-linux-gnu" }); + comp.target = try std.zig.system.resolveTargetQuery(target_query); + + try Test.checkIntBits(&comp, -1, 1); + try Test.checkIntBits(&comp, -2, 2); + try Test.checkIntBits(&comp, -10, 5); + try Test.checkIntBits(&comp, -101, 8); + try Test.checkIntBits(&comp, std.math.minInt(i8), 8); + try Test.checkIntBits(&comp, std.math.minInt(i16), 16); + try Test.checkIntBits(&comp, std.math.minInt(i32), 32); + try Test.checkIntBits(&comp, std.math.minInt(i64), 64); +} + +pub const FloatToIntChangeKind = enum { + /// value did not change + none, + /// floating point number too small or large for destination integer type + out_of_range, + /// tried to convert a NaN or Infinity + overflow, + /// fractional value was converted to zero + nonzero_to_zero, + /// fractional part truncated + value_changed, +}; + +/// Converts the stored value from a float to an integer. +/// `.none` value remains unchanged. +pub fn floatToInt(v: *Value, dest_ty: Type, comp: *Compilation) !FloatToIntChangeKind { + if (v.opt_ref == .none) return .none; + + const float_val = v.toFloat(f128, comp); + const was_zero = float_val == 0; + + if (dest_ty.is(.bool)) { + const was_one = float_val == 1.0; + v.* = fromBool(!was_zero); + if (was_zero or was_one) return .none; + return .value_changed; + } else if (dest_ty.isUnsignedInt(comp) and float_val < 0) { + v.* = zero; + return .out_of_range; + } + + const had_fraction = @rem(float_val, 1) != 0; + const is_negative = std.math.signbit(float_val); + const floored = @floor(@abs(float_val)); + + var rational = try std.math.big.Rational.init(comp.gpa); + defer rational.deinit(); + rational.setFloat(f128, floored) catch |err| switch (err) { + error.NonFiniteFloat => { + v.* = .{}; + return .overflow; + }, + error.OutOfMemory => return error.OutOfMemory, + }; + + // The float is reduced in rational.setFloat, so we assert that denominator is equal to one + const big_one = BigIntConst{ .limbs = &.{1}, .positive = true }; + assert(rational.q.toConst().eqlAbs(big_one)); + + if (is_negative) { + rational.negate(); + } + + const signedness = dest_ty.signedness(comp); + const bits: usize = @intCast(dest_ty.bitSizeof(comp).?); + + // rational.p.truncate(rational.p.toConst(), signedness: Signedness, bit_count: usize) + const fits = rational.p.fitsInTwosComp(signedness, bits); + v.* = try intern(comp, .{ .int = .{ .big_int = rational.p.toConst() } }); + try rational.p.truncate(&rational.p, signedness, bits); + + if (!was_zero and v.isZero(comp)) return .nonzero_to_zero; + if (!fits) return .out_of_range; + if (had_fraction) return .value_changed; + return .none; +} + +/// Converts the stored value from an integer to a float. +/// `.none` value remains unchanged. +pub fn intToFloat(v: *Value, dest_ty: Type, comp: *Compilation) !void { + if (v.opt_ref == .none) return; + + if (dest_ty.isComplex()) { + const bits = dest_ty.bitSizeof(comp).?; + const cf: Interner.Key.Complex = switch (bits) { + 32 => .{ .cf16 = .{ v.toFloat(f16, comp), 0 } }, + 64 => .{ .cf32 = .{ v.toFloat(f32, comp), 0 } }, + 128 => .{ .cf64 = .{ v.toFloat(f64, comp), 0 } }, + 160 => .{ .cf80 = .{ v.toFloat(f80, comp), 0 } }, + 256 => .{ .cf128 = .{ v.toFloat(f128, comp), 0 } }, + else => unreachable, + }; + v.* = try intern(comp, .{ .complex = cf }); + return; + } + const bits = dest_ty.bitSizeof(comp).?; + return switch (comp.interner.get(v.ref()).int) { + inline .u64, .i64 => |data| { + const f: Interner.Key.Float = switch (bits) { + 16 => .{ .f16 = @floatFromInt(data) }, + 32 => .{ .f32 = @floatFromInt(data) }, + 64 => .{ .f64 = @floatFromInt(data) }, + 80 => .{ .f80 = @floatFromInt(data) }, + 128 => .{ .f128 = @floatFromInt(data) }, + else => unreachable, + }; + v.* = try intern(comp, .{ .float = f }); + }, + .big_int => |data| { + const big_f = bigIntToFloat(data.limbs, data.positive); + const f: Interner.Key.Float = switch (bits) { + 16 => .{ .f16 = @floatCast(big_f) }, + 32 => .{ .f32 = @floatCast(big_f) }, + 64 => .{ .f64 = @floatCast(big_f) }, + 80 => .{ .f80 = @floatCast(big_f) }, + 128 => .{ .f128 = @floatCast(big_f) }, + else => unreachable, + }; + v.* = try intern(comp, .{ .float = f }); + }, + }; +} + +pub const IntCastChangeKind = enum { + /// value did not change + none, + /// Truncation occurred (e.g., i32 to i16) + truncated, + /// Sign conversion occurred (e.g., i32 to u32) + sign_changed, +}; + +/// Truncates or extends bits based on type. +/// `.none` value remains unchanged. +pub fn intCast(v: *Value, dest_ty: Type, comp: *Compilation) !IntCastChangeKind { + if (v.opt_ref == .none) return .none; + + const dest_bits: usize = @intCast(dest_ty.bitSizeof(comp).?); + const dest_signed = dest_ty.signedness(comp) == .signed; + + var space: BigIntSpace = undefined; + const big = v.toBigInt(&space, comp); + const value_bits = big.bitCountTwosComp(); + + // if big is negative, then is signed. + const src_signed = !big.positive; + const sign_change = src_signed != dest_signed; + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcTwosCompLimbCount(@max(value_bits, dest_bits)), + ); + defer comp.gpa.free(limbs); + + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + result_bigint.truncate(big, dest_ty.signedness(comp), dest_bits); + + v.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); + + const truncation_occurred = value_bits > dest_bits; + if (truncation_occurred) { + return .truncated; + } else if (sign_change) { + return .sign_changed; + } else { + return .none; + } +} + +/// Converts the stored value to a float of the specified type +/// `.none` value remains unchanged. +pub fn floatCast(v: *Value, dest_ty: Type, comp: *Compilation) !void { + if (v.opt_ref == .none) return; + const bits = dest_ty.bitSizeof(comp).?; + if (dest_ty.isComplex()) { + const cf: Interner.Key.Complex = switch (bits) { + 32 => .{ .cf16 = .{ v.toFloat(f16, comp), v.imag(f16, comp) } }, + 64 => .{ .cf32 = .{ v.toFloat(f32, comp), v.imag(f32, comp) } }, + 128 => .{ .cf64 = .{ v.toFloat(f64, comp), v.imag(f64, comp) } }, + 160 => .{ .cf80 = .{ v.toFloat(f80, comp), v.imag(f80, comp) } }, + 256 => .{ .cf128 = .{ v.toFloat(f128, comp), v.imag(f128, comp) } }, + else => unreachable, + }; + v.* = try intern(comp, .{ .complex = cf }); + } else { + const f: Interner.Key.Float = switch (bits) { + 16 => .{ .f16 = v.toFloat(f16, comp) }, + 32 => .{ .f32 = v.toFloat(f32, comp) }, + 64 => .{ .f64 = v.toFloat(f64, comp) }, + 80 => .{ .f80 = v.toFloat(f80, comp) }, + 128 => .{ .f128 = v.toFloat(f128, comp) }, + else => unreachable, + }; + v.* = try intern(comp, .{ .float = f }); + } +} + +pub fn imag(v: Value, comptime T: type, comp: *const Compilation) T { + return switch (comp.interner.get(v.ref())) { + .int => 0.0, + .float => 0.0, + .complex => |repr| switch (repr) { + inline else => |components| return @floatCast(components[1]), + }, + else => unreachable, + }; +} + +pub fn toFloat(v: Value, comptime T: type, comp: *const Compilation) T { + return switch (comp.interner.get(v.ref())) { + .int => |repr| switch (repr) { + inline .u64, .i64 => |data| @floatFromInt(data), + .big_int => |data| @floatCast(bigIntToFloat(data.limbs, data.positive)), + }, + .float => |repr| switch (repr) { + inline else => |data| @floatCast(data), + }, + .complex => |repr| switch (repr) { + inline else => |components| @floatCast(components[0]), + }, + else => unreachable, + }; +} + +pub fn realPart(v: Value, comp: *Compilation) !Value { + if (v.opt_ref == .none) return v; + return switch (comp.interner.get(v.ref())) { + .int, .float => v, + .complex => |repr| Value.intern(comp, switch (repr) { + .cf16 => |components| .{ .float = .{ .f16 = components[0] } }, + .cf32 => |components| .{ .float = .{ .f32 = components[0] } }, + .cf64 => |components| .{ .float = .{ .f64 = components[0] } }, + .cf80 => |components| .{ .float = .{ .f80 = components[0] } }, + .cf128 => |components| .{ .float = .{ .f128 = components[0] } }, + }), + else => unreachable, + }; +} + +pub fn imaginaryPart(v: Value, comp: *Compilation) !Value { + if (v.opt_ref == .none) return v; + return switch (comp.interner.get(v.ref())) { + .int, .float => Value.zero, + .complex => |repr| Value.intern(comp, switch (repr) { + .cf16 => |components| .{ .float = .{ .f16 = components[1] } }, + .cf32 => |components| .{ .float = .{ .f32 = components[1] } }, + .cf64 => |components| .{ .float = .{ .f64 = components[1] } }, + .cf80 => |components| .{ .float = .{ .f80 = components[1] } }, + .cf128 => |components| .{ .float = .{ .f128 = components[1] } }, + }), + else => unreachable, + }; +} + +fn bigIntToFloat(limbs: []const std.math.big.Limb, positive: bool) f128 { + if (limbs.len == 0) return 0; + + const base = std.math.maxInt(std.math.big.Limb) + 1; + var result: f128 = 0; + var i: usize = limbs.len; + while (i != 0) { + i -= 1; + const limb: f128 = @as(f128, @floatFromInt(limbs[i])); + result = @mulAdd(f128, base, result, limb); + } + if (positive) { + return result; + } else { + return -result; + } +} + +pub fn toBigInt(val: Value, space: *BigIntSpace, comp: *const Compilation) BigIntConst { + return switch (comp.interner.get(val.ref()).int) { + inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(), + .big_int => |b| b, + }; +} + +pub fn isZero(v: Value, comp: *const Compilation) bool { + if (v.opt_ref == .none) return false; + switch (v.ref()) { + .zero => return true, + .one => return false, + .null => return target_util.nullRepr(comp.target) == 0, + else => {}, + } + const key = comp.interner.get(v.ref()); + switch (key) { + .float => |repr| switch (repr) { + inline else => |data| return data == 0, + }, + .int => |repr| switch (repr) { + inline .i64, .u64 => |data| return data == 0, + .big_int => |data| return data.eqlZero(), + }, + .complex => |repr| switch (repr) { + inline else => |data| return data[0] == 0.0 and data[1] == 0.0, + }, + .bytes => return false, + else => unreachable, + } +} + +const IsInfKind = enum(i32) { + negative = -1, + finite = 0, + positive = 1, + unknown = std.math.maxInt(i32), +}; + +pub fn isInfSign(v: Value, comp: *const Compilation) IsInfKind { + if (v.opt_ref == .none) return .unknown; + return switch (comp.interner.get(v.ref())) { + .float => |repr| switch (repr) { + inline else => |data| if (std.math.isPositiveInf(data)) .positive else if (std.math.isNegativeInf(data)) .negative else .finite, + }, + else => .unknown, + }; +} +pub fn isInf(v: Value, comp: *const Compilation) bool { + if (v.opt_ref == .none) return false; + return switch (comp.interner.get(v.ref())) { + .float => |repr| switch (repr) { + inline else => |data| std.math.isInf(data), + }, + .complex => |repr| switch (repr) { + inline else => |components| std.math.isInf(components[0]) or std.math.isInf(components[1]), + }, + else => false, + }; +} + +pub fn isNan(v: Value, comp: *const Compilation) bool { + if (v.opt_ref == .none) return false; + return switch (comp.interner.get(v.ref())) { + .float => |repr| switch (repr) { + inline else => |data| std.math.isNan(data), + }, + .complex => |repr| switch (repr) { + inline else => |components| std.math.isNan(components[0]) or std.math.isNan(components[1]), + }, + else => false, + }; +} + +/// Converts value to zero or one; +/// `.none` value remains unchanged. +pub fn boolCast(v: *Value, comp: *const Compilation) void { + if (v.opt_ref == .none) return; + v.* = fromBool(v.toBool(comp)); +} + +pub fn fromBool(b: bool) Value { + return if (b) one else zero; +} + +pub fn toBool(v: Value, comp: *const Compilation) bool { + return !v.isZero(comp); +} + +pub fn toInt(v: Value, comptime T: type, comp: *const Compilation) ?T { + if (v.opt_ref == .none) return null; + if (comp.interner.get(v.ref()) != .int) return null; + var space: BigIntSpace = undefined; + const big_int = v.toBigInt(&space, comp); + return big_int.toInt(T) catch null; +} + +const ComplexOp = enum { + add, + sub, +}; + +fn complexAddSub(lhs: Value, rhs: Value, comptime T: type, op: ComplexOp, comp: *Compilation) !Value { + const res_re = switch (op) { + .add => lhs.toFloat(T, comp) + rhs.toFloat(T, comp), + .sub => lhs.toFloat(T, comp) - rhs.toFloat(T, comp), + }; + const res_im = switch (op) { + .add => lhs.imag(T, comp) + rhs.imag(T, comp), + .sub => lhs.imag(T, comp) - rhs.imag(T, comp), + }; + + return switch (T) { + f16 => intern(comp, .{ .complex = .{ .cf16 = .{ res_re, res_im } } }), + f32 => intern(comp, .{ .complex = .{ .cf32 = .{ res_re, res_im } } }), + f64 => intern(comp, .{ .complex = .{ .cf64 = .{ res_re, res_im } } }), + f80 => intern(comp, .{ .complex = .{ .cf80 = .{ res_re, res_im } } }), + f128 => intern(comp, .{ .complex = .{ .cf128 = .{ res_re, res_im } } }), + else => unreachable, + }; +} + +pub fn add(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool { + const bits: usize = @intCast(ty.bitSizeof(comp).?); + if (ty.isFloat()) { + if (ty.isComplex()) { + res.* = switch (bits) { + 32 => try complexAddSub(lhs, rhs, f16, .add, comp), + 64 => try complexAddSub(lhs, rhs, f32, .add, comp), + 128 => try complexAddSub(lhs, rhs, f64, .add, comp), + 160 => try complexAddSub(lhs, rhs, f80, .add, comp), + 256 => try complexAddSub(lhs, rhs, f128, .add, comp), + else => unreachable, + }; + return false; + } + const f: Interner.Key.Float = switch (bits) { + 16 => .{ .f16 = lhs.toFloat(f16, comp) + rhs.toFloat(f16, comp) }, + 32 => .{ .f32 = lhs.toFloat(f32, comp) + rhs.toFloat(f32, comp) }, + 64 => .{ .f64 = lhs.toFloat(f64, comp) + rhs.toFloat(f64, comp) }, + 80 => .{ .f80 = lhs.toFloat(f80, comp) + rhs.toFloat(f80, comp) }, + 128 => .{ .f128 = lhs.toFloat(f128, comp) + rhs.toFloat(f128, comp) }, + else => unreachable, + }; + res.* = try intern(comp, .{ .float = f }); + return false; + } else { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcTwosCompLimbCount(bits), + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, ty.signedness(comp), bits); + res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); + return overflowed; + } +} + +pub fn sub(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool { + const bits: usize = @intCast(ty.bitSizeof(comp).?); + if (ty.isFloat()) { + if (ty.isComplex()) { + res.* = switch (bits) { + 32 => try complexAddSub(lhs, rhs, f16, .sub, comp), + 64 => try complexAddSub(lhs, rhs, f32, .sub, comp), + 128 => try complexAddSub(lhs, rhs, f64, .sub, comp), + 160 => try complexAddSub(lhs, rhs, f80, .sub, comp), + 256 => try complexAddSub(lhs, rhs, f128, .sub, comp), + else => unreachable, + }; + return false; + } + const f: Interner.Key.Float = switch (bits) { + 16 => .{ .f16 = lhs.toFloat(f16, comp) - rhs.toFloat(f16, comp) }, + 32 => .{ .f32 = lhs.toFloat(f32, comp) - rhs.toFloat(f32, comp) }, + 64 => .{ .f64 = lhs.toFloat(f64, comp) - rhs.toFloat(f64, comp) }, + 80 => .{ .f80 = lhs.toFloat(f80, comp) - rhs.toFloat(f80, comp) }, + 128 => .{ .f128 = lhs.toFloat(f128, comp) - rhs.toFloat(f128, comp) }, + else => unreachable, + }; + res.* = try intern(comp, .{ .float = f }); + return false; + } else { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcTwosCompLimbCount(bits), + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, ty.signedness(comp), bits); + res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); + return overflowed; + } +} + +pub fn mul(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool { + const bits: usize = @intCast(ty.bitSizeof(comp).?); + if (ty.isFloat()) { + if (ty.isComplex()) { + const cf: Interner.Key.Complex = switch (bits) { + 32 => .{ .cf16 = annex_g.complexFloatMul(f16, lhs.toFloat(f16, comp), lhs.imag(f16, comp), rhs.toFloat(f16, comp), rhs.imag(f16, comp)) }, + 64 => .{ .cf32 = annex_g.complexFloatMul(f32, lhs.toFloat(f32, comp), lhs.imag(f32, comp), rhs.toFloat(f32, comp), rhs.imag(f32, comp)) }, + 128 => .{ .cf64 = annex_g.complexFloatMul(f64, lhs.toFloat(f64, comp), lhs.imag(f64, comp), rhs.toFloat(f64, comp), rhs.imag(f64, comp)) }, + 160 => .{ .cf80 = annex_g.complexFloatMul(f80, lhs.toFloat(f80, comp), lhs.imag(f80, comp), rhs.toFloat(f80, comp), rhs.imag(f80, comp)) }, + 256 => .{ .cf128 = annex_g.complexFloatMul(f128, lhs.toFloat(f128, comp), lhs.imag(f128, comp), rhs.toFloat(f128, comp), rhs.imag(f128, comp)) }, + else => unreachable, + }; + res.* = try intern(comp, .{ .complex = cf }); + return false; + } + const f: Interner.Key.Float = switch (bits) { + 16 => .{ .f16 = lhs.toFloat(f16, comp) * rhs.toFloat(f16, comp) }, + 32 => .{ .f32 = lhs.toFloat(f32, comp) * rhs.toFloat(f32, comp) }, + 64 => .{ .f64 = lhs.toFloat(f64, comp) * rhs.toFloat(f64, comp) }, + 80 => .{ .f80 = lhs.toFloat(f80, comp) * rhs.toFloat(f80, comp) }, + 128 => .{ .f128 = lhs.toFloat(f128, comp) * rhs.toFloat(f128, comp) }, + else => unreachable, + }; + res.* = try intern(comp, .{ .float = f }); + return false; + } else { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + lhs_bigint.limbs.len + rhs_bigint.limbs.len, + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + const limbs_buffer = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcMulLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len, 1), + ); + defer comp.gpa.free(limbs_buffer); + + result_bigint.mul(lhs_bigint, rhs_bigint, limbs_buffer, comp.gpa); + + const signedness = ty.signedness(comp); + const overflowed = !result_bigint.toConst().fitsInTwosComp(signedness, bits); + if (overflowed) { + result_bigint.truncate(result_bigint.toConst(), signedness, bits); + } + res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); + return overflowed; + } +} + +/// caller guarantees rhs != 0 +pub fn div(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool { + const bits: usize = @intCast(ty.bitSizeof(comp).?); + if (ty.isFloat()) { + if (ty.isComplex()) { + const cf: Interner.Key.Complex = switch (bits) { + 32 => .{ .cf16 = annex_g.complexFloatDiv(f16, lhs.toFloat(f16, comp), lhs.imag(f16, comp), rhs.toFloat(f16, comp), rhs.imag(f16, comp)) }, + 64 => .{ .cf32 = annex_g.complexFloatDiv(f32, lhs.toFloat(f32, comp), lhs.imag(f32, comp), rhs.toFloat(f32, comp), rhs.imag(f32, comp)) }, + 128 => .{ .cf64 = annex_g.complexFloatDiv(f64, lhs.toFloat(f64, comp), lhs.imag(f64, comp), rhs.toFloat(f64, comp), rhs.imag(f64, comp)) }, + 160 => .{ .cf80 = annex_g.complexFloatDiv(f80, lhs.toFloat(f80, comp), lhs.imag(f80, comp), rhs.toFloat(f80, comp), rhs.imag(f80, comp)) }, + 256 => .{ .cf128 = annex_g.complexFloatDiv(f128, lhs.toFloat(f128, comp), lhs.imag(f128, comp), rhs.toFloat(f128, comp), rhs.imag(f128, comp)) }, + else => unreachable, + }; + res.* = try intern(comp, .{ .complex = cf }); + return false; + } + const f: Interner.Key.Float = switch (bits) { + 16 => .{ .f16 = lhs.toFloat(f16, comp) / rhs.toFloat(f16, comp) }, + 32 => .{ .f32 = lhs.toFloat(f32, comp) / rhs.toFloat(f32, comp) }, + 64 => .{ .f64 = lhs.toFloat(f64, comp) / rhs.toFloat(f64, comp) }, + 80 => .{ .f80 = lhs.toFloat(f80, comp) / rhs.toFloat(f80, comp) }, + 128 => .{ .f128 = lhs.toFloat(f128, comp) / rhs.toFloat(f128, comp) }, + else => unreachable, + }; + res.* = try intern(comp, .{ .float = f }); + return false; + } else { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const limbs_q = try comp.gpa.alloc( + std.math.big.Limb, + lhs_bigint.limbs.len, + ); + defer comp.gpa.free(limbs_q); + var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; + + const limbs_r = try comp.gpa.alloc( + std.math.big.Limb, + rhs_bigint.limbs.len, + ); + defer comp.gpa.free(limbs_r); + var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; + + const limbs_buffer = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len), + ); + defer comp.gpa.free(limbs_buffer); + + result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); + + res.* = try intern(comp, .{ .int = .{ .big_int = result_q.toConst() } }); + return !result_q.toConst().fitsInTwosComp(ty.signedness(comp), bits); + } +} + +/// caller guarantees rhs != 0 +/// caller guarantees lhs != std.math.minInt(T) OR rhs != -1 +pub fn rem(lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !Value { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const signedness = ty.signedness(comp); + if (signedness == .signed) { + var spaces: [2]BigIntSpace = undefined; + const min_val = try Value.minInt(ty, comp); + const negative = BigIntMutable.init(&spaces[0].limbs, -1).toConst(); + const big_one = BigIntMutable.init(&spaces[1].limbs, 1).toConst(); + if (lhs.compare(.eq, min_val, comp) and rhs_bigint.eql(negative)) { + return .{}; + } else if (rhs_bigint.order(big_one).compare(.lt)) { + // lhs - @divTrunc(lhs, rhs) * rhs + var tmp: Value = undefined; + _ = try tmp.div(lhs, rhs, ty, comp); + _ = try tmp.mul(tmp, rhs, ty, comp); + _ = try tmp.sub(lhs, tmp, ty, comp); + return tmp; + } + } + + const limbs_q = try comp.gpa.alloc( + std.math.big.Limb, + lhs_bigint.limbs.len, + ); + defer comp.gpa.free(limbs_q); + var result_q = BigIntMutable{ .limbs = limbs_q, .positive = undefined, .len = undefined }; + + const limbs_r = try comp.gpa.alloc( + std.math.big.Limb, + rhs_bigint.limbs.len, + ); + defer comp.gpa.free(limbs_r); + var result_r = BigIntMutable{ .limbs = limbs_r, .positive = undefined, .len = undefined }; + + const limbs_buffer = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcDivLimbsBufferLen(lhs_bigint.limbs.len, rhs_bigint.limbs.len), + ); + defer comp.gpa.free(limbs_buffer); + + result_q.divTrunc(&result_r, lhs_bigint, rhs_bigint, limbs_buffer); + return intern(comp, .{ .int = .{ .big_int = result_r.toConst() } }); +} + +pub fn bitOr(lhs: Value, rhs: Value, comp: *Compilation) !Value { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len), + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + result_bigint.bitOr(lhs_bigint, rhs_bigint); + return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); +} + +pub fn bitXor(lhs: Value, rhs: Value, comp: *Compilation) !Value { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const extra = @intFromBool(lhs_bigint.positive != rhs_bigint.positive); + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + extra, + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + result_bigint.bitXor(lhs_bigint, rhs_bigint); + return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); +} + +pub fn bitAnd(lhs: Value, rhs: Value, comp: *Compilation) !Value { + var lhs_space: BigIntSpace = undefined; + var rhs_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_space, comp); + + const limb_count = if (lhs_bigint.positive and rhs_bigint.positive) + @min(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + else if (lhs_bigint.positive) + lhs_bigint.limbs.len + else if (rhs_bigint.positive) + rhs_bigint.limbs.len + else + @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1; + + const limbs = try comp.gpa.alloc(std.math.big.Limb, limb_count); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + result_bigint.bitAnd(lhs_bigint, rhs_bigint); + return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); +} + +pub fn bitNot(val: Value, ty: Type, comp: *Compilation) !Value { + const bits: usize = @intCast(ty.bitSizeof(comp).?); + var val_space: Value.BigIntSpace = undefined; + const val_bigint = val.toBigInt(&val_space, comp); + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcTwosCompLimbCount(bits), + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + result_bigint.bitNotWrap(val_bigint, ty.signedness(comp), bits); + return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); +} + +pub fn shl(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !bool { + var lhs_space: Value.BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const shift = rhs.toInt(usize, comp) orelse std.math.maxInt(usize); + + const bits: usize = @intCast(ty.bitSizeof(comp).?); + if (shift > bits) { + if (lhs_bigint.positive) { + res.* = try Value.maxInt(ty, comp); + } else { + res.* = try Value.minInt(ty, comp); + } + return true; + } + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1, + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + result_bigint.shiftLeft(lhs_bigint, shift); + const signedness = ty.signedness(comp); + const overflowed = !result_bigint.toConst().fitsInTwosComp(signedness, bits); + if (overflowed) { + result_bigint.truncate(result_bigint.toConst(), signedness, bits); + } + res.* = try intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); + return overflowed; +} + +pub fn shr(lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !Value { + var lhs_space: Value.BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_space, comp); + const shift = rhs.toInt(usize, comp) orelse return zero; + + const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8)); + if (result_limbs == 0) { + // The shift is enough to remove all the bits from the number, which means the + // result is 0 or -1 depending on the sign. + if (lhs_bigint.positive) { + return zero; + } else { + return intern(comp, .{ .int = .{ .i64 = -1 } }); + } + } + + const bits: usize = @intCast(ty.bitSizeof(comp).?); + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcTwosCompLimbCount(bits), + ); + defer comp.gpa.free(limbs); + var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; + + result_bigint.shiftRight(lhs_bigint, shift); + return intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); +} + +pub fn complexConj(val: Value, ty: Type, comp: *Compilation) !Value { + const bits = ty.bitSizeof(comp).?; + const cf: Interner.Key.Complex = switch (bits) { + 32 => .{ .cf16 = .{ val.toFloat(f16, comp), -val.imag(f16, comp) } }, + 64 => .{ .cf32 = .{ val.toFloat(f32, comp), -val.imag(f32, comp) } }, + 128 => .{ .cf64 = .{ val.toFloat(f64, comp), -val.imag(f64, comp) } }, + 160 => .{ .cf80 = .{ val.toFloat(f80, comp), -val.imag(f80, comp) } }, + 256 => .{ .cf128 = .{ val.toFloat(f128, comp), -val.imag(f128, comp) } }, + else => unreachable, + }; + return intern(comp, .{ .complex = cf }); +} + +pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, comp: *const Compilation) bool { + if (op == .eq) { + return lhs.opt_ref == rhs.opt_ref; + } else if (lhs.opt_ref == rhs.opt_ref) { + return std.math.Order.eq.compare(op); + } + + const lhs_key = comp.interner.get(lhs.ref()); + const rhs_key = comp.interner.get(rhs.ref()); + if (lhs_key == .float or rhs_key == .float) { + const lhs_f128 = lhs.toFloat(f128, comp); + const rhs_f128 = rhs.toFloat(f128, comp); + return std.math.compare(lhs_f128, op, rhs_f128); + } + if (lhs_key == .complex or rhs_key == .complex) { + assert(op == .neq); + const real_equal = std.math.compare(lhs.toFloat(f128, comp), .eq, rhs.toFloat(f128, comp)); + const imag_equal = std.math.compare(lhs.imag(f128, comp), .eq, rhs.imag(f128, comp)); + return !real_equal or !imag_equal; + } + + var lhs_bigint_space: BigIntSpace = undefined; + var rhs_bigint_space: BigIntSpace = undefined; + const lhs_bigint = lhs.toBigInt(&lhs_bigint_space, comp); + const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, comp); + return lhs_bigint.order(rhs_bigint).compare(op); +} + +fn twosCompIntLimit(limit: std.math.big.int.TwosCompIntLimit, ty: Type, comp: *Compilation) !Value { + const signedness = ty.signedness(comp); + if (limit == .min and signedness == .unsigned) return Value.zero; + const mag_bits: usize = @intCast(ty.bitSizeof(comp).?); + switch (mag_bits) { + inline 8, 16, 32, 64 => |bits| { + if (limit == .min) return Value.int(@as(i64, std.math.minInt(std.meta.Int(.signed, bits))), comp); + return switch (signedness) { + inline else => |sign| Value.int(std.math.maxInt(std.meta.Int(sign, bits)), comp), + }; + }, + else => {}, + } + + const sign_bits = @intFromBool(signedness == .signed); + const total_bits = mag_bits + sign_bits; + + const limbs = try comp.gpa.alloc( + std.math.big.Limb, + std.math.big.int.calcTwosCompLimbCount(total_bits), + ); + defer comp.gpa.free(limbs); + + var result_bigint: BigIntMutable = .{ .limbs = limbs, .positive = undefined, .len = undefined }; + result_bigint.setTwosCompIntLimit(limit, signedness, mag_bits); + return Value.intern(comp, .{ .int = .{ .big_int = result_bigint.toConst() } }); +} + +pub fn minInt(ty: Type, comp: *Compilation) !Value { + return twosCompIntLimit(.min, ty, comp); +} + +pub fn maxInt(ty: Type, comp: *Compilation) !Value { + return twosCompIntLimit(.max, ty, comp); +} + +pub fn print(v: Value, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w).Error!void { + if (ty.is(.bool)) { + return w.writeAll(if (v.isZero(comp)) "false" else "true"); + } + const key = comp.interner.get(v.ref()); + switch (key) { + .null => return w.writeAll("nullptr_t"), + .int => |repr| switch (repr) { + inline else => |x| return w.print("{d}", .{x}), + }, + .float => |repr| switch (repr) { + .f16 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000) / 1000}), + .f32 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000000) / 1000000}), + inline else => |x| return w.print("{d}", .{@as(f64, @floatCast(x))}), + }, + .bytes => |b| return printString(b, ty, comp, w), + .complex => |repr| switch (repr) { + .cf32 => |components| return w.print("{d} + {d}i", .{ @round(@as(f64, @floatCast(components[0])) * 1000000) / 1000000, @round(@as(f64, @floatCast(components[1])) * 1000000) / 1000000 }), + inline else => |components| return w.print("{d} + {d}i", .{ @as(f64, @floatCast(components[0])), @as(f64, @floatCast(components[1])) }), + }, + else => unreachable, // not a value + } +} + +pub fn printString(bytes: []const u8, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w).Error!void { + const size: Compilation.CharUnitSize = @enumFromInt(ty.elemType().sizeof(comp).?); + const without_null = bytes[0 .. bytes.len - @intFromEnum(size)]; + try w.writeByte('"'); + switch (size) { + .@"1" => try w.print("{}", .{std.zig.fmtEscapes(without_null)}), + .@"2" => { + var items: [2]u16 = undefined; + var i: usize = 0; + while (i < without_null.len) { + @memcpy(std.mem.sliceAsBytes(items[0..1]), without_null[i..][0..2]); + i += 2; + const is_surrogate = std.unicode.utf16IsHighSurrogate(items[0]); + if (is_surrogate and i < without_null.len) { + @memcpy(std.mem.sliceAsBytes(items[1..2]), without_null[i..][0..2]); + if (std.unicode.utf16DecodeSurrogatePair(&items)) |decoded| { + i += 2; + try w.print("{u}", .{decoded}); + } else |_| { + try w.print("\\x{x}", .{items[0]}); + } + } else if (is_surrogate) { + try w.print("\\x{x}", .{items[0]}); + } else { + try w.print("{u}", .{items[0]}); + } + } + }, + .@"4" => { + var item: [1]u32 = undefined; + const data_slice = std.mem.sliceAsBytes(item[0..1]); + for (0..@divExact(without_null.len, 4)) |n| { + @memcpy(data_slice, without_null[n * 4 ..][0..4]); + if (item[0] <= std.math.maxInt(u21) and std.unicode.utf8ValidCodepoint(@intCast(item[0]))) { + const codepoint: u21 = @intCast(item[0]); + try w.print("{u}", .{codepoint}); + } else { + try w.print("\\x{x}", .{item[0]}); + } + } + }, + } + try w.writeByte('"'); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/annex_g.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/annex_g.zig new file mode 100644 index 00000000..56765ee3 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/annex_g.zig @@ -0,0 +1,118 @@ +//! Complex arithmetic algorithms from C99 Annex G + +const std = @import("std"); +const copysign = std.math.copysign; +const ilogb = std.math.ilogb; +const inf = std.math.inf; +const isFinite = std.math.isFinite; +const isInf = std.math.isInf; +const isNan = std.math.isNan; +const isPositiveZero = std.math.isPositiveZero; +const scalbn = std.math.scalbn; + +/// computes floating point z*w where a_param, b_param are real, imaginary parts of z and c_param, d_param are real, imaginary parts of w +pub fn complexFloatMul(comptime T: type, a_param: T, b_param: T, c_param: T, d_param: T) [2]T { + var a = a_param; + var b = b_param; + var c = c_param; + var d = d_param; + + const ac = a * c; + const bd = b * d; + const ad = a * d; + const bc = b * c; + var x = ac - bd; + var y = ad + bc; + if (isNan(x) and isNan(y)) { + var recalc = false; + if (isInf(a) or isInf(b)) { + // lhs infinite + // Box the infinity and change NaNs in the other factor to 0 + a = copysign(if (isInf(a)) @as(T, 1.0) else @as(T, 0.0), a); + b = copysign(if (isInf(b)) @as(T, 1.0) else @as(T, 0.0), b); + if (isNan(c)) c = copysign(@as(T, 0.0), c); + if (isNan(d)) d = copysign(@as(T, 0.0), d); + recalc = true; + } + if (isInf(c) or isInf(d)) { + // rhs infinite + // Box the infinity and change NaNs in the other factor to 0 + c = copysign(if (isInf(c)) @as(T, 1.0) else @as(T, 0.0), c); + d = copysign(if (isInf(d)) @as(T, 1.0) else @as(T, 0.0), d); + if (isNan(a)) a = copysign(@as(T, 0.0), a); + if (isNan(b)) b = copysign(@as(T, 0.0), b); + recalc = true; + } + if (!recalc and (isInf(ac) or isInf(bd) or isInf(ad) or isInf(bc))) { + // Recover infinities from overflow by changing NaN's to 0 + if (isNan(a)) a = copysign(@as(T, 0.0), a); + if (isNan(b)) b = copysign(@as(T, 0.0), b); + if (isNan(c)) c = copysign(@as(T, 0.0), c); + if (isNan(d)) d = copysign(@as(T, 0.0), d); + } + if (recalc) { + x = inf(T) * (a * c - b * d); + y = inf(T) * (a * d + b * c); + } + } + return .{ x, y }; +} + +/// computes floating point z / w where a_param, b_param are real, imaginary parts of z and c_param, d_param are real, imaginary parts of w +pub fn complexFloatDiv(comptime T: type, a_param: T, b_param: T, c_param: T, d_param: T) [2]T { + var a = a_param; + var b = b_param; + var c = c_param; + var d = d_param; + var denom_logb: i32 = 0; + const max_cd = @max(@abs(c), @abs(d)); + if (isFinite(max_cd)) { + if (max_cd == 0) { + denom_logb = std.math.minInt(i32) + 1; + c = 0; + d = 0; + } else { + denom_logb = ilogb(max_cd); + c = scalbn(c, -denom_logb); + d = scalbn(d, -denom_logb); + } + } + const denom = c * c + d * d; + var x = scalbn((a * c + b * d) / denom, -denom_logb); + var y = scalbn((b * c - a * d) / denom, -denom_logb); + if (isNan(x) and isNan(y)) { + if (isPositiveZero(denom) and (!isNan(a) or !isNan(b))) { + x = copysign(inf(T), c) * a; + y = copysign(inf(T), c) * b; + } else if ((isInf(a) or isInf(b)) and isFinite(c) and isFinite(d)) { + a = copysign(if (isInf(a)) @as(T, 1.0) else @as(T, 0.0), a); + b = copysign(if (isInf(b)) @as(T, 1.0) else @as(T, 0.0), b); + x = inf(T) * (a * c + b * d); + y = inf(T) * (b * c - a * d); + } else if (isInf(max_cd) and isFinite(a) and isFinite(b)) { + c = copysign(if (isInf(c)) @as(T, 1.0) else @as(T, 0.0), c); + d = copysign(if (isInf(d)) @as(T, 1.0) else @as(T, 0.0), d); + x = 0.0 * (a * c + b * d); + y = 0.0 * (b * c - a * d); + } + } + return .{ x, y }; +} + +test complexFloatMul { + // Naive algorithm would produce NaN + NaNi instead of inf + NaNi + const result = complexFloatMul(f64, inf(f64), std.math.nan(f64), 2, 0); + try std.testing.expect(isInf(result[0])); + try std.testing.expect(isNan(result[1])); +} + +test complexFloatDiv { + // Naive algorithm would produce NaN + NaNi instead of inf + NaNi + var result = complexFloatDiv(f64, inf(f64), std.math.nan(f64), 2, 0); + try std.testing.expect(isInf(result[0])); + try std.testing.expect(isNan(result[1])); + + result = complexFloatDiv(f64, 2.0, 2.0, 0.0, 0.0); + try std.testing.expect(isInf(result[0])); + try std.testing.expect(isInf(result[1])); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/char_info.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/char_info.zig new file mode 100644 index 00000000..c2134efa --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/char_info.zig @@ -0,0 +1,1111 @@ +//! This module provides functions for classifying characters according to +//! various C standards. All classification routines *do not* consider +//! characters from the basic character set; it is assumed those will be +//! checked separately +//! isXidStart and isXidContinue are adapted from https://github.com/dtolnay/unicode-ident + +const assert = @import("std").debug.assert; +const tables = @import("char_info/identifier_tables.zig"); + +/// C11 Standard Annex D +pub fn isC11IdChar(codepoint: u21) bool { + assert(codepoint > 0x7F); + return switch (codepoint) { + // 1 + 0x00A8, + 0x00AA, + 0x00AD, + 0x00AF, + 0x00B2...0x00B5, + 0x00B7...0x00BA, + 0x00BC...0x00BE, + 0x00C0...0x00D6, + 0x00D8...0x00F6, + 0x00F8...0x00FF, + + // 2 + 0x0100...0x167F, + 0x1681...0x180D, + 0x180F...0x1FFF, + + // 3 + 0x200B...0x200D, + 0x202A...0x202E, + 0x203F...0x2040, + 0x2054, + 0x2060...0x206F, + + // 4 + 0x2070...0x218F, + 0x2460...0x24FF, + 0x2776...0x2793, + 0x2C00...0x2DFF, + 0x2E80...0x2FFF, + + // 5 + 0x3004...0x3007, + 0x3021...0x302F, + 0x3031...0x303F, + + // 6 + 0x3040...0xD7FF, + + // 7 + 0xF900...0xFD3D, + 0xFD40...0xFDCF, + 0xFDF0...0xFE44, + 0xFE47...0xFFFD, + + // 8 + 0x10000...0x1FFFD, + 0x20000...0x2FFFD, + 0x30000...0x3FFFD, + 0x40000...0x4FFFD, + 0x50000...0x5FFFD, + 0x60000...0x6FFFD, + 0x70000...0x7FFFD, + 0x80000...0x8FFFD, + 0x90000...0x9FFFD, + 0xA0000...0xAFFFD, + 0xB0000...0xBFFFD, + 0xC0000...0xCFFFD, + 0xD0000...0xDFFFD, + 0xE0000...0xEFFFD, + => true, + else => false, + }; +} + +/// C99 Standard Annex D +pub fn isC99IdChar(codepoint: u21) bool { + assert(codepoint > 0x7F); + return switch (codepoint) { + // Latin + 0x00AA, + 0x00BA, + 0x00C0...0x00D6, + 0x00D8...0x00F6, + 0x00F8...0x01F5, + 0x01FA...0x0217, + 0x0250...0x02A8, + 0x1E00...0x1E9B, + 0x1EA0...0x1EF9, + 0x207F, + + // Greek + 0x0386, + 0x0388...0x038A, + 0x038C, + 0x038E...0x03A1, + 0x03A3...0x03CE, + 0x03D0...0x03D6, + 0x03DA, + 0x03DC, + 0x03DE, + 0x03E0, + 0x03E2...0x03F3, + 0x1F00...0x1F15, + 0x1F18...0x1F1D, + 0x1F20...0x1F45, + 0x1F48...0x1F4D, + 0x1F50...0x1F57, + 0x1F59, + 0x1F5B, + 0x1F5D, + 0x1F5F...0x1F7D, + 0x1F80...0x1FB4, + 0x1FB6...0x1FBC, + 0x1FC2...0x1FC4, + 0x1FC6...0x1FCC, + 0x1FD0...0x1FD3, + 0x1FD6...0x1FDB, + 0x1FE0...0x1FEC, + 0x1FF2...0x1FF4, + 0x1FF6...0x1FFC, + + // Cyrillic + 0x0401...0x040C, + 0x040E...0x044F, + 0x0451...0x045C, + 0x045E...0x0481, + 0x0490...0x04C4, + 0x04C7...0x04C8, + 0x04CB...0x04CC, + 0x04D0...0x04EB, + 0x04EE...0x04F5, + 0x04F8...0x04F9, + + // Armenian + 0x0531...0x0556, + 0x0561...0x0587, + + // Hebrew + 0x05B0...0x05B9, + 0x05BB...0x05BD, + 0x05BF, + 0x05C1...0x05C2, + 0x05D0...0x05EA, + 0x05F0...0x05F2, + + // Arabic + 0x0621...0x063A, + 0x0640...0x0652, + 0x0670...0x06B7, + 0x06BA...0x06BE, + 0x06C0...0x06CE, + 0x06D0...0x06DC, + 0x06E5...0x06E8, + 0x06EA...0x06ED, + + // Devanagari + 0x0901...0x0903, + 0x0905...0x0939, + 0x093E...0x094D, + 0x0950...0x0952, + 0x0958...0x0963, + + // Bengali + 0x0981...0x0983, + 0x0985...0x098C, + 0x098F...0x0990, + 0x0993...0x09A8, + 0x09AA...0x09B0, + 0x09B2, + 0x09B6...0x09B9, + 0x09BE...0x09C4, + 0x09C7...0x09C8, + 0x09CB...0x09CD, + 0x09DC...0x09DD, + 0x09DF...0x09E3, + 0x09F0...0x09F1, + + // Gurmukhi + 0x0A02, + 0x0A05...0x0A0A, + 0x0A0F...0x0A10, + 0x0A13...0x0A28, + 0x0A2A...0x0A30, + 0x0A32...0x0A33, + 0x0A35...0x0A36, + 0x0A38...0x0A39, + 0x0A3E...0x0A42, + 0x0A47...0x0A48, + 0x0A4B...0x0A4D, + 0x0A59...0x0A5C, + 0x0A5E, + 0x0A74, + + // Gujarati + 0x0A81...0x0A83, + 0x0A85...0x0A8B, + 0x0A8D, + 0x0A8F...0x0A91, + 0x0A93...0x0AA8, + 0x0AAA...0x0AB0, + 0x0AB2...0x0AB3, + 0x0AB5...0x0AB9, + 0x0ABD...0x0AC5, + 0x0AC7...0x0AC9, + 0x0ACB...0x0ACD, + 0x0AD0, + 0x0AE0, + + // Oriya + 0x0B01...0x0B03, + 0x0B05...0x0B0C, + 0x0B0F...0x0B10, + 0x0B13...0x0B28, + 0x0B2A...0x0B30, + 0x0B32...0x0B33, + 0x0B36...0x0B39, + 0x0B3E...0x0B43, + 0x0B47...0x0B48, + 0x0B4B...0x0B4D, + 0x0B5C...0x0B5D, + 0x0B5F...0x0B61, + + // Tamil + 0x0B82...0x0B83, + 0x0B85...0x0B8A, + 0x0B8E...0x0B90, + 0x0B92...0x0B95, + 0x0B99...0x0B9A, + 0x0B9C, + 0x0B9E...0x0B9F, + 0x0BA3...0x0BA4, + 0x0BA8...0x0BAA, + 0x0BAE...0x0BB5, + 0x0BB7...0x0BB9, + 0x0BBE...0x0BC2, + 0x0BC6...0x0BC8, + 0x0BCA...0x0BCD, + + // Telugu + 0x0C01...0x0C03, + 0x0C05...0x0C0C, + 0x0C0E...0x0C10, + 0x0C12...0x0C28, + 0x0C2A...0x0C33, + 0x0C35...0x0C39, + 0x0C3E...0x0C44, + 0x0C46...0x0C48, + 0x0C4A...0x0C4D, + 0x0C60...0x0C61, + + // Kannada + 0x0C82...0x0C83, + 0x0C85...0x0C8C, + 0x0C8E...0x0C90, + 0x0C92...0x0CA8, + 0x0CAA...0x0CB3, + 0x0CB5...0x0CB9, + 0x0CBE...0x0CC4, + 0x0CC6...0x0CC8, + 0x0CCA...0x0CCD, + 0x0CDE, + 0x0CE0...0x0CE1, + + // Malayalam + 0x0D02...0x0D03, + 0x0D05...0x0D0C, + 0x0D0E...0x0D10, + 0x0D12...0x0D28, + 0x0D2A...0x0D39, + 0x0D3E...0x0D43, + 0x0D46...0x0D48, + 0x0D4A...0x0D4D, + 0x0D60...0x0D61, + + // Thai (excluding digits 0x0E50...0x0E59; originally 0x0E01...0x0E3A and 0x0E40...0x0E5B + 0x0E01...0x0E3A, + 0x0E40...0x0E4F, + 0x0E5A...0x0E5B, + + // Lao + 0x0E81...0x0E82, + 0x0E84, + 0x0E87...0x0E88, + 0x0E8A, + 0x0E8D, + 0x0E94...0x0E97, + 0x0E99...0x0E9F, + 0x0EA1...0x0EA3, + 0x0EA5, + 0x0EA7, + 0x0EAA...0x0EAB, + 0x0EAD...0x0EAE, + 0x0EB0...0x0EB9, + 0x0EBB...0x0EBD, + 0x0EC0...0x0EC4, + 0x0EC6, + 0x0EC8...0x0ECD, + 0x0EDC...0x0EDD, + + // Tibetan + 0x0F00, + 0x0F18...0x0F19, + 0x0F35, + 0x0F37, + 0x0F39, + 0x0F3E...0x0F47, + 0x0F49...0x0F69, + 0x0F71...0x0F84, + 0x0F86...0x0F8B, + 0x0F90...0x0F95, + 0x0F97, + 0x0F99...0x0FAD, + 0x0FB1...0x0FB7, + 0x0FB9, + + // Georgian + 0x10A0...0x10C5, + 0x10D0...0x10F6, + + // Hiragana + 0x3041...0x3093, + 0x309B...0x309C, + + // Katakana + 0x30A1...0x30F6, + 0x30FB...0x30FC, + + // Bopomofo + 0x3105...0x312C, + + // CJK Unified Ideographs + 0x4E00...0x9FA5, + + // Hangul + 0xAC00...0xD7A3, + + // Digits + 0x0660...0x0669, + 0x06F0...0x06F9, + 0x0966...0x096F, + 0x09E6...0x09EF, + 0x0A66...0x0A6F, + 0x0AE6...0x0AEF, + 0x0B66...0x0B6F, + 0x0BE7...0x0BEF, + 0x0C66...0x0C6F, + 0x0CE6...0x0CEF, + 0x0D66...0x0D6F, + 0x0E50...0x0E59, + 0x0ED0...0x0ED9, + 0x0F20...0x0F33, + + // Special characters + 0x00B5, + 0x00B7, + 0x02B0...0x02B8, + 0x02BB, + 0x02BD...0x02C1, + 0x02D0...0x02D1, + 0x02E0...0x02E4, + 0x037A, + 0x0559, + 0x093D, + 0x0B3D, + 0x1FBE, + 0x203F...0x2040, + 0x2102, + 0x2107, + 0x210A...0x2113, + 0x2115, + 0x2118...0x211D, + 0x2124, + 0x2126, + 0x2128, + 0x212A...0x2131, + 0x2133...0x2138, + 0x2160...0x2182, + 0x3005...0x3007, + 0x3021...0x3029, + => true, + else => false, + }; +} + +/// C11 standard Annex D +pub fn isC11DisallowedInitialIdChar(codepoint: u21) bool { + assert(codepoint > 0x7F); + return switch (codepoint) { + 0x0300...0x036F, + 0x1DC0...0x1DFF, + 0x20D0...0x20FF, + 0xFE20...0xFE2F, + => true, + else => false, + }; +} + +/// These are "digit" characters; C99 disallows them as the first +/// character of an identifier +pub fn isC99DisallowedInitialIDChar(codepoint: u21) bool { + assert(codepoint > 0x7F); + return switch (codepoint) { + 0x0660...0x0669, + 0x06F0...0x06F9, + 0x0966...0x096F, + 0x09E6...0x09EF, + 0x0A66...0x0A6F, + 0x0AE6...0x0AEF, + 0x0B66...0x0B6F, + 0x0BE7...0x0BEF, + 0x0C66...0x0C6F, + 0x0CE6...0x0CEF, + 0x0D66...0x0D6F, + 0x0E50...0x0E59, + 0x0ED0...0x0ED9, + 0x0F20...0x0F33, + => true, + else => false, + }; +} + +pub fn isInvisible(codepoint: u21) bool { + assert(codepoint > 0x7F); + return switch (codepoint) { + 0x00ad, // SOFT HYPHEN + 0x200b, // ZERO WIDTH SPACE + 0x200c, // ZERO WIDTH NON-JOINER + 0x200d, // ZERO WIDTH JOINER + 0x2060, // WORD JOINER + 0x2061, // FUNCTION APPLICATION + 0x2062, // INVISIBLE TIMES + 0x2063, // INVISIBLE SEPARATOR + 0x2064, // INVISIBLE PLUS + 0xfeff, // ZERO WIDTH NO-BREAK SPACE + => true, + else => false, + }; +} + +/// Checks for identifier characters which resemble non-identifier characters +pub fn homoglyph(codepoint: u21) ?u21 { + assert(codepoint > 0x7F); + return switch (codepoint) { + 0x01c3 => '!', // LATIN LETTER RETROFLEX CLICK + 0x037e => ';', // GREEK QUESTION MARK + 0x2212 => '-', // MINUS SIGN + 0x2215 => '/', // DIVISION SLASH + 0x2216 => '\\', // SET MINUS + 0x2217 => '*', // ASTERISK OPERATOR + 0x2223 => '|', // DIVIDES + 0x2227 => '^', // LOGICAL AND + 0x2236 => ':', // RATIO + 0x223c => '~', // TILDE OPERATOR + 0xa789 => ':', // MODIFIER LETTER COLON + 0xff01 => '!', // FULLWIDTH EXCLAMATION MARK + 0xff03 => '#', // FULLWIDTH NUMBER SIGN + 0xff04 => '$', // FULLWIDTH DOLLAR SIGN + 0xff05 => '%', // FULLWIDTH PERCENT SIGN + 0xff06 => '&', // FULLWIDTH AMPERSAND + 0xff08 => '(', // FULLWIDTH LEFT PARENTHESIS + 0xff09 => ')', // FULLWIDTH RIGHT PARENTHESIS + 0xff0a => '*', // FULLWIDTH ASTERISK + 0xff0b => '+', // FULLWIDTH ASTERISK + 0xff0c => ',', // FULLWIDTH COMMA + 0xff0d => '-', // FULLWIDTH HYPHEN-MINUS + 0xff0e => '.', // FULLWIDTH FULL STOP + 0xff0f => '/', // FULLWIDTH SOLIDUS + 0xff1a => ':', // FULLWIDTH COLON + 0xff1b => ';', // FULLWIDTH SEMICOLON + 0xff1c => '<', // FULLWIDTH LESS-THAN SIGN + 0xff1d => '=', // FULLWIDTH EQUALS SIGN + 0xff1e => '>', // FULLWIDTH GREATER-THAN SIGN + 0xff1f => '?', // FULLWIDTH QUESTION MARK + 0xff20 => '@', // FULLWIDTH COMMERCIAL AT + 0xff3b => '[', // FULLWIDTH LEFT SQUARE BRACKET + 0xff3c => '\\', // FULLWIDTH REVERSE SOLIDUS + 0xff3d => ']', // FULLWIDTH RIGHT SQUARE BRACKET + 0xff3e => '^', // FULLWIDTH CIRCUMFLEX ACCENT + 0xff5b => '{', // FULLWIDTH LEFT CURLY BRACKET + 0xff5c => '|', // FULLWIDTH VERTICAL LINE + 0xff5d => '}', // FULLWIDTH RIGHT CURLY BRACKET + 0xff5e => '~', // FULLWIDTH TILDE + else => null, + }; +} + +pub fn isXidStart(c: u21) bool { + assert(c > 0x7F); + const idx = c / 8 / tables.chunk; + const chunk: usize = if (idx < tables.trie_start.len) tables.trie_start[idx] else 0; + const offset = chunk * tables.chunk / 2 + c / 8 % tables.chunk; + return (tables.leaf[offset] >> (@as(u3, @intCast(c % 8)))) & 1 != 0; +} + +pub fn isXidContinue(c: u21) bool { + assert(c > 0x7F); + const idx = c / 8 / tables.chunk; + const chunk: usize = if (idx < tables.trie_continue.len) tables.trie_continue[idx] else 0; + const offset = chunk * tables.chunk / 2 + c / 8 % tables.chunk; + return (tables.leaf[offset] >> (@as(u3, @intCast(c % 8)))) & 1 != 0; +} + +test "isXidStart / isXidContinue panic check" { + const std = @import("std"); + for (0x80..0x110000) |i| { + const c: u21 = @intCast(i); + if (std.unicode.utf8ValidCodepoint(c)) { + _ = isXidStart(c); + _ = isXidContinue(c); + } + } +} + +test isXidStart { + const std = @import("std"); + try std.testing.expect(!isXidStart('᠑')); + try std.testing.expect(!isXidStart('™')); + try std.testing.expect(!isXidStart('£')); + try std.testing.expect(!isXidStart('\u{1f914}')); // 🤔 +} + +test isXidContinue { + const std = @import("std"); + try std.testing.expect(isXidContinue('᠑')); + try std.testing.expect(!isXidContinue('™')); + try std.testing.expect(!isXidContinue('£')); + try std.testing.expect(!isXidContinue('\u{1f914}')); // 🤔 +} + +pub const NfcQuickCheck = enum { no, maybe, yes }; + +pub fn isNormalized(codepoint: u21) NfcQuickCheck { + return switch (codepoint) { + 0x0340...0x0341, + 0x0343...0x0344, + 0x0374, + 0x037E, + 0x0387, + 0x0958...0x095F, + 0x09DC...0x09DD, + 0x09DF, + 0x0A33, + 0x0A36, + 0x0A59...0x0A5B, + 0x0A5E, + 0x0B5C...0x0B5D, + 0x0F43, + 0x0F4D, + 0x0F52, + 0x0F57, + 0x0F5C, + 0x0F69, + 0x0F73, + 0x0F75...0x0F76, + 0x0F78, + 0x0F81, + 0x0F93, + 0x0F9D, + 0x0FA2, + 0x0FA7, + 0x0FAC, + 0x0FB9, + 0x1F71, + 0x1F73, + 0x1F75, + 0x1F77, + 0x1F79, + 0x1F7B, + 0x1F7D, + 0x1FBB, + 0x1FBE, + 0x1FC9, + 0x1FCB, + 0x1FD3, + 0x1FDB, + 0x1FE3, + 0x1FEB, + 0x1FEE...0x1FEF, + 0x1FF9, + 0x1FFB, + 0x1FFD, + 0x2000...0x2001, + 0x2126, + 0x212A...0x212B, + 0x2329, + 0x232A, + 0x2ADC, + 0xF900...0xFA0D, + 0xFA10, + 0xFA12, + 0xFA15...0xFA1E, + 0xFA20, + 0xFA22, + 0xFA25...0xFA26, + 0xFA2A...0xFA6D, + 0xFA70...0xFAD9, + 0xFB1D, + 0xFB1F, + 0xFB2A...0xFB36, + 0xFB38...0xFB3C, + 0xFB3E, + 0xFB40...0xFB41, + 0xFB43...0xFB44, + 0xFB46...0xFB4E, + 0x1D15E...0x1D164, + 0x1D1BB...0x1D1C0, + 0x2F800...0x2FA1D, + => .no, + 0x0300...0x0304, + 0x0306...0x030C, + 0x030F, + 0x0311, + 0x0313...0x0314, + 0x031B, + 0x0323...0x0328, + 0x032D...0x032E, + 0x0330...0x0331, + 0x0338, + 0x0342, + 0x0345, + 0x0653...0x0655, + 0x093C, + 0x09BE, + 0x09D7, + 0x0B3E, + 0x0B56, + 0x0B57, + 0x0BBE, + 0x0BD7, + 0x0C56, + 0x0CC2, + 0x0CD5...0x0CD6, + 0x0D3E, + 0x0D57, + 0x0DCA, + 0x0DCF, + 0x0DDF, + 0x102E, + 0x1161...0x1175, + 0x11A8...0x11C2, + 0x1B35, + 0x3099...0x309A, + 0x110BA, + 0x11127, + 0x1133E, + 0x11357, + 0x114B0, + 0x114BA, + 0x114BD, + 0x115AF, + => .maybe, + else => .yes, + }; +} + +pub const CanonicalCombiningClass = enum(u8) { + not_reordered = 0, + overlay = 1, + han_reading = 6, + nukta = 7, + kana_voicing = 8, + virama = 9, + ccc10 = 10, + ccc11 = 11, + ccc12 = 12, + ccc13 = 13, + ccc14 = 14, + ccc15 = 15, + ccc16 = 16, + ccc17 = 17, + ccc18 = 18, + ccc19 = 19, + ccc20 = 20, + ccc21 = 21, + ccc22 = 22, + ccc23 = 23, + ccc24 = 24, + ccc25 = 25, + ccc26 = 26, + ccc27 = 27, + ccc28 = 28, + ccc29 = 29, + ccc30 = 30, + ccc31 = 31, + ccc32 = 32, + ccc33 = 33, + ccc34 = 34, + ccc35 = 35, + ccc36 = 36, + ccc84 = 84, + ccc91 = 91, + ccc103 = 103, + ccc107 = 107, + ccc118 = 118, + ccc122 = 122, + ccc129 = 129, + ccc130 = 130, + ccc132 = 132, + attached_below = 202, + attached_above = 214, + attached_above_right = 216, + below_left = 218, + below = 220, + below_right = 222, + left = 224, + right = 226, + above_left = 228, + above = 230, + above_right = 232, + double_below = 233, + double_above = 234, + iota_subscript = 240, +}; + +pub fn getCanonicalClass(codepoint: u21) CanonicalCombiningClass { + return switch (codepoint) { + 0x300...0x314 => .above, + 0x315...0x315 => .above_right, + 0x316...0x319 => .below, + 0x31A...0x31A => .above_right, + 0x31B...0x31B => .attached_above_right, + 0x31C...0x320 => .below, + 0x321...0x322 => .attached_below, + 0x323...0x326 => .below, + 0x327...0x328 => .attached_below, + 0x329...0x333 => .below, + 0x334...0x338 => .overlay, + 0x339...0x33C => .below, + 0x33D...0x344 => .above, + 0x345...0x345 => .iota_subscript, + 0x346...0x346 => .above, + 0x347...0x349 => .below, + 0x34A...0x34C => .above, + 0x34D...0x34E => .below, + 0x350...0x352 => .above, + 0x353...0x356 => .below, + 0x357...0x357 => .above, + 0x358...0x358 => .above_right, + 0x359...0x35A => .below, + 0x35B...0x35B => .above, + 0x35C...0x35C => .double_below, + 0x35D...0x35E => .double_above, + 0x35F...0x35F => .double_below, + 0x360...0x361 => .double_above, + 0x362...0x362 => .double_below, + 0x363...0x36F => .above, + 0x483...0x487 => .above, + 0x591...0x591 => .below, + 0x592...0x595 => .above, + 0x596...0x596 => .below, + 0x597...0x599 => .above, + 0x59A...0x59A => .below_right, + 0x59B...0x59B => .below, + 0x59C...0x5A1 => .above, + 0x5A2...0x5A7 => .below, + 0x5A8...0x5A9 => .above, + 0x5AA...0x5AA => .below, + 0x5AB...0x5AC => .above, + 0x5AD...0x5AD => .below_right, + 0x5AE...0x5AE => .above_left, + 0x5AF...0x5AF => .above, + 0x5B0...0x5B0 => .ccc10, + 0x5B1...0x5B1 => .ccc11, + 0x5B2...0x5B2 => .ccc12, + 0x5B3...0x5B3 => .ccc13, + 0x5B4...0x5B4 => .ccc14, + 0x5B5...0x5B5 => .ccc15, + 0x5B6...0x5B6 => .ccc16, + 0x5B7...0x5B7 => .ccc17, + 0x5B8...0x5B8 => .ccc18, + 0x5B9...0x5BA => .ccc19, + 0x5BB...0x5BB => .ccc20, + 0x5BC...0x5BC => .ccc21, + 0x5BD...0x5BD => .ccc22, + 0x5BF...0x5BF => .ccc23, + 0x5C1...0x5C1 => .ccc24, + 0x5C2...0x5C2 => .ccc25, + 0x5C4...0x5C4 => .above, + 0x5C5...0x5C5 => .below, + 0x5C7...0x5C7 => .ccc18, + 0x610...0x617 => .above, + 0x618...0x618 => .ccc30, + 0x619...0x619 => .ccc31, + 0x61A...0x61A => .ccc32, + 0x64B...0x64B => .ccc27, + 0x64C...0x64C => .ccc28, + 0x64D...0x64D => .ccc29, + 0x64E...0x64E => .ccc30, + 0x64F...0x64F => .ccc31, + 0x650...0x650 => .ccc32, + 0x651...0x651 => .ccc33, + 0x652...0x652 => .ccc34, + 0x653...0x654 => .above, + 0x655...0x656 => .below, + 0x657...0x65B => .above, + 0x65C...0x65C => .below, + 0x65D...0x65E => .above, + 0x65F...0x65F => .below, + 0x670...0x670 => .ccc35, + 0x6D6...0x6DC => .above, + 0x6DF...0x6E2 => .above, + 0x6E3...0x6E3 => .below, + 0x6E4...0x6E4 => .above, + 0x6E7...0x6E8 => .above, + 0x6EA...0x6EA => .below, + 0x6EB...0x6EC => .above, + 0x6ED...0x6ED => .below, + 0x711...0x711 => .ccc36, + 0x730...0x730 => .above, + 0x731...0x731 => .below, + 0x732...0x733 => .above, + 0x734...0x734 => .below, + 0x735...0x736 => .above, + 0x737...0x739 => .below, + 0x73A...0x73A => .above, + 0x73B...0x73C => .below, + 0x73D...0x73D => .above, + 0x73E...0x73E => .below, + 0x73F...0x741 => .above, + 0x742...0x742 => .below, + 0x743...0x743 => .above, + 0x744...0x744 => .below, + 0x745...0x745 => .above, + 0x746...0x746 => .below, + 0x747...0x747 => .above, + 0x748...0x748 => .below, + 0x749...0x74A => .above, + 0x7EB...0x7F1 => .above, + 0x7F2...0x7F2 => .below, + 0x7F3...0x7F3 => .above, + 0x7FD...0x7FD => .below, + 0x816...0x819 => .above, + 0x81B...0x823 => .above, + 0x825...0x827 => .above, + 0x829...0x82D => .above, + 0x859...0x85B => .below, + 0x898...0x898 => .above, + 0x899...0x89B => .below, + 0x89C...0x89F => .above, + 0x8CA...0x8CE => .above, + 0x8CF...0x8D3 => .below, + 0x8D4...0x8E1 => .above, + 0x8E3...0x8E3 => .below, + 0x8E4...0x8E5 => .above, + 0x8E6...0x8E6 => .below, + 0x8E7...0x8E8 => .above, + 0x8E9...0x8E9 => .below, + 0x8EA...0x8EC => .above, + 0x8ED...0x8EF => .below, + 0x8F0...0x8F0 => .ccc27, + 0x8F1...0x8F1 => .ccc28, + 0x8F2...0x8F2 => .ccc29, + 0x8F3...0x8F5 => .above, + 0x8F6...0x8F6 => .below, + 0x8F7...0x8F8 => .above, + 0x8F9...0x8FA => .below, + 0x8FB...0x8FF => .above, + 0x93C...0x93C => .nukta, + 0x94D...0x94D => .virama, + 0x951...0x951 => .above, + 0x952...0x952 => .below, + 0x953...0x954 => .above, + 0x9BC...0x9BC => .nukta, + 0x9CD...0x9CD => .virama, + 0x9FE...0x9FE => .above, + 0xA3C...0xA3C => .nukta, + 0xA4D...0xA4D => .virama, + 0xABC...0xABC => .nukta, + 0xACD...0xACD => .virama, + 0xB3C...0xB3C => .nukta, + 0xB4D...0xB4D => .virama, + 0xBCD...0xBCD => .virama, + 0xC3C...0xC3C => .nukta, + 0xC4D...0xC4D => .virama, + 0xC55...0xC55 => .ccc84, + 0xC56...0xC56 => .ccc91, + 0xCBC...0xCBC => .nukta, + 0xCCD...0xCCD => .virama, + 0xD3B...0xD3C => .virama, + 0xD4D...0xD4D => .virama, + 0xDCA...0xDCA => .virama, + 0xE38...0xE39 => .ccc103, + 0xE3A...0xE3A => .virama, + 0xE48...0xE4B => .ccc107, + 0xEB8...0xEB9 => .ccc118, + 0xEBA...0xEBA => .virama, + 0xEC8...0xECB => .ccc122, + 0xF18...0xF19 => .below, + 0xF35...0xF35 => .below, + 0xF37...0xF37 => .below, + 0xF39...0xF39 => .attached_above_right, + 0xF71...0xF71 => .ccc129, + 0xF72...0xF72 => .ccc130, + 0xF74...0xF74 => .ccc132, + 0xF7A...0xF7D => .ccc130, + 0xF80...0xF80 => .ccc130, + 0xF82...0xF83 => .above, + 0xF84...0xF84 => .virama, + 0xF86...0xF87 => .above, + 0xFC6...0xFC6 => .below, + 0x1037...0x1037 => .nukta, + 0x1039...0x103A => .virama, + 0x108D...0x108D => .below, + 0x135D...0x135F => .above, + 0x1714...0x1715 => .virama, + 0x1734...0x1734 => .virama, + 0x17D2...0x17D2 => .virama, + 0x17DD...0x17DD => .above, + 0x18A9...0x18A9 => .above_left, + 0x1939...0x1939 => .below_right, + 0x193A...0x193A => .above, + 0x193B...0x193B => .below, + 0x1A17...0x1A17 => .above, + 0x1A18...0x1A18 => .below, + 0x1A60...0x1A60 => .virama, + 0x1A75...0x1A7C => .above, + 0x1A7F...0x1A7F => .below, + 0x1AB0...0x1AB4 => .above, + 0x1AB5...0x1ABA => .below, + 0x1ABB...0x1ABC => .above, + 0x1ABD...0x1ABD => .below, + 0x1ABF...0x1AC0 => .below, + 0x1AC1...0x1AC2 => .above, + 0x1AC3...0x1AC4 => .below, + 0x1AC5...0x1AC9 => .above, + 0x1ACA...0x1ACA => .below, + 0x1ACB...0x1ACE => .above, + 0x1B34...0x1B34 => .nukta, + 0x1B44...0x1B44 => .virama, + 0x1B6B...0x1B6B => .above, + 0x1B6C...0x1B6C => .below, + 0x1B6D...0x1B73 => .above, + 0x1BAA...0x1BAB => .virama, + 0x1BE6...0x1BE6 => .nukta, + 0x1BF2...0x1BF3 => .virama, + 0x1C37...0x1C37 => .nukta, + 0x1CD0...0x1CD2 => .above, + 0x1CD4...0x1CD4 => .overlay, + 0x1CD5...0x1CD9 => .below, + 0x1CDA...0x1CDB => .above, + 0x1CDC...0x1CDF => .below, + 0x1CE0...0x1CE0 => .above, + 0x1CE2...0x1CE8 => .overlay, + 0x1CED...0x1CED => .below, + 0x1CF4...0x1CF4 => .above, + 0x1CF8...0x1CF9 => .above, + 0x1DC0...0x1DC1 => .above, + 0x1DC2...0x1DC2 => .below, + 0x1DC3...0x1DC9 => .above, + 0x1DCA...0x1DCA => .below, + 0x1DCB...0x1DCC => .above, + 0x1DCD...0x1DCD => .double_above, + 0x1DCE...0x1DCE => .attached_above, + 0x1DCF...0x1DCF => .below, + 0x1DD0...0x1DD0 => .attached_below, + 0x1DD1...0x1DF5 => .above, + 0x1DF6...0x1DF6 => .above_right, + 0x1DF7...0x1DF8 => .above_left, + 0x1DF9...0x1DF9 => .below, + 0x1DFA...0x1DFA => .below_left, + 0x1DFB...0x1DFB => .above, + 0x1DFC...0x1DFC => .double_below, + 0x1DFD...0x1DFD => .below, + 0x1DFE...0x1DFE => .above, + 0x1DFF...0x1DFF => .below, + 0x20D0...0x20D1 => .above, + 0x20D2...0x20D3 => .overlay, + 0x20D4...0x20D7 => .above, + 0x20D8...0x20DA => .overlay, + 0x20DB...0x20DC => .above, + 0x20E1...0x20E1 => .above, + 0x20E5...0x20E6 => .overlay, + 0x20E7...0x20E7 => .above, + 0x20E8...0x20E8 => .below, + 0x20E9...0x20E9 => .above, + 0x20EA...0x20EB => .overlay, + 0x20EC...0x20EF => .below, + 0x20F0...0x20F0 => .above, + 0x2CEF...0x2CF1 => .above, + 0x2D7F...0x2D7F => .virama, + 0x2DE0...0x2DFF => .above, + 0x302A...0x302A => .below_left, + 0x302B...0x302B => .above_left, + 0x302C...0x302C => .above_right, + 0x302D...0x302D => .below_right, + 0x302E...0x302F => .left, + 0x3099...0x309A => .kana_voicing, + 0xA66F...0xA66F => .above, + 0xA674...0xA67D => .above, + 0xA69E...0xA69F => .above, + 0xA6F0...0xA6F1 => .above, + 0xA806...0xA806 => .virama, + 0xA82C...0xA82C => .virama, + 0xA8C4...0xA8C4 => .virama, + 0xA8E0...0xA8F1 => .above, + 0xA92B...0xA92D => .below, + 0xA953...0xA953 => .virama, + 0xA9B3...0xA9B3 => .nukta, + 0xA9C0...0xA9C0 => .virama, + 0xAAB0...0xAAB0 => .above, + 0xAAB2...0xAAB3 => .above, + 0xAAB4...0xAAB4 => .below, + 0xAAB7...0xAAB8 => .above, + 0xAABE...0xAABF => .above, + 0xAAC1...0xAAC1 => .above, + 0xAAF6...0xAAF6 => .virama, + 0xABED...0xABED => .virama, + 0xFB1E...0xFB1E => .ccc26, + 0xFE20...0xFE26 => .above, + 0xFE27...0xFE2D => .below, + 0xFE2E...0xFE2F => .above, + 0x101FD...0x101FD => .below, + 0x102E0...0x102E0 => .below, + 0x10376...0x1037A => .above, + 0x10A0D...0x10A0D => .below, + 0x10A0F...0x10A0F => .above, + 0x10A38...0x10A38 => .above, + 0x10A39...0x10A39 => .overlay, + 0x10A3A...0x10A3A => .below, + 0x10A3F...0x10A3F => .virama, + 0x10AE5...0x10AE5 => .above, + 0x10AE6...0x10AE6 => .below, + 0x10D24...0x10D27 => .above, + 0x10EAB...0x10EAC => .above, + 0x10EFD...0x10EFF => .below, + 0x10F46...0x10F47 => .below, + 0x10F48...0x10F4A => .above, + 0x10F4B...0x10F4B => .below, + 0x10F4C...0x10F4C => .above, + 0x10F4D...0x10F50 => .below, + 0x10F82...0x10F82 => .above, + 0x10F83...0x10F83 => .below, + 0x10F84...0x10F84 => .above, + 0x10F85...0x10F85 => .below, + 0x11046...0x11046 => .virama, + 0x11070...0x11070 => .virama, + 0x1107F...0x1107F => .virama, + 0x110B9...0x110B9 => .virama, + 0x110BA...0x110BA => .nukta, + 0x11100...0x11102 => .above, + 0x11133...0x11134 => .virama, + 0x11173...0x11173 => .nukta, + 0x111C0...0x111C0 => .virama, + 0x111CA...0x111CA => .nukta, + 0x11235...0x11235 => .virama, + 0x11236...0x11236 => .nukta, + 0x112E9...0x112E9 => .nukta, + 0x112EA...0x112EA => .virama, + 0x1133B...0x1133C => .nukta, + 0x1134D...0x1134D => .virama, + 0x11366...0x1136C => .above, + 0x11370...0x11374 => .above, + 0x11442...0x11442 => .virama, + 0x11446...0x11446 => .nukta, + 0x1145E...0x1145E => .above, + 0x114C2...0x114C2 => .virama, + 0x114C3...0x114C3 => .nukta, + 0x115BF...0x115BF => .virama, + 0x115C0...0x115C0 => .nukta, + 0x1163F...0x1163F => .virama, + 0x116B6...0x116B6 => .virama, + 0x116B7...0x116B7 => .nukta, + 0x1172B...0x1172B => .virama, + 0x11839...0x11839 => .virama, + 0x1183A...0x1183A => .nukta, + 0x1193D...0x1193E => .virama, + 0x11943...0x11943 => .nukta, + 0x119E0...0x119E0 => .virama, + 0x11A34...0x11A34 => .virama, + 0x11A47...0x11A47 => .virama, + 0x11A99...0x11A99 => .virama, + 0x11C3F...0x11C3F => .virama, + 0x11D42...0x11D42 => .nukta, + 0x11D44...0x11D45 => .virama, + 0x11D97...0x11D97 => .virama, + 0x11F41...0x11F42 => .virama, + 0x16AF0...0x16AF4 => .overlay, + 0x16B30...0x16B36 => .above, + 0x16FF0...0x16FF1 => .han_reading, + 0x1BC9E...0x1BC9E => .overlay, + 0x1D165...0x1D166 => .attached_above_right, + 0x1D167...0x1D169 => .overlay, + 0x1D16D...0x1D16D => .right, + 0x1D16E...0x1D172 => .attached_above_right, + 0x1D17B...0x1D182 => .below, + 0x1D185...0x1D189 => .above, + 0x1D18A...0x1D18B => .below, + 0x1D1AA...0x1D1AD => .above, + 0x1D242...0x1D244 => .above, + 0x1E000...0x1E006 => .above, + 0x1E008...0x1E018 => .above, + 0x1E01B...0x1E021 => .above, + 0x1E023...0x1E024 => .above, + 0x1E026...0x1E02A => .above, + 0x1E08F...0x1E08F => .above, + 0x1E130...0x1E136 => .above, + 0x1E2AE...0x1E2AE => .above, + 0x1E2EC...0x1E2EF => .above, + 0x1E4EC...0x1E4ED => .above_right, + 0x1E4EE...0x1E4EE => .below, + 0x1E4EF...0x1E4EF => .above, + 0x1E8D0...0x1E8D6 => .below, + 0x1E944...0x1E949 => .above, + 0x1E94A...0x1E94A => .nukta, + else => .not_reordered, + }; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/char_info/identifier_tables.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/char_info/identifier_tables.zig new file mode 100644 index 00000000..dae796d8 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/char_info/identifier_tables.zig @@ -0,0 +1,627 @@ +//! Adapted from the `unicode-ident` crate: https://github.com/dtolnay/unicode-ident +//! and Unicode Standard Annex #31 https://www.unicode.org/reports/tr31/ +//! Licensed under the MIT License and the Unicode license + +pub const chunk = 64; + +pub const trie_start: [402]u8 align(8) = .{ + 0x04, 0x0B, 0x0F, 0x13, 0x17, 0x1B, 0x1F, 0x23, 0x27, 0x2D, 0x31, 0x34, 0x38, 0x3C, 0x40, 0x02, + 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x51, 0x54, 0x58, 0x5C, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60, 0x64, 0x66, + 0x6A, 0x6E, 0x72, 0x28, 0x76, 0x78, 0x7C, 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9E, 0xA2, + 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xB1, 0x00, 0xB5, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC8, 0x00, 0x00, 0x00, 0xAF, + 0xCE, 0xD2, 0xD6, 0xBC, 0xDA, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0xE7, +}; + +pub const trie_continue: [1793]u8 align(8) = .{ + 0x08, 0x0D, 0x11, 0x15, 0x19, 0x1D, 0x21, 0x25, 0x2A, 0x2F, 0x31, 0x36, 0x3A, 0x3E, 0x42, 0x02, + 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x4F, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x51, 0x56, 0x5A, 0x5E, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x64, 0x68, + 0x6C, 0x70, 0x74, 0x28, 0x76, 0x7A, 0x7E, 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9B, 0xA0, 0xA4, + 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xB3, 0x00, 0xB7, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC, 0xC4, 0xC6, 0xCA, 0x00, 0xCC, 0x00, 0xAF, + 0xD0, 0xD4, 0xD8, 0xBC, 0xDC, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC2, +}; + +pub const leaf: [7584]u8 align(64) = .{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xAA, 0xFF, 0xFF, 0xFF, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x5F, 0xDC, 0x1F, 0xCF, 0x0F, 0xFF, 0x1F, 0xDC, 0x1F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xA0, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xB8, + 0x40, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xB8, + 0xC0, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFB, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x01, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xB6, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x60, 0xC0, 0x00, 0x9C, + 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x02, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x07, 0x30, 0x04, + 0x00, 0x00, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x9F, 0xFF, 0xFD, 0xFF, 0x9F, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x24, + 0xFF, 0xFF, 0x3F, 0x04, 0x10, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0xFF, + 0xFF, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0x01, 0xFF, 0x03, 0x00, 0xFE, 0xFF, + 0xE1, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0x23, 0x00, 0x40, 0x00, 0xB0, 0x03, 0x00, 0x03, 0x10, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x07, 0xFF, 0xFF, + 0xFF, 0x7E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0xFF, + 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0xF3, 0x9F, 0x79, 0x80, 0xB0, 0xCF, 0xFF, 0x03, 0x50, + 0xE0, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0x03, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x1C, 0x00, + 0xE0, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, + 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x00, 0xB0, 0x03, 0x00, 0x02, 0x00, + 0xE8, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEE, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0xD3, 0x87, 0x39, 0x02, 0x5E, 0xC0, 0xFF, 0x3F, 0x00, + 0xEE, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0xBF, 0x3B, 0x01, 0x00, 0xCF, 0xFF, 0x00, 0xFE, + 0xEE, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0x9F, 0x39, 0xE0, 0xB0, 0xCF, 0xFF, 0x02, 0x00, + 0xEC, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0xC3, 0xC7, 0x3D, 0x81, 0x00, 0xC0, 0xFF, 0x00, 0x00, + 0xE0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0x23, 0x00, 0x00, 0x00, 0x27, 0x03, 0x00, 0x00, 0x00, + 0xE1, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0x23, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x06, 0x00, + 0xF0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00, 0x40, 0x70, 0x80, 0x03, 0x00, 0x00, 0xFC, + 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xF3, 0xDF, 0x3D, 0x60, 0x27, 0xCF, 0xFF, 0x00, 0x00, + 0xEF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0xF3, 0xDF, 0x3D, 0x60, 0x60, 0xCF, 0xFF, 0x0E, 0x00, + 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7D, 0xF0, 0x80, 0xCF, 0xFF, 0x00, 0xFC, + 0xEE, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x84, 0x5F, 0xFF, 0xC0, 0xFF, 0x0C, 0x00, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0x05, 0x20, 0x5F, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, + 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x7F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0x3F, 0x5F, 0x7F, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x03, 0xFF, 0x03, 0xA0, 0xC2, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0xFE, 0xFF, + 0xDF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x80, 0x00, 0x00, 0x3F, 0x3C, 0x62, 0xC0, 0xE1, 0xFF, + 0x03, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0xFE, 0x03, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, + 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01, + 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xDF, 0x01, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, + 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01, + 0xFF, 0xFF, 0x3F, 0x80, 0xFF, 0xFF, 0x1F, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xDF, 0x0D, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x30, 0xFF, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, + 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xB8, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, + 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x0F, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x9F, + 0xFF, 0x03, 0xFF, 0x03, 0x80, 0x00, 0xFF, 0xBF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x03, 0x00, 0xF8, 0x0F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, + 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x6F, 0x04, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, + 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0xF0, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, + 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x80, + 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x1F, 0xE2, 0xFF, 0x01, 0x00, + 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x78, 0x0C, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0x0F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x80, + 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x7F, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x7F, 0xE6, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1F, 0xFF, 0xFF, 0x00, 0x0C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x80, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF, + 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xBF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, + 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF, + 0xBB, 0xF7, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, + 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x68, + 0x00, 0xFC, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0xDF, 0xFF, 0x00, 0x7C, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xE8, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF7, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0xC4, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x3E, 0x05, 0x00, 0x00, 0x38, 0xFF, 0x07, 0x1C, 0x00, + 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0x7F, 0xFC, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x38, 0xFF, 0xFF, 0x7C, 0x00, + 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x37, 0xFF, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x00, 0xF8, 0xA0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x00, 0xF8, 0xE0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, + 0x00, 0x00, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7, + 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7, + 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x91, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00, + 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x37, 0x00, + 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00, + 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6F, 0xF0, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x87, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, + 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00, + 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, + 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x90, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x80, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xDE, 0xFF, 0x17, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x0F, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, + 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0xE0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x03, + 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xFB, 0x9F, 0x39, 0x81, 0xE0, 0xCF, 0x1F, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xC3, 0x03, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x11, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0x0F, 0xFF, 0x03, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, + 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x80, + 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0xBF, 0xF9, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1B, 0x00, 0x00, 0x00, + 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0x00, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x03, 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x6F, + 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xBF, 0xFD, 0xFF, 0xFF, + 0xFF, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x01, 0x00, 0xFF, 0x03, 0x00, 0x00, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xB4, 0xFF, 0x00, 0xFF, 0x03, 0xBF, 0xFD, 0xFF, 0xFF, + 0xFF, 0x7F, 0xFB, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x00, + 0xF4, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, + 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x07, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE3, 0x07, 0xF8, + 0xE7, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xE0, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x0F, 0x00, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xE0, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x6F, 0xFF, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F, + 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F, + 0xFF, 0x01, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xDF, 0x64, 0xDE, 0xFF, 0xEB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xBF, 0xE7, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0x7B, 0x5F, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x00, + 0x10, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x3F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xF9, 0xDB, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEF, 0xFF, 0xFF, 0xFF, 0x96, 0xFE, 0xF7, 0x0A, 0x84, 0xEA, 0x96, 0xAA, 0x96, 0xF7, 0xF7, 0x5E, + 0xFF, 0xFB, 0xFF, 0x0F, 0xEE, 0xFB, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/features.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/features.zig new file mode 100644 index 00000000..fdc49b72 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/features.zig @@ -0,0 +1,76 @@ +const std = @import("std"); +const Compilation = @import("Compilation.zig"); +const target_util = @import("target.zig"); + +/// Used to implement the __has_feature macro. +pub fn hasFeature(comp: *Compilation, ext: []const u8) bool { + const list = .{ + .assume_nonnull = true, + .attribute_analyzer_noreturn = true, + .attribute_availability = true, + .attribute_availability_with_message = true, + .attribute_availability_app_extension = true, + .attribute_availability_with_version_underscores = true, + .attribute_availability_tvos = true, + .attribute_availability_watchos = true, + .attribute_availability_with_strict = true, + .attribute_availability_with_replacement = true, + .attribute_availability_in_templates = true, + .attribute_availability_swift = true, + .attribute_cf_returns_not_retained = true, + .attribute_cf_returns_retained = true, + .attribute_cf_returns_on_parameters = true, + .attribute_deprecated_with_message = true, + .attribute_deprecated_with_replacement = true, + .attribute_ext_vector_type = true, + .attribute_ns_returns_not_retained = true, + .attribute_ns_returns_retained = true, + .attribute_ns_consumes_self = true, + .attribute_ns_consumed = true, + .attribute_cf_consumed = true, + .attribute_overloadable = true, + .attribute_unavailable_with_message = true, + .attribute_unused_on_fields = true, + .attribute_diagnose_if_objc = true, + .blocks = false, // TODO + .c_thread_safety_attributes = true, + .enumerator_attributes = true, + .nullability = true, + .nullability_on_arrays = true, + .nullability_nullable_result = true, + .c_alignas = comp.langopts.standard.atLeast(.c11), + .c_alignof = comp.langopts.standard.atLeast(.c11), + .c_atomic = comp.langopts.standard.atLeast(.c11), + .c_generic_selections = comp.langopts.standard.atLeast(.c11), + .c_static_assert = comp.langopts.standard.atLeast(.c11), + .c_thread_local = comp.langopts.standard.atLeast(.c11) and target_util.isTlsSupported(comp.target), + }; + inline for (@typeInfo(@TypeOf(list)).@"struct".fields) |f| { + if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name); + } + return false; +} + +/// Used to implement the __has_extension macro. +pub fn hasExtension(comp: *Compilation, ext: []const u8) bool { + const list = .{ + // C11 features + .c_alignas = true, + .c_alignof = true, + .c_atomic = false, // TODO + .c_generic_selections = true, + .c_static_assert = true, + .c_thread_local = target_util.isTlsSupported(comp.target), + // misc + .overloadable_unmarked = false, // TODO + .statement_attributes_with_gnu_syntax = false, // TODO + .gnu_asm = true, + .gnu_asm_goto_with_outputs = true, + .matrix_types = false, // TODO + .matrix_types_scalar_division = false, // TODO + }; + inline for (@typeInfo(@TypeOf(list)).@"struct".fields) |f| { + if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name); + } + return false; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/gcc.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/gcc.zig new file mode 100644 index 00000000..ce67698b --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/gcc.zig @@ -0,0 +1,199 @@ +const std = @import("std"); +const mem = std.mem; +const Compilation = @import("../Compilation.zig"); +const Pragma = @import("../Pragma.zig"); +const Diagnostics = @import("../Diagnostics.zig"); +const Preprocessor = @import("../Preprocessor.zig"); +const Parser = @import("../Parser.zig"); +const TokenIndex = @import("../Tree.zig").TokenIndex; + +const GCC = @This(); + +pragma: Pragma = .{ + .beforeParse = beforeParse, + .beforePreprocess = beforePreprocess, + .afterParse = afterParse, + .deinit = deinit, + .preprocessorHandler = preprocessorHandler, + .parserHandler = parserHandler, + .preserveTokens = preserveTokens, +}, +original_options: Diagnostics.Options = .{}, +options_stack: std.ArrayListUnmanaged(Diagnostics.Options) = .empty, + +const Directive = enum { + warning, + @"error", + diagnostic, + poison, + const Diagnostics = enum { + ignored, + warning, + @"error", + fatal, + push, + pop, + }; +}; + +fn beforePreprocess(pragma: *Pragma, comp: *Compilation) void { + var self: *GCC = @fieldParentPtr("pragma", pragma); + self.original_options = comp.diagnostics.options; +} + +fn beforeParse(pragma: *Pragma, comp: *Compilation) void { + var self: *GCC = @fieldParentPtr("pragma", pragma); + comp.diagnostics.options = self.original_options; + self.options_stack.items.len = 0; +} + +fn afterParse(pragma: *Pragma, comp: *Compilation) void { + var self: *GCC = @fieldParentPtr("pragma", pragma); + comp.diagnostics.options = self.original_options; + self.options_stack.items.len = 0; +} + +pub fn init(allocator: mem.Allocator) !*Pragma { + var gcc = try allocator.create(GCC); + gcc.* = .{}; + return &gcc.pragma; +} + +fn deinit(pragma: *Pragma, comp: *Compilation) void { + var self: *GCC = @fieldParentPtr("pragma", pragma); + self.options_stack.deinit(comp.gpa); + comp.gpa.destroy(self); +} + +fn diagnosticHandler(self: *GCC, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void { + const diagnostic_tok = pp.tokens.get(start_idx); + if (diagnostic_tok.id == .nl) return; + + const diagnostic = std.meta.stringToEnum(Directive.Diagnostics, pp.expandedSlice(diagnostic_tok)) orelse + return error.UnknownPragma; + + switch (diagnostic) { + .ignored, .warning, .@"error", .fatal => { + const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) { + error.ExpectedStringLiteral => { + return pp.comp.addDiagnostic(.{ + .tag = .pragma_requires_string_literal, + .loc = diagnostic_tok.loc, + .extra = .{ .str = "GCC diagnostic" }, + }, pp.expansionSlice(start_idx)); + }, + else => |e| return e, + }; + if (!mem.startsWith(u8, str, "-W")) { + const next = pp.tokens.get(start_idx + 1); + return pp.comp.addDiagnostic(.{ + .tag = .malformed_warning_check, + .loc = next.loc, + .extra = .{ .str = "GCC diagnostic" }, + }, pp.expansionSlice(start_idx + 1)); + } + const new_kind: Diagnostics.Kind = switch (diagnostic) { + .ignored => .off, + .warning => .warning, + .@"error" => .@"error", + .fatal => .@"fatal error", + else => unreachable, + }; + + try pp.comp.diagnostics.set(str[2..], new_kind); + }, + .push => try self.options_stack.append(pp.comp.gpa, pp.comp.diagnostics.options), + .pop => pp.comp.diagnostics.options = self.options_stack.pop() orelse self.original_options, + } +} + +fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void { + var self: *GCC = @fieldParentPtr("pragma", pragma); + const directive_tok = pp.tokens.get(start_idx + 1); + if (directive_tok.id == .nl) return; + + const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse + return pp.comp.addDiagnostic(.{ + .tag = .unknown_gcc_pragma, + .loc = directive_tok.loc, + }, pp.expansionSlice(start_idx + 1)); + + switch (gcc_pragma) { + .warning, .@"error" => { + const text = Pragma.pasteTokens(pp, start_idx + 2) catch |err| switch (err) { + error.ExpectedStringLiteral => { + return pp.comp.addDiagnostic(.{ + .tag = .pragma_requires_string_literal, + .loc = directive_tok.loc, + .extra = .{ .str = @tagName(gcc_pragma) }, + }, pp.expansionSlice(start_idx + 1)); + }, + else => |e| return e, + }; + const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diagnostics.arena.allocator().dupe(u8, text) }; + const diagnostic_tag: Diagnostics.Tag = if (gcc_pragma == .warning) .pragma_warning_message else .pragma_error_message; + return pp.comp.addDiagnostic( + .{ .tag = diagnostic_tag, .loc = directive_tok.loc, .extra = extra }, + pp.expansionSlice(start_idx + 1), + ); + }, + .diagnostic => return self.diagnosticHandler(pp, start_idx + 2) catch |err| switch (err) { + error.UnknownPragma => { + const tok = pp.tokens.get(start_idx + 2); + return pp.comp.addDiagnostic(.{ + .tag = .unknown_gcc_pragma_directive, + .loc = tok.loc, + }, pp.expansionSlice(start_idx + 2)); + }, + else => |e| return e, + }, + .poison => { + var i: u32 = 2; + while (true) : (i += 1) { + const tok = pp.tokens.get(start_idx + i); + if (tok.id == .nl) break; + + if (!tok.id.isMacroIdentifier()) { + return pp.comp.addDiagnostic(.{ + .tag = .pragma_poison_identifier, + .loc = tok.loc, + }, pp.expansionSlice(start_idx + i)); + } + const str = pp.expandedSlice(tok); + if (pp.defines.get(str) != null) { + try pp.comp.addDiagnostic(.{ + .tag = .pragma_poison_macro, + .loc = tok.loc, + }, pp.expansionSlice(start_idx + i)); + } + try pp.poisoned_identifiers.put(str, {}); + } + return; + }, + } +} + +fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void { + var self: *GCC = @fieldParentPtr("pragma", pragma); + const directive_tok = p.pp.tokens.get(start_idx + 1); + if (directive_tok.id == .nl) return; + const name = p.pp.expandedSlice(directive_tok); + if (mem.eql(u8, name, "diagnostic")) { + return self.diagnosticHandler(p.pp, start_idx + 2) catch |err| switch (err) { + error.UnknownPragma => {}, // handled during preprocessing + error.StopPreprocessing => unreachable, // Only used by #pragma once + else => |e| return e, + }; + } +} + +fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool { + const next = pp.tokens.get(start_idx + 1); + if (next.id != .nl) { + const name = pp.expandedSlice(next); + if (mem.eql(u8, name, "poison")) { + return false; + } + } + return true; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/message.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/message.zig new file mode 100644 index 00000000..a364c6d8 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/message.zig @@ -0,0 +1,50 @@ +const std = @import("std"); +const mem = std.mem; +const Compilation = @import("../Compilation.zig"); +const Pragma = @import("../Pragma.zig"); +const Diagnostics = @import("../Diagnostics.zig"); +const Preprocessor = @import("../Preprocessor.zig"); +const Parser = @import("../Parser.zig"); +const TokenIndex = @import("../Tree.zig").TokenIndex; +const Source = @import("../Source.zig"); + +const Message = @This(); + +pragma: Pragma = .{ + .deinit = deinit, + .preprocessorHandler = preprocessorHandler, +}, + +pub fn init(allocator: mem.Allocator) !*Pragma { + var once = try allocator.create(Message); + once.* = .{}; + return &once.pragma; +} + +fn deinit(pragma: *Pragma, comp: *Compilation) void { + const self: *Message = @fieldParentPtr("pragma", pragma); + comp.gpa.destroy(self); +} + +fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void { + const message_tok = pp.tokens.get(start_idx); + const message_expansion_locs = pp.expansionSlice(start_idx); + + const str = Pragma.pasteTokens(pp, start_idx + 1) catch |err| switch (err) { + error.ExpectedStringLiteral => { + return pp.comp.addDiagnostic(.{ + .tag = .pragma_requires_string_literal, + .loc = message_tok.loc, + .extra = .{ .str = "message" }, + }, message_expansion_locs); + }, + else => |e| return e, + }; + + const loc = if (message_expansion_locs.len != 0) + message_expansion_locs[message_expansion_locs.len - 1] + else + message_tok.loc; + const extra = Diagnostics.Message.Extra{ .str = try pp.comp.diagnostics.arena.allocator().dupe(u8, str) }; + return pp.comp.addDiagnostic(.{ .tag = .pragma_message, .loc = loc, .extra = extra }, &.{}); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/once.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/once.zig new file mode 100644 index 00000000..21d6c985 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/once.zig @@ -0,0 +1,56 @@ +const std = @import("std"); +const mem = std.mem; +const Compilation = @import("../Compilation.zig"); +const Pragma = @import("../Pragma.zig"); +const Diagnostics = @import("../Diagnostics.zig"); +const Preprocessor = @import("../Preprocessor.zig"); +const Parser = @import("../Parser.zig"); +const TokenIndex = @import("../Tree.zig").TokenIndex; +const Source = @import("../Source.zig"); + +const Once = @This(); + +pragma: Pragma = .{ + .afterParse = afterParse, + .deinit = deinit, + .preprocessorHandler = preprocessorHandler, +}, +pragma_once: std.AutoHashMap(Source.Id, void), +preprocess_count: u32 = 0, + +pub fn init(allocator: mem.Allocator) !*Pragma { + var once = try allocator.create(Once); + once.* = .{ + .pragma_once = std.AutoHashMap(Source.Id, void).init(allocator), + }; + return &once.pragma; +} + +fn afterParse(pragma: *Pragma, _: *Compilation) void { + var self: *Once = @fieldParentPtr("pragma", pragma); + self.pragma_once.clearRetainingCapacity(); +} + +fn deinit(pragma: *Pragma, comp: *Compilation) void { + var self: *Once = @fieldParentPtr("pragma", pragma); + self.pragma_once.deinit(); + comp.gpa.destroy(self); +} + +fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void { + var self: *Once = @fieldParentPtr("pragma", pragma); + const name_tok = pp.tokens.get(start_idx); + const next = pp.tokens.get(start_idx + 1); + if (next.id != .nl) { + try pp.comp.addDiagnostic(.{ + .tag = .extra_tokens_directive_end, + .loc = name_tok.loc, + }, pp.expansionSlice(start_idx + 1)); + } + const seen = self.preprocess_count == pp.preprocess_count; + const prev = try self.pragma_once.fetchPut(name_tok.loc.id, {}); + if (prev != null and !seen) { + return error.StopPreprocessing; + } + self.preprocess_count = pp.preprocess_count; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/pack.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/pack.zig new file mode 100644 index 00000000..baa44509 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/pragmas/pack.zig @@ -0,0 +1,164 @@ +const std = @import("std"); +const mem = std.mem; +const Compilation = @import("../Compilation.zig"); +const Pragma = @import("../Pragma.zig"); +const Diagnostics = @import("../Diagnostics.zig"); +const Preprocessor = @import("../Preprocessor.zig"); +const Parser = @import("../Parser.zig"); +const Tree = @import("../Tree.zig"); +const TokenIndex = Tree.TokenIndex; + +const Pack = @This(); + +pragma: Pragma = .{ + .deinit = deinit, + .parserHandler = parserHandler, + .preserveTokens = preserveTokens, +}, +stack: std.ArrayListUnmanaged(struct { label: []const u8, val: u8 }) = .empty, + +pub fn init(allocator: mem.Allocator) !*Pragma { + var pack = try allocator.create(Pack); + pack.* = .{}; + return &pack.pragma; +} + +fn deinit(pragma: *Pragma, comp: *Compilation) void { + var self: *Pack = @fieldParentPtr("pragma", pragma); + self.stack.deinit(comp.gpa); + comp.gpa.destroy(self); +} + +fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation.Error!void { + var pack: *Pack = @fieldParentPtr("pragma", pragma); + var idx = start_idx + 1; + const l_paren = p.pp.tokens.get(idx); + if (l_paren.id != .l_paren) { + return p.comp.addDiagnostic(.{ + .tag = .pragma_pack_lparen, + .loc = l_paren.loc, + }, p.pp.expansionSlice(idx)); + } + idx += 1; + + // TODO -fapple-pragma-pack -fxl-pragma-pack + const apple_or_xl = false; + const tok_ids = p.pp.tokens.items(.id); + const arg = idx; + switch (tok_ids[arg]) { + .identifier => { + idx += 1; + const Action = enum { + show, + push, + pop, + }; + const action = std.meta.stringToEnum(Action, p.tokSlice(arg)) orelse { + return p.errTok(.pragma_pack_unknown_action, arg); + }; + switch (action) { + .show => { + try p.errExtra(.pragma_pack_show, arg, .{ .unsigned = p.pragma_pack orelse 8 }); + }, + .push, .pop => { + var new_val: ?u8 = null; + var label: ?[]const u8 = null; + if (tok_ids[idx] == .comma) { + idx += 1; + const next = idx; + idx += 1; + switch (tok_ids[next]) { + .pp_num => new_val = (try packInt(p, next)) orelse return, + .identifier => { + label = p.tokSlice(next); + if (tok_ids[idx] == .comma) { + idx += 1; + const int = idx; + idx += 1; + if (tok_ids[int] != .pp_num) return p.errTok(.pragma_pack_int_ident, int); + new_val = (try packInt(p, int)) orelse return; + } + }, + else => return p.errTok(.pragma_pack_int_ident, next), + } + } + if (action == .push) { + try pack.stack.append(p.gpa, .{ .label = label orelse "", .val = p.pragma_pack orelse 8 }); + } else { + pack.pop(p, label); + if (new_val != null) { + try p.errTok(.pragma_pack_undefined_pop, arg); + } else if (pack.stack.items.len == 0) { + try p.errTok(.pragma_pack_empty_stack, arg); + } + } + if (new_val) |some| { + p.pragma_pack = some; + } + }, + } + }, + .r_paren => if (apple_or_xl) { + pack.pop(p, null); + } else { + p.pragma_pack = null; + }, + .pp_num => { + const new_val = (try packInt(p, arg)) orelse return; + idx += 1; + if (apple_or_xl) { + try pack.stack.append(p.gpa, .{ .label = "", .val = p.pragma_pack }); + } + p.pragma_pack = new_val; + }, + else => {}, + } + + if (tok_ids[idx] != .r_paren) { + return p.errTok(.pragma_pack_rparen, idx); + } +} + +fn packInt(p: *Parser, tok_i: TokenIndex) Compilation.Error!?u8 { + const res = p.parseNumberToken(tok_i) catch |err| switch (err) { + error.ParsingFailed => { + try p.errTok(.pragma_pack_int, tok_i); + return null; + }, + else => |e| return e, + }; + const int = res.val.toInt(u64, p.comp) orelse 99; + switch (int) { + 1, 2, 4, 8, 16 => return @intCast(int), + else => { + try p.errTok(.pragma_pack_int, tok_i); + return null; + }, + } +} + +fn pop(pack: *Pack, p: *Parser, maybe_label: ?[]const u8) void { + if (maybe_label) |label| { + var i = pack.stack.items.len; + while (i > 0) { + i -= 1; + if (std.mem.eql(u8, pack.stack.items[i].label, label)) { + const prev = pack.stack.orderedRemove(i); + p.pragma_pack = prev.val; + return; + } + } + } else { + const prev = pack.stack.pop() orelse { + p.pragma_pack = 2; + return; + }; + p.pragma_pack = prev.val; + } +} + +fn preserveTokens(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) bool { + _ = pp; + _ = start_idx; + return true; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/record_layout.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/record_layout.zig new file mode 100644 index 00000000..da0517d9 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/record_layout.zig @@ -0,0 +1,669 @@ +//! Record layout code adapted from https://github.com/mahkoh/repr-c +//! Licensed under MIT license: https://github.com/mahkoh/repr-c/tree/master/repc/facade + +const std = @import("std"); +const Type = @import("Type.zig"); +const Attribute = @import("Attribute.zig"); +const Compilation = @import("Compilation.zig"); +const Parser = @import("Parser.zig"); +const Record = Type.Record; +const Field = Record.Field; +const TypeLayout = Type.TypeLayout; +const FieldLayout = Type.FieldLayout; +const target_util = @import("target.zig"); + +const BITS_PER_BYTE = 8; + +const OngoingBitfield = struct { + size_bits: u64, + unused_size_bits: u64, +}; + +pub const Error = error{Overflow}; + +fn alignForward(addr: u64, alignment: u64) !u64 { + const forward_addr = try std.math.add(u64, addr, alignment - 1); + return std.mem.alignBackward(u64, forward_addr, alignment); +} + +const SysVContext = struct { + /// Does the record have an __attribute__((packed)) annotation. + attr_packed: bool, + /// The value of #pragma pack(N) at the type level if any. + max_field_align_bits: ?u64, + /// The alignment of this record. + aligned_bits: u32, + is_union: bool, + /// The size of the record. This might not be a multiple of 8 if the record contains bit-fields. + /// For structs, this is also the offset of the first bit after the last field. + size_bits: u64, + /// non-null if the previous field was a non-zero-sized bit-field. Only used by MinGW. + ongoing_bitfield: ?OngoingBitfield, + + comp: *const Compilation, + + fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) SysVContext { + const pack_value: ?u64 = if (pragma_pack) |pak| @as(u64, pak) * BITS_PER_BYTE else null; + const req_align = @as(u32, (ty.requestedAlignment(comp) orelse 1)) * BITS_PER_BYTE; + return SysVContext{ + .attr_packed = ty.hasAttribute(.@"packed"), + .max_field_align_bits = pack_value, + .aligned_bits = req_align, + .is_union = ty.is(.@"union"), + .size_bits = 0, + .comp = comp, + .ongoing_bitfield = null, + }; + } + + fn layoutFields(self: *SysVContext, rec: *const Record) !void { + for (rec.fields, 0..) |*fld, fld_indx| { + if (fld.ty.specifier == .invalid) continue; + const type_layout = computeLayout(fld.ty, self.comp); + + var field_attrs: ?[]const Attribute = null; + if (rec.field_attributes) |attrs| { + field_attrs = attrs[fld_indx]; + } + if (self.comp.target.isMinGW()) { + fld.layout = try self.layoutMinGWField(fld, field_attrs, type_layout); + } else { + if (fld.isRegularField()) { + fld.layout = try self.layoutRegularField(field_attrs, type_layout); + } else { + fld.layout = try self.layoutBitField(field_attrs, type_layout, fld.isNamed(), fld.specifiedBitWidth()); + } + } + } + } + + /// On MinGW the alignment of the field is calculated in the usual way except that the alignment of + /// the underlying type is ignored in three cases + /// - the field is packed + /// - the field is a bit-field and the previous field was a non-zero-sized bit-field with the same type size + /// - the field is a zero-sized bit-field and the previous field was not a non-zero-sized bit-field + /// See test case 0068. + fn ignoreTypeAlignment(is_attr_packed: bool, bit_width: ?u32, ongoing_bitfield: ?OngoingBitfield, fld_layout: TypeLayout) bool { + if (is_attr_packed) return true; + if (bit_width) |width| { + if (ongoing_bitfield) |ongoing| { + if (ongoing.size_bits == fld_layout.size_bits) return true; + } else { + if (width == 0) return true; + } + } + return false; + } + + fn layoutMinGWField( + self: *SysVContext, + field: *const Field, + field_attrs: ?[]const Attribute, + field_layout: TypeLayout, + ) !FieldLayout { + const annotation_alignment_bits = BITS_PER_BYTE * @as(u32, (Type.annotationAlignment(self.comp, Attribute.Iterator.initSlice(field_attrs)) orelse 1)); + const is_attr_packed = self.attr_packed or isPacked(field_attrs); + const ignore_type_alignment = ignoreTypeAlignment(is_attr_packed, field.bit_width, self.ongoing_bitfield, field_layout); + + var field_alignment_bits: u64 = field_layout.field_alignment_bits; + if (ignore_type_alignment) { + field_alignment_bits = BITS_PER_BYTE; + } + field_alignment_bits = @max(field_alignment_bits, annotation_alignment_bits); + if (self.max_field_align_bits) |bits| { + field_alignment_bits = @min(field_alignment_bits, bits); + } + + // The field affects the record alignment in one of three cases + // - the field is a regular field + // - the field is a zero-width bit-field following a non-zero-width bit-field + // - the field is a non-zero-width bit-field and not packed. + // See test case 0069. + const update_record_alignment = + field.isRegularField() or + (field.specifiedBitWidth() == 0 and self.ongoing_bitfield != null) or + (field.specifiedBitWidth() != 0 and !is_attr_packed); + + // If a field affects the alignment of a record, the alignment is calculated in the + // usual way except that __attribute__((packed)) is ignored on a zero-width bit-field. + // See test case 0068. + if (update_record_alignment) { + var ty_alignment_bits = field_layout.field_alignment_bits; + if (is_attr_packed and (field.isRegularField() or field.specifiedBitWidth() != 0)) { + ty_alignment_bits = BITS_PER_BYTE; + } + ty_alignment_bits = @max(ty_alignment_bits, annotation_alignment_bits); + if (self.max_field_align_bits) |bits| { + ty_alignment_bits = @intCast(@min(ty_alignment_bits, bits)); + } + self.aligned_bits = @max(self.aligned_bits, ty_alignment_bits); + } + + // NOTE: ty_alignment_bits and field_alignment_bits are different in the following case: + // Y = { size: 64, alignment: 64 }struct { + // { offset: 0, size: 1 }c { size: 8, alignment: 8 }char:1, + // @attr_packed _ { size: 64, alignment: 64 }long long:0, + // { offset: 8, size: 8 }d { size: 8, alignment: 8 }char, + // } + if (field.isRegularField()) { + return self.layoutRegularFieldMinGW(field_layout.size_bits, field_alignment_bits); + } else { + return self.layoutBitFieldMinGW(field_layout.size_bits, field_alignment_bits, field.isNamed(), field.specifiedBitWidth()); + } + } + + fn layoutBitFieldMinGW( + self: *SysVContext, + ty_size_bits: u64, + field_alignment_bits: u64, + is_named: bool, + width: u64, + ) !FieldLayout { + std.debug.assert(width <= ty_size_bits); // validated in parser + + // In a union, the size of the underlying type does not affect the size of the union. + // See test case 0070. + if (self.is_union) { + self.size_bits = @max(self.size_bits, width); + if (!is_named) return .{}; + return .{ + .offset_bits = 0, + .size_bits = width, + }; + } + if (width == 0) { + self.ongoing_bitfield = null; + } else { + // If there is an ongoing bit-field in a struct whose underlying type has the same size and + // if there is enough space left to place this bit-field, then this bit-field is placed in + // the ongoing bit-field and the size of the struct is not affected by this + // bit-field. See test case 0037. + if (self.ongoing_bitfield) |*ongoing| { + if (ongoing.size_bits == ty_size_bits and ongoing.unused_size_bits >= width) { + const offset_bits = self.size_bits - ongoing.unused_size_bits; + ongoing.unused_size_bits -= width; + if (!is_named) return .{}; + return .{ + .offset_bits = offset_bits, + .size_bits = width, + }; + } + } + // Otherwise this field is part of a new ongoing bit-field. + self.ongoing_bitfield = .{ + .size_bits = ty_size_bits, + .unused_size_bits = ty_size_bits - width, + }; + } + const offset_bits = try alignForward(self.size_bits, field_alignment_bits); + self.size_bits = if (width == 0) offset_bits else try std.math.add(u64, offset_bits, ty_size_bits); + if (!is_named) return .{}; + return .{ + .offset_bits = offset_bits, + .size_bits = width, + }; + } + + fn layoutRegularFieldMinGW( + self: *SysVContext, + ty_size_bits: u64, + field_alignment_bits: u64, + ) !FieldLayout { + self.ongoing_bitfield = null; + // A struct field starts at the next offset in the struct that is properly + // aligned with respect to the start of the struct. See test case 0033. + // A union field always starts at offset 0. + const offset_bits = if (self.is_union) 0 else try alignForward(self.size_bits, field_alignment_bits); + + // Set the size of the record to the maximum of the current size and the end of + // the field. See test case 0034. + self.size_bits = @max(self.size_bits, try std.math.add(u64, offset_bits, ty_size_bits)); + + return .{ + .offset_bits = offset_bits, + .size_bits = ty_size_bits, + }; + } + + fn layoutRegularField( + self: *SysVContext, + fld_attrs: ?[]const Attribute, + fld_layout: TypeLayout, + ) !FieldLayout { + var fld_align_bits = fld_layout.field_alignment_bits; + + // If the struct or the field is packed, then the alignment of the underlying type is + // ignored. See test case 0084. + if (self.attr_packed or isPacked(fld_attrs)) { + fld_align_bits = BITS_PER_BYTE; + } + + // The field alignment can be increased by __attribute__((aligned)) annotations on the + // field. See test case 0085. + if (Type.annotationAlignment(self.comp, Attribute.Iterator.initSlice(fld_attrs))) |anno| { + fld_align_bits = @max(fld_align_bits, @as(u32, anno) * BITS_PER_BYTE); + } + + // #pragma pack takes precedence over all other attributes. See test cases 0084 and + // 0085. + if (self.max_field_align_bits) |req_bits| { + fld_align_bits = @intCast(@min(fld_align_bits, req_bits)); + } + + // A struct field starts at the next offset in the struct that is properly + // aligned with respect to the start of the struct. + const offset_bits = if (self.is_union) 0 else try alignForward(self.size_bits, fld_align_bits); + const size_bits = fld_layout.size_bits; + + // The alignment of a record is the maximum of its field alignments. See test cases + // 0084, 0085, 0086. + self.size_bits = @max(self.size_bits, try std.math.add(u64, offset_bits, size_bits)); + self.aligned_bits = @max(self.aligned_bits, fld_align_bits); + + return .{ + .offset_bits = offset_bits, + .size_bits = size_bits, + }; + } + + fn layoutBitField( + self: *SysVContext, + fld_attrs: ?[]const Attribute, + fld_layout: TypeLayout, + is_named: bool, + bit_width: u64, + ) !FieldLayout { + const ty_size_bits = fld_layout.size_bits; + var ty_fld_algn_bits: u32 = fld_layout.field_alignment_bits; + + if (bit_width > 0) { + std.debug.assert(bit_width <= ty_size_bits); // Checked in parser + // Some targets ignore the alignment of the underlying type when laying out + // non-zero-sized bit-fields. See test case 0072. On such targets, bit-fields never + // cross a storage boundary. See test case 0081. + if (target_util.ignoreNonZeroSizedBitfieldTypeAlignment(self.comp.target)) { + ty_fld_algn_bits = 1; + } + } else { + // Some targets ignore the alignment of the underlying type when laying out + // zero-sized bit-fields. See test case 0073. + if (target_util.ignoreZeroSizedBitfieldTypeAlignment(self.comp.target)) { + ty_fld_algn_bits = 1; + } + // Some targets have a minimum alignment of zero-sized bit-fields. See test case + // 0074. + if (target_util.minZeroWidthBitfieldAlignment(self.comp.target)) |target_align| { + ty_fld_algn_bits = @max(ty_fld_algn_bits, target_align); + } + } + + // __attribute__((packed)) on the record is identical to __attribute__((packed)) on each + // field. See test case 0067. + const attr_packed = self.attr_packed or isPacked(fld_attrs); + const has_packing_annotation = attr_packed or self.max_field_align_bits != null; + + const annotation_alignment = if (Type.annotationAlignment(self.comp, Attribute.Iterator.initSlice(fld_attrs))) |anno| @as(u32, anno) * BITS_PER_BYTE else 1; + + const first_unused_bit: u64 = if (self.is_union) 0 else self.size_bits; + var field_align_bits: u64 = 1; + + if (bit_width == 0) { + field_align_bits = @max(ty_fld_algn_bits, annotation_alignment); + } else if (self.comp.langopts.emulate == .gcc) { + // On GCC, the field alignment is at least the alignment requested by annotations + // except as restricted by #pragma pack. See test case 0083. + field_align_bits = annotation_alignment; + if (self.max_field_align_bits) |max_bits| { + field_align_bits = @min(annotation_alignment, max_bits); + } + + // On GCC, if there are no packing annotations and + // - the field would otherwise start at an offset such that it would cross a + // storage boundary or + // - the alignment of the type is larger than its size, + // then it is aligned to the type's field alignment. See test case 0083. + if (!has_packing_annotation) { + const start_bit = try alignForward(first_unused_bit, field_align_bits); + + const does_field_cross_boundary = start_bit % ty_fld_algn_bits + bit_width > ty_size_bits; + + if (ty_fld_algn_bits > ty_size_bits or does_field_cross_boundary) { + field_align_bits = @max(field_align_bits, ty_fld_algn_bits); + } + } + } else { + std.debug.assert(self.comp.langopts.emulate == .clang); + + // On Clang, the alignment requested by annotations is not respected if it is + // larger than the value of #pragma pack. See test case 0083. + if (annotation_alignment <= self.max_field_align_bits orelse std.math.maxInt(u29)) { + field_align_bits = @max(field_align_bits, annotation_alignment); + } + // On Clang, if there are no packing annotations and the field would cross a + // storage boundary if it were positioned at the first unused bit in the record, + // it is aligned to the type's field alignment. See test case 0083. + if (!has_packing_annotation) { + const does_field_cross_boundary = first_unused_bit % ty_fld_algn_bits + bit_width > ty_size_bits; + + if (does_field_cross_boundary) + field_align_bits = @max(field_align_bits, ty_fld_algn_bits); + } + } + + const offset_bits = try alignForward(first_unused_bit, field_align_bits); + self.size_bits = @max(self.size_bits, try std.math.add(u64, offset_bits, bit_width)); + + // Unnamed fields do not contribute to the record alignment except on a few targets. + // See test case 0079. + if (is_named or target_util.unnamedFieldAffectsAlignment(self.comp.target)) { + var inherited_align_bits: u32 = undefined; + + if (bit_width == 0) { + // If the width is 0, #pragma pack and __attribute__((packed)) are ignored. + // See test case 0075. + inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment); + } else if (self.max_field_align_bits) |max_align_bits| { + // Otherwise, if a #pragma pack is in effect, __attribute__((packed)) on the field or + // record is ignored. See test case 0076. + inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment); + inherited_align_bits = @intCast(@min(inherited_align_bits, max_align_bits)); + } else if (attr_packed) { + // Otherwise, if the field or the record is packed, the field alignment is 1 bit unless + // it is explicitly increased with __attribute__((aligned)). See test case 0077. + inherited_align_bits = annotation_alignment; + } else { + // Otherwise, the field alignment is the field alignment of the underlying type unless + // it is explicitly increased with __attribute__((aligned)). See test case 0078. + inherited_align_bits = @max(ty_fld_algn_bits, annotation_alignment); + } + self.aligned_bits = @max(self.aligned_bits, inherited_align_bits); + } + + if (!is_named) return .{}; + return .{ + .size_bits = bit_width, + .offset_bits = offset_bits, + }; + } +}; + +const MsvcContext = struct { + req_align_bits: u32, + max_field_align_bits: ?u32, + /// The alignment of pointers that point to an object of this type. This is greater than or equal + /// to the required alignment. Once all fields have been laid out, the size of the record will be + /// rounded up to this value. + pointer_align_bits: u32, + /// The alignment of this type when it is used as a record field. This is greater than or equal to + /// the pointer alignment. + field_align_bits: u32, + size_bits: u64, + ongoing_bitfield: ?OngoingBitfield, + contains_non_bitfield: bool, + is_union: bool, + comp: *const Compilation, + + fn init(ty: Type, comp: *const Compilation, pragma_pack: ?u8) MsvcContext { + var pack_value: ?u32 = null; + if (ty.hasAttribute(.@"packed")) { + // __attribute__((packed)) behaves like #pragma pack(1) in clang. See test case 0056. + pack_value = BITS_PER_BYTE; + } + if (pack_value == null) { + if (pragma_pack) |pack| { + pack_value = pack * BITS_PER_BYTE; + } + } + if (pack_value) |pack| { + pack_value = msvcPragmaPack(comp, pack); + } + + // The required alignment can be increased by adding a __declspec(align) + // annotation. See test case 0023. + const must_align = @as(u32, (ty.requestedAlignment(comp) orelse 1)) * BITS_PER_BYTE; + return MsvcContext{ + .req_align_bits = must_align, + .pointer_align_bits = must_align, + .field_align_bits = must_align, + .size_bits = 0, + .max_field_align_bits = pack_value, + .ongoing_bitfield = null, + .contains_non_bitfield = false, + .is_union = ty.is(.@"union"), + .comp = comp, + }; + } + + fn layoutField(self: *MsvcContext, fld: *const Field, fld_attrs: ?[]const Attribute) !FieldLayout { + const type_layout = computeLayout(fld.ty, self.comp); + + // The required alignment of the field is the maximum of the required alignment of the + // underlying type and the __declspec(align) annotation on the field itself. + // See test case 0028. + var req_align = type_layout.required_alignment_bits; + if (Type.annotationAlignment(self.comp, Attribute.Iterator.initSlice(fld_attrs))) |anno| { + req_align = @max(@as(u32, anno) * BITS_PER_BYTE, req_align); + } + + // The required alignment of a record is the maximum of the required alignments of its + // fields except that the required alignment of bitfields is ignored. + // See test case 0029. + if (fld.isRegularField()) { + self.req_align_bits = @max(self.req_align_bits, req_align); + } + + // The offset of the field is based on the field alignment of the underlying type. + // See test case 0027. + var fld_align_bits = type_layout.field_alignment_bits; + if (self.max_field_align_bits) |max_align| { + fld_align_bits = @min(fld_align_bits, max_align); + } + // check the requested alignment of the field type. + if (fld.ty.requestedAlignment(self.comp)) |type_req_align| { + fld_align_bits = @max(fld_align_bits, type_req_align * 8); + } + + if (isPacked(fld_attrs)) { + // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma + // pack(1) had been applied only to this field. See test case 0057. + fld_align_bits = BITS_PER_BYTE; + } + // __attribute__((packed)) on a field is a clang extension. It behaves as if #pragma + // pack(1) had been applied only to this field. See test case 0057. + fld_align_bits = @max(fld_align_bits, req_align); + if (fld.isRegularField()) { + return self.layoutRegularField(type_layout.size_bits, fld_align_bits); + } else { + return self.layoutBitField(type_layout.size_bits, fld_align_bits, fld.specifiedBitWidth()); + } + } + + fn layoutBitField(self: *MsvcContext, ty_size_bits: u64, field_align: u32, bit_width: u32) !FieldLayout { + if (bit_width == 0) { + // A zero-sized bit-field that does not follow a non-zero-sized bit-field does not affect + // the overall layout of the record. Even in a union where the order would otherwise + // not matter. See test case 0035. + if (self.ongoing_bitfield) |_| { + self.ongoing_bitfield = null; + } else { + // this field takes 0 space. + return .{ .offset_bits = self.size_bits, .size_bits = bit_width }; + } + } else { + std.debug.assert(bit_width <= ty_size_bits); + // If there is an ongoing bit-field in a struct whose underlying type has the same size and + // if there is enough space left to place this bit-field, then this bit-field is placed in + // the ongoing bit-field and the overall layout of the struct is not affected by this + // bit-field. See test case 0037. + if (!self.is_union) { + if (self.ongoing_bitfield) |*p| { + if (p.size_bits == ty_size_bits and p.unused_size_bits >= bit_width) { + const offset_bits = self.size_bits - p.unused_size_bits; + p.unused_size_bits -= bit_width; + return .{ .offset_bits = offset_bits, .size_bits = bit_width }; + } + } + } + // Otherwise this field is part of a new ongoing bit-field. + self.ongoing_bitfield = .{ .size_bits = ty_size_bits, .unused_size_bits = ty_size_bits - bit_width }; + } + const offset_bits = if (!self.is_union) bits: { + // This is the one place in the layout of a record where the pointer alignment might + // get assigned a smaller value than the field alignment. This can only happen if + // the field or the type of the field has a required alignment. Otherwise the value + // of field_alignment_bits is already bound by max_field_alignment_bits. + // See test case 0038. + const p_align = if (self.max_field_align_bits) |max_fld_align| + @min(max_fld_align, field_align) + else + field_align; + self.pointer_align_bits = @max(self.pointer_align_bits, p_align); + self.field_align_bits = @max(self.field_align_bits, field_align); + + const offset_bits = try alignForward(self.size_bits, field_align); + self.size_bits = if (bit_width == 0) offset_bits else offset_bits + ty_size_bits; + + break :bits offset_bits; + } else bits: { + // Bit-fields do not affect the alignment of a union. See test case 0041. + self.size_bits = @max(self.size_bits, ty_size_bits); + break :bits 0; + }; + return .{ .offset_bits = offset_bits, .size_bits = bit_width }; + } + + fn layoutRegularField(self: *MsvcContext, size_bits: u64, field_align: u32) !FieldLayout { + self.contains_non_bitfield = true; + self.ongoing_bitfield = null; + // The alignment of the field affects both the pointer alignment and the field + // alignment of the record. See test case 0032. + self.pointer_align_bits = @max(self.pointer_align_bits, field_align); + self.field_align_bits = @max(self.field_align_bits, field_align); + const offset_bits = switch (self.is_union) { + true => 0, + false => try alignForward(self.size_bits, field_align), + }; + self.size_bits = @max(self.size_bits, offset_bits + size_bits); + return .{ .offset_bits = offset_bits, .size_bits = size_bits }; + } + fn handleZeroSizedRecord(self: *MsvcContext) void { + if (self.is_union) { + // MSVC does not allow unions without fields. + // If all fields in a union have size 0, the size of the union is set to + // - its field alignment if it contains at least one non-bitfield + // - 4 bytes if it contains only bitfields + // See test case 0025. + if (self.contains_non_bitfield) { + self.size_bits = self.field_align_bits; + } else { + self.size_bits = 4 * BITS_PER_BYTE; + } + } else { + // If all fields in a struct have size 0, its size is set to its required alignment + // but at least to 4 bytes. See test case 0026. + self.size_bits = @max(self.req_align_bits, 4 * BITS_PER_BYTE); + self.pointer_align_bits = @intCast(@min(self.pointer_align_bits, self.size_bits)); + } + } +}; + +pub fn compute(rec: *Type.Record, ty: Type, comp: *const Compilation, pragma_pack: ?u8) Error!void { + switch (comp.langopts.emulate) { + .gcc, .clang => { + var context = SysVContext.init(ty, comp, pragma_pack); + + try context.layoutFields(rec); + + context.size_bits = try alignForward(context.size_bits, context.aligned_bits); + + rec.type_layout = .{ + .size_bits = context.size_bits, + .field_alignment_bits = context.aligned_bits, + .pointer_alignment_bits = context.aligned_bits, + .required_alignment_bits = BITS_PER_BYTE, + }; + }, + .msvc => { + var context = MsvcContext.init(ty, comp, pragma_pack); + for (rec.fields, 0..) |*fld, fld_indx| { + if (fld.ty.specifier == .invalid) continue; + var field_attrs: ?[]const Attribute = null; + if (rec.field_attributes) |attrs| { + field_attrs = attrs[fld_indx]; + } + + fld.layout = try context.layoutField(fld, field_attrs); + } + if (context.size_bits == 0) { + // As an extension, MSVC allows records that only contain zero-sized bitfields and empty + // arrays. Such records would be zero-sized but this case is handled here separately to + // ensure that there are no zero-sized records. + context.handleZeroSizedRecord(); + } + context.size_bits = try alignForward(context.size_bits, context.pointer_align_bits); + rec.type_layout = .{ + .size_bits = context.size_bits, + .field_alignment_bits = context.field_align_bits, + .pointer_alignment_bits = context.pointer_align_bits, + .required_alignment_bits = context.req_align_bits, + }; + }, + } +} + +fn computeLayout(ty: Type, comp: *const Compilation) TypeLayout { + if (ty.getRecord()) |rec| { + const requested = BITS_PER_BYTE * (ty.requestedAlignment(comp) orelse 0); + return .{ + .size_bits = rec.type_layout.size_bits, + .pointer_alignment_bits = @max(requested, rec.type_layout.pointer_alignment_bits), + .field_alignment_bits = @max(requested, rec.type_layout.field_alignment_bits), + .required_alignment_bits = rec.type_layout.required_alignment_bits, + }; + } else { + const type_align = ty.alignof(comp) * BITS_PER_BYTE; + return .{ + .size_bits = ty.bitSizeof(comp) orelse 0, + .pointer_alignment_bits = type_align, + .field_alignment_bits = type_align, + .required_alignment_bits = BITS_PER_BYTE, + }; + } +} + +fn isPacked(attrs: ?[]const Attribute) bool { + const a = attrs orelse return false; + + for (a) |attribute| { + if (attribute.tag != .@"packed") continue; + return true; + } + return false; +} + +// The effect of #pragma pack(N) depends on the target. +// +// x86: By default, there is no maximum field alignment. N={1,2,4} set the maximum field +// alignment to that value. All other N activate the default. +// x64: By default, there is no maximum field alignment. N={1,2,4,8} set the maximum field +// alignment to that value. All other N activate the default. +// arm: By default, the maximum field alignment is 8. N={1,2,4,8,16} set the maximum field +// alignment to that value. All other N activate the default. +// arm64: By default, the maximum field alignment is 8. N={1,2,4,8} set the maximum field +// alignment to that value. N=16 disables the maximum field alignment. All other N +// activate the default. +// +// See test case 0020. +pub fn msvcPragmaPack(comp: *const Compilation, pack: u32) ?u32 { + return switch (pack) { + 8, 16, 32 => pack, + 64 => if (comp.target.cpu.arch == .x86) null else pack, + 128 => if (comp.target.cpu.arch == .thumb) pack else null, + else => { + return switch (comp.target.cpu.arch) { + .thumb, .aarch64 => 64, + else => null, + }; + }, + }; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/target.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/target.zig new file mode 100644 index 00000000..7495eb5d --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/target.zig @@ -0,0 +1,777 @@ +const std = @import("std"); +const LangOpts = @import("LangOpts.zig"); +const Type = @import("Type.zig"); +const TargetSet = @import("Builtins/Properties.zig").TargetSet; + +/// intmax_t for this target +pub fn intMaxType(target: std.Target) Type { + switch (target.cpu.arch) { + .aarch64, + .aarch64_be, + .sparc64, + => if (target.os.tag != .openbsd) return .{ .specifier = .long }, + + .bpfel, + .bpfeb, + .loongarch64, + .riscv64, + .powerpc64, + .powerpc64le, + .ve, + => return .{ .specifier = .long }, + + .x86_64 => switch (target.os.tag) { + .windows, .openbsd => {}, + else => switch (target.abi) { + .gnux32, .muslx32 => {}, + else => return .{ .specifier = .long }, + }, + }, + + else => {}, + } + return .{ .specifier = .long_long }; +} + +/// intptr_t for this target +pub fn intPtrType(target: std.Target) Type { + if (target.os.tag == .haiku) return .{ .specifier = .long }; + + switch (target.cpu.arch) { + .aarch64, .aarch64_be => switch (target.os.tag) { + .windows => return .{ .specifier = .long_long }, + else => {}, + }, + + .msp430, + .csky, + .loongarch32, + .riscv32, + .xcore, + .hexagon, + .m68k, + .spirv32, + .arc, + .avr, + => return .{ .specifier = .int }, + + .sparc => switch (target.os.tag) { + .netbsd, .openbsd => {}, + else => return .{ .specifier = .int }, + }, + + .powerpc, .powerpcle => switch (target.os.tag) { + .linux, .freebsd, .netbsd => return .{ .specifier = .int }, + else => {}, + }, + + // 32-bit x86 Darwin, OpenBSD, and RTEMS use long (the default); others use int + .x86 => switch (target.os.tag) { + .openbsd, .rtems => {}, + else => if (!target.os.tag.isDarwin()) return .{ .specifier = .int }, + }, + + .x86_64 => switch (target.os.tag) { + .windows => return .{ .specifier = .long_long }, + else => switch (target.abi) { + .gnux32, .muslx32 => return .{ .specifier = .int }, + else => {}, + }, + }, + + else => {}, + } + + return .{ .specifier = .long }; +} + +/// int16_t for this target +pub fn int16Type(target: std.Target) Type { + return switch (target.cpu.arch) { + .avr => .{ .specifier = .int }, + else => .{ .specifier = .short }, + }; +} + +/// sig_atomic_t for this target +pub fn sigAtomicType(target: std.Target) Type { + if (target.cpu.arch.isWasm()) return .{ .specifier = .long }; + return switch (target.cpu.arch) { + .avr => .{ .specifier = .schar }, + .msp430 => .{ .specifier = .long }, + else => .{ .specifier = .int }, + }; +} + +/// int64_t for this target +pub fn int64Type(target: std.Target) Type { + switch (target.cpu.arch) { + .loongarch64, + .ve, + .riscv64, + .powerpc64, + .powerpc64le, + .bpfel, + .bpfeb, + => return .{ .specifier = .long }, + + .sparc64 => return intMaxType(target), + + .x86, .x86_64 => if (!target.os.tag.isDarwin()) return intMaxType(target), + .aarch64, .aarch64_be => if (!target.os.tag.isDarwin() and target.os.tag != .openbsd and target.os.tag != .windows) return .{ .specifier = .long }, + else => {}, + } + return .{ .specifier = .long_long }; +} + +pub fn float80Type(target: std.Target) ?Type { + switch (target.cpu.arch) { + .x86, .x86_64 => return .{ .specifier = .long_double }, + else => {}, + } + return null; +} + +/// This function returns 1 if function alignment is not observable or settable. +pub fn defaultFunctionAlignment(target: std.Target) u8 { + return switch (target.cpu.arch) { + .arm, .armeb => 4, + .aarch64, .aarch64_be => 4, + .sparc, .sparc64 => 4, + .riscv64 => 2, + else => 1, + }; +} + +pub fn isTlsSupported(target: std.Target) bool { + if (target.os.tag.isDarwin()) { + var supported = false; + switch (target.os.tag) { + .macos => supported = !(target.os.isAtLeast(.macos, .{ .major = 10, .minor = 7, .patch = 0 }) orelse false), + else => {}, + } + return supported; + } + return switch (target.cpu.arch) { + .bpfel, .bpfeb, .msp430, .nvptx, .nvptx64, .x86, .arm, .armeb, .thumb, .thumbeb => false, + else => true, + }; +} + +pub fn ignoreNonZeroSizedBitfieldTypeAlignment(target: std.Target) bool { + switch (target.cpu.arch) { + .avr => return true, + .arm => { + if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) { + switch (target.os.tag) { + .ios => return true, + else => return false, + } + } + }, + else => return false, + } + return false; +} + +pub fn ignoreZeroSizedBitfieldTypeAlignment(target: std.Target) bool { + switch (target.cpu.arch) { + .avr => return true, + else => return false, + } +} + +pub fn minZeroWidthBitfieldAlignment(target: std.Target) ?u29 { + switch (target.cpu.arch) { + .avr => return 8, + .arm => { + if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) { + switch (target.os.tag) { + .ios => return 32, + else => return null, + } + } else return null; + }, + else => return null, + } +} + +pub fn unnamedFieldAffectsAlignment(target: std.Target) bool { + switch (target.cpu.arch) { + .aarch64 => { + if (target.os.tag.isDarwin() or target.os.tag == .windows) return false; + return true; + }, + .armeb => { + if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) { + if (std.Target.Abi.default(target.cpu.arch, target.os) == .eabi) return true; + } + }, + .arm => return true, + .avr => return true, + .thumb => { + if (target.os.tag == .windows) return false; + return true; + }, + else => return false, + } + return false; +} + +pub fn packAllEnums(target: std.Target) bool { + return switch (target.cpu.arch) { + .hexagon => true, + else => false, + }; +} + +/// Default alignment (in bytes) for __attribute__((aligned)) when no alignment is specified +pub fn defaultAlignment(target: std.Target) u29 { + switch (target.cpu.arch) { + .avr => return 1, + .arm => if (target.abi.isAndroid() or target.os.tag == .ios) return 16 else return 8, + .sparc => if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) return 16 else return 8, + .mips, .mipsel => switch (target.abi) { + .none, .gnuabi64 => return 16, + else => return 8, + }, + .s390x, .armeb, .thumbeb, .thumb => return 8, + else => return 16, + } +} +pub fn systemCompiler(target: std.Target) LangOpts.Compiler { + // Android is linux but not gcc, so these checks go first + // the rest for documentation as fn returns .clang + if (target.abi.isAndroid() or + target.os.tag.isBSD() or + target.os.tag == .fuchsia or + target.os.tag == .solaris or + target.os.tag == .haiku or + target.cpu.arch == .hexagon) + { + return .clang; + } + if (target.os.tag == .uefi) return .msvc; + // this is before windows to grab WindowsGnu + if (target.abi.isGnu() or + target.os.tag == .linux) + { + return .gcc; + } + if (target.os.tag == .windows) { + return .msvc; + } + if (target.cpu.arch == .avr) return .gcc; + return .clang; +} + +pub fn hasFloat128(target: std.Target) bool { + if (target.cpu.arch.isWasm()) return true; + if (target.os.tag.isDarwin()) return false; + if (target.cpu.arch.isPowerPC()) return std.Target.powerpc.featureSetHas(target.cpu.features, .float128); + return switch (target.os.tag) { + .dragonfly, + .haiku, + .linux, + .openbsd, + .solaris, + => target.cpu.arch.isX86(), + else => false, + }; +} + +pub fn hasInt128(target: std.Target) bool { + if (target.cpu.arch == .wasm32) return true; + if (target.cpu.arch == .x86_64) return true; + return target.ptrBitWidth() >= 64; +} + +pub fn hasHalfPrecisionFloatABI(target: std.Target) bool { + return switch (target.cpu.arch) { + .thumb, .thumbeb, .arm, .aarch64 => true, + else => false, + }; +} + +pub const FPSemantics = enum { + None, + IEEEHalf, + BFloat, + IEEESingle, + IEEEDouble, + IEEEQuad, + /// Minifloat 5-bit exponent 2-bit mantissa + E5M2, + /// Minifloat 4-bit exponent 3-bit mantissa + E4M3, + x87ExtendedDouble, + IBMExtendedDouble, + + /// Only intended for generating float.h macros for the preprocessor + pub fn forType(ty: std.Target.CType, target: std.Target) FPSemantics { + std.debug.assert(ty == .float or ty == .double or ty == .longdouble); + return switch (target.cTypeBitSize(ty)) { + 32 => .IEEESingle, + 64 => .IEEEDouble, + 80 => .x87ExtendedDouble, + 128 => switch (target.cpu.arch) { + .powerpc, .powerpcle, .powerpc64, .powerpc64le => .IBMExtendedDouble, + else => .IEEEQuad, + }, + else => unreachable, + }; + } + + pub fn halfPrecisionType(target: std.Target) ?FPSemantics { + switch (target.cpu.arch) { + .aarch64, + .aarch64_be, + .arm, + .armeb, + .hexagon, + .riscv32, + .riscv64, + .spirv32, + .spirv64, + => return .IEEEHalf, + .x86, .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .sse2)) return .IEEEHalf, + else => {}, + } + return null; + } + + pub fn chooseValue(self: FPSemantics, comptime T: type, values: [6]T) T { + return switch (self) { + .IEEEHalf => values[0], + .IEEESingle => values[1], + .IEEEDouble => values[2], + .x87ExtendedDouble => values[3], + .IBMExtendedDouble => values[4], + .IEEEQuad => values[5], + else => unreachable, + }; + } +}; + +pub fn isLP64(target: std.Target) bool { + return target.cTypeBitSize(.int) == 32 and target.ptrBitWidth() == 64; +} + +pub fn isKnownWindowsMSVCEnvironment(target: std.Target) bool { + return target.os.tag == .windows and target.abi == .msvc; +} + +pub fn isWindowsMSVCEnvironment(target: std.Target) bool { + return target.os.tag == .windows and (target.abi == .msvc or target.abi == .none); +} + +pub fn isCygwinMinGW(target: std.Target) bool { + return target.os.tag == .windows and (target.abi == .gnu or target.abi == .cygnus); +} + +pub fn builtinEnabled(target: std.Target, enabled_for: TargetSet) bool { + var it = enabled_for.iterator(); + while (it.next()) |val| { + switch (val) { + .basic => return true, + .x86_64 => if (target.cpu.arch == .x86_64) return true, + .aarch64 => if (target.cpu.arch == .aarch64) return true, + .arm => if (target.cpu.arch == .arm) return true, + .ppc => switch (target.cpu.arch) { + .powerpc, .powerpc64, .powerpc64le => return true, + else => {}, + }, + else => { + // Todo: handle other target predicates + }, + } + } + return false; +} + +pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod { + if (target.os.tag == .aix) return .double; + switch (target.cpu.arch) { + .x86, .x86_64 => { + if (target.ptrBitWidth() == 32 and target.os.tag == .netbsd) { + if (target.os.version_range.semver.min.order(.{ .major = 6, .minor = 99, .patch = 26 }) != .gt) { + // NETBSD <= 6.99.26 on 32-bit x86 defaults to double + return .double; + } + } + if (std.Target.x86.featureSetHas(target.cpu.features, .sse)) { + return .source; + } + return .extended; + }, + else => {}, + } + return .source; +} + +/// Value of the `-m` flag for `ld` for this target +pub fn ldEmulationOption(target: std.Target, arm_endianness: ?std.builtin.Endian) ?[]const u8 { + return switch (target.cpu.arch) { + .x86 => if (target.os.tag == .elfiamcu) "elf_iamcu" else "elf_i386", + .arm, + .armeb, + .thumb, + .thumbeb, + => switch (arm_endianness orelse target.cpu.arch.endian()) { + .little => "armelf_linux_eabi", + .big => "armelfb_linux_eabi", + }, + .aarch64 => "aarch64linux", + .aarch64_be => "aarch64linuxb", + .m68k => "m68kelf", + .powerpc => if (target.os.tag == .linux) "elf32ppclinux" else "elf32ppc", + .powerpcle => if (target.os.tag == .linux) "elf32lppclinux" else "elf32lppc", + .powerpc64 => "elf64ppc", + .powerpc64le => "elf64lppc", + .riscv32 => "elf32lriscv", + .riscv64 => "elf64lriscv", + .sparc => "elf32_sparc", + .sparc64 => "elf64_sparc", + .loongarch32 => "elf32loongarch", + .loongarch64 => "elf64loongarch", + .mips => "elf32btsmip", + .mipsel => "elf32ltsmip", + .mips64 => switch (target.abi) { + .gnuabin32, .muslabin32 => "elf32btsmipn32", + else => "elf64btsmip", + }, + .mips64el => switch (target.abi) { + .gnuabin32, .muslabin32 => "elf32ltsmipn32", + else => "elf64ltsmip", + }, + .x86_64 => switch (target.abi) { + .gnux32, .muslx32 => "elf32_x86_64", + else => "elf_x86_64", + }, + .ve => "elf64ve", + .csky => "cskyelf_linux", + else => null, + }; +} + +pub fn get32BitArchVariant(target: std.Target) ?std.Target { + var copy = target; + switch (target.cpu.arch) { + .amdgcn, + .avr, + .msp430, + .ve, + .bpfel, + .bpfeb, + .s390x, + => return null, + + .arc, + .arm, + .armeb, + .csky, + .hexagon, + .m68k, + .mips, + .mipsel, + .powerpc, + .powerpcle, + .riscv32, + .sparc, + .thumb, + .thumbeb, + .x86, + .xcore, + .nvptx, + .kalimba, + .lanai, + .wasm32, + .spirv, + .spirv32, + .loongarch32, + .xtensa, + => {}, // Already 32 bit + + .aarch64 => copy.cpu.arch = .arm, + .aarch64_be => copy.cpu.arch = .armeb, + .nvptx64 => copy.cpu.arch = .nvptx, + .wasm64 => copy.cpu.arch = .wasm32, + .spirv64 => copy.cpu.arch = .spirv32, + .loongarch64 => copy.cpu.arch = .loongarch32, + .mips64 => copy.cpu.arch = .mips, + .mips64el => copy.cpu.arch = .mipsel, + .powerpc64 => copy.cpu.arch = .powerpc, + .powerpc64le => copy.cpu.arch = .powerpcle, + .riscv64 => copy.cpu.arch = .riscv32, + .sparc64 => copy.cpu.arch = .sparc, + .x86_64 => copy.cpu.arch = .x86, + } + return copy; +} + +pub fn get64BitArchVariant(target: std.Target) ?std.Target { + var copy = target; + switch (target.cpu.arch) { + .arc, + .avr, + .csky, + .hexagon, + .kalimba, + .lanai, + .m68k, + .msp430, + .xcore, + .xtensa, + => return null, + + .aarch64, + .aarch64_be, + .amdgcn, + .bpfeb, + .bpfel, + .nvptx64, + .wasm64, + .spirv64, + .loongarch64, + .mips64, + .mips64el, + .powerpc64, + .powerpc64le, + .riscv64, + .s390x, + .sparc64, + .ve, + .x86_64, + => {}, // Already 64 bit + + .arm => copy.cpu.arch = .aarch64, + .armeb => copy.cpu.arch = .aarch64_be, + .loongarch32 => copy.cpu.arch = .loongarch64, + .mips => copy.cpu.arch = .mips64, + .mipsel => copy.cpu.arch = .mips64el, + .nvptx => copy.cpu.arch = .nvptx64, + .powerpc => copy.cpu.arch = .powerpc64, + .powerpcle => copy.cpu.arch = .powerpc64le, + .riscv32 => copy.cpu.arch = .riscv64, + .sparc => copy.cpu.arch = .sparc64, + .spirv => copy.cpu.arch = .spirv64, + .spirv32 => copy.cpu.arch = .spirv64, + .thumb => copy.cpu.arch = .aarch64, + .thumbeb => copy.cpu.arch = .aarch64_be, + .wasm32 => copy.cpu.arch = .wasm64, + .x86 => copy.cpu.arch = .x86_64, + } + return copy; +} + +/// Adapted from Zig's src/codegen/llvm.zig +pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 { + // 64 bytes is assumed to be large enough to hold any target triple; increase if necessary + std.debug.assert(buf.len >= 64); + + var stream = std.io.fixedBufferStream(buf); + const writer = stream.writer(); + + const llvm_arch = switch (target.cpu.arch) { + .arm => "arm", + .armeb => "armeb", + .aarch64 => if (target.abi == .ilp32) "aarch64_32" else "aarch64", + .aarch64_be => "aarch64_be", + .arc => "arc", + .avr => "avr", + .bpfel => "bpfel", + .bpfeb => "bpfeb", + .csky => "csky", + .hexagon => "hexagon", + .loongarch32 => "loongarch32", + .loongarch64 => "loongarch64", + .m68k => "m68k", + .mips => "mips", + .mipsel => "mipsel", + .mips64 => "mips64", + .mips64el => "mips64el", + .msp430 => "msp430", + .powerpc => "powerpc", + .powerpcle => "powerpcle", + .powerpc64 => "powerpc64", + .powerpc64le => "powerpc64le", + .amdgcn => "amdgcn", + .riscv32 => "riscv32", + .riscv64 => "riscv64", + .sparc => "sparc", + .sparc64 => "sparc64", + .s390x => "s390x", + .thumb => "thumb", + .thumbeb => "thumbeb", + .x86 => "i386", + .x86_64 => "x86_64", + .xcore => "xcore", + .xtensa => "xtensa", + .nvptx => "nvptx", + .nvptx64 => "nvptx64", + .spirv => "spirv", + .spirv32 => "spirv32", + .spirv64 => "spirv64", + .kalimba => "kalimba", + .lanai => "lanai", + .wasm32 => "wasm32", + .wasm64 => "wasm64", + .ve => "ve", + }; + writer.writeAll(llvm_arch) catch unreachable; + writer.writeByte('-') catch unreachable; + + const llvm_os = switch (target.os.tag) { + .freestanding => "unknown", + .dragonfly => "dragonfly", + .freebsd => "freebsd", + .fuchsia => "fuchsia", + .linux => "linux", + .ps3 => "lv2", + .netbsd => "netbsd", + .openbsd => "openbsd", + .solaris => "solaris", + .illumos => "illumos", + .windows => "windows", + .zos => "zos", + .haiku => "haiku", + .rtems => "rtems", + .aix => "aix", + .cuda => "cuda", + .nvcl => "nvcl", + .amdhsa => "amdhsa", + .ps4 => "ps4", + .ps5 => "ps5", + .elfiamcu => "elfiamcu", + .mesa3d => "mesa3d", + .contiki => "contiki", + .amdpal => "amdpal", + .hermit => "hermit", + .hurd => "hurd", + .wasi => "wasi", + .emscripten => "emscripten", + .uefi => "windows", + .macos => "macosx", + .ios => "ios", + .tvos => "tvos", + .watchos => "watchos", + .driverkit => "driverkit", + .visionos => "xros", + .serenity => "serenity", + .opencl, + .opengl, + .vulkan, + .plan9, + .other, + => "unknown", + }; + writer.writeAll(llvm_os) catch unreachable; + + if (target.os.tag.isDarwin()) { + const min_version = target.os.version_range.semver.min; + writer.print("{d}.{d}.{d}", .{ + min_version.major, + min_version.minor, + min_version.patch, + }) catch unreachable; + } + writer.writeByte('-') catch unreachable; + + const llvm_abi = switch (target.abi) { + .none, .ilp32 => "unknown", + .gnu => "gnu", + .gnuabin32 => "gnuabin32", + .gnuabi64 => "gnuabi64", + .gnueabi => "gnueabi", + .gnueabihf => "gnueabihf", + .gnuf32 => "gnuf32", + .gnusf => "gnusf", + .gnux32 => "gnux32", + .gnuilp32 => "gnu_ilp32", + .code16 => "code16", + .eabi => "eabi", + .eabihf => "eabihf", + .android => "android", + .androideabi => "androideabi", + .musl => "musl", + .muslabin32 => "muslabin32", + .muslabi64 => "muslabi64", + .musleabi => "musleabi", + .musleabihf => "musleabihf", + .muslx32 => "muslx32", + .msvc => "msvc", + .itanium => "itanium", + .cygnus => "cygnus", + .simulator => "simulator", + .macabi => "macabi", + .ohos => "ohos", + .ohoseabi => "ohoseabi", + }; + writer.writeAll(llvm_abi) catch unreachable; + return stream.getWritten(); +} + +test "alignment functions - smoke test" { + var target: std.Target = undefined; + const x86 = std.Target.Cpu.Arch.x86_64; + target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86, .none); + target.cpu = std.Target.Cpu.baseline(x86, target.os); + target.abi = std.Target.Abi.default(x86, target.os); + + try std.testing.expect(isTlsSupported(target)); + try std.testing.expect(!ignoreNonZeroSizedBitfieldTypeAlignment(target)); + try std.testing.expect(minZeroWidthBitfieldAlignment(target) == null); + try std.testing.expect(!unnamedFieldAffectsAlignment(target)); + try std.testing.expect(defaultAlignment(target) == 16); + try std.testing.expect(!packAllEnums(target)); + try std.testing.expect(systemCompiler(target) == .gcc); + + const arm = std.Target.Cpu.Arch.arm; + target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm, .none); + target.cpu = std.Target.Cpu.baseline(arm, target.os); + target.abi = std.Target.Abi.default(arm, target.os); + + try std.testing.expect(!isTlsSupported(target)); + try std.testing.expect(ignoreNonZeroSizedBitfieldTypeAlignment(target)); + try std.testing.expectEqual(@as(?u29, 32), minZeroWidthBitfieldAlignment(target)); + try std.testing.expect(unnamedFieldAffectsAlignment(target)); + try std.testing.expect(defaultAlignment(target) == 16); + try std.testing.expect(!packAllEnums(target)); + try std.testing.expect(systemCompiler(target) == .clang); +} + +test "target size/align tests" { + var comp: @import("Compilation.zig") = undefined; + + const x86 = std.Target.Cpu.Arch.x86; + comp.target.cpu.arch = x86; + comp.target.cpu.model = &std.Target.x86.cpu.i586; + comp.target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86, .none); + comp.target.abi = std.Target.Abi.gnu; + + const tt: Type = .{ + .specifier = .long_long, + }; + + try std.testing.expectEqual(@as(u64, 8), tt.sizeof(&comp).?); + try std.testing.expectEqual(@as(u64, 4), tt.alignof(&comp)); + + const arm = std.Target.Cpu.Arch.arm; + comp.target.cpu = std.Target.Cpu.Model.toCpu(&std.Target.arm.cpu.cortex_r4, arm); + comp.target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm, .none); + comp.target.abi = std.Target.Abi.none; + + const ct: Type = .{ + .specifier = .char, + }; + + try std.testing.expectEqual(true, std.Target.arm.featureSetHas(comp.target.cpu.features, .has_v7)); + try std.testing.expectEqual(@as(u64, 1), ct.sizeof(&comp).?); + try std.testing.expectEqual(@as(u64, 1), ct.alignof(&comp)); + try std.testing.expectEqual(true, ignoreNonZeroSizedBitfieldTypeAlignment(comp.target)); +} + +/// The canonical integer representation of nullptr_t. +pub fn nullRepr(_: std.Target) u64 { + return 0; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/text_literal.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/text_literal.zig new file mode 100644 index 00000000..7bc8fd95 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/text_literal.zig @@ -0,0 +1,383 @@ +//! Parsing and classification of string and character literals + +const std = @import("std"); +const Compilation = @import("Compilation.zig"); +const Type = @import("Type.zig"); +const Diagnostics = @import("Diagnostics.zig"); +const Tokenizer = @import("Tokenizer.zig"); +const mem = std.mem; + +pub const Item = union(enum) { + /// decoded hex or character escape + value: u32, + /// validated unicode codepoint + codepoint: u21, + /// Char literal in the source text is not utf8 encoded + improperly_encoded: []const u8, + /// 1 or more unescaped bytes + utf8_text: std.unicode.Utf8View, +}; + +const CharDiagnostic = struct { + tag: Diagnostics.Tag, + extra: Diagnostics.Message.Extra, +}; + +pub const Kind = enum { + char, + wide, + utf_8, + utf_16, + utf_32, + /// Error kind that halts parsing + unterminated, + + pub fn classify(id: Tokenizer.Token.Id, context: enum { string_literal, char_literal }) ?Kind { + return switch (context) { + .string_literal => switch (id) { + .string_literal => .char, + .string_literal_utf_8 => .utf_8, + .string_literal_wide => .wide, + .string_literal_utf_16 => .utf_16, + .string_literal_utf_32 => .utf_32, + .unterminated_string_literal => .unterminated, + else => null, + }, + .char_literal => switch (id) { + .char_literal => .char, + .char_literal_utf_8 => .utf_8, + .char_literal_wide => .wide, + .char_literal_utf_16 => .utf_16, + .char_literal_utf_32 => .utf_32, + else => null, + }, + }; + } + + /// Should only be called for string literals. Determines the result kind of two adjacent string + /// literals + pub fn concat(self: Kind, other: Kind) !Kind { + if (self == .unterminated or other == .unterminated) return .unterminated; + if (self == other) return self; // can always concat with own kind + if (self == .char) return other; // char + X -> X + if (other == .char) return self; // X + char -> X + return error.CannotConcat; + } + + /// Largest unicode codepoint that can be represented by this character kind + /// May be smaller than the largest value that can be represented. + /// For example u8 char literals may only specify 0-127 via literals or + /// character escapes, but may specify up to \xFF via hex escapes. + pub fn maxCodepoint(kind: Kind, comp: *const Compilation) u21 { + return @intCast(switch (kind) { + .char => std.math.maxInt(u7), + .wide => @min(0x10FFFF, comp.wcharMax()), + .utf_8 => std.math.maxInt(u7), + .utf_16 => std.math.maxInt(u16), + .utf_32 => 0x10FFFF, + .unterminated => unreachable, + }); + } + + /// Largest integer that can be represented by this character kind + pub fn maxInt(kind: Kind, comp: *const Compilation) u32 { + return @intCast(switch (kind) { + .char, .utf_8 => std.math.maxInt(u8), + .wide => comp.wcharMax(), + .utf_16 => std.math.maxInt(u16), + .utf_32 => std.math.maxInt(u32), + .unterminated => unreachable, + }); + } + + /// The C type of a character literal of this kind + pub fn charLiteralType(kind: Kind, comp: *const Compilation) Type { + return switch (kind) { + .char => Type.int, + .wide => comp.types.wchar, + .utf_8 => .{ .specifier = .uchar }, + .utf_16 => comp.types.uint_least16_t, + .utf_32 => comp.types.uint_least32_t, + .unterminated => unreachable, + }; + } + + /// Return the actual contents of the literal with leading / trailing quotes and + /// specifiers removed + pub fn contentSlice(kind: Kind, delimited: []const u8) []const u8 { + const end = delimited.len - 1; // remove trailing quote + return switch (kind) { + .char => delimited[1..end], + .wide => delimited[2..end], + .utf_8 => delimited[3..end], + .utf_16 => delimited[2..end], + .utf_32 => delimited[2..end], + .unterminated => unreachable, + }; + } + + /// The size of a character unit for a string literal of this kind + pub fn charUnitSize(kind: Kind, comp: *const Compilation) Compilation.CharUnitSize { + return switch (kind) { + .char => .@"1", + .wide => switch (comp.types.wchar.sizeof(comp).?) { + 2 => .@"2", + 4 => .@"4", + else => unreachable, + }, + .utf_8 => .@"1", + .utf_16 => .@"2", + .utf_32 => .@"4", + .unterminated => unreachable, + }; + } + + /// Required alignment within aro (on compiler host) for writing to Interner.strings. + pub fn internalStorageAlignment(kind: Kind, comp: *const Compilation) usize { + return switch (kind.charUnitSize(comp)) { + inline else => |size| @alignOf(size.Type()), + }; + } + + /// The C type of an element of a string literal of this kind + pub fn elementType(kind: Kind, comp: *const Compilation) Type { + return switch (kind) { + .unterminated => unreachable, + .char => .{ .specifier = .char }, + .utf_8 => if (comp.langopts.hasChar8_T()) .{ .specifier = .uchar } else .{ .specifier = .char }, + else => kind.charLiteralType(comp), + }; + } +}; + +pub const Parser = struct { + literal: []const u8, + i: usize = 0, + kind: Kind, + max_codepoint: u21, + /// We only want to issue a max of 1 error per char literal + errored: bool = false, + errors_buffer: [4]CharDiagnostic, + errors_len: usize, + comp: *const Compilation, + + pub fn init(literal: []const u8, kind: Kind, max_codepoint: u21, comp: *const Compilation) Parser { + return .{ + .literal = literal, + .comp = comp, + .kind = kind, + .max_codepoint = max_codepoint, + .errors_buffer = undefined, + .errors_len = 0, + }; + } + + fn prefixLen(self: *const Parser) usize { + return switch (self.kind) { + .unterminated => unreachable, + .char => 0, + .utf_8 => 2, + .wide, .utf_16, .utf_32 => 1, + }; + } + + pub fn errors(p: *Parser) []CharDiagnostic { + return p.errors_buffer[0..p.errors_len]; + } + + pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void { + if (self.errored) return; + self.errored = true; + const diagnostic: CharDiagnostic = .{ .tag = tag, .extra = extra }; + if (self.errors_len == self.errors_buffer.len) { + self.errors_buffer[self.errors_buffer.len - 1] = diagnostic; + } else { + self.errors_buffer[self.errors_len] = diagnostic; + self.errors_len += 1; + } + } + + pub fn warn(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void { + if (self.errored) return; + if (self.errors_len < self.errors_buffer.len) { + self.errors_buffer[self.errors_len] = .{ .tag = tag, .extra = extra }; + self.errors_len += 1; + } + } + + pub fn next(self: *Parser) ?Item { + if (self.i >= self.literal.len) return null; + + const start = self.i; + if (self.literal[start] != '\\') { + self.i = mem.indexOfScalarPos(u8, self.literal, start + 1, '\\') orelse self.literal.len; + const unescaped_slice = self.literal[start..self.i]; + + const view = std.unicode.Utf8View.init(unescaped_slice) catch { + if (self.kind != .char) { + self.err(.illegal_char_encoding_error, .{ .none = {} }); + return null; + } + self.warn(.illegal_char_encoding_warning, .{ .none = {} }); + return .{ .improperly_encoded = self.literal[start..self.i] }; + }; + return .{ .utf8_text = view }; + } + switch (self.literal[start + 1]) { + 'u', 'U' => return self.parseUnicodeEscape(), + else => return self.parseEscapedChar(), + } + } + + fn parseUnicodeEscape(self: *Parser) ?Item { + const start = self.i; + + std.debug.assert(self.literal[self.i] == '\\'); + + const kind = self.literal[self.i + 1]; + std.debug.assert(kind == 'u' or kind == 'U'); + + self.i += 2; + if (self.i >= self.literal.len or !std.ascii.isHex(self.literal[self.i])) { + self.err(.missing_hex_escape, .{ .ascii = @intCast(kind) }); + return null; + } + const expected_len: usize = if (kind == 'u') 4 else 8; + var overflowed = false; + var count: usize = 0; + var val: u32 = 0; + + for (self.literal[self.i..], 0..) |c, i| { + if (i == expected_len) break; + + const char = std.fmt.charToDigit(c, 16) catch { + break; + }; + + val, const overflow = @shlWithOverflow(val, 4); + overflowed = overflowed or overflow != 0; + val |= char; + count += 1; + } + self.i += expected_len; + + if (overflowed) { + self.err(.escape_sequence_overflow, .{ .offset = start + self.prefixLen() }); + return null; + } + + if (count != expected_len) { + self.err(.incomplete_universal_character, .{ .none = {} }); + return null; + } + + if (val > std.math.maxInt(u21) or !std.unicode.utf8ValidCodepoint(@intCast(val))) { + self.err(.invalid_universal_character, .{ .offset = start + self.prefixLen() }); + return null; + } + + if (val > self.max_codepoint) { + self.err(.char_too_large, .{ .none = {} }); + return null; + } + + if (val < 0xA0 and (val != '$' and val != '@' and val != '`')) { + const is_error = !self.comp.langopts.standard.atLeast(.c23); + if (val >= 0x20 and val <= 0x7F) { + if (is_error) { + self.err(.ucn_basic_char_error, .{ .ascii = @intCast(val) }); + } else { + self.warn(.ucn_basic_char_warning, .{ .ascii = @intCast(val) }); + } + } else { + if (is_error) { + self.err(.ucn_control_char_error, .{ .none = {} }); + } else { + self.warn(.ucn_control_char_warning, .{ .none = {} }); + } + } + } + + self.warn(.c89_ucn_in_literal, .{ .none = {} }); + return .{ .codepoint = @intCast(val) }; + } + + fn parseEscapedChar(self: *Parser) Item { + self.i += 1; + const c = self.literal[self.i]; + defer if (c != 'x' and (c < '0' or c > '7')) { + self.i += 1; + }; + + switch (c) { + '\n' => unreachable, // removed by line splicing + '\r' => unreachable, // removed by line splicing + '\'', '\"', '\\', '?' => return .{ .value = c }, + 'n' => return .{ .value = '\n' }, + 'r' => return .{ .value = '\r' }, + 't' => return .{ .value = '\t' }, + 'a' => return .{ .value = 0x07 }, + 'b' => return .{ .value = 0x08 }, + 'e', 'E' => { + self.warn(.non_standard_escape_char, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } }); + return .{ .value = 0x1B }; + }, + '(', '{', '[', '%' => { + self.warn(.non_standard_escape_char, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } }); + return .{ .value = c }; + }, + 'f' => return .{ .value = 0x0C }, + 'v' => return .{ .value = 0x0B }, + 'x' => return .{ .value = self.parseNumberEscape(.hex) }, + '0'...'7' => return .{ .value = self.parseNumberEscape(.octal) }, + 'u', 'U' => unreachable, // handled by parseUnicodeEscape + else => { + self.warn(.unknown_escape_sequence, .{ .invalid_escape = .{ .char = c, .offset = @intCast(self.i) } }); + return .{ .value = c }; + }, + } + } + + fn parseNumberEscape(self: *Parser, base: EscapeBase) u32 { + var val: u32 = 0; + var count: usize = 0; + var overflowed = false; + const start = self.i; + defer self.i += count; + const slice = switch (base) { + .octal => self.literal[self.i..@min(self.literal.len, self.i + 3)], // max 3 chars + .hex => blk: { + self.i += 1; + break :blk self.literal[self.i..]; // skip over 'x'; could have an arbitrary number of chars + }, + }; + for (slice) |c| { + const char = std.fmt.charToDigit(c, @intFromEnum(base)) catch break; + val, const overflow = @shlWithOverflow(val, base.log2()); + if (overflow != 0) overflowed = true; + val += char; + count += 1; + } + if (overflowed or val > self.kind.maxInt(self.comp)) { + self.err(.escape_sequence_overflow, .{ .offset = start + self.prefixLen() }); + return 0; + } + if (count == 0) { + std.debug.assert(base == .hex); + self.err(.missing_hex_escape, .{ .ascii = 'x' }); + } + return val; + } +}; + +const EscapeBase = enum(u8) { + octal = 8, + hex = 16, + + fn log2(base: EscapeBase) u4 { + return switch (base) { + .octal => 3, + .hex => 4, + }; + } +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/toolchains/Linux.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/toolchains/Linux.zig new file mode 100644 index 00000000..466a63ee --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/toolchains/Linux.zig @@ -0,0 +1,526 @@ +const std = @import("std"); +const mem = std.mem; +const Compilation = @import("../Compilation.zig"); +const GCCDetector = @import("../Driver/GCCDetector.zig"); +const Toolchain = @import("../Toolchain.zig"); +const Driver = @import("../Driver.zig"); +const Distro = @import("../Driver/Distro.zig"); +const target_util = @import("../target.zig"); +const system_defaults = @import("system_defaults"); + +const Linux = @This(); + +distro: Distro.Tag = .unknown, +extra_opts: std.ArrayListUnmanaged([]const u8) = .empty, +gcc_detector: GCCDetector = .{}, + +pub fn discover(self: *Linux, tc: *Toolchain) !void { + self.distro = Distro.detect(tc.getTarget(), tc.filesystem); + try self.gcc_detector.discover(tc); + tc.selected_multilib = self.gcc_detector.selected; + + try self.gcc_detector.appendToolPath(tc); + try self.buildExtraOpts(tc); + try self.findPaths(tc); +} + +fn buildExtraOpts(self: *Linux, tc: *const Toolchain) !void { + const gpa = tc.driver.comp.gpa; + const target = tc.getTarget(); + const is_android = target.abi.isAndroid(); + if (self.distro.isAlpine() or is_android) { + try self.extra_opts.ensureUnusedCapacity(gpa, 2); + self.extra_opts.appendAssumeCapacity("-z"); + self.extra_opts.appendAssumeCapacity("now"); + } + + if (self.distro.isOpenSUSE() or self.distro.isUbuntu() or self.distro.isAlpine() or is_android) { + try self.extra_opts.ensureUnusedCapacity(gpa, 2); + self.extra_opts.appendAssumeCapacity("-z"); + self.extra_opts.appendAssumeCapacity("relro"); + } + + if ((target.cpu.arch.isArm() and !target.cpu.arch.isThumb()) or target.cpu.arch.isAARCH64() or is_android) { + try self.extra_opts.ensureUnusedCapacity(gpa, 2); + self.extra_opts.appendAssumeCapacity("-z"); + self.extra_opts.appendAssumeCapacity("max-page-size=4096"); + } + + if (target.cpu.arch == .arm or target.cpu.arch == .thumb) { + try self.extra_opts.append(gpa, "-X"); + } + + if (!target.cpu.arch.isMIPS() and target.cpu.arch != .hexagon) { + const hash_style = if (is_android) .both else self.distro.getHashStyle(); + try self.extra_opts.append(gpa, switch (hash_style) { + inline else => |tag| "--hash-style=" ++ @tagName(tag), + }); + } + + if (system_defaults.enable_linker_build_id) { + try self.extra_opts.append(gpa, "--build-id"); + } +} + +fn addMultiLibPaths(self: *Linux, tc: *Toolchain, sysroot: []const u8, os_lib_dir: []const u8) !void { + if (!self.gcc_detector.is_valid) return; + const gcc_triple = self.gcc_detector.gcc_triple; + const lib_path = self.gcc_detector.parent_lib_path; + + // Add lib/gcc/$triple/$version, with an optional /multilib suffix. + try tc.addPathIfExists(&.{ self.gcc_detector.install_path, tc.selected_multilib.gcc_suffix }, .file); + + // Add lib/gcc/$triple/$libdir + // For GCC built with --enable-version-specific-runtime-libs. + try tc.addPathIfExists(&.{ self.gcc_detector.install_path, "..", os_lib_dir }, .file); + + try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", "..", os_lib_dir, tc.selected_multilib.os_suffix }, .file); + + // If the GCC installation we found is inside of the sysroot, we want to + // prefer libraries installed in the parent prefix of the GCC installation. + // It is important to *not* use these paths when the GCC installation is + // outside of the system root as that can pick up unintended libraries. + // This usually happens when there is an external cross compiler on the + // host system, and a more minimal sysroot available that is the target of + // the cross. Note that GCC does include some of these directories in some + // configurations but this seems somewhere between questionable and simply + // a bug. + if (mem.startsWith(u8, lib_path, sysroot)) { + try tc.addPathIfExists(&.{ lib_path, "..", os_lib_dir }, .file); + } +} + +fn addMultiArchPaths(self: *Linux, tc: *Toolchain) !void { + if (!self.gcc_detector.is_valid) return; + const lib_path = self.gcc_detector.parent_lib_path; + const gcc_triple = self.gcc_detector.gcc_triple; + const multilib = self.gcc_detector.selected; + try tc.addPathIfExists(&.{ lib_path, "..", gcc_triple, "lib", multilib.os_suffix }, .file); +} + +/// TODO: Very incomplete +fn findPaths(self: *Linux, tc: *Toolchain) !void { + const target = tc.getTarget(); + const sysroot = tc.getSysroot(); + + var output: [64]u8 = undefined; + + const os_lib_dir = getOSLibDir(target); + const multiarch_triple = getMultiarchTriple(target) orelse target_util.toLLVMTriple(target, &output); + + try self.addMultiLibPaths(tc, sysroot, os_lib_dir); + + try tc.addPathIfExists(&.{ sysroot, "/lib", multiarch_triple }, .file); + try tc.addPathIfExists(&.{ sysroot, "/lib", "..", os_lib_dir }, .file); + + if (target.abi.isAndroid()) { + // TODO + } + try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", multiarch_triple }, .file); + try tc.addPathIfExists(&.{ sysroot, "/usr", "lib", "..", os_lib_dir }, .file); + + try self.addMultiArchPaths(tc); + + try tc.addPathIfExists(&.{ sysroot, "/lib" }, .file); + try tc.addPathIfExists(&.{ sysroot, "/usr", "lib" }, .file); +} + +pub fn deinit(self: *Linux, allocator: std.mem.Allocator) void { + self.extra_opts.deinit(allocator); +} + +fn isPIEDefault(self: *const Linux) bool { + _ = self; + return false; +} + +fn getPIE(self: *const Linux, d: *const Driver) bool { + if (d.shared or d.static or d.relocatable or d.static_pie) { + return false; + } + return d.pie orelse self.isPIEDefault(); +} + +fn getStaticPIE(self: *const Linux, d: *Driver) !bool { + _ = self; + if (d.static_pie and d.pie != null) { + try d.err("cannot specify 'nopie' along with 'static-pie'"); + } + return d.static_pie; +} + +fn getStatic(self: *const Linux, d: *const Driver) bool { + _ = self; + return d.static and !d.static_pie; +} + +pub fn getDefaultLinker(self: *const Linux, target: std.Target) []const u8 { + _ = self; + if (target.abi.isAndroid()) { + return "ld.lld"; + } + return "ld"; +} + +pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.ArrayList([]const u8)) Compilation.Error!void { + const d = tc.driver; + const target = tc.getTarget(); + + const is_pie = self.getPIE(d); + const is_static_pie = try self.getStaticPIE(d); + const is_static = self.getStatic(d); + const is_android = target.abi.isAndroid(); + const is_iamcu = target.os.tag == .elfiamcu; + const is_ve = target.cpu.arch == .ve; + const has_crt_begin_end_files = target.abi != .none; // TODO: clang checks for MIPS vendor + + if (is_pie) { + try argv.append("-pie"); + } + if (is_static_pie) { + try argv.appendSlice(&.{ "-static", "-pie", "--no-dynamic-linker", "-z", "text" }); + } + + if (d.rdynamic) { + try argv.append("-export-dynamic"); + } + + if (d.strip) { + try argv.append("-s"); + } + + try argv.appendSlice(self.extra_opts.items); + try argv.append("--eh-frame-hdr"); + + // Todo: Driver should parse `-EL`/`-EB` for arm to set endianness for arm targets + if (target_util.ldEmulationOption(d.comp.target, null)) |emulation| { + try argv.appendSlice(&.{ "-m", emulation }); + } else { + try d.err("Unknown target triple"); + return; + } + if (d.comp.target.cpu.arch.isRISCV()) { + try argv.append("-X"); + } + if (d.shared) { + try argv.append("-shared"); + } + if (is_static) { + try argv.append("-static"); + } else { + if (d.rdynamic) { + try argv.append("-export-dynamic"); + } + if (!d.shared and !is_static_pie and !d.relocatable) { + const dynamic_linker = d.comp.target.standardDynamicLinkerPath(); + // todo: check for --dyld-prefix + if (dynamic_linker.get()) |path| { + try argv.appendSlice(&.{ "-dynamic-linker", try tc.arena.dupe(u8, path) }); + } else { + try d.err("Could not find dynamic linker path"); + } + } + } + + try argv.appendSlice(&.{ "-o", d.output_name orelse "a.out" }); + + if (!d.nostdlib and !d.nostartfiles and !d.relocatable) { + if (!is_android and !is_iamcu) { + if (!d.shared) { + const crt1 = if (is_pie) + "Scrt1.o" + else if (is_static_pie) + "rcrt1.o" + else + "crt1.o"; + try argv.append(try tc.getFilePath(crt1)); + } + try argv.append(try tc.getFilePath("crti.o")); + } + if (is_ve) { + try argv.appendSlice(&.{ "-z", "max-page-size=0x4000000" }); + } + + if (is_iamcu) { + try argv.append(try tc.getFilePath("crt0.o")); + } else if (has_crt_begin_end_files) { + var path: []const u8 = ""; + if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) { + const crt_begin = try tc.getCompilerRt("crtbegin", .object); + if (tc.filesystem.exists(crt_begin)) { + path = crt_begin; + } + } + if (path.len == 0) { + const crt_begin = if (tc.driver.shared) + if (is_android) "crtbegin_so.o" else "crtbeginS.o" + else if (is_static) + if (is_android) "crtbegin_static.o" else "crtbeginT.o" + else if (is_pie or is_static_pie) + if (is_android) "crtbegin_dynamic.o" else "crtbeginS.o" + else if (is_android) "crtbegin_dynamic.o" else "crtbegin.o"; + path = try tc.getFilePath(crt_begin); + } + try argv.append(path); + } + } + + // TODO add -L opts + // TODO add -u opts + + try tc.addFilePathLibArgs(argv); + + // TODO handle LTO + + try argv.appendSlice(d.link_objects.items); + + if (!d.nostdlib and !d.relocatable) { + if (!d.nodefaultlibs) { + if (is_static or is_static_pie) { + try argv.append("--start-group"); + } + try tc.addRuntimeLibs(argv); + + // TODO: add pthread if needed + if (!d.nolibc) { + try argv.append("-lc"); + } + if (is_iamcu) { + try argv.append("-lgloss"); + } + if (is_static or is_static_pie) { + try argv.append("--end-group"); + } else { + try tc.addRuntimeLibs(argv); + } + if (is_iamcu) { + try argv.appendSlice(&.{ "--as-needed", "-lsoftfp", "--no-as-needed" }); + } + } + if (!d.nostartfiles and !is_iamcu) { + if (has_crt_begin_end_files) { + var path: []const u8 = ""; + if (tc.getRuntimeLibKind() == .compiler_rt and !is_android) { + const crt_end = try tc.getCompilerRt("crtend", .object); + if (tc.filesystem.exists(crt_end)) { + path = crt_end; + } + } + if (path.len == 0) { + const crt_end = if (d.shared) + if (is_android) "crtend_so.o" else "crtendS.o" + else if (is_pie or is_static_pie) + if (is_android) "crtend_android.o" else "crtendS.o" + else if (is_android) "crtend_android.o" else "crtend.o"; + path = try tc.getFilePath(crt_end); + } + try argv.append(path); + } + if (!is_android) { + try argv.append(try tc.getFilePath("crtn.o")); + } + } + } + + // TODO add -T args +} + +fn getMultiarchTriple(target: std.Target) ?[]const u8 { + const is_android = target.abi.isAndroid(); + const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6); + return switch (target.cpu.arch) { + .arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi", + .armeb, .thumbeb => if (target.abi == .gnueabihf) "armeb-linux-gnueabihf" else "armeb-linux-gnueabi", + .aarch64 => if (is_android) "aarch64-linux-android" else "aarch64-linux-gnu", + .aarch64_be => "aarch64_be-linux-gnu", + .x86 => if (is_android) "i686-linux-android" else "i386-linux-gnu", + .x86_64 => if (is_android) "x86_64-linux-android" else if (target.abi == .gnux32) "x86_64-linux-gnux32" else "x86_64-linux-gnu", + .m68k => "m68k-linux-gnu", + .mips => if (is_mips_r6) "mipsisa32r6-linux-gnu" else "mips-linux-gnu", + .mipsel => if (is_android) "mipsel-linux-android" else if (is_mips_r6) "mipsisa32r6el-linux-gnu" else "mipsel-linux-gnu", + .powerpcle => "powerpcle-linux-gnu", + .powerpc64 => "powerpc64-linux-gnu", + .powerpc64le => "powerpc64le-linux-gnu", + .riscv64 => "riscv64-linux-gnu", + .sparc => "sparc-linux-gnu", + .sparc64 => "sparc64-linux-gnu", + .s390x => "s390x-linux-gnu", + + // TODO: expand this + else => null, + }; +} + +fn getOSLibDir(target: std.Target) []const u8 { + switch (target.cpu.arch) { + .x86, + .powerpc, + .powerpcle, + .sparc, + => return "lib32", + else => {}, + } + if (target.cpu.arch == .x86_64 and (target.abi == .gnux32 or target.abi == .muslx32)) { + return "libx32"; + } + if (target.cpu.arch == .riscv32) { + return "lib32"; + } + if (target.ptrBitWidth() == 32) { + return "lib"; + } + return "lib64"; +} + +pub fn defineSystemIncludes(self: *const Linux, tc: *const Toolchain) !void { + if (tc.driver.nostdinc) return; + + const comp = tc.driver.comp; + const target = tc.getTarget(); + + // musl prefers /usr/include before builtin includes, so musl targets will add builtins + // at the end of this function (unless disabled with nostdlibinc) + if (!tc.driver.nobuiltininc and (!target.abi.isMusl() or tc.driver.nostdlibinc)) { + try comp.addBuiltinIncludeDir(tc.driver.aro_name); + } + + if (tc.driver.nostdlibinc) return; + + const sysroot = tc.getSysroot(); + const local_include = try std.fmt.allocPrint(comp.gpa, "{s}{s}", .{ sysroot, "/usr/local/include" }); + defer comp.gpa.free(local_include); + try comp.addSystemIncludeDir(local_include); + + if (self.gcc_detector.is_valid) { + const gcc_include_path = try std.fs.path.join(comp.gpa, &.{ self.gcc_detector.parent_lib_path, "..", self.gcc_detector.gcc_triple, "include" }); + defer comp.gpa.free(gcc_include_path); + try comp.addSystemIncludeDir(gcc_include_path); + } + + if (getMultiarchTriple(target)) |triple| { + const joined = try std.fs.path.join(comp.gpa, &.{ sysroot, "usr", "include", triple }); + defer comp.gpa.free(joined); + if (tc.filesystem.exists(joined)) { + try comp.addSystemIncludeDir(joined); + } + } + + if (target.os.tag == .rtems) return; + + try comp.addSystemIncludeDir("/include"); + try comp.addSystemIncludeDir("/usr/include"); + + std.debug.assert(!tc.driver.nostdlibinc); + if (!tc.driver.nobuiltininc and target.abi.isMusl()) { + try comp.addBuiltinIncludeDir(tc.driver.aro_name); + } +} + +test Linux { + if (@import("builtin").os.tag == .windows) return error.SkipZigTest; + + var arena_instance = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena_instance.deinit(); + const arena = arena_instance.allocator(); + + var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); + defer comp.deinit(); + comp.environment = .{ + .path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + }; + defer comp.environment = .{}; + + const raw_triple = "x86_64-linux-gnu"; + const target_query = try std.Target.Query.parse(.{ .arch_os_abi = raw_triple }); + comp.target = try std.zig.system.resolveTargetQuery(target_query); + comp.langopts.setEmulatedCompiler(.gcc); + + var driver: Driver = .{ .comp = &comp }; + defer driver.deinit(); + driver.raw_target_triple = raw_triple; + + const link_obj = try driver.comp.gpa.dupe(u8, "/tmp/foo.o"); + try driver.link_objects.append(driver.comp.gpa, link_obj); + driver.temp_file_count += 1; + + var toolchain: Toolchain = .{ .driver = &driver, .arena = arena, .filesystem = .{ .fake = &.{ + .{ .path = "/tmp" }, + .{ .path = "/usr" }, + .{ .path = "/usr/lib64" }, + .{ .path = "/usr/bin" }, + .{ .path = "/usr/bin/ld", .executable = true }, + .{ .path = "/lib" }, + .{ .path = "/lib/x86_64-linux-gnu" }, + .{ .path = "/lib/x86_64-linux-gnu/crt1.o" }, + .{ .path = "/lib/x86_64-linux-gnu/crti.o" }, + .{ .path = "/lib/x86_64-linux-gnu/crtn.o" }, + .{ .path = "/lib64" }, + .{ .path = "/usr/lib" }, + .{ .path = "/usr/lib/gcc" }, + .{ .path = "/usr/lib/gcc/x86_64-linux-gnu" }, + .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9" }, + .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o" }, + .{ .path = "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o" }, + .{ .path = "/usr/lib/x86_64-linux-gnu" }, + .{ .path = "/etc/lsb-release", .contents = + \\DISTRIB_ID=Ubuntu + \\DISTRIB_RELEASE=20.04 + \\DISTRIB_CODENAME=focal + \\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS" + \\ + }, + } } }; + defer toolchain.deinit(); + + try toolchain.discover(); + + var argv = std.ArrayList([]const u8).init(driver.comp.gpa); + defer argv.deinit(); + + var linker_path_buf: [std.fs.max_path_bytes]u8 = undefined; + const linker_path = try toolchain.getLinkerPath(&linker_path_buf); + try argv.append(linker_path); + + try toolchain.buildLinkerArgs(&argv); + + const expected = [_][]const u8{ + "/usr/bin/ld", + "-z", + "relro", + "--hash-style=gnu", + "--eh-frame-hdr", + "-m", + "elf_x86_64", + "-dynamic-linker", + "/lib64/ld-linux-x86-64.so.2", + "-o", + "a.out", + "/lib/x86_64-linux-gnu/crt1.o", + "/lib/x86_64-linux-gnu/crti.o", + "/usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o", + "-L/usr/lib/gcc/x86_64-linux-gnu/9", + "-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64", + "-L/lib/x86_64-linux-gnu", + "-L/lib/../lib64", + "-L/usr/lib/x86_64-linux-gnu", + "-L/usr/lib/../lib64", + "-L/lib", + "-L/usr/lib", + link_obj, + "-lgcc", + "--as-needed", + "-lgcc_s", + "--no-as-needed", + "-lc", + "-lgcc", + "--as-needed", + "-lgcc_s", + "--no-as-needed", + "/usr/lib/gcc/x86_64-linux-gnu/9/crtend.o", + "/lib/x86_64-linux-gnu/crtn.o", + }; + try std.testing.expectEqual(expected.len, argv.items.len); + for (expected, argv.items) |expected_item, actual_item| { + try std.testing.expectEqualStrings(expected_item, actual_item); + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/tracy.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/tracy.zig new file mode 100644 index 00000000..e3c4bb67 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/aro/tracy.zig @@ -0,0 +1,310 @@ +//! Copied from https://github.com/ziglang/zig/blob/c9006d9479c619d9ed555164831e11a04d88d382/src/tracy.zig + +const std = @import("std"); +const builtin = @import("builtin"); +const build_options = @import("build_options"); + +pub const enable = if (builtin.is_test) false else build_options.enable_tracy; +pub const enable_allocation = enable and build_options.enable_tracy_allocation; +pub const enable_callstack = enable and build_options.enable_tracy_callstack; + +// TODO: make this configurable +const callstack_depth = 10; + +const ___tracy_c_zone_context = extern struct { + id: u32, + active: c_int, + + pub inline fn end(self: @This()) void { + ___tracy_emit_zone_end(self); + } + + pub inline fn addText(self: @This(), text: []const u8) void { + ___tracy_emit_zone_text(self, text.ptr, text.len); + } + + pub inline fn setName(self: @This(), name: []const u8) void { + ___tracy_emit_zone_name(self, name.ptr, name.len); + } + + pub inline fn setColor(self: @This(), color: u32) void { + ___tracy_emit_zone_color(self, color); + } + + pub inline fn setValue(self: @This(), value: u64) void { + ___tracy_emit_zone_value(self, value); + } +}; + +pub const Ctx = if (enable) ___tracy_c_zone_context else struct { + pub inline fn end(self: @This()) void { + _ = self; + } + + pub inline fn addText(self: @This(), text: []const u8) void { + _ = self; + _ = text; + } + + pub inline fn setName(self: @This(), name: []const u8) void { + _ = self; + _ = name; + } + + pub inline fn setColor(self: @This(), color: u32) void { + _ = self; + _ = color; + } + + pub inline fn setValue(self: @This(), value: u64) void { + _ = self; + _ = value; + } +}; + +pub inline fn trace(comptime src: std.builtin.SourceLocation) Ctx { + if (!enable) return .{}; + + if (enable_callstack) { + return ___tracy_emit_zone_begin_callstack(&.{ + .name = null, + .function = src.fn_name.ptr, + .file = src.file.ptr, + .line = src.line, + .color = 0, + }, callstack_depth, 1); + } else { + return ___tracy_emit_zone_begin(&.{ + .name = null, + .function = src.fn_name.ptr, + .file = src.file.ptr, + .line = src.line, + .color = 0, + }, 1); + } +} + +pub inline fn traceNamed(comptime src: std.builtin.SourceLocation, comptime name: [:0]const u8) Ctx { + if (!enable) return .{}; + + if (enable_callstack) { + return ___tracy_emit_zone_begin_callstack(&.{ + .name = name.ptr, + .function = src.fn_name.ptr, + .file = src.file.ptr, + .line = src.line, + .color = 0, + }, callstack_depth, 1); + } else { + return ___tracy_emit_zone_begin(&.{ + .name = name.ptr, + .function = src.fn_name.ptr, + .file = src.file.ptr, + .line = src.line, + .color = 0, + }, 1); + } +} + +pub fn tracyAllocator(allocator: std.mem.Allocator) TracyAllocator(null) { + return TracyAllocator(null).init(allocator); +} + +pub fn TracyAllocator(comptime name: ?[:0]const u8) type { + return struct { + parent_allocator: std.mem.Allocator, + + const Self = @This(); + + pub fn init(parent_allocator: std.mem.Allocator) Self { + return .{ + .parent_allocator = parent_allocator, + }; + } + + pub fn allocator(self: *Self) std.mem.Allocator { + return std.mem.Allocator.init(self, allocFn, resizeFn, freeFn); + } + + fn allocFn(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 { + const result = self.parent_allocator.rawAlloc(len, ptr_align, len_align, ret_addr); + if (result) |data| { + if (data.len != 0) { + if (name) |n| { + allocNamed(data.ptr, data.len, n); + } else { + alloc(data.ptr, data.len); + } + } + } else |_| { + messageColor("allocation failed", 0xFF0000); + } + return result; + } + + fn resizeFn(self: *Self, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize { + if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ret_addr)) |resized_len| { + if (name) |n| { + freeNamed(buf.ptr, n); + allocNamed(buf.ptr, resized_len, n); + } else { + free(buf.ptr); + alloc(buf.ptr, resized_len); + } + + return resized_len; + } + + // during normal operation the compiler hits this case thousands of times due to this + // emitting messages for it is both slow and causes clutter + return null; + } + + fn freeFn(self: *Self, buf: []u8, buf_align: u29, ret_addr: usize) void { + self.parent_allocator.rawFree(buf, buf_align, ret_addr); + // this condition is to handle free being called on an empty slice that was never even allocated + // example case: `std.process.getSelfExeSharedLibPaths` can return `&[_][:0]u8{}` + if (buf.len != 0) { + if (name) |n| { + freeNamed(buf.ptr, n); + } else { + free(buf.ptr); + } + } + } + }; +} + +// This function only accepts comptime known strings, see `messageCopy` for runtime strings +pub inline fn message(comptime msg: [:0]const u8) void { + if (!enable) return; + ___tracy_emit_messageL(msg.ptr, if (enable_callstack) callstack_depth else 0); +} + +// This function only accepts comptime known strings, see `messageColorCopy` for runtime strings +pub inline fn messageColor(comptime msg: [:0]const u8, color: u32) void { + if (!enable) return; + ___tracy_emit_messageLC(msg.ptr, color, if (enable_callstack) callstack_depth else 0); +} + +pub inline fn messageCopy(msg: []const u8) void { + if (!enable) return; + ___tracy_emit_message(msg.ptr, msg.len, if (enable_callstack) callstack_depth else 0); +} + +pub inline fn messageColorCopy(msg: [:0]const u8, color: u32) void { + if (!enable) return; + ___tracy_emit_messageC(msg.ptr, msg.len, color, if (enable_callstack) callstack_depth else 0); +} + +pub inline fn frameMark() void { + if (!enable) return; + ___tracy_emit_frame_mark(null); +} + +pub inline fn frameMarkNamed(comptime name: [:0]const u8) void { + if (!enable) return; + ___tracy_emit_frame_mark(name.ptr); +} + +pub inline fn namedFrame(comptime name: [:0]const u8) Frame(name) { + frameMarkStart(name); + return .{}; +} + +pub fn Frame(comptime name: [:0]const u8) type { + return struct { + pub fn end(_: @This()) void { + frameMarkEnd(name); + } + }; +} + +inline fn frameMarkStart(comptime name: [:0]const u8) void { + if (!enable) return; + ___tracy_emit_frame_mark_start(name.ptr); +} + +inline fn frameMarkEnd(comptime name: [:0]const u8) void { + if (!enable) return; + ___tracy_emit_frame_mark_end(name.ptr); +} + +extern fn ___tracy_emit_frame_mark_start(name: [*:0]const u8) void; +extern fn ___tracy_emit_frame_mark_end(name: [*:0]const u8) void; + +inline fn alloc(ptr: [*]u8, len: usize) void { + if (!enable) return; + + if (enable_callstack) { + ___tracy_emit_memory_alloc_callstack(ptr, len, callstack_depth, 0); + } else { + ___tracy_emit_memory_alloc(ptr, len, 0); + } +} + +inline fn allocNamed(ptr: [*]u8, len: usize, comptime name: [:0]const u8) void { + if (!enable) return; + + if (enable_callstack) { + ___tracy_emit_memory_alloc_callstack_named(ptr, len, callstack_depth, 0, name.ptr); + } else { + ___tracy_emit_memory_alloc_named(ptr, len, 0, name.ptr); + } +} + +inline fn free(ptr: [*]u8) void { + if (!enable) return; + + if (enable_callstack) { + ___tracy_emit_memory_free_callstack(ptr, callstack_depth, 0); + } else { + ___tracy_emit_memory_free(ptr, 0); + } +} + +inline fn freeNamed(ptr: [*]u8, comptime name: [:0]const u8) void { + if (!enable) return; + + if (enable_callstack) { + ___tracy_emit_memory_free_callstack_named(ptr, callstack_depth, 0, name.ptr); + } else { + ___tracy_emit_memory_free_named(ptr, 0, name.ptr); + } +} + +extern fn ___tracy_emit_zone_begin( + srcloc: *const ___tracy_source_location_data, + active: c_int, +) ___tracy_c_zone_context; +extern fn ___tracy_emit_zone_begin_callstack( + srcloc: *const ___tracy_source_location_data, + depth: c_int, + active: c_int, +) ___tracy_c_zone_context; +extern fn ___tracy_emit_zone_text(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void; +extern fn ___tracy_emit_zone_name(ctx: ___tracy_c_zone_context, txt: [*]const u8, size: usize) void; +extern fn ___tracy_emit_zone_color(ctx: ___tracy_c_zone_context, color: u32) void; +extern fn ___tracy_emit_zone_value(ctx: ___tracy_c_zone_context, value: u64) void; +extern fn ___tracy_emit_zone_end(ctx: ___tracy_c_zone_context) void; +extern fn ___tracy_emit_memory_alloc(ptr: *const anyopaque, size: usize, secure: c_int) void; +extern fn ___tracy_emit_memory_alloc_callstack(ptr: *const anyopaque, size: usize, depth: c_int, secure: c_int) void; +extern fn ___tracy_emit_memory_free(ptr: *const anyopaque, secure: c_int) void; +extern fn ___tracy_emit_memory_free_callstack(ptr: *const anyopaque, depth: c_int, secure: c_int) void; +extern fn ___tracy_emit_memory_alloc_named(ptr: *const anyopaque, size: usize, secure: c_int, name: [*:0]const u8) void; +extern fn ___tracy_emit_memory_alloc_callstack_named(ptr: *const anyopaque, size: usize, depth: c_int, secure: c_int, name: [*:0]const u8) void; +extern fn ___tracy_emit_memory_free_named(ptr: *const anyopaque, secure: c_int, name: [*:0]const u8) void; +extern fn ___tracy_emit_memory_free_callstack_named(ptr: *const anyopaque, depth: c_int, secure: c_int, name: [*:0]const u8) void; +extern fn ___tracy_emit_message(txt: [*]const u8, size: usize, callstack: c_int) void; +extern fn ___tracy_emit_messageL(txt: [*:0]const u8, callstack: c_int) void; +extern fn ___tracy_emit_messageC(txt: [*]const u8, size: usize, color: u32, callstack: c_int) void; +extern fn ___tracy_emit_messageLC(txt: [*:0]const u8, color: u32, callstack: c_int) void; +extern fn ___tracy_emit_frame_mark(name: ?[*:0]const u8) void; + +const ___tracy_source_location_data = extern struct { + name: ?[*:0]const u8, + function: [*:0]const u8, + file: [*:0]const u8, + line: u32, + color: u32, +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend.zig new file mode 100644 index 00000000..04c31c1e --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend.zig @@ -0,0 +1,13 @@ +pub const Interner = @import("backend/Interner.zig"); +pub const Ir = @import("backend/Ir.zig"); +pub const Object = @import("backend/Object.zig"); + +pub const CallingConvention = enum { + C, + stdcall, + thiscall, + vectorcall, +}; + +pub const version_str = "aro-zig"; +pub const version = @import("std").SemanticVersion.parse(version_str) catch unreachable; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Interner.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Interner.zig new file mode 100644 index 00000000..0a910cc9 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Interner.zig @@ -0,0 +1,873 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const BigIntConst = std.math.big.int.Const; +const BigIntMutable = std.math.big.int.Mutable; +const Hash = std.hash.Wyhash; +const Limb = std.math.big.Limb; + +const Interner = @This(); + +map: std.AutoArrayHashMapUnmanaged(void, void) = .empty, +items: std.MultiArrayList(struct { + tag: Tag, + data: u32, +}) = .{}, +extra: std.ArrayListUnmanaged(u32) = .empty, +limbs: std.ArrayListUnmanaged(Limb) = .empty, +strings: std.ArrayListUnmanaged(u8) = .empty, + +const KeyAdapter = struct { + interner: *const Interner, + + pub fn eql(adapter: KeyAdapter, a: Key, b_void: void, b_map_index: usize) bool { + _ = b_void; + return adapter.interner.get(@as(Ref, @enumFromInt(b_map_index))).eql(a); + } + + pub fn hash(adapter: KeyAdapter, a: Key) u32 { + _ = adapter; + return a.hash(); + } +}; + +pub const Key = union(enum) { + int_ty: u16, + float_ty: u16, + complex_ty: u16, + ptr_ty, + noreturn_ty, + void_ty, + func_ty, + array_ty: struct { + len: u64, + child: Ref, + }, + vector_ty: struct { + len: u32, + child: Ref, + }, + record_ty: []const Ref, + /// May not be zero + null, + int: union(enum) { + u64: u64, + i64: i64, + big_int: BigIntConst, + + pub fn toBigInt(repr: @This(), space: *Tag.Int.BigIntSpace) BigIntConst { + return switch (repr) { + .big_int => |x| x, + inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(), + }; + } + }, + float: Float, + complex: Complex, + bytes: []const u8, + + pub const Float = union(enum) { + f16: f16, + f32: f32, + f64: f64, + f80: f80, + f128: f128, + }; + pub const Complex = union(enum) { + cf16: [2]f16, + cf32: [2]f32, + cf64: [2]f64, + cf80: [2]f80, + cf128: [2]f128, + }; + + pub fn hash(key: Key) u32 { + var hasher = Hash.init(0); + const tag = std.meta.activeTag(key); + std.hash.autoHash(&hasher, tag); + switch (key) { + .bytes => |bytes| { + hasher.update(bytes); + }, + .record_ty => |elems| for (elems) |elem| { + std.hash.autoHash(&hasher, elem); + }, + .float => |repr| switch (repr) { + inline else => |data| std.hash.autoHash( + &hasher, + @as(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(data))), @bitCast(data)), + ), + }, + .complex => |repr| switch (repr) { + inline else => |data| std.hash.autoHash( + &hasher, + @as(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(data))), @bitCast(data)), + ), + }, + .int => |repr| { + var space: Tag.Int.BigIntSpace = undefined; + const big = repr.toBigInt(&space); + std.hash.autoHash(&hasher, big.positive); + for (big.limbs) |limb| std.hash.autoHash(&hasher, limb); + }, + inline else => |info| { + std.hash.autoHash(&hasher, info); + }, + } + return @truncate(hasher.final()); + } + + pub fn eql(a: Key, b: Key) bool { + const KeyTag = std.meta.Tag(Key); + const a_tag: KeyTag = a; + const b_tag: KeyTag = b; + if (a_tag != b_tag) return false; + switch (a) { + .record_ty => |a_elems| { + const b_elems = b.record_ty; + if (a_elems.len != b_elems.len) return false; + for (a_elems, b_elems) |a_elem, b_elem| { + if (a_elem != b_elem) return false; + } + return true; + }, + .bytes => |a_bytes| { + const b_bytes = b.bytes; + return std.mem.eql(u8, a_bytes, b_bytes); + }, + .int => |a_repr| { + var a_space: Tag.Int.BigIntSpace = undefined; + const a_big = a_repr.toBigInt(&a_space); + var b_space: Tag.Int.BigIntSpace = undefined; + const b_big = b.int.toBigInt(&b_space); + + return a_big.eql(b_big); + }, + inline else => |a_info, tag| { + const b_info = @field(b, @tagName(tag)); + return std.meta.eql(a_info, b_info); + }, + } + } + + fn toRef(key: Key) ?Ref { + switch (key) { + .int_ty => |bits| switch (bits) { + 1 => return .i1, + 8 => return .i8, + 16 => return .i16, + 32 => return .i32, + 64 => return .i64, + 128 => return .i128, + else => {}, + }, + .float_ty => |bits| switch (bits) { + 16 => return .f16, + 32 => return .f32, + 64 => return .f64, + 80 => return .f80, + 128 => return .f128, + else => unreachable, + }, + .complex_ty => |bits| switch (bits) { + 16 => return .cf16, + 32 => return .cf32, + 64 => return .cf64, + 80 => return .cf80, + 128 => return .cf128, + else => unreachable, + }, + .ptr_ty => return .ptr, + .func_ty => return .func, + .noreturn_ty => return .noreturn, + .void_ty => return .void, + .int => |repr| { + var space: Tag.Int.BigIntSpace = undefined; + const big = repr.toBigInt(&space); + if (big.eqlZero()) return .zero; + const big_one = BigIntConst{ .limbs = &.{1}, .positive = true }; + if (big.eql(big_one)) return .one; + }, + .float => |repr| switch (repr) { + inline else => |data| { + if (std.math.isPositiveZero(data)) return .zero; + if (data == 1) return .one; + }, + }, + .null => return .null, + else => {}, + } + return null; + } +}; + +pub const Ref = enum(u32) { + const max = std.math.maxInt(u32); + + ptr = max - 1, + noreturn = max - 2, + void = max - 3, + i1 = max - 4, + i8 = max - 5, + i16 = max - 6, + i32 = max - 7, + i64 = max - 8, + i128 = max - 9, + f16 = max - 10, + f32 = max - 11, + f64 = max - 12, + f80 = max - 13, + f128 = max - 14, + func = max - 15, + zero = max - 16, + one = max - 17, + null = max - 18, + cf16 = max - 19, + cf32 = max - 20, + cf64 = max - 21, + cf80 = max - 22, + cf128 = max - 23, + _, +}; + +pub const OptRef = enum(u32) { + const max = std.math.maxInt(u32); + + none = max - 0, + ptr = max - 1, + noreturn = max - 2, + void = max - 3, + i1 = max - 4, + i8 = max - 5, + i16 = max - 6, + i32 = max - 7, + i64 = max - 8, + i128 = max - 9, + f16 = max - 10, + f32 = max - 11, + f64 = max - 12, + f80 = max - 13, + f128 = max - 14, + func = max - 15, + zero = max - 16, + one = max - 17, + null = max - 18, + cf16 = max - 19, + cf32 = max - 20, + cf64 = max - 21, + cf80 = max - 22, + cf128 = max - 23, + _, +}; + +pub const Tag = enum(u8) { + /// `data` is `u16` + int_ty, + /// `data` is `u16` + float_ty, + /// `data` is `u16` + complex_ty, + /// `data` is index to `Array` + array_ty, + /// `data` is index to `Vector` + vector_ty, + /// `data` is `u32` + u32, + /// `data` is `i32` + i32, + /// `data` is `Int` + int_positive, + /// `data` is `Int` + int_negative, + /// `data` is `f16` + f16, + /// `data` is `f32` + f32, + /// `data` is `F64` + f64, + /// `data` is `F80` + f80, + /// `data` is `F128` + f128, + /// `data` is `CF16` + cf16, + /// `data` is `CF32` + cf32, + /// `data` is `CF64` + cf64, + /// `data` is `CF80` + cf80, + /// `data` is `CF128` + cf128, + /// `data` is `Bytes` + bytes, + /// `data` is `Record` + record_ty, + + pub const Array = struct { + len0: u32, + len1: u32, + child: Ref, + + pub fn getLen(a: Array) u64 { + return (PackedU64{ + .a = a.len0, + .b = a.len1, + }).get(); + } + }; + + pub const Vector = struct { + len: u32, + child: Ref, + }; + + pub const Int = struct { + limbs_index: u32, + limbs_len: u32, + + /// Big enough to fit any non-BigInt value + pub const BigIntSpace = struct { + /// The +1 is headroom so that operations such as incrementing once + /// or decrementing once are possible without using an allocator. + limbs: [(@sizeOf(u64) / @sizeOf(std.math.big.Limb)) + 1]std.math.big.Limb, + }; + }; + + pub const F64 = struct { + piece0: u32, + piece1: u32, + + pub fn get(self: F64) f64 { + const int_bits = @as(u64, self.piece0) | (@as(u64, self.piece1) << 32); + return @bitCast(int_bits); + } + + fn pack(val: f64) F64 { + const bits = @as(u64, @bitCast(val)); + return .{ + .piece0 = @as(u32, @truncate(bits)), + .piece1 = @as(u32, @truncate(bits >> 32)), + }; + } + }; + + pub const F80 = struct { + piece0: u32, + piece1: u32, + piece2: u32, // u16 part, top bits + + pub fn get(self: F80) f80 { + const int_bits = @as(u80, self.piece0) | + (@as(u80, self.piece1) << 32) | + (@as(u80, self.piece2) << 64); + return @bitCast(int_bits); + } + + fn pack(val: f80) F80 { + const bits = @as(u80, @bitCast(val)); + return .{ + .piece0 = @as(u32, @truncate(bits)), + .piece1 = @as(u32, @truncate(bits >> 32)), + .piece2 = @as(u16, @truncate(bits >> 64)), + }; + } + }; + + pub const F128 = struct { + piece0: u32, + piece1: u32, + piece2: u32, + piece3: u32, + + pub fn get(self: F128) f128 { + const int_bits = @as(u128, self.piece0) | + (@as(u128, self.piece1) << 32) | + (@as(u128, self.piece2) << 64) | + (@as(u128, self.piece3) << 96); + return @bitCast(int_bits); + } + + fn pack(val: f128) F128 { + const bits = @as(u128, @bitCast(val)); + return .{ + .piece0 = @as(u32, @truncate(bits)), + .piece1 = @as(u32, @truncate(bits >> 32)), + .piece2 = @as(u32, @truncate(bits >> 64)), + .piece3 = @as(u32, @truncate(bits >> 96)), + }; + } + }; + + pub const CF16 = struct { + piece0: u32, + + pub fn get(self: CF16) [2]f16 { + const real: f16 = @bitCast(@as(u16, @truncate(self.piece0 >> 16))); + const imag: f16 = @bitCast(@as(u16, @truncate(self.piece0))); + return .{ + real, + imag, + }; + } + + fn pack(val: [2]f16) CF16 { + const real: u16 = @bitCast(val[0]); + const imag: u16 = @bitCast(val[1]); + return .{ + .piece0 = (@as(u32, real) << 16) | @as(u32, imag), + }; + } + }; + + pub const CF32 = struct { + piece0: u32, + piece1: u32, + + pub fn get(self: CF32) [2]f32 { + return .{ + @bitCast(self.piece0), + @bitCast(self.piece1), + }; + } + + fn pack(val: [2]f32) CF32 { + return .{ + .piece0 = @bitCast(val[0]), + .piece1 = @bitCast(val[1]), + }; + } + }; + + pub const CF64 = struct { + piece0: u32, + piece1: u32, + piece2: u32, + piece3: u32, + + pub fn get(self: CF64) [2]f64 { + return .{ + (F64{ .piece0 = self.piece0, .piece1 = self.piece1 }).get(), + (F64{ .piece0 = self.piece2, .piece1 = self.piece3 }).get(), + }; + } + + fn pack(val: [2]f64) CF64 { + const real = F64.pack(val[0]); + const imag = F64.pack(val[1]); + return .{ + .piece0 = real.piece0, + .piece1 = real.piece1, + .piece2 = imag.piece0, + .piece3 = imag.piece1, + }; + } + }; + + /// TODO pack into 5 pieces + pub const CF80 = struct { + piece0: u32, + piece1: u32, + piece2: u32, // u16 part, top bits + piece3: u32, + piece4: u32, + piece5: u32, // u16 part, top bits + + pub fn get(self: CF80) [2]f80 { + return .{ + (F80{ .piece0 = self.piece0, .piece1 = self.piece1, .piece2 = self.piece2 }).get(), + (F80{ .piece0 = self.piece3, .piece1 = self.piece4, .piece2 = self.piece5 }).get(), + }; + } + + fn pack(val: [2]f80) CF80 { + const real = F80.pack(val[0]); + const imag = F80.pack(val[1]); + return .{ + .piece0 = real.piece0, + .piece1 = real.piece1, + .piece2 = real.piece2, + .piece3 = imag.piece0, + .piece4 = imag.piece1, + .piece5 = imag.piece2, + }; + } + }; + + pub const CF128 = struct { + piece0: u32, + piece1: u32, + piece2: u32, + piece3: u32, + piece4: u32, + piece5: u32, + piece6: u32, + piece7: u32, + + pub fn get(self: CF128) [2]f128 { + return .{ + (F128{ .piece0 = self.piece0, .piece1 = self.piece1, .piece2 = self.piece2, .piece3 = self.piece3 }).get(), + (F128{ .piece0 = self.piece4, .piece1 = self.piece5, .piece2 = self.piece6, .piece3 = self.piece7 }).get(), + }; + } + + fn pack(val: [2]f128) CF128 { + const real = F128.pack(val[0]); + const imag = F128.pack(val[1]); + return .{ + .piece0 = real.piece0, + .piece1 = real.piece1, + .piece2 = real.piece2, + .piece3 = real.piece3, + .piece4 = imag.piece0, + .piece5 = imag.piece1, + .piece6 = imag.piece2, + .piece7 = imag.piece3, + }; + } + }; + + pub const Bytes = struct { + strings_index: u32, + len: u32, + }; + + pub const Record = struct { + elements_len: u32, + // trailing + // [elements_len]Ref + }; +}; + +pub const PackedU64 = packed struct(u64) { + a: u32, + b: u32, + + pub fn get(x: PackedU64) u64 { + return @bitCast(x); + } + + pub fn init(x: u64) PackedU64 { + return @bitCast(x); + } +}; + +pub fn deinit(i: *Interner, gpa: Allocator) void { + i.map.deinit(gpa); + i.items.deinit(gpa); + i.extra.deinit(gpa); + i.limbs.deinit(gpa); + i.strings.deinit(gpa); +} + +pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref { + if (key.toRef()) |some| return some; + const adapter: KeyAdapter = .{ .interner = i }; + const gop = try i.map.getOrPutAdapted(gpa, key, adapter); + if (gop.found_existing) return @enumFromInt(gop.index); + try i.items.ensureUnusedCapacity(gpa, 1); + + switch (key) { + .int_ty => |bits| { + i.items.appendAssumeCapacity(.{ + .tag = .int_ty, + .data = bits, + }); + }, + .float_ty => |bits| { + i.items.appendAssumeCapacity(.{ + .tag = .float_ty, + .data = bits, + }); + }, + .complex_ty => |bits| { + i.items.appendAssumeCapacity(.{ + .tag = .complex_ty, + .data = bits, + }); + }, + .array_ty => |info| { + const split_len = PackedU64.init(info.len); + i.items.appendAssumeCapacity(.{ + .tag = .array_ty, + .data = try i.addExtra(gpa, Tag.Array{ + .len0 = split_len.a, + .len1 = split_len.b, + .child = info.child, + }), + }); + }, + .vector_ty => |info| { + i.items.appendAssumeCapacity(.{ + .tag = .vector_ty, + .data = try i.addExtra(gpa, Tag.Vector{ + .len = info.len, + .child = info.child, + }), + }); + }, + .int => |repr| int: { + var space: Tag.Int.BigIntSpace = undefined; + const big = repr.toBigInt(&space); + switch (repr) { + .u64 => |data| if (std.math.cast(u32, data)) |small| { + i.items.appendAssumeCapacity(.{ + .tag = .u32, + .data = small, + }); + break :int; + }, + .i64 => |data| if (std.math.cast(i32, data)) |small| { + i.items.appendAssumeCapacity(.{ + .tag = .i32, + .data = @bitCast(small), + }); + break :int; + }, + .big_int => |data| { + if (data.fitsInTwosComp(.unsigned, 32)) { + i.items.appendAssumeCapacity(.{ + .tag = .u32, + .data = data.toInt(u32) catch unreachable, + }); + break :int; + } else if (data.fitsInTwosComp(.signed, 32)) { + i.items.appendAssumeCapacity(.{ + .tag = .i32, + .data = @bitCast(data.toInt(i32) catch unreachable), + }); + break :int; + } + }, + } + const limbs_index: u32 = @intCast(i.limbs.items.len); + try i.limbs.appendSlice(gpa, big.limbs); + i.items.appendAssumeCapacity(.{ + .tag = if (big.positive) .int_positive else .int_negative, + .data = try i.addExtra(gpa, Tag.Int{ + .limbs_index = limbs_index, + .limbs_len = @intCast(big.limbs.len), + }), + }); + }, + .float => |repr| switch (repr) { + .f16 => |data| i.items.appendAssumeCapacity(.{ + .tag = .f16, + .data = @as(u16, @bitCast(data)), + }), + .f32 => |data| i.items.appendAssumeCapacity(.{ + .tag = .f32, + .data = @as(u32, @bitCast(data)), + }), + .f64 => |data| i.items.appendAssumeCapacity(.{ + .tag = .f64, + .data = try i.addExtra(gpa, Tag.F64.pack(data)), + }), + .f80 => |data| i.items.appendAssumeCapacity(.{ + .tag = .f80, + .data = try i.addExtra(gpa, Tag.F80.pack(data)), + }), + .f128 => |data| i.items.appendAssumeCapacity(.{ + .tag = .f128, + .data = try i.addExtra(gpa, Tag.F128.pack(data)), + }), + }, + .complex => |repr| switch (repr) { + .cf16 => |data| i.items.appendAssumeCapacity(.{ + .tag = .cf16, + .data = try i.addExtra(gpa, Tag.CF16.pack(data)), + }), + .cf32 => |data| i.items.appendAssumeCapacity(.{ + .tag = .cf32, + .data = try i.addExtra(gpa, Tag.CF32.pack(data)), + }), + .cf64 => |data| i.items.appendAssumeCapacity(.{ + .tag = .cf64, + .data = try i.addExtra(gpa, Tag.CF64.pack(data)), + }), + .cf80 => |data| i.items.appendAssumeCapacity(.{ + .tag = .cf80, + .data = try i.addExtra(gpa, Tag.CF80.pack(data)), + }), + .cf128 => |data| i.items.appendAssumeCapacity(.{ + .tag = .cf128, + .data = try i.addExtra(gpa, Tag.CF128.pack(data)), + }), + }, + .bytes => |bytes| { + const strings_index: u32 = @intCast(i.strings.items.len); + try i.strings.appendSlice(gpa, bytes); + i.items.appendAssumeCapacity(.{ + .tag = .bytes, + .data = try i.addExtra(gpa, Tag.Bytes{ + .strings_index = strings_index, + .len = @intCast(bytes.len), + }), + }); + }, + .record_ty => |elems| { + try i.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.Record).@"struct".fields.len + + elems.len); + i.items.appendAssumeCapacity(.{ + .tag = .record_ty, + .data = i.addExtraAssumeCapacity(Tag.Record{ + .elements_len = @intCast(elems.len), + }), + }); + i.extra.appendSliceAssumeCapacity(@ptrCast(elems)); + }, + .ptr_ty, + .noreturn_ty, + .void_ty, + .func_ty, + .null, + => unreachable, + } + + return @enumFromInt(gop.index); +} + +fn addExtra(i: *Interner, gpa: Allocator, extra: anytype) Allocator.Error!u32 { + const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; + try i.extra.ensureUnusedCapacity(gpa, fields.len); + return i.addExtraAssumeCapacity(extra); +} + +fn addExtraAssumeCapacity(i: *Interner, extra: anytype) u32 { + const result = @as(u32, @intCast(i.extra.items.len)); + inline for (@typeInfo(@TypeOf(extra)).@"struct".fields) |field| { + i.extra.appendAssumeCapacity(switch (field.type) { + Ref => @intFromEnum(@field(extra, field.name)), + u32 => @field(extra, field.name), + else => @compileError("bad field type: " ++ @typeName(field.type)), + }); + } + return result; +} + +pub fn get(i: *const Interner, ref: Ref) Key { + switch (ref) { + .ptr => return .ptr_ty, + .func => return .func_ty, + .noreturn => return .noreturn_ty, + .void => return .void_ty, + .i1 => return .{ .int_ty = 1 }, + .i8 => return .{ .int_ty = 8 }, + .i16 => return .{ .int_ty = 16 }, + .i32 => return .{ .int_ty = 32 }, + .i64 => return .{ .int_ty = 64 }, + .i128 => return .{ .int_ty = 128 }, + .f16 => return .{ .float_ty = 16 }, + .f32 => return .{ .float_ty = 32 }, + .f64 => return .{ .float_ty = 64 }, + .f80 => return .{ .float_ty = 80 }, + .f128 => return .{ .float_ty = 128 }, + .zero => return .{ .int = .{ .u64 = 0 } }, + .one => return .{ .int = .{ .u64 = 1 } }, + .null => return .null, + .cf16 => return .{ .complex_ty = 16 }, + .cf32 => return .{ .complex_ty = 32 }, + .cf64 => return .{ .complex_ty = 64 }, + .cf80 => return .{ .complex_ty = 80 }, + else => {}, + } + + const item = i.items.get(@intFromEnum(ref)); + const data = item.data; + return switch (item.tag) { + .int_ty => .{ .int_ty = @intCast(data) }, + .float_ty => .{ .float_ty = @intCast(data) }, + .complex_ty => .{ .complex_ty = @intCast(data) }, + .array_ty => { + const array_ty = i.extraData(Tag.Array, data); + return .{ .array_ty = .{ + .len = array_ty.getLen(), + .child = array_ty.child, + } }; + }, + .vector_ty => { + const vector_ty = i.extraData(Tag.Vector, data); + return .{ .vector_ty = .{ + .len = vector_ty.len, + .child = vector_ty.child, + } }; + }, + .u32 => .{ .int = .{ .u64 = data } }, + .i32 => .{ .int = .{ .i64 = @as(i32, @bitCast(data)) } }, + .int_positive, .int_negative => { + const int_info = i.extraData(Tag.Int, data); + const limbs = i.limbs.items[int_info.limbs_index..][0..int_info.limbs_len]; + return .{ .int = .{ + .big_int = .{ + .positive = item.tag == .int_positive, + .limbs = limbs, + }, + } }; + }, + .f16 => .{ .float = .{ .f16 = @bitCast(@as(u16, @intCast(data))) } }, + .f32 => .{ .float = .{ .f32 = @bitCast(data) } }, + .f64 => { + const float = i.extraData(Tag.F64, data); + return .{ .float = .{ .f64 = float.get() } }; + }, + .f80 => { + const float = i.extraData(Tag.F80, data); + return .{ .float = .{ .f80 = float.get() } }; + }, + .f128 => { + const float = i.extraData(Tag.F128, data); + return .{ .float = .{ .f128 = float.get() } }; + }, + .cf16 => { + const components = i.extraData(Tag.CF16, data); + return .{ .complex = .{ .cf16 = components.get() } }; + }, + .cf32 => { + const components = i.extraData(Tag.CF32, data); + return .{ .complex = .{ .cf32 = components.get() } }; + }, + .cf64 => { + const components = i.extraData(Tag.CF64, data); + return .{ .complex = .{ .cf64 = components.get() } }; + }, + .cf80 => { + const components = i.extraData(Tag.CF80, data); + return .{ .complex = .{ .cf80 = components.get() } }; + }, + .cf128 => { + const components = i.extraData(Tag.CF128, data); + return .{ .complex = .{ .cf128 = components.get() } }; + }, + .bytes => { + const bytes = i.extraData(Tag.Bytes, data); + return .{ .bytes = i.strings.items[bytes.strings_index..][0..bytes.len] }; + }, + .record_ty => { + const extra = i.extraDataTrail(Tag.Record, data); + return .{ + .record_ty = @ptrCast(i.extra.items[extra.end..][0..extra.data.elements_len]), + }; + }, + }; +} + +fn extraData(i: *const Interner, comptime T: type, index: usize) T { + return i.extraDataTrail(T, index).data; +} + +fn extraDataTrail(i: *const Interner, comptime T: type, index: usize) struct { data: T, end: u32 } { + var result: T = undefined; + const fields = @typeInfo(T).@"struct".fields; + inline for (fields, 0..) |field, field_i| { + const int32 = i.extra.items[field_i + index]; + @field(result, field.name) = switch (field.type) { + Ref => @enumFromInt(int32), + u32 => int32, + else => @compileError("bad field type: " ++ @typeName(field.type)), + }; + } + return .{ + .data = result, + .end = @intCast(index + fields.len), + }; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Ir.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Ir.zig new file mode 100644 index 00000000..e90bf56c --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Ir.zig @@ -0,0 +1,697 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const Interner = @import("Interner.zig"); +const Object = @import("Object.zig"); + +const Ir = @This(); + +interner: *Interner, +decls: std.StringArrayHashMapUnmanaged(Decl), + +pub const Decl = struct { + instructions: std.MultiArrayList(Inst), + body: std.ArrayListUnmanaged(Ref), + arena: std.heap.ArenaAllocator.State, + + pub fn deinit(decl: *Decl, gpa: Allocator) void { + decl.instructions.deinit(gpa); + decl.body.deinit(gpa); + decl.arena.promote(gpa).deinit(); + } +}; + +pub const Builder = struct { + gpa: Allocator, + arena: std.heap.ArenaAllocator, + interner: *Interner, + + decls: std.StringArrayHashMapUnmanaged(Decl) = .empty, + instructions: std.MultiArrayList(Ir.Inst) = .{}, + body: std.ArrayListUnmanaged(Ref) = .empty, + alloc_count: u32 = 0, + arg_count: u32 = 0, + current_label: Ref = undefined, + + pub fn deinit(b: *Builder) void { + for (b.decls.values()) |*decl| { + decl.deinit(b.gpa); + } + b.decls.deinit(b.gpa); + b.arena.deinit(); + b.instructions.deinit(b.gpa); + b.body.deinit(b.gpa); + b.* = undefined; + } + + pub fn finish(b: *Builder) Ir { + return .{ + .interner = b.interner, + .decls = b.decls.move(), + }; + } + + pub fn startFn(b: *Builder) Allocator.Error!void { + const entry = try b.makeLabel("entry"); + try b.body.append(b.gpa, entry); + b.current_label = entry; + } + + pub fn finishFn(b: *Builder, name: []const u8) !void { + var duped_instructions = try b.instructions.clone(b.gpa); + errdefer duped_instructions.deinit(b.gpa); + var duped_body = try b.body.clone(b.gpa); + errdefer duped_body.deinit(b.gpa); + + try b.decls.put(b.gpa, name, .{ + .instructions = duped_instructions, + .body = duped_body, + .arena = b.arena.state, + }); + b.instructions.shrinkRetainingCapacity(0); + b.body.shrinkRetainingCapacity(0); + b.arena = std.heap.ArenaAllocator.init(b.gpa); + b.alloc_count = 0; + b.arg_count = 0; + } + + pub fn startBlock(b: *Builder, label: Ref) !void { + try b.body.append(b.gpa, label); + b.current_label = label; + } + + pub fn addArg(b: *Builder, ty: Interner.Ref) Allocator.Error!Ref { + const ref: Ref = @enumFromInt(b.instructions.len); + try b.instructions.append(b.gpa, .{ .tag = .arg, .data = .{ .none = {} }, .ty = ty }); + try b.body.insert(b.gpa, b.arg_count, ref); + b.arg_count += 1; + return ref; + } + + pub fn addAlloc(b: *Builder, size: u32, @"align": u32) Allocator.Error!Ref { + const ref: Ref = @enumFromInt(b.instructions.len); + try b.instructions.append(b.gpa, .{ + .tag = .alloc, + .data = .{ .alloc = .{ .size = size, .@"align" = @"align" } }, + .ty = .ptr, + }); + try b.body.insert(b.gpa, b.alloc_count + b.arg_count + 1, ref); + b.alloc_count += 1; + return ref; + } + + pub fn addInst(b: *Builder, tag: Ir.Inst.Tag, data: Ir.Inst.Data, ty: Interner.Ref) Allocator.Error!Ref { + const ref: Ref = @enumFromInt(b.instructions.len); + try b.instructions.append(b.gpa, .{ .tag = tag, .data = data, .ty = ty }); + try b.body.append(b.gpa, ref); + return ref; + } + + pub fn makeLabel(b: *Builder, name: [*:0]const u8) Allocator.Error!Ref { + const ref: Ref = @enumFromInt(b.instructions.len); + try b.instructions.append(b.gpa, .{ .tag = .label, .data = .{ .label = name }, .ty = .void }); + return ref; + } + + pub fn addJump(b: *Builder, label: Ref) Allocator.Error!void { + _ = try b.addInst(.jmp, .{ .un = label }, .noreturn); + } + + pub fn addBranch(b: *Builder, cond: Ref, true_label: Ref, false_label: Ref) Allocator.Error!void { + const branch = try b.arena.allocator().create(Ir.Inst.Branch); + branch.* = .{ + .cond = cond, + .then = true_label, + .@"else" = false_label, + }; + _ = try b.addInst(.branch, .{ .branch = branch }, .noreturn); + } + + pub fn addSwitch(b: *Builder, target: Ref, values: []Interner.Ref, labels: []Ref, default: Ref) Allocator.Error!void { + assert(values.len == labels.len); + const a = b.arena.allocator(); + const @"switch" = try a.create(Ir.Inst.Switch); + @"switch".* = .{ + .target = target, + .cases_len = @intCast(values.len), + .case_vals = (try a.dupe(Interner.Ref, values)).ptr, + .case_labels = (try a.dupe(Ref, labels)).ptr, + .default = default, + }; + _ = try b.addInst(.@"switch", .{ .@"switch" = @"switch" }, .noreturn); + } + + pub fn addStore(b: *Builder, ptr: Ref, val: Ref) Allocator.Error!void { + _ = try b.addInst(.store, .{ .bin = .{ .lhs = ptr, .rhs = val } }, .void); + } + + pub fn addConstant(b: *Builder, val: Interner.Ref, ty: Interner.Ref) Allocator.Error!Ref { + const ref: Ref = @enumFromInt(b.instructions.len); + try b.instructions.append(b.gpa, .{ + .tag = .constant, + .data = .{ .constant = val }, + .ty = ty, + }); + return ref; + } + + pub fn addPhi(b: *Builder, inputs: []const Inst.Phi.Input, ty: Interner.Ref) Allocator.Error!Ref { + const a = b.arena.allocator(); + const input_refs = try a.alloc(Ref, inputs.len * 2 + 1); + input_refs[0] = @enumFromInt(inputs.len); + @memcpy(input_refs[1..], std.mem.bytesAsSlice(Ref, std.mem.sliceAsBytes(inputs))); + + return b.addInst(.phi, .{ .phi = .{ .ptr = input_refs.ptr } }, ty); + } + + pub fn addSelect(b: *Builder, cond: Ref, then: Ref, @"else": Ref, ty: Interner.Ref) Allocator.Error!Ref { + const branch = try b.arena.allocator().create(Ir.Inst.Branch); + branch.* = .{ + .cond = cond, + .then = then, + .@"else" = @"else", + }; + return b.addInst(.select, .{ .branch = branch }, ty); + } +}; + +pub const Renderer = struct { + gpa: Allocator, + obj: *Object, + ir: *const Ir, + errors: ErrorList = .{}, + + pub const ErrorList = std.StringArrayHashMapUnmanaged([]const u8); + + pub const Error = Allocator.Error || error{LowerFail}; + + pub fn deinit(r: *Renderer) void { + for (r.errors.values()) |msg| r.gpa.free(msg); + r.errors.deinit(r.gpa); + } + + pub fn render(r: *Renderer) !void { + switch (r.obj.target.cpu.arch) { + .x86, .x86_64 => return @import("Ir/x86/Renderer.zig").render(r), + else => unreachable, + } + } + + pub fn fail( + r: *Renderer, + name: []const u8, + comptime format: []const u8, + args: anytype, + ) Error { + try r.errors.ensureUnusedCapacity(r.gpa, 1); + r.errors.putAssumeCapacity(name, try std.fmt.allocPrint(r.gpa, format, args)); + return error.LowerFail; + } +}; + +pub fn render( + ir: *const Ir, + gpa: Allocator, + target: std.Target, + errors: ?*Renderer.ErrorList, +) !*Object { + const obj = try Object.create(gpa, target); + errdefer obj.deinit(); + + var renderer: Renderer = .{ + .gpa = gpa, + .obj = obj, + .ir = ir, + }; + defer { + if (errors) |some| { + some.* = renderer.errors.move(); + } + renderer.deinit(); + } + + try renderer.render(); + return obj; +} + +pub const Ref = enum(u32) { none = std.math.maxInt(u32), _ }; + +pub const Inst = struct { + tag: Tag, + data: Data, + ty: Interner.Ref, + + pub const Tag = enum { + // data.constant + // not included in blocks + constant, + + // data.arg + // not included in blocks + arg, + symbol, + + // data.label + label, + + // data.block + label_addr, + jmp, + + // data.switch + @"switch", + + // data.branch + branch, + select, + + // data.un + jmp_val, + + // data.call + call, + + // data.alloc + alloc, + + // data.phi + phi, + + // data.bin + store, + bit_or, + bit_xor, + bit_and, + bit_shl, + bit_shr, + cmp_eq, + cmp_ne, + cmp_lt, + cmp_lte, + cmp_gt, + cmp_gte, + add, + sub, + mul, + div, + mod, + + // data.un + ret, + load, + bit_not, + negate, + trunc, + zext, + sext, + }; + + pub const Data = union { + constant: Interner.Ref, + none: void, + bin: struct { + lhs: Ref, + rhs: Ref, + }, + un: Ref, + arg: u32, + alloc: struct { + size: u32, + @"align": u32, + }, + @"switch": *Switch, + call: *Call, + label: [*:0]const u8, + branch: *Branch, + phi: Phi, + }; + + pub const Branch = struct { + cond: Ref, + then: Ref, + @"else": Ref, + }; + + pub const Switch = struct { + target: Ref, + cases_len: u32, + default: Ref, + case_vals: [*]Interner.Ref, + case_labels: [*]Ref, + }; + + pub const Call = struct { + func: Ref, + args_len: u32, + args_ptr: [*]Ref, + + pub fn args(c: Call) []Ref { + return c.args_ptr[0..c.args_len]; + } + }; + + pub const Phi = struct { + ptr: [*]Ir.Ref, + + pub const Input = struct { + label: Ir.Ref, + value: Ir.Ref, + }; + + pub fn inputs(p: Phi) []Input { + const len = @intFromEnum(p.ptr[0]) * 2; + const slice = (p.ptr + 1)[0..len]; + return std.mem.bytesAsSlice(Input, std.mem.sliceAsBytes(slice)); + } + }; +}; + +pub fn deinit(ir: *Ir, gpa: std.mem.Allocator) void { + for (ir.decls.values()) |*decl| { + decl.deinit(gpa); + } + ir.decls.deinit(gpa); + ir.* = undefined; +} + +const TYPE = std.io.tty.Color.bright_magenta; +const INST = std.io.tty.Color.bright_cyan; +const REF = std.io.tty.Color.bright_blue; +const LITERAL = std.io.tty.Color.bright_green; +const ATTRIBUTE = std.io.tty.Color.bright_yellow; + +const RefMap = std.AutoArrayHashMap(Ref, void); + +pub fn dump(ir: *const Ir, gpa: Allocator, config: std.io.tty.Config, w: anytype) !void { + for (ir.decls.keys(), ir.decls.values()) |name, *decl| { + try ir.dumpDecl(decl, gpa, name, config, w); + } +} + +fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8, config: std.io.tty.Config, w: anytype) !void { + const tags = decl.instructions.items(.tag); + const data = decl.instructions.items(.data); + + var ref_map = RefMap.init(gpa); + defer ref_map.deinit(); + + var label_map = RefMap.init(gpa); + defer label_map.deinit(); + + const ret_inst = decl.body.items[decl.body.items.len - 1]; + const ret_operand = data[@intFromEnum(ret_inst)].un; + const ret_ty = decl.instructions.items(.ty)[@intFromEnum(ret_operand)]; + try ir.writeType(ret_ty, config, w); + try config.setColor(w, REF); + try w.print(" @{s}", .{name}); + try config.setColor(w, .reset); + try w.writeAll("("); + + var arg_count: u32 = 0; + while (true) : (arg_count += 1) { + const ref = decl.body.items[arg_count]; + if (tags[@intFromEnum(ref)] != .arg) break; + if (arg_count != 0) try w.writeAll(", "); + try ref_map.put(ref, {}); + try ir.writeRef(decl, &ref_map, ref, config, w); + try config.setColor(w, .reset); + } + try w.writeAll(") {\n"); + for (decl.body.items[arg_count..]) |ref| { + switch (tags[@intFromEnum(ref)]) { + .label => try label_map.put(ref, {}), + else => {}, + } + } + + for (decl.body.items[arg_count..]) |ref| { + const i = @intFromEnum(ref); + const tag = tags[i]; + switch (tag) { + .arg, .constant, .symbol => unreachable, + .label => { + const label_index = label_map.getIndex(ref).?; + try config.setColor(w, REF); + try w.print("{s}.{d}:\n", .{ data[i].label, label_index }); + }, + // .label_val => { + // const un = data[i].un; + // try w.print(" %{d} = label.{d}\n", .{ i, @intFromEnum(un) }); + // }, + .jmp => { + const un = data[i].un; + try config.setColor(w, INST); + try w.writeAll(" jmp "); + try writeLabel(decl, &label_map, un, config, w); + try w.writeByte('\n'); + }, + .branch => { + const br = data[i].branch; + try config.setColor(w, INST); + try w.writeAll(" branch "); + try ir.writeRef(decl, &ref_map, br.cond, config, w); + try config.setColor(w, .reset); + try w.writeAll(", "); + try writeLabel(decl, &label_map, br.then, config, w); + try config.setColor(w, .reset); + try w.writeAll(", "); + try writeLabel(decl, &label_map, br.@"else", config, w); + try w.writeByte('\n'); + }, + .select => { + const br = data[i].branch; + try ir.writeNewRef(decl, &ref_map, ref, config, w); + try w.writeAll("select "); + try ir.writeRef(decl, &ref_map, br.cond, config, w); + try config.setColor(w, .reset); + try w.writeAll(", "); + try ir.writeRef(decl, &ref_map, br.then, config, w); + try config.setColor(w, .reset); + try w.writeAll(", "); + try ir.writeRef(decl, &ref_map, br.@"else", config, w); + try w.writeByte('\n'); + }, + // .jmp_val => { + // const bin = data[i].bin; + // try w.print(" %{s} %{d} label.{d}\n", .{ @tagName(tag), @intFromEnum(bin.lhs), @intFromEnum(bin.rhs) }); + // }, + .@"switch" => { + const @"switch" = data[i].@"switch"; + try config.setColor(w, INST); + try w.writeAll(" switch "); + try ir.writeRef(decl, &ref_map, @"switch".target, config, w); + try config.setColor(w, .reset); + try w.writeAll(" {"); + for (@"switch".case_vals[0..@"switch".cases_len], @"switch".case_labels) |val_ref, label_ref| { + try w.writeAll("\n "); + try ir.writeValue(val_ref, config, w); + try config.setColor(w, .reset); + try w.writeAll(" => "); + try writeLabel(decl, &label_map, label_ref, config, w); + try config.setColor(w, .reset); + } + try config.setColor(w, LITERAL); + try w.writeAll("\n default "); + try config.setColor(w, .reset); + try w.writeAll("=> "); + try writeLabel(decl, &label_map, @"switch".default, config, w); + try config.setColor(w, .reset); + try w.writeAll("\n }\n"); + }, + .call => { + const call = data[i].call; + try ir.writeNewRef(decl, &ref_map, ref, config, w); + try w.writeAll("call "); + try ir.writeRef(decl, &ref_map, call.func, config, w); + try config.setColor(w, .reset); + try w.writeAll("("); + for (call.args(), 0..) |arg, arg_i| { + if (arg_i != 0) try w.writeAll(", "); + try ir.writeRef(decl, &ref_map, arg, config, w); + try config.setColor(w, .reset); + } + try w.writeAll(")\n"); + }, + .alloc => { + const alloc = data[i].alloc; + try ir.writeNewRef(decl, &ref_map, ref, config, w); + try w.writeAll("alloc "); + try config.setColor(w, ATTRIBUTE); + try w.writeAll("size "); + try config.setColor(w, LITERAL); + try w.print("{d}", .{alloc.size}); + try config.setColor(w, ATTRIBUTE); + try w.writeAll(" align "); + try config.setColor(w, LITERAL); + try w.print("{d}", .{alloc.@"align"}); + try w.writeByte('\n'); + }, + .phi => { + try ir.writeNewRef(decl, &ref_map, ref, config, w); + try w.writeAll("phi"); + try config.setColor(w, .reset); + try w.writeAll(" {"); + for (data[i].phi.inputs()) |input| { + try w.writeAll("\n "); + try writeLabel(decl, &label_map, input.label, config, w); + try config.setColor(w, .reset); + try w.writeAll(" => "); + try ir.writeRef(decl, &ref_map, input.value, config, w); + try config.setColor(w, .reset); + } + try config.setColor(w, .reset); + try w.writeAll("\n }\n"); + }, + .store => { + const bin = data[i].bin; + try config.setColor(w, INST); + try w.writeAll(" store "); + try ir.writeRef(decl, &ref_map, bin.lhs, config, w); + try config.setColor(w, .reset); + try w.writeAll(", "); + try ir.writeRef(decl, &ref_map, bin.rhs, config, w); + try w.writeByte('\n'); + }, + .ret => { + try config.setColor(w, INST); + try w.writeAll(" ret "); + if (data[i].un != .none) try ir.writeRef(decl, &ref_map, data[i].un, config, w); + try w.writeByte('\n'); + }, + .load => { + try ir.writeNewRef(decl, &ref_map, ref, config, w); + try w.writeAll("load "); + try ir.writeRef(decl, &ref_map, data[i].un, config, w); + try w.writeByte('\n'); + }, + .bit_or, + .bit_xor, + .bit_and, + .bit_shl, + .bit_shr, + .cmp_eq, + .cmp_ne, + .cmp_lt, + .cmp_lte, + .cmp_gt, + .cmp_gte, + .add, + .sub, + .mul, + .div, + .mod, + => { + const bin = data[i].bin; + try ir.writeNewRef(decl, &ref_map, ref, config, w); + try w.print("{s} ", .{@tagName(tag)}); + try ir.writeRef(decl, &ref_map, bin.lhs, config, w); + try config.setColor(w, .reset); + try w.writeAll(", "); + try ir.writeRef(decl, &ref_map, bin.rhs, config, w); + try w.writeByte('\n'); + }, + .bit_not, + .negate, + .trunc, + .zext, + .sext, + => { + const un = data[i].un; + try ir.writeNewRef(decl, &ref_map, ref, config, w); + try w.print("{s} ", .{@tagName(tag)}); + try ir.writeRef(decl, &ref_map, un, config, w); + try w.writeByte('\n'); + }, + .label_addr, .jmp_val => {}, + } + } + try config.setColor(w, .reset); + try w.writeAll("}\n\n"); +} + +fn writeType(ir: Ir, ty_ref: Interner.Ref, config: std.io.tty.Config, w: anytype) !void { + const ty = ir.interner.get(ty_ref); + try config.setColor(w, TYPE); + switch (ty) { + .ptr_ty, .noreturn_ty, .void_ty, .func_ty => try w.writeAll(@tagName(ty)), + .int_ty => |bits| try w.print("i{d}", .{bits}), + .float_ty => |bits| try w.print("f{d}", .{bits}), + .array_ty => |info| { + try w.print("[{d} * ", .{info.len}); + try ir.writeType(info.child, .no_color, w); + try w.writeByte(']'); + }, + .vector_ty => |info| { + try w.print("<{d} * ", .{info.len}); + try ir.writeType(info.child, .no_color, w); + try w.writeByte('>'); + }, + .record_ty => |elems| { + // TODO collect into buffer and only print once + try w.writeAll("{ "); + for (elems, 0..) |elem, i| { + if (i != 0) try w.writeAll(", "); + try ir.writeType(elem, config, w); + } + try w.writeAll(" }"); + }, + else => unreachable, // not a type + } +} + +fn writeValue(ir: Ir, val: Interner.Ref, config: std.io.tty.Config, w: anytype) !void { + try config.setColor(w, LITERAL); + const key = ir.interner.get(val); + switch (key) { + .null => return w.writeAll("nullptr_t"), + .int => |repr| switch (repr) { + inline else => |x| return w.print("{d}", .{x}), + }, + .float => |repr| switch (repr) { + inline else => |x| return w.print("{d}", .{@as(f64, @floatCast(x))}), + }, + .bytes => |b| return std.zig.stringEscape(b, "", .{}, w), + else => unreachable, // not a value + } +} + +fn writeRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void { + assert(ref != .none); + const index = @intFromEnum(ref); + const ty_ref = decl.instructions.items(.ty)[index]; + if (decl.instructions.items(.tag)[index] == .constant) { + try ir.writeType(ty_ref, config, w); + const v_ref = decl.instructions.items(.data)[index].constant; + try w.writeByte(' '); + try ir.writeValue(v_ref, config, w); + return; + } else if (decl.instructions.items(.tag)[index] == .symbol) { + const name = decl.instructions.items(.data)[index].label; + try ir.writeType(ty_ref, config, w); + try config.setColor(w, REF); + try w.print(" @{s}", .{name}); + return; + } + try ir.writeType(ty_ref, config, w); + try config.setColor(w, REF); + const ref_index = ref_map.getIndex(ref).?; + try w.print(" %{d}", .{ref_index}); +} + +fn writeNewRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void { + try ref_map.put(ref, {}); + try w.writeAll(" "); + try ir.writeRef(decl, ref_map, ref, config, w); + try config.setColor(w, .reset); + try w.writeAll(" = "); + try config.setColor(w, INST); +} + +fn writeLabel(decl: *const Decl, label_map: *RefMap, ref: Ref, config: std.io.tty.Config, w: anytype) !void { + assert(ref != .none); + const index = @intFromEnum(ref); + const label = decl.instructions.items(.data)[index].label; + try config.setColor(w, REF); + const label_index = label_map.getIndex(ref).?; + try w.print("{s}.{d}", .{ label, label_index }); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Ir/x86/Renderer.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Ir/x86/Renderer.zig new file mode 100644 index 00000000..0726e638 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Ir/x86/Renderer.zig @@ -0,0 +1,65 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const Interner = @import("../../Interner.zig"); +const Ir = @import("../../Ir.zig"); +const BaseRenderer = Ir.Renderer; +const zig = @import("zig"); +const abi = zig.arch.x86_64.abi; +const bits = zig.arch.x86_64.bits; + +const Condition = bits.Condition; +const Immediate = bits.Immediate; +const Memory = bits.Memory; +const Register = bits.Register; +const RegisterLock = RegisterManager.RegisterLock; +const FrameIndex = bits.FrameIndex; + +const RegisterManager = zig.RegisterManager(Renderer, Register, Ir.Ref, abi.allocatable_regs); + +// Register classes +const RegisterBitSet = RegisterManager.RegisterBitSet; +const RegisterClass = struct { + const gp: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index); + break :blk set; + }; + const x87: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index); + break :blk set; + }; + const sse: RegisterBitSet = blk: { + var set = RegisterBitSet.initEmpty(); + for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index); + break :blk set; + }; +}; + +const Renderer = @This(); + +base: *BaseRenderer, +interner: *Interner, + +register_manager: RegisterManager = .{}, + +pub fn render(base: *BaseRenderer) !void { + var renderer: Renderer = .{ + .base = base, + .interner = base.ir.interner, + }; + + for (renderer.base.ir.decls.keys(), renderer.base.ir.decls.values()) |name, decl| { + renderer.renderFn(name, decl) catch |e| switch (e) { + error.OutOfMemory => return e, + error.LowerFail => continue, + }; + } + if (renderer.base.errors.entries.len != 0) return error.LowerFail; +} + +fn renderFn(r: *Renderer, name: []const u8, decl: Ir.Decl) !void { + _ = decl; + return r.base.fail(name, "TODO implement lowering functions", .{}); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Object.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Object.zig new file mode 100644 index 00000000..98355e88 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Object.zig @@ -0,0 +1,73 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const Elf = @import("Object/Elf.zig"); + +const Object = @This(); + +format: std.Target.ObjectFormat, +target: std.Target, + +pub fn create(gpa: Allocator, target: std.Target) !*Object { + switch (target.ofmt) { + .elf => return Elf.create(gpa, target), + else => unreachable, + } +} + +pub fn deinit(obj: *Object) void { + switch (obj.format) { + .elf => @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).deinit(), + else => unreachable, + } +} + +pub const Section = union(enum) { + undefined, + data, + read_only_data, + func, + strings, + custom: []const u8, +}; + +pub fn getSection(obj: *Object, section: Section) !*std.ArrayList(u8) { + switch (obj.format) { + .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).getSection(section), + else => unreachable, + } +} + +pub const SymbolType = enum { + func, + variable, + external, +}; + +pub fn declareSymbol( + obj: *Object, + section: Section, + name: ?[]const u8, + linkage: std.builtin.GlobalLinkage, + @"type": SymbolType, + offset: u64, + size: u64, +) ![]const u8 { + switch (obj.format) { + .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).declareSymbol(section, name, linkage, @"type", offset, size), + else => unreachable, + } +} + +pub fn addRelocation(obj: *Object, name: []const u8, section: Section, address: u64, addend: i64) !void { + switch (obj.format) { + .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).addRelocation(name, section, address, addend), + else => unreachable, + } +} + +pub fn finish(obj: *Object, file: std.fs.File) !void { + switch (obj.format) { + .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).finish(file), + else => unreachable, + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Object/Elf.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Object/Elf.zig new file mode 100644 index 00000000..9b4f347d --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro/backend/Object/Elf.zig @@ -0,0 +1,378 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const Target = std.Target; +const Object = @import("../Object.zig"); + +const Section = struct { + data: std.ArrayList(u8), + relocations: std.ArrayListUnmanaged(Relocation) = .empty, + flags: u64, + type: u32, + index: u16 = undefined, +}; + +const Symbol = struct { + section: ?*Section, + size: u64, + offset: u64, + index: u16 = undefined, + info: u8, +}; + +const Relocation = struct { + symbol: *Symbol, + addend: i64, + offset: u48, + type: u8, +}; + +const additional_sections = 3; // null section, strtab, symtab +const strtab_index = 1; +const symtab_index = 2; +const strtab_default = "\x00.strtab\x00.symtab\x00"; +const strtab_name = 1; +const symtab_name = "\x00.strtab\x00".len; + +const Elf = @This(); + +obj: Object, +/// The keys are owned by the Codegen.tree +sections: std.StringHashMapUnmanaged(*Section) = .empty, +local_symbols: std.StringHashMapUnmanaged(*Symbol) = .empty, +global_symbols: std.StringHashMapUnmanaged(*Symbol) = .empty, +unnamed_symbol_mangle: u32 = 0, +strtab_len: u64 = strtab_default.len, +arena: std.heap.ArenaAllocator, + +pub fn create(gpa: Allocator, target: Target) !*Object { + const elf = try gpa.create(Elf); + elf.* = .{ + .obj = .{ .format = .elf, .target = target }, + .arena = std.heap.ArenaAllocator.init(gpa), + }; + return &elf.obj; +} + +pub fn deinit(elf: *Elf) void { + const gpa = elf.arena.child_allocator; + { + var it = elf.sections.valueIterator(); + while (it.next()) |sect| { + sect.*.data.deinit(); + sect.*.relocations.deinit(gpa); + } + } + elf.sections.deinit(gpa); + elf.local_symbols.deinit(gpa); + elf.global_symbols.deinit(gpa); + elf.arena.deinit(); + gpa.destroy(elf); +} + +fn sectionString(sec: Object.Section) []const u8 { + return switch (sec) { + .undefined => unreachable, + .data => "data", + .read_only_data => "rodata", + .func => "text", + .strings => "rodata.str", + .custom => |name| name, + }; +} + +pub fn getSection(elf: *Elf, section_kind: Object.Section) !*std.ArrayList(u8) { + const section_name = sectionString(section_kind); + const section = elf.sections.get(section_name) orelse blk: { + const section = try elf.arena.allocator().create(Section); + section.* = .{ + .data = std.ArrayList(u8).init(elf.arena.child_allocator), + .type = std.elf.SHT_PROGBITS, + .flags = switch (section_kind) { + .func, .custom => std.elf.SHF_ALLOC + std.elf.SHF_EXECINSTR, + .strings => std.elf.SHF_ALLOC + std.elf.SHF_MERGE + std.elf.SHF_STRINGS, + .read_only_data => std.elf.SHF_ALLOC, + .data => std.elf.SHF_ALLOC + std.elf.SHF_WRITE, + .undefined => unreachable, + }, + }; + try elf.sections.putNoClobber(elf.arena.child_allocator, section_name, section); + elf.strtab_len += section_name.len + ".\x00".len; + break :blk section; + }; + return §ion.data; +} + +pub fn declareSymbol( + elf: *Elf, + section_kind: Object.Section, + maybe_name: ?[]const u8, + linkage: std.builtin.GlobalLinkage, + @"type": Object.SymbolType, + offset: u64, + size: u64, +) ![]const u8 { + const section = blk: { + if (section_kind == .undefined) break :blk null; + const section_name = sectionString(section_kind); + break :blk elf.sections.get(section_name); + }; + const binding: u8 = switch (linkage) { + .Internal => std.elf.STB_LOCAL, + .Strong => std.elf.STB_GLOBAL, + .Weak => std.elf.STB_WEAK, + .LinkOnce => unreachable, + }; + const sym_type: u8 = switch (@"type") { + .func => std.elf.STT_FUNC, + .variable => std.elf.STT_OBJECT, + .external => std.elf.STT_NOTYPE, + }; + const name = if (maybe_name) |some| some else blk: { + defer elf.unnamed_symbol_mangle += 1; + break :blk try std.fmt.allocPrint(elf.arena.allocator(), ".L.{d}", .{elf.unnamed_symbol_mangle}); + }; + + const gop = if (linkage == .Internal) + try elf.local_symbols.getOrPut(elf.arena.child_allocator, name) + else + try elf.global_symbols.getOrPut(elf.arena.child_allocator, name); + + if (!gop.found_existing) { + gop.value_ptr.* = try elf.arena.allocator().create(Symbol); + elf.strtab_len += name.len + 1; // +1 for null byte + } + gop.value_ptr.*.* = .{ + .section = section, + .size = size, + .offset = offset, + .info = (binding << 4) + sym_type, + }; + return name; +} + +pub fn addRelocation(elf: *Elf, name: []const u8, section_kind: Object.Section, address: u64, addend: i64) !void { + const section_name = sectionString(section_kind); + const symbol = elf.local_symbols.get(name) orelse elf.global_symbols.get(name).?; // reference to undeclared symbol + const section = elf.sections.get(section_name).?; + if (section.relocations.items.len == 0) elf.strtab_len += ".rela".len; + + try section.relocations.append(elf.arena.child_allocator, .{ + .symbol = symbol, + .offset = @intCast(address), + .addend = addend, + .type = if (symbol.section == null) 4 else 2, // TODO + }); +} + +/// elf header +/// sections contents +/// symbols +/// relocations +/// strtab +/// section headers +pub fn finish(elf: *Elf, file: std.fs.File) !void { + var buf_writer = std.io.bufferedWriter(file.writer()); + const w = buf_writer.writer(); + + var num_sections: std.elf.Elf64_Half = additional_sections; + var relocations_len: std.elf.Elf64_Off = 0; + var sections_len: std.elf.Elf64_Off = 0; + { + var it = elf.sections.valueIterator(); + while (it.next()) |sect| { + sections_len += sect.*.data.items.len; + relocations_len += sect.*.relocations.items.len * @sizeOf(std.elf.Elf64_Rela); + sect.*.index = num_sections; + num_sections += 1; + num_sections += @intFromBool(sect.*.relocations.items.len != 0); + } + } + const symtab_len = (elf.local_symbols.count() + elf.global_symbols.count() + 1) * @sizeOf(std.elf.Elf64_Sym); + + const symtab_offset = @sizeOf(std.elf.Elf64_Ehdr) + sections_len; + const symtab_offset_aligned = std.mem.alignForward(u64, symtab_offset, 8); + const rela_offset = symtab_offset_aligned + symtab_len; + const strtab_offset = rela_offset + relocations_len; + const sh_offset = strtab_offset + elf.strtab_len; + const sh_offset_aligned = std.mem.alignForward(u64, sh_offset, 16); + + const elf_header = std.elf.Elf64_Ehdr{ + .e_ident = .{ 0x7F, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + .e_type = std.elf.ET.REL, // we only produce relocatables + .e_machine = elf.obj.target.toElfMachine(), + .e_version = 1, + .e_entry = 0, // linker will handle this + .e_phoff = 0, // no program header + .e_shoff = sh_offset_aligned, // section headers offset + .e_flags = 0, // no flags + .e_ehsize = @sizeOf(std.elf.Elf64_Ehdr), + .e_phentsize = 0, // no program header + .e_phnum = 0, // no program header + .e_shentsize = @sizeOf(std.elf.Elf64_Shdr), + .e_shnum = num_sections, + .e_shstrndx = strtab_index, + }; + try w.writeStruct(elf_header); + + // write contents of sections + { + var it = elf.sections.valueIterator(); + while (it.next()) |sect| try w.writeAll(sect.*.data.items); + } + + // pad to 8 bytes + try w.writeByteNTimes(0, @intCast(symtab_offset_aligned - symtab_offset)); + + var name_offset: u32 = strtab_default.len; + // write symbols + { + // first symbol must be null + try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Sym)); + + var sym_index: u16 = 1; + var it = elf.local_symbols.iterator(); + while (it.next()) |entry| { + const sym = entry.value_ptr.*; + try w.writeStruct(std.elf.Elf64_Sym{ + .st_name = name_offset, + .st_info = sym.info, + .st_other = 0, + .st_shndx = if (sym.section) |some| some.index else 0, + .st_value = sym.offset, + .st_size = sym.size, + }); + sym.index = sym_index; + sym_index += 1; + name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte + } + it = elf.global_symbols.iterator(); + while (it.next()) |entry| { + const sym = entry.value_ptr.*; + try w.writeStruct(std.elf.Elf64_Sym{ + .st_name = name_offset, + .st_info = sym.info, + .st_other = 0, + .st_shndx = if (sym.section) |some| some.index else 0, + .st_value = sym.offset, + .st_size = sym.size, + }); + sym.index = sym_index; + sym_index += 1; + name_offset += @intCast(entry.key_ptr.len + 1); // +1 for null byte + } + } + + // write relocations + { + var it = elf.sections.valueIterator(); + while (it.next()) |sect| { + for (sect.*.relocations.items) |rela| { + try w.writeStruct(std.elf.Elf64_Rela{ + .r_offset = rela.offset, + .r_addend = rela.addend, + .r_info = (@as(u64, rela.symbol.index) << 32) | rela.type, + }); + } + } + } + + // write strtab + try w.writeAll(strtab_default); + { + var it = elf.local_symbols.keyIterator(); + while (it.next()) |key| try w.print("{s}\x00", .{key.*}); + it = elf.global_symbols.keyIterator(); + while (it.next()) |key| try w.print("{s}\x00", .{key.*}); + } + { + var it = elf.sections.iterator(); + while (it.next()) |entry| { + if (entry.value_ptr.*.relocations.items.len != 0) try w.writeAll(".rela"); + try w.print(".{s}\x00", .{entry.key_ptr.*}); + } + } + + // pad to 16 bytes + try w.writeByteNTimes(0, @intCast(sh_offset_aligned - sh_offset)); + // mandatory null header + try w.writeStruct(std.mem.zeroes(std.elf.Elf64_Shdr)); + + // write strtab section header + { + const sect_header = std.elf.Elf64_Shdr{ + .sh_name = strtab_name, + .sh_type = std.elf.SHT_STRTAB, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = strtab_offset, + .sh_size = elf.strtab_len, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = 1, + .sh_entsize = 0, + }; + try w.writeStruct(sect_header); + } + + // write symtab section header + { + const sect_header = std.elf.Elf64_Shdr{ + .sh_name = symtab_name, + .sh_type = std.elf.SHT_SYMTAB, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = symtab_offset_aligned, + .sh_size = symtab_len, + .sh_link = strtab_index, + .sh_info = elf.local_symbols.size + 1, + .sh_addralign = 8, + .sh_entsize = @sizeOf(std.elf.Elf64_Sym), + }; + try w.writeStruct(sect_header); + } + + // remaining section headers + { + var sect_offset: u64 = @sizeOf(std.elf.Elf64_Ehdr); + var rela_sect_offset: u64 = rela_offset; + var it = elf.sections.iterator(); + while (it.next()) |entry| { + const sect = entry.value_ptr.*; + const rela_count = sect.relocations.items.len; + const rela_name_offset: u32 = if (rela_count != 0) @truncate(".rela".len) else 0; + try w.writeStruct(std.elf.Elf64_Shdr{ + .sh_name = rela_name_offset + name_offset, + .sh_type = sect.type, + .sh_flags = sect.flags, + .sh_addr = 0, + .sh_offset = sect_offset, + .sh_size = sect.data.items.len, + .sh_link = 0, + .sh_info = 0, + .sh_addralign = if (sect.flags & std.elf.SHF_EXECINSTR != 0) 16 else 1, + .sh_entsize = 0, + }); + + if (rela_count != 0) { + const size = rela_count * @sizeOf(std.elf.Elf64_Rela); + try w.writeStruct(std.elf.Elf64_Shdr{ + .sh_name = name_offset, + .sh_type = std.elf.SHT_RELA, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = rela_sect_offset, + .sh_size = rela_count * @sizeOf(std.elf.Elf64_Rela), + .sh_link = symtab_index, + .sh_info = sect.index, + .sh_addralign = 8, + .sh_entsize = @sizeOf(std.elf.Elf64_Rela), + }); + rela_sect_offset += size; + } + + sect_offset += sect.data.items.len; + name_offset += @as(u32, @intCast(entry.key_ptr.len + ".\x00".len)) + rela_name_offset; + } + } + try buf_writer.flush(); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro_translate_c.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro_translate_c.zig new file mode 100644 index 00000000..9485bc79 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro_translate_c.zig @@ -0,0 +1,1829 @@ +const std = @import("std"); +const mem = std.mem; +const assert = std.debug.assert; +const CallingConvention = std.builtin.CallingConvention; +const aro = @import("aro"); +const CToken = aro.Tokenizer.Token; +const Tree = aro.Tree; +const NodeIndex = Tree.NodeIndex; +const TokenIndex = Tree.TokenIndex; +const Type = aro.Type; +pub const ast = @import("aro_translate_c/ast.zig"); +const ZigNode = ast.Node; +const ZigTag = ZigNode.Tag; +const Scope = ScopeExtra(Context, Type); +const Context = @This(); + +gpa: mem.Allocator, +arena: mem.Allocator, +decl_table: std.AutoArrayHashMapUnmanaged(usize, []const u8) = .empty, +alias_list: AliasList, +global_scope: *Scope.Root, +mangle_count: u32 = 0, +/// Table of record decls that have been demoted to opaques. +opaque_demotes: std.AutoHashMapUnmanaged(usize, void) = .empty, +/// Table of unnamed enums and records that are child types of typedefs. +unnamed_typedefs: std.AutoHashMapUnmanaged(usize, []const u8) = .empty, +/// Needed to decide if we are parsing a typename +typedefs: std.StringArrayHashMapUnmanaged(void) = .empty, + +/// This one is different than the root scope's name table. This contains +/// a list of names that we found by visiting all the top level decls without +/// translating them. The other maps are updated as we translate; this one is updated +/// up front in a pre-processing step. +global_names: std.StringArrayHashMapUnmanaged(void) = .empty, + +/// This is similar to `global_names`, but contains names which we would +/// *like* to use, but do not strictly *have* to if they are unavailable. +/// These are relevant to types, which ideally we would name like +/// 'struct_foo' with an alias 'foo', but if either of those names is taken, +/// may be mangled. +/// This is distinct from `global_names` so we can detect at a type +/// declaration whether or not the name is available. +weak_global_names: std.StringArrayHashMapUnmanaged(void) = .empty, + +pattern_list: PatternList, +tree: Tree, +comp: *aro.Compilation, +mapper: aro.TypeMapper, + +fn getMangle(c: *Context) u32 { + c.mangle_count += 1; + return c.mangle_count; +} + +/// Convert an aro TokenIndex to a 'file:line:column' string +fn locStr(c: *Context, tok_idx: TokenIndex) ![]const u8 { + const token_loc = c.tree.tokens.items(.loc)[tok_idx]; + const source = c.comp.getSource(token_loc.id); + const line_col = source.lineCol(token_loc); + const filename = source.path; + + const line = source.physicalLine(token_loc); + const col = line_col.col; + + return std.fmt.allocPrint(c.arena, "{s}:{d}:{d}", .{ filename, line, col }); +} + +fn maybeSuppressResult(c: *Context, used: ResultUsed, result: ZigNode) TransError!ZigNode { + if (used == .used) return result; + return ZigTag.discard.create(c.arena, .{ .should_skip = false, .value = result }); +} + +fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: ZigNode) !void { + const gop = try c.global_scope.sym_table.getOrPut(name); + if (!gop.found_existing) { + gop.value_ptr.* = decl_node; + try c.global_scope.nodes.append(decl_node); + } +} + +fn fail( + c: *Context, + err: anytype, + source_loc: TokenIndex, + comptime format: []const u8, + args: anytype, +) (@TypeOf(err) || error{OutOfMemory}) { + try warn(c, &c.global_scope.base, source_loc, format, args); + return err; +} + +fn failDecl(c: *Context, loc: TokenIndex, name: []const u8, comptime format: []const u8, args: anytype) Error!void { + // location + // pub const name = @compileError(msg); + const fail_msg = try std.fmt.allocPrint(c.arena, format, args); + try addTopLevelDecl(c, name, try ZigTag.fail_decl.create(c.arena, .{ .actual = name, .mangled = fail_msg })); + const str = try c.locStr(loc); + const location_comment = try std.fmt.allocPrint(c.arena, "// {s}", .{str}); + try c.global_scope.nodes.append(try ZigTag.warning.create(c.arena, location_comment)); +} + +fn warn(c: *Context, scope: *Scope, loc: TokenIndex, comptime format: []const u8, args: anytype) !void { + const str = try c.locStr(loc); + const value = try std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, .{str} ++ args); + try scope.appendNode(try ZigTag.warning.create(c.arena, value)); +} + +pub fn translate( + gpa: mem.Allocator, + comp: *aro.Compilation, + args: []const []const u8, +) !std.zig.Ast { + try comp.addDefaultPragmaHandlers(); + comp.langopts.setEmulatedCompiler(aro.target_util.systemCompiler(comp.target)); + + var driver: aro.Driver = .{ .comp = comp }; + defer driver.deinit(); + + var macro_buf = std.ArrayList(u8).init(gpa); + defer macro_buf.deinit(); + + assert(!try driver.parseArgs(std.io.null_writer, macro_buf.writer(), args)); + assert(driver.inputs.items.len == 1); + const source = driver.inputs.items[0]; + + const builtin_macros = try comp.generateBuiltinMacros(.include_system_defines); + const user_macros = try comp.addSourceFromBuffer("", macro_buf.items); + + var pp = try aro.Preprocessor.initDefault(comp); + defer pp.deinit(); + + try pp.preprocessSources(&.{ source, builtin_macros, user_macros }); + + var tree = try pp.parse(); + defer tree.deinit(); + + // Workaround for https://github.com/Vexu/arocc/issues/603 + for (comp.diagnostics.list.items) |msg| { + if (msg.kind == .@"error" or msg.kind == .@"fatal error") return error.ParsingFailed; + } + + const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper(); + defer mapper.deinit(tree.comp.gpa); + + var arena_allocator = std.heap.ArenaAllocator.init(gpa); + defer arena_allocator.deinit(); + const arena = arena_allocator.allocator(); + + var context = Context{ + .gpa = gpa, + .arena = arena, + .alias_list = AliasList.init(gpa), + .global_scope = try arena.create(Scope.Root), + .pattern_list = try PatternList.init(gpa), + .comp = comp, + .mapper = mapper, + .tree = tree, + }; + context.global_scope.* = Scope.Root.init(&context); + defer { + context.decl_table.deinit(gpa); + context.alias_list.deinit(); + context.global_names.deinit(gpa); + context.opaque_demotes.deinit(gpa); + context.unnamed_typedefs.deinit(gpa); + context.typedefs.deinit(gpa); + context.global_scope.deinit(); + context.pattern_list.deinit(gpa); + } + + @setEvalBranchQuota(2000); + inline for (@typeInfo(std.zig.c_builtins).@"struct".decls) |decl| { + const builtin_fn = try ZigTag.pub_var_simple.create(arena, .{ + .name = decl.name, + .init = try ZigTag.import_c_builtin.create(arena, decl.name), + }); + try addTopLevelDecl(&context, decl.name, builtin_fn); + } + + try prepopulateGlobalNameTable(&context); + try transTopLevelDecls(&context); + + for (context.alias_list.items) |alias| { + if (!context.global_scope.sym_table.contains(alias.alias)) { + const node = try ZigTag.alias.create(arena, .{ .actual = alias.alias, .mangled = alias.name }); + try addTopLevelDecl(&context, alias.alias, node); + } + } + + return ast.render(gpa, context.global_scope.nodes.items); +} + +fn prepopulateGlobalNameTable(c: *Context) !void { + const node_tags = c.tree.nodes.items(.tag); + const node_types = c.tree.nodes.items(.ty); + const node_data = c.tree.nodes.items(.data); + for (c.tree.root_decls) |node| { + const data = node_data[@intFromEnum(node)]; + switch (node_tags[@intFromEnum(node)]) { + .typedef => {}, + + .struct_decl_two, + .union_decl_two, + .struct_decl, + .union_decl, + .struct_forward_decl, + .union_forward_decl, + .enum_decl_two, + .enum_decl, + .enum_forward_decl, + => { + const raw_ty = node_types[@intFromEnum(node)]; + const ty = raw_ty.canonicalize(.standard); + const name_id = if (ty.isRecord()) ty.data.record.name else ty.data.@"enum".name; + const decl_name = c.mapper.lookup(name_id); + const container_prefix = if (ty.is(.@"struct")) "struct" else if (ty.is(.@"union")) "union" else "enum"; + const prefixed_name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ container_prefix, decl_name }); + // `decl_name` and `prefixed_name` are the preferred names for this type. + // However, we can name it anything else if necessary, so these are "weak names". + try c.weak_global_names.ensureUnusedCapacity(c.gpa, 2); + c.weak_global_names.putAssumeCapacity(decl_name, {}); + c.weak_global_names.putAssumeCapacity(prefixed_name, {}); + }, + + .fn_proto, + .static_fn_proto, + .inline_fn_proto, + .inline_static_fn_proto, + .fn_def, + .static_fn_def, + .inline_fn_def, + .inline_static_fn_def, + .@"var", + .extern_var, + .static_var, + .threadlocal_var, + .threadlocal_extern_var, + .threadlocal_static_var, + => { + const decl_name = c.tree.tokSlice(data.decl.name); + try c.global_names.put(c.gpa, decl_name, {}); + }, + .static_assert => {}, + else => unreachable, + } + } +} + +fn transTopLevelDecls(c: *Context) !void { + for (c.tree.root_decls) |node| { + try transDecl(c, &c.global_scope.base, node); + } +} + +fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void { + const node_tags = c.tree.nodes.items(.tag); + const node_data = c.tree.nodes.items(.data); + const node_ty = c.tree.nodes.items(.ty); + const data = node_data[@intFromEnum(decl)]; + switch (node_tags[@intFromEnum(decl)]) { + .typedef => { + try transTypeDef(c, scope, decl); + }, + + .struct_decl_two, + .union_decl_two, + => { + try transRecordDecl(c, scope, node_ty[@intFromEnum(decl)]); + }, + .struct_decl, + .union_decl, + => { + try transRecordDecl(c, scope, node_ty[@intFromEnum(decl)]); + }, + + .enum_decl_two => { + var fields = [2]NodeIndex{ data.bin.lhs, data.bin.rhs }; + var field_count: u8 = 0; + if (fields[0] != .none) field_count += 1; + if (fields[1] != .none) field_count += 1; + const enum_decl = node_ty[@intFromEnum(decl)].canonicalize(.standard).data.@"enum"; + try transEnumDecl(c, scope, enum_decl, fields[0..field_count]); + }, + .enum_decl => { + const fields = c.tree.data[data.range.start..data.range.end]; + const enum_decl = node_ty[@intFromEnum(decl)].canonicalize(.standard).data.@"enum"; + try transEnumDecl(c, scope, enum_decl, fields); + }, + + .enum_field_decl, + .record_field_decl, + .indirect_record_field_decl, + .struct_forward_decl, + .union_forward_decl, + .enum_forward_decl, + => return, + + .fn_proto, + .static_fn_proto, + .inline_fn_proto, + .inline_static_fn_proto, + .fn_def, + .static_fn_def, + .inline_fn_def, + .inline_static_fn_def, + => { + try transFnDecl(c, decl, true); + }, + + .@"var", + .extern_var, + .static_var, + .threadlocal_var, + .threadlocal_extern_var, + .threadlocal_static_var, + => { + try transVarDecl(c, decl); + }, + .static_assert => try warn(c, &c.global_scope.base, 0, "ignoring _Static_assert declaration", .{}), + else => unreachable, + } +} + +fn transTypeDef(c: *Context, scope: *Scope, typedef_decl: NodeIndex) Error!void { + const ty = c.tree.nodes.items(.ty)[@intFromEnum(typedef_decl)]; + const data = c.tree.nodes.items(.data)[@intFromEnum(typedef_decl)]; + + const toplevel = scope.id == .root; + const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined; + + var name: []const u8 = c.tree.tokSlice(data.decl.name); + try c.typedefs.put(c.gpa, name, {}); + + if (!toplevel) name = try bs.makeMangledName(c, name); + + const typedef_loc = data.decl.name; + const init_node = transType(c, scope, ty, .standard, typedef_loc) catch |err| switch (err) { + error.UnsupportedType => { + return failDecl(c, typedef_loc, name, "unable to resolve typedef child type", .{}); + }, + error.OutOfMemory => |e| return e, + }; + + const payload = try c.arena.create(ast.Payload.SimpleVarDecl); + payload.* = .{ + .base = .{ .tag = ([2]ZigTag{ .var_simple, .pub_var_simple })[@intFromBool(toplevel)] }, + .data = .{ + .name = name, + .init = init_node, + }, + }; + const node = ZigNode.initPayload(&payload.base); + + if (toplevel) { + try addTopLevelDecl(c, name, node); + } else { + try scope.appendNode(node); + if (node.tag() != .pub_var_simple) { + try bs.discardVariable(c, name); + } + } +} + +fn mangleWeakGlobalName(c: *Context, want_name: []const u8) ![]const u8 { + var cur_name = want_name; + + if (!c.weak_global_names.contains(want_name)) { + // This type wasn't noticed by the name detection pass, so nothing has been treating this as + // a weak global name. We must mangle it to avoid conflicts with locals. + cur_name = try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ want_name, c.getMangle() }); + } + + while (c.global_names.contains(cur_name)) { + cur_name = try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ want_name, c.getMangle() }); + } + return cur_name; +} + +fn transRecordDecl(c: *Context, scope: *Scope, record_ty: Type) Error!void { + const record_decl = record_ty.getRecord().?; + if (c.decl_table.get(@intFromPtr(record_decl))) |_| + return; // Avoid processing this decl twice + const toplevel = scope.id == .root; + const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined; + + const container_kind: ZigTag = if (record_ty.is(.@"union")) .@"union" else .@"struct"; + const container_kind_name: []const u8 = @tagName(container_kind); + + var is_unnamed = false; + var bare_name: []const u8 = c.mapper.lookup(record_decl.name); + var name = bare_name; + + if (c.unnamed_typedefs.get(@intFromPtr(record_decl))) |typedef_name| { + bare_name = typedef_name; + name = typedef_name; + } else { + if (record_ty.isAnonymousRecord(c.comp)) { + bare_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{c.getMangle()}); + is_unnamed = true; + } + name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ container_kind_name, bare_name }); + if (toplevel and !is_unnamed) { + name = try mangleWeakGlobalName(c, name); + } + } + if (!toplevel) name = try bs.makeMangledName(c, name); + try c.decl_table.putNoClobber(c.gpa, @intFromPtr(record_decl), name); + + const is_pub = toplevel and !is_unnamed; + const init_node = blk: { + if (record_decl.isIncomplete()) { + try c.opaque_demotes.put(c.gpa, @intFromPtr(record_decl), {}); + break :blk ZigTag.opaque_literal.init(); + } + + var fields = try std.ArrayList(ast.Payload.Record.Field).initCapacity(c.gpa, record_decl.fields.len); + defer fields.deinit(); + + // TODO: Add support for flexible array field functions + var functions = std.ArrayList(ZigNode).init(c.gpa); + defer functions.deinit(); + + var unnamed_field_count: u32 = 0; + + // If a record doesn't have any attributes that would affect the alignment and + // layout, then we can just use a simple `extern` type. If it does have attributes, + // then we need to inspect the layout and assign an `align` value for each field. + const has_alignment_attributes = record_decl.field_attributes != null or + record_ty.hasAttribute(.@"packed") or + record_ty.hasAttribute(.aligned); + const head_field_alignment: ?c_uint = if (has_alignment_attributes) headFieldAlignment(record_decl) else null; + + for (record_decl.fields, 0..) |field, field_index| { + const field_loc = field.name_tok; + + // Demote record to opaque if it contains a bitfield + if (!field.isRegularField()) { + try c.opaque_demotes.put(c.gpa, @intFromPtr(record_decl), {}); + try warn(c, scope, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name}); + break :blk ZigTag.opaque_literal.init(); + } + + var field_name = c.mapper.lookup(field.name); + if (!field.isNamed()) { + field_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{unnamed_field_count}); + unnamed_field_count += 1; + } + const field_type = transType(c, scope, field.ty, .preserve_quals, field_loc) catch |err| switch (err) { + error.UnsupportedType => { + try c.opaque_demotes.put(c.gpa, @intFromPtr(record_decl), {}); + try warn(c, scope, 0, "{s} demoted to opaque type - unable to translate type of field {s}", .{ + container_kind_name, + field_name, + }); + break :blk ZigTag.opaque_literal.init(); + }, + else => |e| return e, + }; + + const field_alignment = if (has_alignment_attributes) + alignmentForField(record_decl, head_field_alignment, field_index) + else + null; + + // C99 introduced designated initializers for structs. Omitted fields are implicitly + // initialized to zero. Some C APIs are designed with this in mind. Defaulting to zero + // values for translated struct fields permits Zig code to comfortably use such an API. + const default_value = if (container_kind == .@"struct") + try ZigTag.std_mem_zeroes.create(c.arena, field_type) + else + null; + + fields.appendAssumeCapacity(.{ + .name = field_name, + .type = field_type, + .alignment = field_alignment, + .default_value = default_value, + }); + } + + const record_payload = try c.arena.create(ast.Payload.Record); + record_payload.* = .{ + .base = .{ .tag = container_kind }, + .data = .{ + .layout = .@"extern", + .fields = try c.arena.dupe(ast.Payload.Record.Field, fields.items), + .functions = try c.arena.dupe(ZigNode, functions.items), + .variables = &.{}, + }, + }; + break :blk ZigNode.initPayload(&record_payload.base); + }; + + const payload = try c.arena.create(ast.Payload.SimpleVarDecl); + payload.* = .{ + .base = .{ .tag = ([2]ZigTag{ .var_simple, .pub_var_simple })[@intFromBool(is_pub)] }, + .data = .{ + .name = name, + .init = init_node, + }, + }; + const node = ZigNode.initPayload(&payload.base); + if (toplevel) { + try addTopLevelDecl(c, name, node); + // Only add the alias if the name is available *and* it was caught by + // name detection. Don't bother performing a weak mangle, since a + // mangled name is of no real use here. + if (!is_unnamed and !c.global_names.contains(bare_name) and c.weak_global_names.contains(bare_name)) + try c.alias_list.append(.{ .alias = bare_name, .name = name }); + } else { + try scope.appendNode(node); + if (node.tag() != .pub_var_simple) { + try bs.discardVariable(c, name); + } + } +} + +fn transFnDecl(c: *Context, fn_decl: NodeIndex, is_pub: bool) Error!void { + const raw_ty = c.tree.nodes.items(.ty)[@intFromEnum(fn_decl)]; + const fn_ty = raw_ty.canonicalize(.standard); + const node_data = c.tree.nodes.items(.data)[@intFromEnum(fn_decl)]; + if (c.decl_table.get(@intFromPtr(fn_ty.data.func))) |_| + return; // Avoid processing this decl twice + + const fn_name = c.tree.tokSlice(node_data.decl.name); + if (c.global_scope.sym_table.contains(fn_name)) + return; // Avoid processing this decl twice + + const fn_decl_loc = 0; // TODO + const has_body = node_data.decl.node != .none; + const is_always_inline = has_body and raw_ty.getAttribute(.always_inline) != null; + const proto_ctx = FnProtoContext{ + .fn_name = fn_name, + .is_inline = is_always_inline, + .is_extern = !has_body, + .is_export = switch (c.tree.nodes.items(.tag)[@intFromEnum(fn_decl)]) { + .fn_proto, .fn_def => has_body and !is_always_inline, + + .inline_fn_proto, .inline_fn_def, .inline_static_fn_proto, .inline_static_fn_def, .static_fn_proto, .static_fn_def => false, + + else => unreachable, + }, + .is_pub = is_pub, + }; + + const proto_node = transFnType(c, &c.global_scope.base, raw_ty, fn_ty, fn_decl_loc, proto_ctx) catch |err| switch (err) { + error.UnsupportedType => { + return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function", .{}); + }, + error.OutOfMemory => |e| return e, + }; + + if (!has_body) { + return addTopLevelDecl(c, fn_name, proto_node); + } + const proto_payload = proto_node.castTag(.func).?; + + // actual function definition with body + const body_stmt = node_data.decl.node; + var block_scope = try Scope.Block.init(c, &c.global_scope.base, false); + block_scope.return_type = fn_ty.data.func.return_type; + defer block_scope.deinit(); + + var scope = &block_scope.base; + _ = &scope; + + var param_id: c_uint = 0; + for (proto_payload.data.params, fn_ty.data.func.params) |*param, param_info| { + const param_name = param.name orelse { + proto_payload.data.is_extern = true; + proto_payload.data.is_export = false; + proto_payload.data.is_inline = false; + try warn(c, &c.global_scope.base, fn_decl_loc, "function {s} parameter has no name, demoted to extern", .{fn_name}); + return addTopLevelDecl(c, fn_name, proto_node); + }; + + const is_const = param_info.ty.qual.@"const"; + + const mangled_param_name = try block_scope.makeMangledName(c, param_name); + param.name = mangled_param_name; + + if (!is_const) { + const bare_arg_name = try std.fmt.allocPrint(c.arena, "arg_{s}", .{mangled_param_name}); + const arg_name = try block_scope.makeMangledName(c, bare_arg_name); + param.name = arg_name; + + const redecl_node = try ZigTag.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name }); + try block_scope.statements.append(redecl_node); + } + try block_scope.discardVariable(c, mangled_param_name); + + param_id += 1; + } + + transCompoundStmtInline(c, body_stmt, &block_scope) catch |err| switch (err) { + error.OutOfMemory => |e| return e, + error.UnsupportedTranslation, + error.UnsupportedType, + => { + proto_payload.data.is_extern = true; + proto_payload.data.is_export = false; + proto_payload.data.is_inline = false; + try warn(c, &c.global_scope.base, fn_decl_loc, "unable to translate function, demoted to extern", .{}); + return addTopLevelDecl(c, fn_name, proto_node); + }, + }; + + proto_payload.data.body = try block_scope.complete(c); + return addTopLevelDecl(c, fn_name, proto_node); +} + +fn transVarDecl(c: *Context, node: NodeIndex) Error!void { + const data = c.tree.nodes.items(.data)[@intFromEnum(node)]; + const name = c.tree.tokSlice(data.decl.name); + return failDecl(c, data.decl.name, name, "unable to translate variable declaration", .{}); +} + +fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const Type.Enum, field_nodes: []const NodeIndex) Error!void { + if (c.decl_table.get(@intFromPtr(enum_decl))) |_| + return; // Avoid processing this decl twice + const toplevel = scope.id == .root; + const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined; + + var is_unnamed = false; + var bare_name: []const u8 = c.mapper.lookup(enum_decl.name); + var name = bare_name; + if (c.unnamed_typedefs.get(@intFromPtr(enum_decl))) |typedef_name| { + bare_name = typedef_name; + name = typedef_name; + } else { + if (bare_name.len == 0) { + bare_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{c.getMangle()}); + is_unnamed = true; + } + name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name}); + } + if (!toplevel) name = try bs.makeMangledName(c, name); + try c.decl_table.putNoClobber(c.gpa, @intFromPtr(enum_decl), name); + + const enum_type_node = if (!enum_decl.isIncomplete()) blk: { + for (enum_decl.fields, field_nodes) |field, field_node| { + var enum_val_name: []const u8 = c.mapper.lookup(field.name); + if (!toplevel) { + enum_val_name = try bs.makeMangledName(c, enum_val_name); + } + + const enum_const_type_node: ?ZigNode = transType(c, scope, field.ty, .standard, field.name_tok) catch |err| switch (err) { + error.UnsupportedType => null, + else => |e| return e, + }; + + const val = c.tree.value_map.get(field_node).?; + const enum_const_def = try ZigTag.enum_constant.create(c.arena, .{ + .name = enum_val_name, + .is_public = toplevel, + .type = enum_const_type_node, + .value = try transCreateNodeAPInt(c, val), + }); + if (toplevel) + try addTopLevelDecl(c, enum_val_name, enum_const_def) + else { + try scope.appendNode(enum_const_def); + try bs.discardVariable(c, enum_val_name); + } + } + + break :blk transType(c, scope, enum_decl.tag_ty, .standard, 0) catch |err| switch (err) { + error.UnsupportedType => { + return failDecl(c, 0, name, "unable to translate enum integer type", .{}); + }, + else => |e| return e, + }; + } else blk: { + try c.opaque_demotes.put(c.gpa, @intFromPtr(enum_decl), {}); + break :blk ZigTag.opaque_literal.init(); + }; + + const is_pub = toplevel and !is_unnamed; + const payload = try c.arena.create(ast.Payload.SimpleVarDecl); + payload.* = .{ + .base = .{ .tag = ([2]ZigTag{ .var_simple, .pub_var_simple })[@intFromBool(is_pub)] }, + .data = .{ + .init = enum_type_node, + .name = name, + }, + }; + const node = ZigNode.initPayload(&payload.base); + if (toplevel) { + try addTopLevelDecl(c, name, node); + if (!is_unnamed) + try c.alias_list.append(.{ .alias = bare_name, .name = name }); + } else { + try scope.appendNode(node); + if (node.tag() != .pub_var_simple) { + try bs.discardVariable(c, name); + } + } +} + +fn getTypeStr(c: *Context, ty: Type) ![]const u8 { + var buf: std.ArrayListUnmanaged(u8) = .empty; + defer buf.deinit(c.gpa); + const w = buf.writer(c.gpa); + try ty.print(c.mapper, c.comp.langopts, w); + return c.arena.dupe(u8, buf.items); +} + +fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualHandling, source_loc: TokenIndex) TypeError!ZigNode { + const ty = raw_ty.canonicalize(qual_handling); + if (ty.qual.atomic) { + const type_name = try getTypeStr(c, ty); + return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name}); + } + + switch (ty.specifier) { + .void => return ZigTag.type.create(c.arena, "anyopaque"), + .bool => return ZigTag.type.create(c.arena, "bool"), + .char => return ZigTag.type.create(c.arena, "c_char"), + .schar => return ZigTag.type.create(c.arena, "i8"), + .uchar => return ZigTag.type.create(c.arena, "u8"), + .short => return ZigTag.type.create(c.arena, "c_short"), + .ushort => return ZigTag.type.create(c.arena, "c_ushort"), + .int => return ZigTag.type.create(c.arena, "c_int"), + .uint => return ZigTag.type.create(c.arena, "c_uint"), + .long => return ZigTag.type.create(c.arena, "c_long"), + .ulong => return ZigTag.type.create(c.arena, "c_ulong"), + .long_long => return ZigTag.type.create(c.arena, "c_longlong"), + .ulong_long => return ZigTag.type.create(c.arena, "c_ulonglong"), + .int128 => return ZigTag.type.create(c.arena, "i128"), + .uint128 => return ZigTag.type.create(c.arena, "u128"), + .fp16, .float16 => return ZigTag.type.create(c.arena, "f16"), + .float => return ZigTag.type.create(c.arena, "f32"), + .double => return ZigTag.type.create(c.arena, "f64"), + .long_double => return ZigTag.type.create(c.arena, "c_longdouble"), + .float128 => return ZigTag.type.create(c.arena, "f128"), + .@"enum" => { + const enum_decl = ty.data.@"enum"; + var trans_scope = scope; + if (enum_decl.name != .empty) { + const decl_name = c.mapper.lookup(enum_decl.name); + if (c.weak_global_names.contains(decl_name)) trans_scope = &c.global_scope.base; + } + try transEnumDecl(c, trans_scope, enum_decl, &.{}); + return ZigTag.identifier.create(c.arena, c.decl_table.get(@intFromPtr(enum_decl)).?); + }, + .pointer => { + const child_type = ty.elemType(); + + const is_fn_proto = child_type.isFunc(); + const is_const = is_fn_proto or child_type.isConst(); + const is_volatile = child_type.qual.@"volatile"; + const elem_type = try transType(c, scope, child_type, qual_handling, source_loc); + const ptr_info: @FieldType(ast.Payload.Pointer, "data") = .{ + .is_const = is_const, + .is_volatile = is_volatile, + .elem_type = elem_type, + }; + if (is_fn_proto or + typeIsOpaque(c, child_type) or + typeWasDemotedToOpaque(c, child_type)) + { + const ptr = try ZigTag.single_pointer.create(c.arena, ptr_info); + return ZigTag.optional_type.create(c.arena, ptr); + } + + return ZigTag.c_pointer.create(c.arena, ptr_info); + }, + .unspecified_variable_len_array, .incomplete_array => { + const child_type = ty.elemType(); + const is_const = child_type.qual.@"const"; + const is_volatile = child_type.qual.@"volatile"; + const elem_type = try transType(c, scope, child_type, qual_handling, source_loc); + + return ZigTag.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type }); + }, + .array, + .static_array, + => { + const size = ty.arrayLen().?; + const elem_type = try transType(c, scope, ty.elemType(), qual_handling, source_loc); + return ZigTag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type }); + }, + .func, + .var_args_func, + .old_style_func, + => return transFnType(c, scope, ty, ty, source_loc, .{}), + .@"struct", + .@"union", + => { + var trans_scope = scope; + if (ty.isAnonymousRecord(c.comp)) { + const record_decl = ty.data.record; + const name_id = c.mapper.lookup(record_decl.name); + if (c.weak_global_names.contains(name_id)) trans_scope = &c.global_scope.base; + } + try transRecordDecl(c, trans_scope, ty); + const name = c.decl_table.get(@intFromPtr(ty.data.record)).?; + return ZigTag.identifier.create(c.arena, name); + }, + .attributed, + .typeof_type, + .typeof_expr, + => unreachable, + else => return error.UnsupportedType, + } +} + +/// Look ahead through the fields of the record to determine what the alignment of the record +/// would be without any align/packed/etc. attributes. This helps us determine whether or not +/// the fields with 0 offset need an `align` qualifier. Strictly speaking, we could just +/// pedantically assign those fields the same alignment as the parent's pointer alignment, +/// but this helps the generated code to be a little less verbose. +fn headFieldAlignment(record_decl: *const Type.Record) ?c_uint { + const bits_per_byte = 8; + const parent_ptr_alignment_bits = record_decl.type_layout.pointer_alignment_bits; + const parent_ptr_alignment = parent_ptr_alignment_bits / bits_per_byte; + var max_field_alignment_bits: u64 = 0; + for (record_decl.fields) |field| { + if (field.ty.getRecord()) |field_record_decl| { + const child_record_alignment = field_record_decl.type_layout.field_alignment_bits; + if (child_record_alignment > max_field_alignment_bits) + max_field_alignment_bits = child_record_alignment; + } else { + const field_size = field.layout.size_bits; + if (field_size > max_field_alignment_bits) + max_field_alignment_bits = field_size; + } + } + if (max_field_alignment_bits != parent_ptr_alignment_bits) { + return parent_ptr_alignment; + } else { + return null; + } +} + +/// This function inspects the generated layout of a record to determine the alignment for a +/// particular field. This approach is necessary because unlike Zig, a C compiler is not +/// required to fulfill the requested alignment, which means we'd risk generating different code +/// if we only look at the user-requested alignment. +/// +/// Returns a ?c_uint to match Clang's behaviour of using c_uint. The return type can be changed +/// after the Clang frontend for translate-c is removed. A null value indicates that a field is +/// 'naturally aligned'. +fn alignmentForField( + record_decl: *const Type.Record, + head_field_alignment: ?c_uint, + field_index: usize, +) ?c_uint { + const fields = record_decl.fields; + assert(fields.len != 0); + const field = fields[field_index]; + + const bits_per_byte = 8; + const parent_ptr_alignment_bits = record_decl.type_layout.pointer_alignment_bits; + const parent_ptr_alignment = parent_ptr_alignment_bits / bits_per_byte; + + // bitfields aren't supported yet. Until support is added, records with bitfields + // should be demoted to opaque, and this function shouldn't be called for them. + if (!field.isRegularField()) { + @panic("TODO: add bitfield support for records"); + } + + const field_offset_bits: u64 = field.layout.offset_bits; + const field_size_bits: u64 = field.layout.size_bits; + + // Fields with zero width always have an alignment of 1 + if (field_size_bits == 0) { + return 1; + } + + // Fields with 0 offset inherit the parent's pointer alignment. + if (field_offset_bits == 0) { + return head_field_alignment; + } + + // Records have a natural alignment when used as a field, and their size is + // a multiple of this alignment value. For all other types, the natural alignment + // is their size. + const field_natural_alignment_bits: u64 = if (field.ty.getRecord()) |record| record.type_layout.field_alignment_bits else field_size_bits; + const rem_bits = field_offset_bits % field_natural_alignment_bits; + + // If there's a remainder, then the alignment is smaller than the field's + // natural alignment + if (rem_bits > 0) { + const rem_alignment = rem_bits / bits_per_byte; + if (rem_alignment > 0 and std.math.isPowerOfTwo(rem_alignment)) { + const actual_alignment = @min(rem_alignment, parent_ptr_alignment); + return @as(c_uint, @truncate(actual_alignment)); + } else { + return 1; + } + } + + // A field may have an offset which positions it to be naturally aligned, but the + // parent's pointer alignment determines if this is actually true, so we take the minimum + // value. + // For example, a float field (4 bytes wide) with a 4 byte offset is positioned to have natural + // alignment, but if the parent pointer alignment is 2, then the actual alignment of the + // float is 2. + const field_natural_alignment: u64 = field_natural_alignment_bits / bits_per_byte; + const offset_alignment = field_offset_bits / bits_per_byte; + const possible_alignment = @min(parent_ptr_alignment, offset_alignment); + if (possible_alignment == field_natural_alignment) { + return null; + } else if (possible_alignment < field_natural_alignment) { + if (std.math.isPowerOfTwo(possible_alignment)) { + return possible_alignment; + } else { + return 1; + } + } else { // possible_alignment > field_natural_alignment + // Here, the field is positioned be at a higher alignment than it's natural alignment. This means we + // need to determine whether it's a specified alignment. We can determine that from the padding preceding + // the field. + const padding_from_prev_field: u64 = blk: { + if (field_offset_bits != 0) { + const previous_field = fields[field_index - 1]; + break :blk (field_offset_bits - previous_field.layout.offset_bits) - previous_field.layout.size_bits; + } else { + break :blk 0; + } + }; + if (padding_from_prev_field < field_natural_alignment_bits) { + return null; + } else { + return possible_alignment; + } + } +} + +const FnProtoContext = struct { + is_pub: bool = false, + is_export: bool = false, + is_extern: bool = false, + is_inline: bool = false, + fn_name: ?[]const u8 = null, +}; + +fn transFnType( + c: *Context, + scope: *Scope, + raw_ty: Type, + fn_ty: Type, + source_loc: TokenIndex, + ctx: FnProtoContext, +) !ZigNode { + const param_count: usize = fn_ty.data.func.params.len; + const fn_params = try c.arena.alloc(ast.Payload.Param, param_count); + + for (fn_ty.data.func.params, fn_params) |param_info, *param_node| { + const param_ty = param_info.ty; + const is_noalias = param_ty.qual.restrict; + + const param_name: ?[]const u8 = if (param_info.name == .empty) + null + else + c.mapper.lookup(param_info.name); + + const type_node = try transType(c, scope, param_ty, .standard, param_info.name_tok); + param_node.* = .{ + .is_noalias = is_noalias, + .name = param_name, + .type = type_node, + }; + } + + const linksection_string = blk: { + if (raw_ty.getAttribute(.section)) |section| { + break :blk c.comp.interner.get(section.name.ref()).bytes; + } + break :blk null; + }; + + const alignment: ?c_uint = raw_ty.requestedAlignment(c.comp) orelse null; + + const explicit_callconv = null; + // const explicit_callconv = if ((ctx.is_inline or ctx.is_export or ctx.is_extern) and ctx.cc == .C) null else ctx.cc; + + const return_type_node = blk: { + if (raw_ty.getAttribute(.noreturn) != null) { + break :blk ZigTag.noreturn_type.init(); + } else { + const return_ty = fn_ty.data.func.return_type; + if (return_ty.is(.void)) { + // convert primitive anyopaque to actual void (only for return type) + break :blk ZigTag.void_type.init(); + } else { + break :blk transType(c, scope, return_ty, .standard, source_loc) catch |err| switch (err) { + error.UnsupportedType => { + try warn(c, scope, source_loc, "unsupported function proto return type", .{}); + return err; + }, + error.OutOfMemory => |e| return e, + }; + } + } + }; + + const payload = try c.arena.create(ast.Payload.Func); + payload.* = .{ + .base = .{ .tag = .func }, + .data = .{ + .is_pub = ctx.is_pub, + .is_extern = ctx.is_extern, + .is_export = ctx.is_export, + .is_inline = ctx.is_inline, + .is_var_args = switch (fn_ty.specifier) { + .func => false, + .var_args_func => true, + .old_style_func => !ctx.is_export and !ctx.is_inline, + else => unreachable, + }, + .name = ctx.fn_name, + .linksection_string = linksection_string, + .explicit_callconv = explicit_callconv, + .params = fn_params, + .return_type = return_type_node, + .body = null, + .alignment = alignment, + }, + }; + return ZigNode.initPayload(&payload.base); +} + +fn transStmt(c: *Context, node: NodeIndex) TransError!ZigNode { + _ = c; + _ = node; + return error.UnsupportedTranslation; +} + +fn transCompoundStmtInline(c: *Context, compound: NodeIndex, block: *Scope.Block) TransError!void { + const data = c.tree.nodes.items(.data)[@intFromEnum(compound)]; + var buf: [2]NodeIndex = undefined; + // TODO move these helpers to Aro + const stmts = switch (c.tree.nodes.items(.tag)[@intFromEnum(compound)]) { + .compound_stmt_two => blk: { + if (data.bin.lhs != .none) buf[0] = data.bin.lhs; + if (data.bin.rhs != .none) buf[1] = data.bin.rhs; + break :blk buf[0 .. @as(u32, @intFromBool(data.bin.lhs != .none)) + @intFromBool(data.bin.rhs != .none)]; + }, + .compound_stmt => c.tree.data[data.range.start..data.range.end], + else => unreachable, + }; + for (stmts) |stmt| { + const result = try transStmt(c, stmt); + switch (result.tag()) { + .declaration, .empty_block => {}, + else => try block.statements.append(result), + } + } +} + +fn recordHasBitfield(record: *const Type.Record) bool { + if (record.isIncomplete()) return false; + for (record.fields) |field| { + if (!field.isRegularField()) return true; + } + return false; +} + +fn typeIsOpaque(c: *Context, ty: Type) bool { + return switch (ty.specifier) { + .void => true, + .@"struct", .@"union" => recordHasBitfield(ty.getRecord().?), + .typeof_type => typeIsOpaque(c, ty.data.sub_type.*), + .typeof_expr => typeIsOpaque(c, ty.data.expr.ty), + .attributed => typeIsOpaque(c, ty.data.attributed.base), + else => false, + }; +} + +fn typeWasDemotedToOpaque(c: *Context, ty: Type) bool { + switch (ty.specifier) { + .@"struct", .@"union" => { + const record = ty.getRecord().?; + if (c.opaque_demotes.contains(@intFromPtr(record))) return true; + for (record.fields) |field| { + if (typeWasDemotedToOpaque(c, field.ty)) return true; + } + return false; + }, + + .@"enum" => return c.opaque_demotes.contains(@intFromPtr(ty.data.@"enum")), + + .typeof_type => return typeWasDemotedToOpaque(c, ty.data.sub_type.*), + .typeof_expr => return typeWasDemotedToOpaque(c, ty.data.expr.ty), + .attributed => return typeWasDemotedToOpaque(c, ty.data.attributed.base), + else => return false, + } +} + +fn transCompoundStmt(c: *Context, scope: *Scope, compound: NodeIndex) TransError!ZigNode { + var block_scope = try Scope.Block.init(c, scope, false); + defer block_scope.deinit(); + try transCompoundStmtInline(c, compound, &block_scope); + return try block_scope.complete(c); +} + +fn transExpr(c: *Context, node: NodeIndex, result_used: ResultUsed) TransError!ZigNode { + std.debug.assert(node != .none); + const ty = c.tree.nodes.items(.ty)[@intFromEnum(node)]; + if (c.tree.value_map.get(node)) |val| { + // TODO handle other values + const int = try transCreateNodeAPInt(c, val); + const as_node = try ZigTag.as.create(c.arena, .{ + .lhs = try transType(c, undefined, ty, .standard, undefined), + .rhs = int, + }); + return maybeSuppressResult(c, result_used, as_node); + } + const node_tags = c.tree.nodes.items(.tag); + switch (node_tags[@intFromEnum(node)]) { + else => unreachable, // Not an expression. + } + return .none; +} + +fn transCreateNodeAPInt(c: *Context, int: aro.Value) !ZigNode { + var space: aro.Interner.Tag.Int.BigIntSpace = undefined; + var big = int.toBigInt(&space, c.comp); + const is_negative = !big.positive; + big.positive = true; + + const str = big.toStringAlloc(c.arena, 10, .lower) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + }; + const res = try ZigTag.integer_literal.create(c.arena, str); + if (is_negative) return ZigTag.negate.create(c.arena, res); + return res; +} + +pub const PatternList = struct { + patterns: []Pattern, + + /// Templates must be function-like macros + /// first element is macro source, second element is the name of the function + /// in std.lib.zig.c_translation.Macros which implements it + const templates = [_][2][]const u8{ + [2][]const u8{ "f_SUFFIX(X) (X ## f)", "F_SUFFIX" }, + [2][]const u8{ "F_SUFFIX(X) (X ## F)", "F_SUFFIX" }, + + [2][]const u8{ "u_SUFFIX(X) (X ## u)", "U_SUFFIX" }, + [2][]const u8{ "U_SUFFIX(X) (X ## U)", "U_SUFFIX" }, + + [2][]const u8{ "l_SUFFIX(X) (X ## l)", "L_SUFFIX" }, + [2][]const u8{ "L_SUFFIX(X) (X ## L)", "L_SUFFIX" }, + + [2][]const u8{ "ul_SUFFIX(X) (X ## ul)", "UL_SUFFIX" }, + [2][]const u8{ "uL_SUFFIX(X) (X ## uL)", "UL_SUFFIX" }, + [2][]const u8{ "Ul_SUFFIX(X) (X ## Ul)", "UL_SUFFIX" }, + [2][]const u8{ "UL_SUFFIX(X) (X ## UL)", "UL_SUFFIX" }, + + [2][]const u8{ "ll_SUFFIX(X) (X ## ll)", "LL_SUFFIX" }, + [2][]const u8{ "LL_SUFFIX(X) (X ## LL)", "LL_SUFFIX" }, + + [2][]const u8{ "ull_SUFFIX(X) (X ## ull)", "ULL_SUFFIX" }, + [2][]const u8{ "uLL_SUFFIX(X) (X ## uLL)", "ULL_SUFFIX" }, + [2][]const u8{ "Ull_SUFFIX(X) (X ## Ull)", "ULL_SUFFIX" }, + [2][]const u8{ "ULL_SUFFIX(X) (X ## ULL)", "ULL_SUFFIX" }, + + [2][]const u8{ "f_SUFFIX(X) X ## f", "F_SUFFIX" }, + [2][]const u8{ "F_SUFFIX(X) X ## F", "F_SUFFIX" }, + + [2][]const u8{ "u_SUFFIX(X) X ## u", "U_SUFFIX" }, + [2][]const u8{ "U_SUFFIX(X) X ## U", "U_SUFFIX" }, + + [2][]const u8{ "l_SUFFIX(X) X ## l", "L_SUFFIX" }, + [2][]const u8{ "L_SUFFIX(X) X ## L", "L_SUFFIX" }, + + [2][]const u8{ "ul_SUFFIX(X) X ## ul", "UL_SUFFIX" }, + [2][]const u8{ "uL_SUFFIX(X) X ## uL", "UL_SUFFIX" }, + [2][]const u8{ "Ul_SUFFIX(X) X ## Ul", "UL_SUFFIX" }, + [2][]const u8{ "UL_SUFFIX(X) X ## UL", "UL_SUFFIX" }, + + [2][]const u8{ "ll_SUFFIX(X) X ## ll", "LL_SUFFIX" }, + [2][]const u8{ "LL_SUFFIX(X) X ## LL", "LL_SUFFIX" }, + + [2][]const u8{ "ull_SUFFIX(X) X ## ull", "ULL_SUFFIX" }, + [2][]const u8{ "uLL_SUFFIX(X) X ## uLL", "ULL_SUFFIX" }, + [2][]const u8{ "Ull_SUFFIX(X) X ## Ull", "ULL_SUFFIX" }, + [2][]const u8{ "ULL_SUFFIX(X) X ## ULL", "ULL_SUFFIX" }, + + [2][]const u8{ "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL" }, + [2][]const u8{ "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL" }, + + [2][]const u8{ + \\wl_container_of(ptr, sample, member) \ + \\(__typeof__(sample))((char *)(ptr) - \ + \\ offsetof(__typeof__(*sample), member)) + , + "WL_CONTAINER_OF", + }, + + [2][]const u8{ "IGNORE_ME(X) ((void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((const void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (const void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((volatile void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (volatile void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (const volatile void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (volatile const void)(X)", "DISCARD" }, + }; + + /// Assumes that `ms` represents a tokenized function-like macro. + fn buildArgsHash(allocator: mem.Allocator, ms: MacroSlicer, hash: *ArgsPositionMap) MacroProcessingError!void { + assert(ms.tokens.len > 2); + assert(ms.tokens[0].id == .identifier or ms.tokens[0].id == .extended_identifier); + assert(ms.tokens[1].id == .l_paren); + + var i: usize = 2; + while (true) : (i += 1) { + const token = ms.tokens[i]; + switch (token.id) { + .r_paren => break, + .comma => continue, + .identifier, .extended_identifier => { + const identifier = ms.slice(token); + try hash.put(allocator, identifier, i); + }, + else => return error.UnexpectedMacroToken, + } + } + } + + const Pattern = struct { + tokens: []const CToken, + source: []const u8, + impl: []const u8, + args_hash: ArgsPositionMap, + + fn init(self: *Pattern, allocator: mem.Allocator, template: [2][]const u8) Error!void { + const source = template[0]; + const impl = template[1]; + + var tok_list = std.ArrayList(CToken).init(allocator); + defer tok_list.deinit(); + try tokenizeMacro(source, &tok_list); + const tokens = try allocator.dupe(CToken, tok_list.items); + + self.* = .{ + .tokens = tokens, + .source = source, + .impl = impl, + .args_hash = .{}, + }; + const ms = MacroSlicer{ .source = source, .tokens = tokens }; + buildArgsHash(allocator, ms, &self.args_hash) catch |err| switch (err) { + error.UnexpectedMacroToken => unreachable, + else => |e| return e, + }; + } + + fn deinit(self: *Pattern, allocator: mem.Allocator) void { + self.args_hash.deinit(allocator); + allocator.free(self.tokens); + } + + /// This function assumes that `ms` has already been validated to contain a function-like + /// macro, and that the parsed template macro in `self` also contains a function-like + /// macro. Please review this logic carefully if changing that assumption. Two + /// function-like macros are considered equivalent if and only if they contain the same + /// list of tokens, modulo parameter names. + pub fn isEquivalent(self: Pattern, ms: MacroSlicer, args_hash: ArgsPositionMap) bool { + if (self.tokens.len != ms.tokens.len) return false; + if (args_hash.count() != self.args_hash.count()) return false; + + var i: usize = 2; + while (self.tokens[i].id != .r_paren) : (i += 1) {} + + const pattern_slicer = MacroSlicer{ .source = self.source, .tokens = self.tokens }; + while (i < self.tokens.len) : (i += 1) { + const pattern_token = self.tokens[i]; + const macro_token = ms.tokens[i]; + if (pattern_token.id != macro_token.id) return false; + + const pattern_bytes = pattern_slicer.slice(pattern_token); + const macro_bytes = ms.slice(macro_token); + switch (pattern_token.id) { + .identifier, .extended_identifier => { + const pattern_arg_index = self.args_hash.get(pattern_bytes); + const macro_arg_index = args_hash.get(macro_bytes); + + if (pattern_arg_index == null and macro_arg_index == null) { + if (!mem.eql(u8, pattern_bytes, macro_bytes)) return false; + } else if (pattern_arg_index != null and macro_arg_index != null) { + if (pattern_arg_index.? != macro_arg_index.?) return false; + } else { + return false; + } + }, + .string_literal, .char_literal, .pp_num => { + if (!mem.eql(u8, pattern_bytes, macro_bytes)) return false; + }, + else => { + // other tags correspond to keywords and operators that do not contain a "payload" + // that can vary + }, + } + } + return true; + } + }; + + pub fn init(allocator: mem.Allocator) Error!PatternList { + const patterns = try allocator.alloc(Pattern, templates.len); + for (templates, 0..) |template, i| { + try patterns[i].init(allocator, template); + } + return PatternList{ .patterns = patterns }; + } + + pub fn deinit(self: *PatternList, allocator: mem.Allocator) void { + for (self.patterns) |*pattern| pattern.deinit(allocator); + allocator.free(self.patterns); + } + + pub fn match(self: PatternList, allocator: mem.Allocator, ms: MacroSlicer) Error!?Pattern { + var args_hash: ArgsPositionMap = .{}; + defer args_hash.deinit(allocator); + + buildArgsHash(allocator, ms, &args_hash) catch |err| switch (err) { + error.UnexpectedMacroToken => return null, + else => |e| return e, + }; + + for (self.patterns) |pattern| if (pattern.isEquivalent(ms, args_hash)) return pattern; + return null; + } +}; + +pub const MacroSlicer = struct { + source: []const u8, + tokens: []const CToken, + + pub fn slice(self: MacroSlicer, token: CToken) []const u8 { + return self.source[token.start..token.end]; + } +}; + +// Maps macro parameter names to token position, for determining if different +// identifiers refer to the same positional argument in different macros. +pub const ArgsPositionMap = std.StringArrayHashMapUnmanaged(usize); + +pub const Error = std.mem.Allocator.Error; +pub const MacroProcessingError = Error || error{UnexpectedMacroToken}; +pub const TypeError = Error || error{UnsupportedType}; +pub const TransError = TypeError || error{UnsupportedTranslation}; + +pub const SymbolTable = std.StringArrayHashMap(ast.Node); +pub const AliasList = std.ArrayList(struct { + alias: []const u8, + name: []const u8, +}); + +pub const ResultUsed = enum { + used, + unused, +}; + +pub fn ScopeExtra(comptime ScopeExtraContext: type, comptime ScopeExtraType: type) type { + return struct { + id: Id, + parent: ?*ScopeExtraScope, + + const ScopeExtraScope = @This(); + + pub const Id = enum { + block, + root, + condition, + loop, + do_loop, + }; + + /// Used for the scope of condition expressions, for example `if (cond)`. + /// The block is lazily initialised because it is only needed for rare + /// cases of comma operators being used. + pub const Condition = struct { + base: ScopeExtraScope, + block: ?Block = null, + + pub fn getBlockScope(self: *Condition, c: *ScopeExtraContext) !*Block { + if (self.block) |*b| return b; + self.block = try Block.init(c, &self.base, true); + return &self.block.?; + } + + pub fn deinit(self: *Condition) void { + if (self.block) |*b| b.deinit(); + } + }; + + /// Represents an in-progress Node.Block. This struct is stack-allocated. + /// When it is deinitialized, it produces an Node.Block which is allocated + /// into the main arena. + pub const Block = struct { + base: ScopeExtraScope, + statements: std.ArrayList(ast.Node), + variables: AliasList, + mangle_count: u32 = 0, + label: ?[]const u8 = null, + + /// By default all variables are discarded, since we do not know in advance if they + /// will be used. This maps the variable's name to the Discard payload, so that if + /// the variable is subsequently referenced we can indicate that the discard should + /// be skipped during the intermediate AST -> Zig AST render step. + variable_discards: std.StringArrayHashMap(*ast.Payload.Discard), + + /// When the block corresponds to a function, keep track of the return type + /// so that the return expression can be cast, if necessary + return_type: ?ScopeExtraType = null, + + /// C static local variables are wrapped in a block-local struct. The struct + /// is named after the (mangled) variable name, the Zig variable within the + /// struct itself is given this name. + pub const static_inner_name = "static"; + + /// C extern variables declared within a block are wrapped in a block-local + /// struct. The struct is named ExternLocal_[variable_name], the Zig variable + /// within the struct itself is [variable_name] by neccessity since it's an + /// extern reference to an existing symbol. + pub const extern_inner_prepend = "ExternLocal"; + + pub fn init(c: *ScopeExtraContext, parent: *ScopeExtraScope, labeled: bool) !Block { + var blk = Block{ + .base = .{ + .id = .block, + .parent = parent, + }, + .statements = std.ArrayList(ast.Node).init(c.gpa), + .variables = AliasList.init(c.gpa), + .variable_discards = std.StringArrayHashMap(*ast.Payload.Discard).init(c.gpa), + }; + if (labeled) { + blk.label = try blk.makeMangledName(c, "blk"); + } + return blk; + } + + pub fn deinit(self: *Block) void { + self.statements.deinit(); + self.variables.deinit(); + self.variable_discards.deinit(); + self.* = undefined; + } + + pub fn complete(self: *Block, c: *ScopeExtraContext) !ast.Node { + if (self.base.parent.?.id == .do_loop) { + // We reserve 1 extra statement if the parent is a do_loop. This is in case of + // do while, we want to put `if (cond) break;` at the end. + const alloc_len = self.statements.items.len + @intFromBool(self.base.parent.?.id == .do_loop); + var stmts = try c.arena.alloc(ast.Node, alloc_len); + stmts.len = self.statements.items.len; + @memcpy(stmts[0..self.statements.items.len], self.statements.items); + return ast.Node.Tag.block.create(c.arena, .{ + .label = self.label, + .stmts = stmts, + }); + } + if (self.statements.items.len == 0) return ast.Node.Tag.empty_block.init(); + return ast.Node.Tag.block.create(c.arena, .{ + .label = self.label, + .stmts = try c.arena.dupe(ast.Node, self.statements.items), + }); + } + + /// Given the desired name, return a name that does not shadow anything from outer scopes. + /// Inserts the returned name into the scope. + /// The name will not be visible to callers of getAlias. + pub fn reserveMangledName(scope: *Block, c: *ScopeExtraContext, name: []const u8) ![]const u8 { + return scope.createMangledName(c, name, true); + } + + /// Same as reserveMangledName, but enables the alias immediately. + pub fn makeMangledName(scope: *Block, c: *ScopeExtraContext, name: []const u8) ![]const u8 { + return scope.createMangledName(c, name, false); + } + + pub fn createMangledName(scope: *Block, c: *ScopeExtraContext, name: []const u8, reservation: bool) ![]const u8 { + const name_copy = try c.arena.dupe(u8, name); + var proposed_name = name_copy; + while (scope.contains(proposed_name)) { + scope.mangle_count += 1; + proposed_name = try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ name, scope.mangle_count }); + } + const new_mangle = try scope.variables.addOne(); + if (reservation) { + new_mangle.* = .{ .name = name_copy, .alias = name_copy }; + } else { + new_mangle.* = .{ .name = name_copy, .alias = proposed_name }; + } + return proposed_name; + } + + pub fn getAlias(scope: *Block, name: []const u8) []const u8 { + for (scope.variables.items) |p| { + if (std.mem.eql(u8, p.name, name)) + return p.alias; + } + return scope.base.parent.?.getAlias(name); + } + + /// Finds the (potentially) mangled struct name for a locally scoped extern variable or function given the original declaration name. + /// + /// Block scoped extern declarations translate to: + /// const MangledStructName = struct {extern [qualifiers] original_extern_variable_name: [type]}; + /// This finds MangledStructName given original_extern_variable_name for referencing correctly in transDeclRefExpr() + pub fn getLocalExternAlias(scope: *Block, name: []const u8) ?[]const u8 { + for (scope.statements.items) |node| { + switch (node.tag()) { + .extern_local_var => { + const parent_node = node.castTag(.extern_local_var).?; + const init_node = parent_node.data.init.castTag(.var_decl).?; + if (std.mem.eql(u8, init_node.data.name, name)) { + return parent_node.data.name; + } + }, + .extern_local_fn => { + const parent_node = node.castTag(.extern_local_fn).?; + const init_node = parent_node.data.init.castTag(.func).?; + if (std.mem.eql(u8, init_node.data.name.?, name)) { + return parent_node.data.name; + } + }, + else => {}, + } + } + return null; + } + + pub fn localContains(scope: *Block, name: []const u8) bool { + for (scope.variables.items) |p| { + if (std.mem.eql(u8, p.alias, name)) + return true; + } + return false; + } + + pub fn contains(scope: *Block, name: []const u8) bool { + if (scope.localContains(name)) + return true; + return scope.base.parent.?.contains(name); + } + + pub fn discardVariable(scope: *Block, c: *ScopeExtraContext, name: []const u8) Error!void { + const name_node = try ast.Node.Tag.identifier.create(c.arena, name); + const discard = try ast.Node.Tag.discard.create(c.arena, .{ .should_skip = false, .value = name_node }); + try scope.statements.append(discard); + try scope.variable_discards.putNoClobber(name, discard.castTag(.discard).?); + } + }; + + pub const Root = struct { + base: ScopeExtraScope, + sym_table: SymbolTable, + blank_macros: std.StringArrayHashMap(void), + context: *ScopeExtraContext, + nodes: std.ArrayList(ast.Node), + + pub fn init(c: *ScopeExtraContext) Root { + return .{ + .base = .{ + .id = .root, + .parent = null, + }, + .sym_table = SymbolTable.init(c.gpa), + .blank_macros = std.StringArrayHashMap(void).init(c.gpa), + .context = c, + .nodes = std.ArrayList(ast.Node).init(c.gpa), + }; + } + + pub fn deinit(scope: *Root) void { + scope.sym_table.deinit(); + scope.blank_macros.deinit(); + scope.nodes.deinit(); + } + + /// Check if the global scope contains this name, without looking into the "future", e.g. + /// ignore the preprocessed decl and macro names. + pub fn containsNow(scope: *Root, name: []const u8) bool { + return scope.sym_table.contains(name); + } + + /// Check if the global scope contains the name, includes all decls that haven't been translated yet. + pub fn contains(scope: *Root, name: []const u8) bool { + return scope.containsNow(name) or scope.context.global_names.contains(name) or scope.context.weak_global_names.contains(name); + } + }; + + pub fn findBlockScope(inner: *ScopeExtraScope, c: *ScopeExtraContext) !*Block { + var scope = inner; + while (true) { + switch (scope.id) { + .root => unreachable, + .block => return @fieldParentPtr("base", scope), + .condition => return @as(*Condition, @fieldParentPtr("base", scope)).getBlockScope(c), + else => scope = scope.parent.?, + } + } + } + + pub fn findBlockReturnType(inner: *ScopeExtraScope) ScopeExtraType { + var scope = inner; + while (true) { + switch (scope.id) { + .root => unreachable, + .block => { + const block: *Block = @fieldParentPtr("base", scope); + if (block.return_type) |ty| return ty; + scope = scope.parent.?; + }, + else => scope = scope.parent.?, + } + } + } + + pub fn getAlias(scope: *ScopeExtraScope, name: []const u8) []const u8 { + return switch (scope.id) { + .root => name, + .block => @as(*Block, @fieldParentPtr("base", scope)).getAlias(name), + .loop, .do_loop, .condition => scope.parent.?.getAlias(name), + }; + } + + pub fn getLocalExternAlias(scope: *ScopeExtraScope, name: []const u8) ?[]const u8 { + return switch (scope.id) { + .root => null, + .block => ret: { + const block = @as(*Block, @fieldParentPtr("base", scope)); + const alias_name = block.getLocalExternAlias(name); + if (alias_name) |_alias_name| { + break :ret _alias_name; + } + break :ret scope.parent.?.getLocalExternAlias(name); + }, + .loop, .do_loop, .condition => scope.parent.?.getLocalExternAlias(name), + }; + } + + pub fn contains(scope: *ScopeExtraScope, name: []const u8) bool { + return switch (scope.id) { + .root => @as(*Root, @fieldParentPtr("base", scope)).contains(name), + .block => @as(*Block, @fieldParentPtr("base", scope)).contains(name), + .loop, .do_loop, .condition => scope.parent.?.contains(name), + }; + } + + pub fn getBreakableScope(inner: *ScopeExtraScope) *ScopeExtraScope { + var scope = inner; + while (true) { + switch (scope.id) { + .root => unreachable, + .loop, .do_loop => return scope, + else => scope = scope.parent.?, + } + } + } + + /// Appends a node to the first block scope if inside a function, or to the root tree if not. + pub fn appendNode(inner: *ScopeExtraScope, node: ast.Node) !void { + var scope = inner; + while (true) { + switch (scope.id) { + .root => { + const root: *Root = @fieldParentPtr("base", scope); + return root.nodes.append(node); + }, + .block => { + const block: *Block = @fieldParentPtr("base", scope); + return block.statements.append(node); + }, + else => scope = scope.parent.?, + } + } + } + + pub fn skipVariableDiscard(inner: *ScopeExtraScope, name: []const u8) void { + if (true) { + // TODO: due to 'local variable is never mutated' errors, we can + // only skip discards if a variable is used as an lvalue, which + // we don't currently have detection for in translate-c. + // Once #17584 is completed, perhaps we can do away with this + // logic entirely, and instead rely on render to fixup code. + return; + } + var scope = inner; + while (true) { + switch (scope.id) { + .root => return, + .block => { + const block: *Block = @fieldParentPtr("base", scope); + if (block.variable_discards.get(name)) |discard| { + discard.data.should_skip = true; + return; + } + }, + else => {}, + } + scope = scope.parent.?; + } + } + }; +} + +pub fn tokenizeMacro(source: []const u8, tok_list: *std.ArrayList(CToken)) Error!void { + var tokenizer: aro.Tokenizer = .{ + .buf = source, + .source = .unused, + .langopts = .{}, + }; + while (true) { + const tok = tokenizer.next(); + switch (tok.id) { + .whitespace => continue, + .nl, .eof => { + try tok_list.append(tok); + break; + }, + else => {}, + } + try tok_list.append(tok); + } +} + +// Testing here instead of test/translate_c.zig allows us to also test that the +// mapped function exists in `std.zig.c_translation.Macros` +test "Macro matching" { + const testing = std.testing; + const helper = struct { + const MacroFunctions = std.zig.c_translation.Macros; + fn checkMacro(allocator: mem.Allocator, pattern_list: PatternList, source: []const u8, comptime expected_match: ?[]const u8) !void { + var tok_list = std.ArrayList(CToken).init(allocator); + defer tok_list.deinit(); + try tokenizeMacro(source, &tok_list); + const macro_slicer: MacroSlicer = .{ .source = source, .tokens = tok_list.items }; + const matched = try pattern_list.match(allocator, macro_slicer); + if (expected_match) |expected| { + try testing.expectEqualStrings(expected, matched.?.impl); + try testing.expect(@hasDecl(MacroFunctions, expected)); + } else { + try testing.expectEqual(@as(@TypeOf(matched), null), matched); + } + } + }; + const allocator = std.testing.allocator; + var pattern_list = try PatternList.init(allocator); + defer pattern_list.deinit(allocator); + + try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## F)", "F_SUFFIX"); + try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## U)", "U_SUFFIX"); + try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## L)", "L_SUFFIX"); + try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## LL)", "LL_SUFFIX"); + try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## UL)", "UL_SUFFIX"); + try helper.checkMacro(allocator, pattern_list, "BAR(Z) (Z ## ULL)", "ULL_SUFFIX"); + try helper.checkMacro(allocator, pattern_list, + \\container_of(a, b, c) \ + \\(__typeof__(b))((char *)(a) - \ + \\ offsetof(__typeof__(*b), c)) + , "WL_CONTAINER_OF"); + + try helper.checkMacro(allocator, pattern_list, "NO_MATCH(X, Y) (X + Y)", null); + try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL"); + try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const volatile void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile const void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD"); +} + +/// Renders errors and fatal errors + associated notes (e.g. "expanded from here"); does not render warnings or associated notes +/// Terminates with exit code 1 +fn renderErrorsAndExit(comp: *aro.Compilation) noreturn { + defer std.process.exit(1); + + var writer = aro.Diagnostics.defaultMsgWriter(std.io.tty.detectConfig(std.io.getStdErr())); + defer writer.deinit(); // writer deinit must run *before* exit so that stderr is flushed + + var saw_error = false; + for (comp.diagnostics.list.items) |msg| { + switch (msg.kind) { + .@"error", .@"fatal error" => { + saw_error = true; + aro.Diagnostics.renderMessage(comp, &writer, msg); + }, + .warning => saw_error = false, + .note => { + if (saw_error) { + aro.Diagnostics.renderMessage(comp, &writer, msg); + } + }, + .off => {}, + .default => unreachable, + } + } +} + +pub fn main() !void { + var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena_instance.deinit(); + const arena = arena_instance.allocator(); + + var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; + const gpa = general_purpose_allocator.allocator(); + + const args = try std.process.argsAlloc(arena); + + var aro_comp = aro.Compilation.init(gpa, std.fs.cwd()); + defer aro_comp.deinit(); + + var tree = translate(gpa, &aro_comp, args) catch |err| switch (err) { + error.ParsingFailed, error.FatalError => renderErrorsAndExit(&aro_comp), + error.OutOfMemory => return error.OutOfMemory, + error.StreamTooLong => std.zig.fatal("An input file was larger than 4GiB", .{}), + }; + defer tree.deinit(gpa); + + const formatted = try tree.render(arena); + try std.io.getStdOut().writeAll(formatted); + return std.process.cleanExit(); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro_translate_c/ast.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro_translate_c/ast.zig new file mode 100644 index 00000000..b3b0e98a --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/aro_translate_c/ast.zig @@ -0,0 +1,3039 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; + +pub const Node = extern union { + /// If the tag value is less than Tag.no_payload_count, then no pointer + /// dereference is needed. + tag_if_small_enough: usize, + ptr_otherwise: *Payload, + + pub const Tag = enum { + /// Declarations add themselves to the correct scopes and should not be emitted as this tag. + declaration, + null_literal, + undefined_literal, + /// opaque {} + opaque_literal, + true_literal, + false_literal, + empty_block, + return_void, + zero_literal, + one_literal, + void_type, + noreturn_type, + @"anytype", + @"continue", + @"break", + // After this, the tag requires a payload. + + integer_literal, + float_literal, + string_literal, + char_literal, + enum_literal, + /// "string"[0..end] + string_slice, + identifier, + fn_identifier, + @"if", + /// if (!operand) break; + if_not_break, + @"while", + /// while (true) operand + while_true, + @"switch", + /// else => operand, + switch_else, + /// items => body, + switch_prong, + break_val, + @"return", + field_access, + array_access, + call, + var_decl, + /// const name = struct { init } + static_local_var, + /// const ExternLocal_name = struct { init } + extern_local_var, + /// const ExternLocal_name = struct { init } + extern_local_fn, + /// var name = init.* + mut_str, + func, + warning, + @"struct", + @"union", + @"comptime", + @"defer", + array_init, + tuple, + container_init, + container_init_dot, + helpers_cast, + /// _ = operand; + discard, + + // a + b + add, + // a = b + add_assign, + // c = (a = b) + add_wrap, + add_wrap_assign, + sub, + sub_assign, + sub_wrap, + sub_wrap_assign, + mul, + mul_assign, + mul_wrap, + mul_wrap_assign, + div, + div_assign, + shl, + shl_assign, + shr, + shr_assign, + mod, + mod_assign, + @"and", + @"or", + less_than, + less_than_equal, + greater_than, + greater_than_equal, + equal, + not_equal, + bit_and, + bit_and_assign, + bit_or, + bit_or_assign, + bit_xor, + bit_xor_assign, + array_cat, + ellipsis3, + assign, + + /// @import("std").zig.c_builtins. + import_c_builtin, + /// @intCast(operand) + int_cast, + /// @constCast(operand) + const_cast, + /// @volatileCast(operand) + volatile_cast, + /// @import("std").zig.c_translation.promoteIntLiteral(value, type, base) + helpers_promoteIntLiteral, + /// @import("std").zig.c_translation.signedRemainder(lhs, rhs) + signed_remainder, + /// @divTrunc(lhs, rhs) + div_trunc, + /// @intFromBool(operand) + int_from_bool, + /// @as(lhs, rhs) + as, + /// @truncate(operand) + truncate, + /// @bitCast(operand) + bit_cast, + /// @floatCast(operand) + float_cast, + /// @intFromFloat(operand) + int_from_float, + /// @floatFromInt(operand) + float_from_int, + /// @ptrFromInt(operand) + ptr_from_int, + /// @intFromPtr(operand) + int_from_ptr, + /// @alignCast(operand) + align_cast, + /// @ptrCast(operand) + ptr_cast, + /// @divExact(lhs, rhs) + div_exact, + /// @offsetOf(lhs, rhs) + offset_of, + /// @splat(operand) + vector_zero_init, + /// @shuffle(type, a, b, mask) + shuffle, + /// @extern(ty, .{ .name = n }) + builtin_extern, + + /// @import("std").zig.c_translation.MacroArithmetic.(lhs, rhs) + macro_arithmetic, + + asm_simple, + + negate, + negate_wrap, + bit_not, + not, + address_of, + /// .? + unwrap, + /// .* + deref, + + block, + /// { operand } + block_single, + + sizeof, + alignof, + typeof, + typeinfo, + type, + + optional_type, + c_pointer, + single_pointer, + array_type, + null_sentinel_array_type, + + /// @import("std").zig.c_translation.sizeof(operand) + helpers_sizeof, + /// @import("std").zig.c_translation.FlexibleArrayType(lhs, rhs) + helpers_flexible_array_type, + /// @import("std").zig.c_translation.shuffleVectorIndex(lhs, rhs) + helpers_shuffle_vector_index, + /// @import("std").zig.c_translation.Macro. + helpers_macro, + /// @Vector(lhs, rhs) + vector, + /// @import("std").mem.zeroes(operand) + std_mem_zeroes, + /// @import("std").mem.zeroInit(lhs, rhs) + std_mem_zeroinit, + // pub const name = @compileError(msg); + fail_decl, + // var actual = mangled; + arg_redecl, + /// pub const alias = actual; + alias, + /// const name = init; + var_simple, + /// pub const name = init; + pub_var_simple, + /// pub? const name (: type)? = value + enum_constant, + + /// pub inline fn name(params) return_type body + pub_inline_fn, + + /// [0]type{} + empty_array, + /// [1]type{val} ** count + array_filler, + + pub const last_no_payload_tag = Tag.@"break"; + pub const no_payload_count = @intFromEnum(last_no_payload_tag) + 1; + + pub fn Type(comptime t: Tag) type { + return switch (t) { + .declaration, + .null_literal, + .undefined_literal, + .opaque_literal, + .true_literal, + .false_literal, + .empty_block, + .return_void, + .zero_literal, + .one_literal, + .void_type, + .noreturn_type, + .@"anytype", + .@"continue", + .@"break", + => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"), + + .std_mem_zeroes, + .@"return", + .@"comptime", + .@"defer", + .asm_simple, + .negate, + .negate_wrap, + .bit_not, + .not, + .optional_type, + .address_of, + .unwrap, + .deref, + .int_from_ptr, + .empty_array, + .while_true, + .if_not_break, + .switch_else, + .block_single, + .helpers_sizeof, + .int_from_bool, + .sizeof, + .alignof, + .typeof, + .typeinfo, + .align_cast, + .truncate, + .bit_cast, + .float_cast, + .int_from_float, + .float_from_int, + .ptr_from_int, + .ptr_cast, + .int_cast, + .const_cast, + .volatile_cast, + .vector_zero_init, + => Payload.UnOp, + + .add, + .add_assign, + .add_wrap, + .add_wrap_assign, + .sub, + .sub_assign, + .sub_wrap, + .sub_wrap_assign, + .mul, + .mul_assign, + .mul_wrap, + .mul_wrap_assign, + .div, + .div_assign, + .shl, + .shl_assign, + .shr, + .shr_assign, + .mod, + .mod_assign, + .@"and", + .@"or", + .less_than, + .less_than_equal, + .greater_than, + .greater_than_equal, + .equal, + .not_equal, + .bit_and, + .bit_and_assign, + .bit_or, + .bit_or_assign, + .bit_xor, + .bit_xor_assign, + .div_trunc, + .signed_remainder, + .as, + .array_cat, + .ellipsis3, + .assign, + .array_access, + .std_mem_zeroinit, + .helpers_flexible_array_type, + .helpers_shuffle_vector_index, + .vector, + .div_exact, + .offset_of, + .helpers_cast, + => Payload.BinOp, + + .integer_literal, + .float_literal, + .string_literal, + .char_literal, + .enum_literal, + .identifier, + .fn_identifier, + .warning, + .type, + .helpers_macro, + .import_c_builtin, + => Payload.Value, + .discard => Payload.Discard, + .@"if" => Payload.If, + .@"while" => Payload.While, + .@"switch", .array_init, .switch_prong => Payload.Switch, + .break_val => Payload.BreakVal, + .call => Payload.Call, + .var_decl => Payload.VarDecl, + .func => Payload.Func, + .@"struct", .@"union" => Payload.Record, + .tuple => Payload.TupleInit, + .container_init => Payload.ContainerInit, + .container_init_dot => Payload.ContainerInitDot, + .helpers_promoteIntLiteral => Payload.PromoteIntLiteral, + .block => Payload.Block, + .c_pointer, .single_pointer => Payload.Pointer, + .array_type, .null_sentinel_array_type => Payload.Array, + .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl, + .var_simple, + .pub_var_simple, + .static_local_var, + .extern_local_var, + .extern_local_fn, + .mut_str, + => Payload.SimpleVarDecl, + .enum_constant => Payload.EnumConstant, + .array_filler => Payload.ArrayFiller, + .pub_inline_fn => Payload.PubInlineFn, + .field_access => Payload.FieldAccess, + .string_slice => Payload.StringSlice, + .shuffle => Payload.Shuffle, + .builtin_extern => Payload.Extern, + .macro_arithmetic => Payload.MacroArithmetic, + }; + } + + pub fn init(comptime t: Tag) Node { + comptime std.debug.assert(@intFromEnum(t) < Tag.no_payload_count); + return .{ .tag_if_small_enough = @intFromEnum(t) }; + } + + pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Node { + const ptr = try ally.create(t.Type()); + ptr.* = .{ + .base = .{ .tag = t }, + .data = data, + }; + return Node{ .ptr_otherwise = &ptr.base }; + } + + pub fn Data(comptime t: Tag) type { + return @FieldType(t.Type(), "data"); + } + }; + + pub fn tag(self: Node) Tag { + if (self.tag_if_small_enough < Tag.no_payload_count) { + return @as(Tag, @enumFromInt(@as(std.meta.Tag(Tag), @intCast(self.tag_if_small_enough)))); + } else { + return self.ptr_otherwise.tag; + } + } + + pub fn castTag(self: Node, comptime t: Tag) ?*t.Type() { + if (self.tag_if_small_enough < Tag.no_payload_count) + return null; + + if (self.ptr_otherwise.tag == t) + return @alignCast(@fieldParentPtr("base", self.ptr_otherwise)); + + return null; + } + + pub fn initPayload(payload: *Payload) Node { + std.debug.assert(@intFromEnum(payload.tag) >= Tag.no_payload_count); + return .{ .ptr_otherwise = payload }; + } + + pub fn isNoreturn(node: Node, break_counts: bool) bool { + switch (node.tag()) { + .block => { + const block_node = node.castTag(.block).?; + if (block_node.data.stmts.len == 0) return false; + + const last = block_node.data.stmts[block_node.data.stmts.len - 1]; + return last.isNoreturn(break_counts); + }, + .@"switch" => { + const switch_node = node.castTag(.@"switch").?; + + for (switch_node.data.cases) |case| { + const body = if (case.castTag(.switch_else)) |some| + some.data + else if (case.castTag(.switch_prong)) |some| + some.data.cond + else + unreachable; + + if (!body.isNoreturn(break_counts)) return false; + } + return true; + }, + .@"return", .return_void => return true, + .@"break" => if (break_counts) return true, + else => {}, + } + return false; + } +}; + +pub const Payload = struct { + tag: Node.Tag, + + pub const Value = struct { + base: Payload, + data: []const u8, + }; + + pub const UnOp = struct { + base: Payload, + data: Node, + }; + + pub const BinOp = struct { + base: Payload, + data: struct { + lhs: Node, + rhs: Node, + }, + }; + + pub const Discard = struct { + base: Payload, + data: struct { + should_skip: bool, + value: Node, + }, + }; + + pub const If = struct { + base: Payload, + data: struct { + cond: Node, + then: Node, + @"else": ?Node, + }, + }; + + pub const While = struct { + base: Payload, + data: struct { + cond: Node, + body: Node, + cont_expr: ?Node, + }, + }; + + pub const Switch = struct { + base: Payload, + data: struct { + cond: Node, + cases: []Node, + }, + }; + + pub const BreakVal = struct { + base: Payload, + data: struct { + label: ?[]const u8, + val: Node, + }, + }; + + pub const Call = struct { + base: Payload, + data: struct { + lhs: Node, + args: []Node, + }, + }; + + pub const VarDecl = struct { + base: Payload, + data: struct { + is_pub: bool, + is_const: bool, + is_extern: bool, + is_export: bool, + is_threadlocal: bool, + alignment: ?c_uint, + linksection_string: ?[]const u8, + name: []const u8, + type: Node, + init: ?Node, + }, + }; + + pub const Func = struct { + base: Payload, + data: struct { + is_pub: bool, + is_extern: bool, + is_export: bool, + is_inline: bool, + is_var_args: bool, + name: ?[]const u8, + linksection_string: ?[]const u8, + explicit_callconv: ?CallingConvention, + params: []Param, + return_type: Node, + body: ?Node, + alignment: ?c_uint, + }, + + pub const CallingConvention = enum { + c, + x86_64_sysv, + x86_64_win, + x86_stdcall, + x86_fastcall, + x86_thiscall, + x86_vectorcall, + aarch64_vfabi, + arm_aapcs, + arm_aapcs_vfp, + m68k_rtd, + }; + }; + + pub const Param = struct { + is_noalias: bool, + name: ?[]const u8, + type: Node, + }; + + pub const Record = struct { + base: Payload, + data: struct { + layout: enum { @"packed", @"extern", none }, + fields: []Field, + functions: []Node, + variables: []Node, + }, + + pub const Field = struct { + name: []const u8, + type: Node, + alignment: ?c_uint, + default_value: ?Node, + }; + }; + + pub const TupleInit = struct { + base: Payload, + data: []Node, + }; + + pub const ContainerInit = struct { + base: Payload, + data: struct { + lhs: Node, + inits: []Initializer, + }, + + pub const Initializer = struct { + name: []const u8, + value: Node, + }; + }; + + pub const ContainerInitDot = struct { + base: Payload, + data: []Initializer, + + pub const Initializer = struct { + name: []const u8, + value: Node, + }; + }; + + pub const Block = struct { + base: Payload, + data: struct { + label: ?[]const u8, + stmts: []Node, + }, + }; + + pub const Array = struct { + base: Payload, + data: ArrayTypeInfo, + + pub const ArrayTypeInfo = struct { + elem_type: Node, + len: usize, + }; + }; + + pub const Pointer = struct { + base: Payload, + data: struct { + elem_type: Node, + is_const: bool, + is_volatile: bool, + }, + }; + + pub const ArgRedecl = struct { + base: Payload, + data: struct { + actual: []const u8, + mangled: []const u8, + }, + }; + + pub const SimpleVarDecl = struct { + base: Payload, + data: struct { + name: []const u8, + init: Node, + }, + }; + + pub const EnumConstant = struct { + base: Payload, + data: struct { + name: []const u8, + is_public: bool, + type: ?Node, + value: Node, + }, + }; + + pub const ArrayFiller = struct { + base: Payload, + data: struct { + type: Node, + filler: Node, + count: usize, + }, + }; + + pub const PubInlineFn = struct { + base: Payload, + data: struct { + name: []const u8, + params: []Param, + return_type: Node, + body: Node, + }, + }; + + pub const FieldAccess = struct { + base: Payload, + data: struct { + lhs: Node, + field_name: []const u8, + }, + }; + + pub const PromoteIntLiteral = struct { + base: Payload, + data: struct { + value: Node, + type: Node, + base: Node, + }, + }; + + pub const StringSlice = struct { + base: Payload, + data: struct { + string: Node, + end: usize, + }, + }; + + pub const Shuffle = struct { + base: Payload, + data: struct { + element_type: Node, + a: Node, + b: Node, + mask_vector: Node, + }, + }; + + pub const Extern = struct { + base: Payload, + data: struct { + type: Node, + name: Node, + }, + }; + + pub const MacroArithmetic = struct { + base: Payload, + data: struct { + op: Operator, + lhs: Node, + rhs: Node, + }, + + pub const Operator = enum { div, rem }; + }; +}; + +/// Converts the nodes into a Zig Ast. +/// Caller must free the source slice. +pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast { + var ctx = Context{ + .gpa = gpa, + .buf = std.ArrayList(u8).init(gpa), + }; + defer ctx.buf.deinit(); + defer ctx.nodes.deinit(gpa); + defer ctx.extra_data.deinit(gpa); + defer ctx.tokens.deinit(gpa); + + // Estimate that each top level node has 10 child nodes. + const estimated_node_count = nodes.len * 10; + try ctx.nodes.ensureTotalCapacity(gpa, estimated_node_count); + // Estimate that each each node has 2 tokens. + const estimated_tokens_count = estimated_node_count * 2; + try ctx.tokens.ensureTotalCapacity(gpa, estimated_tokens_count); + // Estimate that each each token is 3 bytes long. + const estimated_buf_len = estimated_tokens_count * 3; + try ctx.buf.ensureTotalCapacity(estimated_buf_len); + + ctx.nodes.appendAssumeCapacity(.{ + .tag = .root, + .main_token = 0, + .data = .{ + .lhs = undefined, + .rhs = undefined, + }, + }); + + const root_members = blk: { + var result = std.ArrayList(NodeIndex).init(gpa); + defer result.deinit(); + + for (nodes) |node| { + const res = try renderNode(&ctx, node); + if (node.tag() == .warning) continue; + try result.append(res); + } + break :blk try ctx.listToSpan(result.items); + }; + + ctx.nodes.items(.data)[0] = .{ + .lhs = root_members.start, + .rhs = root_members.end, + }; + + try ctx.tokens.append(gpa, .{ + .tag = .eof, + .start = @as(u32, @intCast(ctx.buf.items.len)), + }); + + return std.zig.Ast{ + .source = try ctx.buf.toOwnedSliceSentinel(0), + .tokens = ctx.tokens.toOwnedSlice(), + .nodes = ctx.nodes.toOwnedSlice(), + .extra_data = try ctx.extra_data.toOwnedSlice(gpa), + .errors = &.{}, + .mode = .zig, + }; +} + +const NodeIndex = std.zig.Ast.Node.Index; +const NodeSubRange = std.zig.Ast.Node.SubRange; +const TokenIndex = std.zig.Ast.TokenIndex; +const TokenTag = std.zig.Token.Tag; + +const Context = struct { + gpa: Allocator, + buf: std.ArrayList(u8), + nodes: std.zig.Ast.NodeList = .{}, + extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .empty, + tokens: std.zig.Ast.TokenList = .{}, + + fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex { + const start_index = c.buf.items.len; + try c.buf.writer().print(format ++ " ", args); + + try c.tokens.append(c.gpa, .{ + .tag = tag, + .start = @as(u32, @intCast(start_index)), + }); + + return @as(u32, @intCast(c.tokens.len - 1)); + } + + fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex { + return c.addTokenFmt(tag, "{s}", .{bytes}); + } + + fn addIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex { + if (std.zig.primitives.isPrimitive(bytes)) + return c.addTokenFmt(.identifier, "@\"{s}\"", .{bytes}); + return c.addTokenFmt(.identifier, "{p}", .{std.zig.fmtId(bytes)}); + } + + fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange { + try c.extra_data.appendSlice(c.gpa, list); + return NodeSubRange{ + .start = @as(NodeIndex, @intCast(c.extra_data.items.len - list.len)), + .end = @as(NodeIndex, @intCast(c.extra_data.items.len)), + }; + } + + fn addNode(c: *Context, elem: std.zig.Ast.Node) Allocator.Error!NodeIndex { + const result = @as(NodeIndex, @intCast(c.nodes.len)); + try c.nodes.append(c.gpa, elem); + return result; + } + + fn addExtra(c: *Context, extra: anytype) Allocator.Error!NodeIndex { + const fields = std.meta.fields(@TypeOf(extra)); + try c.extra_data.ensureUnusedCapacity(c.gpa, fields.len); + const result = @as(u32, @intCast(c.extra_data.items.len)); + inline for (fields) |field| { + comptime std.debug.assert(field.type == NodeIndex); + c.extra_data.appendAssumeCapacity(@field(extra, field.name)); + } + return result; + } +}; + +fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange { + var result = std.ArrayList(NodeIndex).init(c.gpa); + defer result.deinit(); + + for (nodes) |node| { + const res = try renderNode(c, node); + if (node.tag() == .warning) continue; + try result.append(res); + } + + return try c.listToSpan(result.items); +} + +fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { + switch (node.tag()) { + .declaration => unreachable, + .warning => { + const payload = node.castTag(.warning).?.data; + try c.buf.append('\n'); + try c.buf.appendSlice(payload); + try c.buf.append('\n'); + return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32' + }, + .helpers_cast => { + const payload = node.castTag(.helpers_cast).?.data; + const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "cast" }); + return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); + }, + .helpers_promoteIntLiteral => { + const payload = node.castTag(.helpers_promoteIntLiteral).?.data; + const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "promoteIntLiteral" }); + return renderCall(c, import_node, &.{ payload.type, payload.value, payload.base }); + }, + .helpers_sizeof => { + const payload = node.castTag(.helpers_sizeof).?.data; + const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "sizeof" }); + return renderCall(c, import_node, &.{payload}); + }, + .std_mem_zeroes => { + const payload = node.castTag(.std_mem_zeroes).?.data; + const import_node = try renderStdImport(c, &.{ "mem", "zeroes" }); + return renderCall(c, import_node, &.{payload}); + }, + .std_mem_zeroinit => { + const payload = node.castTag(.std_mem_zeroinit).?.data; + const import_node = try renderStdImport(c, &.{ "mem", "zeroInit" }); + return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); + }, + .helpers_flexible_array_type => { + const payload = node.castTag(.helpers_flexible_array_type).?.data; + const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "FlexibleArrayType" }); + return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); + }, + .helpers_shuffle_vector_index => { + const payload = node.castTag(.helpers_shuffle_vector_index).?.data; + const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "shuffleVectorIndex" }); + return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); + }, + .vector => { + const payload = node.castTag(.vector).?.data; + return renderBuiltinCall(c, "@Vector", &.{ payload.lhs, payload.rhs }); + }, + .call => { + const payload = node.castTag(.call).?.data; + // Cosmetic: avoids an unnecesary address_of on most function calls. + const lhs = if (payload.lhs.tag() == .fn_identifier) + try c.addNode(.{ + .tag = .identifier, + .main_token = try c.addIdentifier(payload.lhs.castTag(.fn_identifier).?.data), + .data = undefined, + }) + else + try renderNodeGrouped(c, payload.lhs); + return renderCall(c, lhs, payload.args); + }, + .null_literal => return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "null"), + .data = undefined, + }), + .undefined_literal => return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "undefined"), + .data = undefined, + }), + .true_literal => return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "true"), + .data = undefined, + }), + .false_literal => return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "false"), + .data = undefined, + }), + .zero_literal => return c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addToken(.number_literal, "0"), + .data = undefined, + }), + .one_literal => return c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addToken(.number_literal, "1"), + .data = undefined, + }), + .void_type => return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "void"), + .data = undefined, + }), + .noreturn_type => return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "noreturn"), + .data = undefined, + }), + .@"continue" => return c.addNode(.{ + .tag = .@"continue", + .main_token = try c.addToken(.keyword_continue, "continue"), + .data = .{ + .lhs = 0, + .rhs = undefined, + }, + }), + .return_void => return c.addNode(.{ + .tag = .@"return", + .main_token = try c.addToken(.keyword_return, "return"), + .data = .{ + .lhs = 0, + .rhs = undefined, + }, + }), + .@"break" => return c.addNode(.{ + .tag = .@"break", + .main_token = try c.addToken(.keyword_break, "break"), + .data = .{ + .lhs = 0, + .rhs = 0, + }, + }), + .break_val => { + const payload = node.castTag(.break_val).?.data; + const tok = try c.addToken(.keyword_break, "break"); + const break_label = if (payload.label) |some| blk: { + _ = try c.addToken(.colon, ":"); + break :blk try c.addIdentifier(some); + } else 0; + return c.addNode(.{ + .tag = .@"break", + .main_token = tok, + .data = .{ + .lhs = break_label, + .rhs = try renderNode(c, payload.val), + }, + }); + }, + .@"return" => { + const payload = node.castTag(.@"return").?.data; + return c.addNode(.{ + .tag = .@"return", + .main_token = try c.addToken(.keyword_return, "return"), + .data = .{ + .lhs = try renderNode(c, payload), + .rhs = undefined, + }, + }); + }, + .@"comptime" => { + const payload = node.castTag(.@"comptime").?.data; + return c.addNode(.{ + .tag = .@"comptime", + .main_token = try c.addToken(.keyword_comptime, "comptime"), + .data = .{ + .lhs = try renderNode(c, payload), + .rhs = undefined, + }, + }); + }, + .@"defer" => { + const payload = node.castTag(.@"defer").?.data; + return c.addNode(.{ + .tag = .@"defer", + .main_token = try c.addToken(.keyword_defer, "defer"), + .data = .{ + .lhs = undefined, + .rhs = try renderNode(c, payload), + }, + }); + }, + .asm_simple => { + const payload = node.castTag(.asm_simple).?.data; + const asm_token = try c.addToken(.keyword_asm, "asm"); + _ = try c.addToken(.l_paren, "("); + return c.addNode(.{ + .tag = .asm_simple, + .main_token = asm_token, + .data = .{ + .lhs = try renderNode(c, payload), + .rhs = try c.addToken(.r_paren, ")"), + }, + }); + }, + .type => { + const payload = node.castTag(.type).?.data; + return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, payload), + .data = undefined, + }); + }, + .identifier => { + const payload = node.castTag(.identifier).?.data; + return c.addNode(.{ + .tag = .identifier, + .main_token = try c.addIdentifier(payload), + .data = undefined, + }); + }, + .fn_identifier => { + // C semantics are that a function identifier has address + // value (implicit in stage1, explicit in stage2), except in + // the context of an address_of, which is handled there. + const payload = node.castTag(.fn_identifier).?.data; + const tok = try c.addToken(.ampersand, "&"); + const arg = try c.addNode(.{ + .tag = .identifier, + .main_token = try c.addIdentifier(payload), + .data = undefined, + }); + return c.addNode(.{ + .tag = .address_of, + .main_token = tok, + .data = .{ + .lhs = arg, + .rhs = undefined, + }, + }); + }, + .float_literal => { + const payload = node.castTag(.float_literal).?.data; + return c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addToken(.number_literal, payload), + .data = undefined, + }); + }, + .integer_literal => { + const payload = node.castTag(.integer_literal).?.data; + return c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addToken(.number_literal, payload), + .data = undefined, + }); + }, + .string_literal => { + const payload = node.castTag(.string_literal).?.data; + return c.addNode(.{ + .tag = .string_literal, + .main_token = try c.addToken(.string_literal, payload), + .data = undefined, + }); + }, + .char_literal => { + const payload = node.castTag(.char_literal).?.data; + return c.addNode(.{ + .tag = .char_literal, + .main_token = try c.addToken(.char_literal, payload), + .data = undefined, + }); + }, + .enum_literal => { + const payload = node.castTag(.enum_literal).?.data; + _ = try c.addToken(.period, "."); + return c.addNode(.{ + .tag = .enum_literal, + .main_token = try c.addToken(.identifier, payload), + .data = undefined, + }); + }, + .helpers_macro => { + const payload = node.castTag(.helpers_macro).?.data; + const chain = [_][]const u8{ + "zig", + "c_translation", + "Macros", + payload, + }; + return renderStdImport(c, &chain); + }, + .import_c_builtin => { + const payload = node.castTag(.import_c_builtin).?.data; + const chain = [_][]const u8{ + "zig", + "c_builtins", + payload, + }; + return renderStdImport(c, &chain); + }, + .string_slice => { + const payload = node.castTag(.string_slice).?.data; + + const string = try renderNode(c, payload.string); + const l_bracket = try c.addToken(.l_bracket, "["); + const start = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addToken(.number_literal, "0"), + .data = undefined, + }); + _ = try c.addToken(.ellipsis2, ".."); + const end = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.end}), + .data = undefined, + }); + _ = try c.addToken(.r_bracket, "]"); + + return c.addNode(.{ + .tag = .slice, + .main_token = l_bracket, + .data = .{ + .lhs = string, + .rhs = try c.addExtra(std.zig.Ast.Node.Slice{ + .start = start, + .end = end, + }), + }, + }); + }, + .fail_decl => { + const payload = node.castTag(.fail_decl).?.data; + // pub const name = @compileError(msg); + _ = try c.addToken(.keyword_pub, "pub"); + const const_tok = try c.addToken(.keyword_const, "const"); + _ = try c.addIdentifier(payload.actual); + _ = try c.addToken(.equal, "="); + + const compile_error_tok = try c.addToken(.builtin, "@compileError"); + _ = try c.addToken(.l_paren, "("); + const err_msg_tok = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(payload.mangled)}); + const err_msg = try c.addNode(.{ + .tag = .string_literal, + .main_token = err_msg_tok, + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + const compile_error = try c.addNode(.{ + .tag = .builtin_call_two, + .main_token = compile_error_tok, + .data = .{ + .lhs = err_msg, + .rhs = 0, + }, + }); + _ = try c.addToken(.semicolon, ";"); + + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = const_tok, + .data = .{ + .lhs = 0, + .rhs = compile_error, + }, + }); + }, + .pub_var_simple, .var_simple => { + const payload = @as(*Payload.SimpleVarDecl, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; + if (node.tag() == .pub_var_simple) _ = try c.addToken(.keyword_pub, "pub"); + const const_tok = try c.addToken(.keyword_const, "const"); + _ = try c.addIdentifier(payload.name); + _ = try c.addToken(.equal, "="); + + const init = try renderNode(c, payload.init); + _ = try c.addToken(.semicolon, ";"); + + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = const_tok, + .data = .{ + .lhs = 0, + .rhs = init, + }, + }); + }, + .static_local_var => { + const payload = node.castTag(.static_local_var).?.data; + + const const_tok = try c.addToken(.keyword_const, "const"); + _ = try c.addIdentifier(payload.name); + _ = try c.addToken(.equal, "="); + + const kind_tok = try c.addToken(.keyword_struct, "struct"); + _ = try c.addToken(.l_brace, "{"); + + const container_def = try c.addNode(.{ + .tag = .container_decl_two_trailing, + .main_token = kind_tok, + .data = .{ + .lhs = try renderNode(c, payload.init), + .rhs = 0, + }, + }); + _ = try c.addToken(.r_brace, "}"); + _ = try c.addToken(.semicolon, ";"); + + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = const_tok, + .data = .{ + .lhs = 0, + .rhs = container_def, + }, + }); + }, + .extern_local_var, .extern_local_fn => { + const payload = if (node.tag() == .extern_local_var) + node.castTag(.extern_local_var).?.data + else + node.castTag(.extern_local_fn).?.data; + + const const_tok = try c.addToken(.keyword_const, "const"); + _ = try c.addIdentifier(payload.name); + _ = try c.addToken(.equal, "="); + + const kind_tok = try c.addToken(.keyword_struct, "struct"); + _ = try c.addToken(.l_brace, "{"); + + const container_def = try c.addNode(.{ + .tag = .container_decl_two_trailing, + .main_token = kind_tok, + .data = .{ + .lhs = try renderNode(c, payload.init), + .rhs = 0, + }, + }); + _ = try c.addToken(.r_brace, "}"); + _ = try c.addToken(.semicolon, ";"); + + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = const_tok, + .data = .{ + .lhs = 0, + .rhs = container_def, + }, + }); + }, + .mut_str => { + const payload = node.castTag(.mut_str).?.data; + + const var_tok = try c.addToken(.keyword_var, "var"); + _ = try c.addIdentifier(payload.name); + _ = try c.addToken(.equal, "="); + + const deref = try c.addNode(.{ + .tag = .deref, + .data = .{ + .lhs = try renderNodeGrouped(c, payload.init), + .rhs = undefined, + }, + .main_token = try c.addToken(.period_asterisk, ".*"), + }); + _ = try c.addToken(.semicolon, ";"); + + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = var_tok, + .data = .{ .lhs = 0, .rhs = deref }, + }); + }, + .var_decl => return renderVar(c, node), + .arg_redecl, .alias => { + const payload = @as(*Payload.ArgRedecl, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; + if (node.tag() == .alias) _ = try c.addToken(.keyword_pub, "pub"); + const mut_tok = if (node.tag() == .alias) + try c.addToken(.keyword_const, "const") + else + try c.addToken(.keyword_var, "var"); + _ = try c.addIdentifier(payload.actual); + _ = try c.addToken(.equal, "="); + + const init = try c.addNode(.{ + .tag = .identifier, + .main_token = try c.addIdentifier(payload.mangled), + .data = undefined, + }); + _ = try c.addToken(.semicolon, ";"); + + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = mut_tok, + .data = .{ + .lhs = 0, + .rhs = init, + }, + }); + }, + .int_cast => { + const payload = node.castTag(.int_cast).?.data; + return renderBuiltinCall(c, "@intCast", &.{payload}); + }, + .const_cast => { + const payload = node.castTag(.const_cast).?.data; + return renderBuiltinCall(c, "@constCast", &.{payload}); + }, + .volatile_cast => { + const payload = node.castTag(.volatile_cast).?.data; + return renderBuiltinCall(c, "@volatileCast", &.{payload}); + }, + .signed_remainder => { + const payload = node.castTag(.signed_remainder).?.data; + const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "signedRemainder" }); + return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); + }, + .div_trunc => { + const payload = node.castTag(.div_trunc).?.data; + return renderBuiltinCall(c, "@divTrunc", &.{ payload.lhs, payload.rhs }); + }, + .int_from_bool => { + const payload = node.castTag(.int_from_bool).?.data; + return renderBuiltinCall(c, "@intFromBool", &.{payload}); + }, + .as => { + const payload = node.castTag(.as).?.data; + return renderBuiltinCall(c, "@as", &.{ payload.lhs, payload.rhs }); + }, + .truncate => { + const payload = node.castTag(.truncate).?.data; + return renderBuiltinCall(c, "@truncate", &.{payload}); + }, + .bit_cast => { + const payload = node.castTag(.bit_cast).?.data; + return renderBuiltinCall(c, "@bitCast", &.{payload}); + }, + .float_cast => { + const payload = node.castTag(.float_cast).?.data; + return renderBuiltinCall(c, "@floatCast", &.{payload}); + }, + .int_from_float => { + const payload = node.castTag(.int_from_float).?.data; + return renderBuiltinCall(c, "@intFromFloat", &.{payload}); + }, + .float_from_int => { + const payload = node.castTag(.float_from_int).?.data; + return renderBuiltinCall(c, "@floatFromInt", &.{payload}); + }, + .ptr_from_int => { + const payload = node.castTag(.ptr_from_int).?.data; + return renderBuiltinCall(c, "@ptrFromInt", &.{payload}); + }, + .int_from_ptr => { + const payload = node.castTag(.int_from_ptr).?.data; + return renderBuiltinCall(c, "@intFromPtr", &.{payload}); + }, + .align_cast => { + const payload = node.castTag(.align_cast).?.data; + return renderBuiltinCall(c, "@alignCast", &.{payload}); + }, + .ptr_cast => { + const payload = node.castTag(.ptr_cast).?.data; + return renderBuiltinCall(c, "@ptrCast", &.{payload}); + }, + .div_exact => { + const payload = node.castTag(.div_exact).?.data; + return renderBuiltinCall(c, "@divExact", &.{ payload.lhs, payload.rhs }); + }, + .offset_of => { + const payload = node.castTag(.offset_of).?.data; + return renderBuiltinCall(c, "@offsetOf", &.{ payload.lhs, payload.rhs }); + }, + .sizeof => { + const payload = node.castTag(.sizeof).?.data; + return renderBuiltinCall(c, "@sizeOf", &.{payload}); + }, + .shuffle => { + const payload = node.castTag(.shuffle).?.data; + return renderBuiltinCall(c, "@shuffle", &.{ + payload.element_type, + payload.a, + payload.b, + payload.mask_vector, + }); + }, + .builtin_extern => { + const payload = node.castTag(.builtin_extern).?.data; + + var info_inits: [1]Payload.ContainerInitDot.Initializer = .{ + .{ .name = "name", .value = payload.name }, + }; + var info_payload: Payload.ContainerInitDot = .{ + .base = .{ .tag = .container_init_dot }, + .data = &info_inits, + }; + + return renderBuiltinCall(c, "@extern", &.{ + payload.type, + .{ .ptr_otherwise = &info_payload.base }, + }); + }, + .macro_arithmetic => { + const payload = node.castTag(.macro_arithmetic).?.data; + const op = @tagName(payload.op); + const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "MacroArithmetic", op }); + return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); + }, + .alignof => { + const payload = node.castTag(.alignof).?.data; + return renderBuiltinCall(c, "@alignOf", &.{payload}); + }, + .typeof => { + const payload = node.castTag(.typeof).?.data; + return renderBuiltinCall(c, "@TypeOf", &.{payload}); + }, + .typeinfo => { + const payload = node.castTag(.typeinfo).?.data; + return renderBuiltinCall(c, "@typeInfo", &.{payload}); + }, + .negate => return renderPrefixOp(c, node, .negation, .minus, "-"), + .negate_wrap => return renderPrefixOp(c, node, .negation_wrap, .minus_percent, "-%"), + .bit_not => return renderPrefixOp(c, node, .bit_not, .tilde, "~"), + .not => return renderPrefixOp(c, node, .bool_not, .bang, "!"), + .optional_type => return renderPrefixOp(c, node, .optional_type, .question_mark, "?"), + .address_of => { + const payload = node.castTag(.address_of).?.data; + + const ampersand = try c.addToken(.ampersand, "&"); + const base = if (payload.tag() == .fn_identifier) + try c.addNode(.{ + .tag = .identifier, + .main_token = try c.addIdentifier(payload.castTag(.fn_identifier).?.data), + .data = undefined, + }) + else + try renderNodeGrouped(c, payload); + return c.addNode(.{ + .tag = .address_of, + .main_token = ampersand, + .data = .{ + .lhs = base, + .rhs = undefined, + }, + }); + }, + .deref => { + const payload = node.castTag(.deref).?.data; + const operand = try renderNodeGrouped(c, payload); + const deref_tok = try c.addToken(.period_asterisk, ".*"); + return c.addNode(.{ + .tag = .deref, + .main_token = deref_tok, + .data = .{ + .lhs = operand, + .rhs = undefined, + }, + }); + }, + .unwrap => { + const payload = node.castTag(.unwrap).?.data; + const operand = try renderNodeGrouped(c, payload); + const period = try c.addToken(.period, "."); + const question_mark = try c.addToken(.question_mark, "?"); + return c.addNode(.{ + .tag = .unwrap_optional, + .main_token = period, + .data = .{ + .lhs = operand, + .rhs = question_mark, + }, + }); + }, + .c_pointer, .single_pointer => { + const payload = @as(*Payload.Pointer, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; + + const main_token = if (node.tag() == .single_pointer) + try c.addToken(.asterisk, "*") + else blk: { + const res = try c.addToken(.l_bracket, "["); + _ = try c.addToken(.asterisk, "*"); + _ = try c.addIdentifier("c"); + _ = try c.addToken(.r_bracket, "]"); + break :blk res; + }; + if (payload.is_const) _ = try c.addToken(.keyword_const, "const"); + if (payload.is_volatile) _ = try c.addToken(.keyword_volatile, "volatile"); + const elem_type = try renderNodeGrouped(c, payload.elem_type); + + return c.addNode(.{ + .tag = .ptr_type_aligned, + .main_token = main_token, + .data = .{ + .lhs = 0, + .rhs = elem_type, + }, + }); + }, + .add => return renderBinOpGrouped(c, node, .add, .plus, "+"), + .add_assign => return renderBinOp(c, node, .assign_add, .plus_equal, "+="), + .add_wrap => return renderBinOpGrouped(c, node, .add_wrap, .plus_percent, "+%"), + .add_wrap_assign => return renderBinOp(c, node, .assign_add_wrap, .plus_percent_equal, "+%="), + .sub => return renderBinOpGrouped(c, node, .sub, .minus, "-"), + .sub_assign => return renderBinOp(c, node, .assign_sub, .minus_equal, "-="), + .sub_wrap => return renderBinOpGrouped(c, node, .sub_wrap, .minus_percent, "-%"), + .sub_wrap_assign => return renderBinOp(c, node, .assign_sub_wrap, .minus_percent_equal, "-%="), + .mul => return renderBinOpGrouped(c, node, .mul, .asterisk, "*"), + .mul_assign => return renderBinOp(c, node, .assign_mul, .asterisk_equal, "*="), + .mul_wrap => return renderBinOpGrouped(c, node, .mul_wrap, .asterisk_percent, "*%"), + .mul_wrap_assign => return renderBinOp(c, node, .assign_mul_wrap, .asterisk_percent_equal, "*%="), + .div => return renderBinOpGrouped(c, node, .div, .slash, "/"), + .div_assign => return renderBinOp(c, node, .assign_div, .slash_equal, "/="), + .shl => return renderBinOpGrouped(c, node, .shl, .angle_bracket_angle_bracket_left, "<<"), + .shl_assign => return renderBinOp(c, node, .assign_shl, .angle_bracket_angle_bracket_left_equal, "<<="), + .shr => return renderBinOpGrouped(c, node, .shr, .angle_bracket_angle_bracket_right, ">>"), + .shr_assign => return renderBinOp(c, node, .assign_shr, .angle_bracket_angle_bracket_right_equal, ">>="), + .mod => return renderBinOpGrouped(c, node, .mod, .percent, "%"), + .mod_assign => return renderBinOp(c, node, .assign_mod, .percent_equal, "%="), + .@"and" => return renderBinOpGrouped(c, node, .bool_and, .keyword_and, "and"), + .@"or" => return renderBinOpGrouped(c, node, .bool_or, .keyword_or, "or"), + .less_than => return renderBinOpGrouped(c, node, .less_than, .angle_bracket_left, "<"), + .less_than_equal => return renderBinOpGrouped(c, node, .less_or_equal, .angle_bracket_left_equal, "<="), + .greater_than => return renderBinOpGrouped(c, node, .greater_than, .angle_bracket_right, ">="), + .greater_than_equal => return renderBinOpGrouped(c, node, .greater_or_equal, .angle_bracket_right_equal, ">="), + .equal => return renderBinOpGrouped(c, node, .equal_equal, .equal_equal, "=="), + .not_equal => return renderBinOpGrouped(c, node, .bang_equal, .bang_equal, "!="), + .bit_and => return renderBinOpGrouped(c, node, .bit_and, .ampersand, "&"), + .bit_and_assign => return renderBinOp(c, node, .assign_bit_and, .ampersand_equal, "&="), + .bit_or => return renderBinOpGrouped(c, node, .bit_or, .pipe, "|"), + .bit_or_assign => return renderBinOp(c, node, .assign_bit_or, .pipe_equal, "|="), + .bit_xor => return renderBinOpGrouped(c, node, .bit_xor, .caret, "^"), + .bit_xor_assign => return renderBinOp(c, node, .assign_bit_xor, .caret_equal, "^="), + .array_cat => return renderBinOp(c, node, .array_cat, .plus_plus, "++"), + .ellipsis3 => return renderBinOpGrouped(c, node, .switch_range, .ellipsis3, "..."), + .assign => return renderBinOp(c, node, .assign, .equal, "="), + .empty_block => { + const l_brace = try c.addToken(.l_brace, "{"); + _ = try c.addToken(.r_brace, "}"); + return c.addNode(.{ + .tag = .block_two, + .main_token = l_brace, + .data = .{ + .lhs = 0, + .rhs = 0, + }, + }); + }, + .block_single => { + const payload = node.castTag(.block_single).?.data; + const l_brace = try c.addToken(.l_brace, "{"); + + const stmt = try renderNode(c, payload); + try addSemicolonIfNeeded(c, payload); + + _ = try c.addToken(.r_brace, "}"); + return c.addNode(.{ + .tag = .block_two_semicolon, + .main_token = l_brace, + .data = .{ + .lhs = stmt, + .rhs = 0, + }, + }); + }, + .block => { + const payload = node.castTag(.block).?.data; + if (payload.label) |some| { + _ = try c.addIdentifier(some); + _ = try c.addToken(.colon, ":"); + } + const l_brace = try c.addToken(.l_brace, "{"); + + var stmts = std.ArrayList(NodeIndex).init(c.gpa); + defer stmts.deinit(); + for (payload.stmts) |stmt| { + const res = try renderNode(c, stmt); + if (res == 0) continue; + try addSemicolonIfNeeded(c, stmt); + try stmts.append(res); + } + const span = try c.listToSpan(stmts.items); + _ = try c.addToken(.r_brace, "}"); + + const semicolon = c.tokens.items(.tag)[c.tokens.len - 2] == .semicolon; + return c.addNode(.{ + .tag = if (semicolon) .block_semicolon else .block, + .main_token = l_brace, + .data = .{ + .lhs = span.start, + .rhs = span.end, + }, + }); + }, + .func => return renderFunc(c, node), + .pub_inline_fn => return renderMacroFunc(c, node), + .discard => { + const payload = node.castTag(.discard).?.data; + if (payload.should_skip) return @as(NodeIndex, 0); + + const lhs = try c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "_"), + .data = undefined, + }); + const main_token = try c.addToken(.equal, "="); + if (payload.value.tag() == .identifier) { + // Render as `_ = &foo;` to avoid tripping "pointless discard" and "local variable never mutated" errors. + var addr_of_pl: Payload.UnOp = .{ + .base = .{ .tag = .address_of }, + .data = payload.value, + }; + const addr_of: Node = .{ .ptr_otherwise = &addr_of_pl.base }; + return c.addNode(.{ + .tag = .assign, + .main_token = main_token, + .data = .{ + .lhs = lhs, + .rhs = try renderNode(c, addr_of), + }, + }); + } else { + return c.addNode(.{ + .tag = .assign, + .main_token = main_token, + .data = .{ + .lhs = lhs, + .rhs = try renderNode(c, payload.value), + }, + }); + } + }, + .@"while" => { + const payload = node.castTag(.@"while").?.data; + const while_tok = try c.addToken(.keyword_while, "while"); + _ = try c.addToken(.l_paren, "("); + const cond = try renderNode(c, payload.cond); + _ = try c.addToken(.r_paren, ")"); + + const cont_expr = if (payload.cont_expr) |some| blk: { + _ = try c.addToken(.colon, ":"); + _ = try c.addToken(.l_paren, "("); + const res = try renderNode(c, some); + _ = try c.addToken(.r_paren, ")"); + break :blk res; + } else 0; + const body = try renderNode(c, payload.body); + + if (cont_expr == 0) { + return c.addNode(.{ + .tag = .while_simple, + .main_token = while_tok, + .data = .{ + .lhs = cond, + .rhs = body, + }, + }); + } else { + return c.addNode(.{ + .tag = .while_cont, + .main_token = while_tok, + .data = .{ + .lhs = cond, + .rhs = try c.addExtra(std.zig.Ast.Node.WhileCont{ + .cont_expr = cont_expr, + .then_expr = body, + }), + }, + }); + } + }, + .while_true => { + const payload = node.castTag(.while_true).?.data; + const while_tok = try c.addToken(.keyword_while, "while"); + _ = try c.addToken(.l_paren, "("); + const cond = try c.addNode(.{ + .tag = .identifier, + .main_token = try c.addToken(.identifier, "true"), + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + const body = try renderNode(c, payload); + + return c.addNode(.{ + .tag = .while_simple, + .main_token = while_tok, + .data = .{ + .lhs = cond, + .rhs = body, + }, + }); + }, + .@"if" => { + const payload = node.castTag(.@"if").?.data; + const if_tok = try c.addToken(.keyword_if, "if"); + _ = try c.addToken(.l_paren, "("); + const cond = try renderNode(c, payload.cond); + _ = try c.addToken(.r_paren, ")"); + + const then_expr = try renderNode(c, payload.then); + const else_node = payload.@"else" orelse return c.addNode(.{ + .tag = .if_simple, + .main_token = if_tok, + .data = .{ + .lhs = cond, + .rhs = then_expr, + }, + }); + _ = try c.addToken(.keyword_else, "else"); + const else_expr = try renderNode(c, else_node); + + return c.addNode(.{ + .tag = .@"if", + .main_token = if_tok, + .data = .{ + .lhs = cond, + .rhs = try c.addExtra(std.zig.Ast.Node.If{ + .then_expr = then_expr, + .else_expr = else_expr, + }), + }, + }); + }, + .if_not_break => { + const payload = node.castTag(.if_not_break).?.data; + const if_tok = try c.addToken(.keyword_if, "if"); + _ = try c.addToken(.l_paren, "("); + const cond = try c.addNode(.{ + .tag = .bool_not, + .main_token = try c.addToken(.bang, "!"), + .data = .{ + .lhs = try renderNodeGrouped(c, payload), + .rhs = undefined, + }, + }); + _ = try c.addToken(.r_paren, ")"); + const then_expr = try c.addNode(.{ + .tag = .@"break", + .main_token = try c.addToken(.keyword_break, "break"), + .data = .{ + .lhs = 0, + .rhs = 0, + }, + }); + + return c.addNode(.{ + .tag = .if_simple, + .main_token = if_tok, + .data = .{ + .lhs = cond, + .rhs = then_expr, + }, + }); + }, + .@"switch" => { + const payload = node.castTag(.@"switch").?.data; + const switch_tok = try c.addToken(.keyword_switch, "switch"); + _ = try c.addToken(.l_paren, "("); + const cond = try renderNode(c, payload.cond); + _ = try c.addToken(.r_paren, ")"); + + _ = try c.addToken(.l_brace, "{"); + var cases = try c.gpa.alloc(NodeIndex, payload.cases.len); + defer c.gpa.free(cases); + for (payload.cases, 0..) |case, i| { + cases[i] = try renderNode(c, case); + _ = try c.addToken(.comma, ","); + } + const span = try c.listToSpan(cases); + _ = try c.addToken(.r_brace, "}"); + return c.addNode(.{ + .tag = .switch_comma, + .main_token = switch_tok, + .data = .{ + .lhs = cond, + .rhs = try c.addExtra(NodeSubRange{ + .start = span.start, + .end = span.end, + }), + }, + }); + }, + .switch_else => { + const payload = node.castTag(.switch_else).?.data; + _ = try c.addToken(.keyword_else, "else"); + return c.addNode(.{ + .tag = .switch_case_one, + .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), + .data = .{ + .lhs = 0, + .rhs = try renderNode(c, payload), + }, + }); + }, + .switch_prong => { + const payload = node.castTag(.switch_prong).?.data; + var items = try c.gpa.alloc(NodeIndex, @max(payload.cases.len, 1)); + defer c.gpa.free(items); + items[0] = 0; + for (payload.cases, 0..) |item, i| { + if (i != 0) _ = try c.addToken(.comma, ","); + items[i] = try renderNode(c, item); + } + _ = try c.addToken(.r_brace, "}"); + if (items.len < 2) { + return c.addNode(.{ + .tag = .switch_case_one, + .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), + .data = .{ + .lhs = items[0], + .rhs = try renderNode(c, payload.cond), + }, + }); + } else { + const span = try c.listToSpan(items); + return c.addNode(.{ + .tag = .switch_case, + .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), + .data = .{ + .lhs = try c.addExtra(NodeSubRange{ + .start = span.start, + .end = span.end, + }), + .rhs = try renderNode(c, payload.cond), + }, + }); + } + }, + .opaque_literal => { + const opaque_tok = try c.addToken(.keyword_opaque, "opaque"); + _ = try c.addToken(.l_brace, "{"); + _ = try c.addToken(.r_brace, "}"); + + return c.addNode(.{ + .tag = .container_decl_two, + .main_token = opaque_tok, + .data = .{ + .lhs = 0, + .rhs = 0, + }, + }); + }, + .array_access => { + const payload = node.castTag(.array_access).?.data; + const lhs = try renderNodeGrouped(c, payload.lhs); + const l_bracket = try c.addToken(.l_bracket, "["); + const index_expr = try renderNode(c, payload.rhs); + _ = try c.addToken(.r_bracket, "]"); + return c.addNode(.{ + .tag = .array_access, + .main_token = l_bracket, + .data = .{ + .lhs = lhs, + .rhs = index_expr, + }, + }); + }, + .array_type => { + const payload = node.castTag(.array_type).?.data; + return renderArrayType(c, payload.len, payload.elem_type); + }, + .null_sentinel_array_type => { + const payload = node.castTag(.null_sentinel_array_type).?.data; + return renderNullSentinelArrayType(c, payload.len, payload.elem_type); + }, + .array_filler => { + const payload = node.castTag(.array_filler).?.data; + + const type_expr = try renderArrayType(c, 1, payload.type); + const l_brace = try c.addToken(.l_brace, "{"); + const val = try renderNode(c, payload.filler); + _ = try c.addToken(.r_brace, "}"); + + const init = try c.addNode(.{ + .tag = .array_init_one, + .main_token = l_brace, + .data = .{ + .lhs = type_expr, + .rhs = val, + }, + }); + return c.addNode(.{ + .tag = .array_cat, + .main_token = try c.addToken(.asterisk_asterisk, "**"), + .data = .{ + .lhs = init, + .rhs = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.count}), + .data = undefined, + }), + }, + }); + }, + .empty_array => { + const payload = node.castTag(.empty_array).?.data; + + const type_expr = try renderArrayType(c, 0, payload); + return renderArrayInit(c, type_expr, &.{}); + }, + .array_init => { + const payload = node.castTag(.array_init).?.data; + const type_expr = try renderNode(c, payload.cond); + return renderArrayInit(c, type_expr, payload.cases); + }, + .vector_zero_init => { + const payload = node.castTag(.vector_zero_init).?.data; + return renderBuiltinCall(c, "@splat", &.{payload}); + }, + .field_access => { + const payload = node.castTag(.field_access).?.data; + const lhs = try renderNodeGrouped(c, payload.lhs); + return renderFieldAccess(c, lhs, payload.field_name); + }, + .@"struct", .@"union" => return renderRecord(c, node), + .enum_constant => { + const payload = node.castTag(.enum_constant).?.data; + + if (payload.is_public) _ = try c.addToken(.keyword_pub, "pub"); + const const_tok = try c.addToken(.keyword_const, "const"); + _ = try c.addIdentifier(payload.name); + + const type_node = if (payload.type) |enum_const_type| blk: { + _ = try c.addToken(.colon, ":"); + break :blk try renderNode(c, enum_const_type); + } else 0; + + _ = try c.addToken(.equal, "="); + + const init_node = try renderNode(c, payload.value); + _ = try c.addToken(.semicolon, ";"); + + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = const_tok, + .data = .{ + .lhs = type_node, + .rhs = init_node, + }, + }); + }, + .tuple => { + const payload = node.castTag(.tuple).?.data; + _ = try c.addToken(.period, "."); + const l_brace = try c.addToken(.l_brace, "{"); + var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2)); + defer c.gpa.free(inits); + inits[0] = 0; + inits[1] = 0; + for (payload, 0..) |init, i| { + if (i != 0) _ = try c.addToken(.comma, ","); + inits[i] = try renderNode(c, init); + } + _ = try c.addToken(.r_brace, "}"); + if (payload.len < 3) { + return c.addNode(.{ + .tag = .array_init_dot_two, + .main_token = l_brace, + .data = .{ + .lhs = inits[0], + .rhs = inits[1], + }, + }); + } else { + const span = try c.listToSpan(inits); + return c.addNode(.{ + .tag = .array_init_dot, + .main_token = l_brace, + .data = .{ + .lhs = span.start, + .rhs = span.end, + }, + }); + } + }, + .container_init_dot => { + const payload = node.castTag(.container_init_dot).?.data; + _ = try c.addToken(.period, "."); + const l_brace = try c.addToken(.l_brace, "{"); + var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2)); + defer c.gpa.free(inits); + inits[0] = 0; + inits[1] = 0; + for (payload, 0..) |init, i| { + _ = try c.addToken(.period, "."); + _ = try c.addIdentifier(init.name); + _ = try c.addToken(.equal, "="); + inits[i] = try renderNode(c, init.value); + _ = try c.addToken(.comma, ","); + } + _ = try c.addToken(.r_brace, "}"); + + if (payload.len < 3) { + return c.addNode(.{ + .tag = .struct_init_dot_two_comma, + .main_token = l_brace, + .data = .{ + .lhs = inits[0], + .rhs = inits[1], + }, + }); + } else { + const span = try c.listToSpan(inits); + return c.addNode(.{ + .tag = .struct_init_dot_comma, + .main_token = l_brace, + .data = .{ + .lhs = span.start, + .rhs = span.end, + }, + }); + } + }, + .container_init => { + const payload = node.castTag(.container_init).?.data; + const lhs = try renderNode(c, payload.lhs); + + const l_brace = try c.addToken(.l_brace, "{"); + var inits = try c.gpa.alloc(NodeIndex, @max(payload.inits.len, 1)); + defer c.gpa.free(inits); + inits[0] = 0; + for (payload.inits, 0..) |init, i| { + _ = try c.addToken(.period, "."); + _ = try c.addIdentifier(init.name); + _ = try c.addToken(.equal, "="); + inits[i] = try renderNode(c, init.value); + _ = try c.addToken(.comma, ","); + } + _ = try c.addToken(.r_brace, "}"); + + return switch (payload.inits.len) { + 0 => c.addNode(.{ + .tag = .struct_init_one, + .main_token = l_brace, + .data = .{ + .lhs = lhs, + .rhs = 0, + }, + }), + 1 => c.addNode(.{ + .tag = .struct_init_one_comma, + .main_token = l_brace, + .data = .{ + .lhs = lhs, + .rhs = inits[0], + }, + }), + else => blk: { + const span = try c.listToSpan(inits); + break :blk c.addNode(.{ + .tag = .struct_init_comma, + .main_token = l_brace, + .data = .{ + .lhs = lhs, + .rhs = try c.addExtra(NodeSubRange{ + .start = span.start, + .end = span.end, + }), + }, + }); + }, + }; + }, + .@"anytype" => unreachable, // Handled in renderParams + } +} + +fn renderRecord(c: *Context, node: Node) !NodeIndex { + const payload = @as(*Payload.Record, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; + if (payload.layout == .@"packed") + _ = try c.addToken(.keyword_packed, "packed") + else if (payload.layout == .@"extern") + _ = try c.addToken(.keyword_extern, "extern"); + const kind_tok = if (node.tag() == .@"struct") + try c.addToken(.keyword_struct, "struct") + else + try c.addToken(.keyword_union, "union"); + + _ = try c.addToken(.l_brace, "{"); + + const num_vars = payload.variables.len; + const num_funcs = payload.functions.len; + const total_members = payload.fields.len + num_vars + num_funcs; + const members = try c.gpa.alloc(NodeIndex, @max(total_members, 2)); + defer c.gpa.free(members); + members[0] = 0; + members[1] = 0; + + for (payload.fields, 0..) |field, i| { + const name_tok = try c.addTokenFmt(.identifier, "{p}", .{std.zig.fmtId(field.name)}); + _ = try c.addToken(.colon, ":"); + const type_expr = try renderNode(c, field.type); + + const align_expr = if (field.alignment) |alignment| blk: { + _ = try c.addToken(.keyword_align, "align"); + _ = try c.addToken(.l_paren, "("); + const align_expr = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addTokenFmt(.number_literal, "{d}", .{alignment}), + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + break :blk align_expr; + } else 0; + + const value_expr = if (field.default_value) |value| blk: { + _ = try c.addToken(.equal, "="); + break :blk try renderNode(c, value); + } else 0; + + members[i] = try c.addNode(if (align_expr == 0) .{ + .tag = .container_field_init, + .main_token = name_tok, + .data = .{ + .lhs = type_expr, + .rhs = value_expr, + }, + } else if (value_expr == 0) .{ + .tag = .container_field_align, + .main_token = name_tok, + .data = .{ + .lhs = type_expr, + .rhs = align_expr, + }, + } else .{ + .tag = .container_field, + .main_token = name_tok, + .data = .{ + .lhs = type_expr, + .rhs = try c.addExtra(std.zig.Ast.Node.ContainerField{ + .align_expr = align_expr, + .value_expr = value_expr, + }), + }, + }); + _ = try c.addToken(.comma, ","); + } + for (payload.variables, 0..) |variable, i| { + members[payload.fields.len + i] = try renderNode(c, variable); + } + for (payload.functions, 0..) |function, i| { + members[payload.fields.len + num_vars + i] = try renderNode(c, function); + } + _ = try c.addToken(.r_brace, "}"); + + if (total_members == 0) { + return c.addNode(.{ + .tag = .container_decl_two, + .main_token = kind_tok, + .data = .{ + .lhs = 0, + .rhs = 0, + }, + }); + } else if (total_members <= 2) { + return c.addNode(.{ + .tag = if (num_funcs == 0) .container_decl_two_trailing else .container_decl_two, + .main_token = kind_tok, + .data = .{ + .lhs = members[0], + .rhs = members[1], + }, + }); + } else { + const span = try c.listToSpan(members); + return c.addNode(.{ + .tag = if (num_funcs == 0) .container_decl_trailing else .container_decl, + .main_token = kind_tok, + .data = .{ + .lhs = span.start, + .rhs = span.end, + }, + }); + } +} + +fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeIndex { + return c.addNode(.{ + .tag = .field_access, + .main_token = try c.addToken(.period, "."), + .data = .{ + .lhs = lhs, + .rhs = try c.addTokenFmt(.identifier, "{p}", .{std.zig.fmtId(field_name)}), + }, + }); +} + +fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex { + const l_brace = try c.addToken(.l_brace, "{"); + var rendered = try c.gpa.alloc(NodeIndex, @max(inits.len, 1)); + defer c.gpa.free(rendered); + rendered[0] = 0; + for (inits, 0..) |init, i| { + rendered[i] = try renderNode(c, init); + _ = try c.addToken(.comma, ","); + } + _ = try c.addToken(.r_brace, "}"); + if (inits.len < 2) { + return c.addNode(.{ + .tag = .array_init_one_comma, + .main_token = l_brace, + .data = .{ + .lhs = lhs, + .rhs = rendered[0], + }, + }); + } else { + const span = try c.listToSpan(rendered); + return c.addNode(.{ + .tag = .array_init_comma, + .main_token = l_brace, + .data = .{ + .lhs = lhs, + .rhs = try c.addExtra(NodeSubRange{ + .start = span.start, + .end = span.end, + }), + }, + }); + } +} + +fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex { + const l_bracket = try c.addToken(.l_bracket, "["); + const len_expr = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addTokenFmt(.number_literal, "{d}", .{len}), + .data = undefined, + }); + _ = try c.addToken(.r_bracket, "]"); + const elem_type_expr = try renderNode(c, elem_type); + return c.addNode(.{ + .tag = .array_type, + .main_token = l_bracket, + .data = .{ + .lhs = len_expr, + .rhs = elem_type_expr, + }, + }); +} + +fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex { + const l_bracket = try c.addToken(.l_bracket, "["); + const len_expr = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addTokenFmt(.number_literal, "{d}", .{len}), + .data = undefined, + }); + _ = try c.addToken(.colon, ":"); + + const sentinel_expr = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addToken(.number_literal, "0"), + .data = undefined, + }); + + _ = try c.addToken(.r_bracket, "]"); + const elem_type_expr = try renderNode(c, elem_type); + return c.addNode(.{ + .tag = .array_type_sentinel, + .main_token = l_bracket, + .data = .{ + .lhs = len_expr, + .rhs = try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{ + .sentinel = sentinel_expr, + .elem_type = elem_type_expr, + }), + }, + }); +} + +fn addSemicolonIfNeeded(c: *Context, node: Node) !void { + switch (node.tag()) { + .warning => unreachable, + .var_decl, .var_simple, .arg_redecl, .alias, .block, .empty_block, .block_single, .@"switch", .static_local_var, .extern_local_var, .extern_local_fn, .mut_str => {}, + .while_true => { + const payload = node.castTag(.while_true).?.data; + return addSemicolonIfNotBlock(c, payload); + }, + .@"while" => { + const payload = node.castTag(.@"while").?.data; + return addSemicolonIfNotBlock(c, payload.body); + }, + .@"if" => { + const payload = node.castTag(.@"if").?.data; + if (payload.@"else") |some| + return addSemicolonIfNeeded(c, some); + return addSemicolonIfNotBlock(c, payload.then); + }, + else => _ = try c.addToken(.semicolon, ";"), + } +} + +fn addSemicolonIfNotBlock(c: *Context, node: Node) !void { + switch (node.tag()) { + .block, .empty_block, .block_single => {}, + else => _ = try c.addToken(.semicolon, ";"), + } +} + +fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { + switch (node.tag()) { + .declaration => unreachable, + .null_literal, + .undefined_literal, + .true_literal, + .false_literal, + .return_void, + .zero_literal, + .one_literal, + .void_type, + .noreturn_type, + .@"anytype", + .div_trunc, + .signed_remainder, + .int_cast, + .const_cast, + .volatile_cast, + .as, + .truncate, + .bit_cast, + .float_cast, + .int_from_float, + .float_from_int, + .ptr_from_int, + .std_mem_zeroes, + .int_from_ptr, + .sizeof, + .alignof, + .typeof, + .typeinfo, + .vector, + .helpers_sizeof, + .helpers_cast, + .helpers_promoteIntLiteral, + .helpers_shuffle_vector_index, + .helpers_flexible_array_type, + .std_mem_zeroinit, + .integer_literal, + .float_literal, + .string_literal, + .string_slice, + .char_literal, + .enum_literal, + .identifier, + .fn_identifier, + .field_access, + .ptr_cast, + .type, + .array_access, + .align_cast, + .optional_type, + .c_pointer, + .single_pointer, + .unwrap, + .deref, + .not, + .negate, + .negate_wrap, + .bit_not, + .func, + .call, + .array_type, + .null_sentinel_array_type, + .int_from_bool, + .div_exact, + .offset_of, + .shuffle, + .builtin_extern, + .static_local_var, + .extern_local_var, + .extern_local_fn, + .mut_str, + .macro_arithmetic, + => { + // no grouping needed + return renderNode(c, node); + }, + + .opaque_literal, + .empty_array, + .block_single, + .add, + .add_wrap, + .sub, + .sub_wrap, + .mul, + .mul_wrap, + .div, + .shl, + .shr, + .mod, + .@"and", + .@"or", + .less_than, + .less_than_equal, + .greater_than, + .greater_than_equal, + .equal, + .not_equal, + .bit_and, + .bit_or, + .bit_xor, + .empty_block, + .array_cat, + .array_filler, + .@"if", + .@"struct", + .@"union", + .array_init, + .vector_zero_init, + .tuple, + .container_init, + .container_init_dot, + .block, + .address_of, + => return c.addNode(.{ + .tag = .grouped_expression, + .main_token = try c.addToken(.l_paren, "("), + .data = .{ + .lhs = try renderNode(c, node), + .rhs = try c.addToken(.r_paren, ")"), + }, + }), + .ellipsis3, + .switch_prong, + .warning, + .var_decl, + .fail_decl, + .arg_redecl, + .alias, + .var_simple, + .pub_var_simple, + .enum_constant, + .@"while", + .@"switch", + .@"break", + .break_val, + .pub_inline_fn, + .discard, + .@"continue", + .@"return", + .@"comptime", + .@"defer", + .asm_simple, + .while_true, + .if_not_break, + .switch_else, + .add_assign, + .add_wrap_assign, + .sub_assign, + .sub_wrap_assign, + .mul_assign, + .mul_wrap_assign, + .div_assign, + .shl_assign, + .shr_assign, + .mod_assign, + .bit_and_assign, + .bit_or_assign, + .bit_xor_assign, + .assign, + .helpers_macro, + .import_c_builtin, + => { + // these should never appear in places where grouping might be needed. + unreachable; + }, + } +} + +fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex { + const payload = @as(*Payload.UnOp, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; + return c.addNode(.{ + .tag = tag, + .main_token = try c.addToken(tok_tag, bytes), + .data = .{ + .lhs = try renderNodeGrouped(c, payload), + .rhs = undefined, + }, + }); +} + +fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex { + const payload = @as(*Payload.BinOp, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; + const lhs = try renderNodeGrouped(c, payload.lhs); + return c.addNode(.{ + .tag = tag, + .main_token = try c.addToken(tok_tag, bytes), + .data = .{ + .lhs = lhs, + .rhs = try renderNodeGrouped(c, payload.rhs), + }, + }); +} + +fn renderBinOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex { + const payload = @as(*Payload.BinOp, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; + const lhs = try renderNode(c, payload.lhs); + return c.addNode(.{ + .tag = tag, + .main_token = try c.addToken(tok_tag, bytes), + .data = .{ + .lhs = lhs, + .rhs = try renderNode(c, payload.rhs), + }, + }); +} + +fn renderStdImport(c: *Context, parts: []const []const u8) !NodeIndex { + const import_tok = try c.addToken(.builtin, "@import"); + _ = try c.addToken(.l_paren, "("); + const std_tok = try c.addToken(.string_literal, "\"std\""); + const std_node = try c.addNode(.{ + .tag = .string_literal, + .main_token = std_tok, + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + + const import_node = try c.addNode(.{ + .tag = .builtin_call_two, + .main_token = import_tok, + .data = .{ + .lhs = std_node, + .rhs = 0, + }, + }); + + var access_chain = import_node; + for (parts) |part| { + access_chain = try renderFieldAccess(c, access_chain, part); + } + return access_chain; +} + +fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { + const lparen = try c.addToken(.l_paren, "("); + const res = switch (args.len) { + 0 => try c.addNode(.{ + .tag = .call_one, + .main_token = lparen, + .data = .{ + .lhs = lhs, + .rhs = 0, + }, + }), + 1 => blk: { + const arg = try renderNode(c, args[0]); + break :blk try c.addNode(.{ + .tag = .call_one, + .main_token = lparen, + .data = .{ + .lhs = lhs, + .rhs = arg, + }, + }); + }, + else => blk: { + var rendered = try c.gpa.alloc(NodeIndex, args.len); + defer c.gpa.free(rendered); + + for (args, 0..) |arg, i| { + if (i != 0) _ = try c.addToken(.comma, ","); + rendered[i] = try renderNode(c, arg); + } + const span = try c.listToSpan(rendered); + break :blk try c.addNode(.{ + .tag = .call, + .main_token = lparen, + .data = .{ + .lhs = lhs, + .rhs = try c.addExtra(NodeSubRange{ + .start = span.start, + .end = span.end, + }), + }, + }); + }, + }; + _ = try c.addToken(.r_paren, ")"); + return res; +} + +fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !NodeIndex { + const builtin_tok = try c.addToken(.builtin, builtin); + _ = try c.addToken(.l_paren, "("); + var arg_1: NodeIndex = 0; + var arg_2: NodeIndex = 0; + var arg_3: NodeIndex = 0; + var arg_4: NodeIndex = 0; + switch (args.len) { + 0 => {}, + 1 => { + arg_1 = try renderNode(c, args[0]); + }, + 2 => { + arg_1 = try renderNode(c, args[0]); + _ = try c.addToken(.comma, ","); + arg_2 = try renderNode(c, args[1]); + }, + 4 => { + arg_1 = try renderNode(c, args[0]); + _ = try c.addToken(.comma, ","); + arg_2 = try renderNode(c, args[1]); + _ = try c.addToken(.comma, ","); + arg_3 = try renderNode(c, args[2]); + _ = try c.addToken(.comma, ","); + arg_4 = try renderNode(c, args[3]); + }, + else => unreachable, // expand this function as needed. + } + + _ = try c.addToken(.r_paren, ")"); + if (args.len <= 2) { + return c.addNode(.{ + .tag = .builtin_call_two, + .main_token = builtin_tok, + .data = .{ + .lhs = arg_1, + .rhs = arg_2, + }, + }); + } else { + std.debug.assert(args.len == 4); + + const params = try c.listToSpan(&.{ arg_1, arg_2, arg_3, arg_4 }); + return c.addNode(.{ + .tag = .builtin_call, + .main_token = builtin_tok, + .data = .{ + .lhs = params.start, + .rhs = params.end, + }, + }); + } +} + +fn renderVar(c: *Context, node: Node) !NodeIndex { + const payload = node.castTag(.var_decl).?.data; + if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub"); + if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern"); + if (payload.is_export) _ = try c.addToken(.keyword_export, "export"); + if (payload.is_threadlocal) _ = try c.addToken(.keyword_threadlocal, "threadlocal"); + const mut_tok = if (payload.is_const) + try c.addToken(.keyword_const, "const") + else + try c.addToken(.keyword_var, "var"); + _ = try c.addIdentifier(payload.name); + _ = try c.addToken(.colon, ":"); + const type_node = try renderNode(c, payload.type); + + const align_node = if (payload.alignment) |some| blk: { + _ = try c.addToken(.keyword_align, "align"); + _ = try c.addToken(.l_paren, "("); + const res = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addTokenFmt(.number_literal, "{d}", .{some}), + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + break :blk res; + } else 0; + + const section_node = if (payload.linksection_string) |some| blk: { + _ = try c.addToken(.keyword_linksection, "linksection"); + _ = try c.addToken(.l_paren, "("); + const res = try c.addNode(.{ + .tag = .string_literal, + .main_token = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(some)}), + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + break :blk res; + } else 0; + + const init_node = if (payload.init) |some| blk: { + _ = try c.addToken(.equal, "="); + break :blk try renderNode(c, some); + } else 0; + _ = try c.addToken(.semicolon, ";"); + + if (section_node == 0) { + if (align_node == 0) { + return c.addNode(.{ + .tag = .simple_var_decl, + .main_token = mut_tok, + .data = .{ + .lhs = type_node, + .rhs = init_node, + }, + }); + } else { + return c.addNode(.{ + .tag = .local_var_decl, + .main_token = mut_tok, + .data = .{ + .lhs = try c.addExtra(std.zig.Ast.Node.LocalVarDecl{ + .type_node = type_node, + .align_node = align_node, + }), + .rhs = init_node, + }, + }); + } + } else { + return c.addNode(.{ + .tag = .global_var_decl, + .main_token = mut_tok, + .data = .{ + .lhs = try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{ + .type_node = type_node, + .align_node = align_node, + .section_node = section_node, + .addrspace_node = 0, + }), + .rhs = init_node, + }, + }); + } +} + +fn renderFunc(c: *Context, node: Node) !NodeIndex { + const payload = node.castTag(.func).?.data; + if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub"); + if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern"); + if (payload.is_export) _ = try c.addToken(.keyword_export, "export"); + if (payload.is_inline) _ = try c.addToken(.keyword_inline, "inline"); + const fn_token = try c.addToken(.keyword_fn, "fn"); + if (payload.name) |some| _ = try c.addIdentifier(some); + + const params = try renderParams(c, payload.params, payload.is_var_args); + defer params.deinit(); + var span: NodeSubRange = undefined; + if (params.items.len > 1) span = try c.listToSpan(params.items); + + const align_expr = if (payload.alignment) |some| blk: { + _ = try c.addToken(.keyword_align, "align"); + _ = try c.addToken(.l_paren, "("); + const res = try c.addNode(.{ + .tag = .number_literal, + .main_token = try c.addTokenFmt(.number_literal, "{d}", .{some}), + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + break :blk res; + } else 0; + + const section_expr = if (payload.linksection_string) |some| blk: { + _ = try c.addToken(.keyword_linksection, "linksection"); + _ = try c.addToken(.l_paren, "("); + const res = try c.addNode(.{ + .tag = .string_literal, + .main_token = try c.addTokenFmt(.string_literal, "\"{}\"", .{std.zig.fmtEscapes(some)}), + .data = undefined, + }); + _ = try c.addToken(.r_paren, ")"); + break :blk res; + } else 0; + + const callconv_expr = if (payload.explicit_callconv) |some| blk: { + _ = try c.addToken(.keyword_callconv, "callconv"); + _ = try c.addToken(.l_paren, "("); + const cc_node = switch (some) { + .c => cc_node: { + _ = try c.addToken(.period, "."); + break :cc_node try c.addNode(.{ + .tag = .enum_literal, + .main_token = try c.addToken(.identifier, "c"), + .data = undefined, + }); + }, + .x86_64_sysv, + .x86_64_win, + .x86_stdcall, + .x86_fastcall, + .x86_thiscall, + .x86_vectorcall, + .aarch64_vfabi, + .arm_aapcs, + .arm_aapcs_vfp, + .m68k_rtd, + => cc_node: { + // .{ .foo = .{} } + _ = try c.addToken(.period, "."); + const outer_lbrace = try c.addToken(.l_brace, "{"); + _ = try c.addToken(.period, "."); + _ = try c.addToken(.identifier, @tagName(some)); + _ = try c.addToken(.equal, "="); + _ = try c.addToken(.period, "."); + const inner_lbrace = try c.addToken(.l_brace, "{"); + _ = try c.addToken(.r_brace, "}"); + _ = try c.addToken(.r_brace, "}"); + break :cc_node try c.addNode(.{ + .tag = .struct_init_dot_two, + .main_token = outer_lbrace, + .data = .{ + .lhs = try c.addNode(.{ + .tag = .struct_init_dot_two, + .main_token = inner_lbrace, + .data = .{ .lhs = 0, .rhs = 0 }, + }), + .rhs = 0, + }, + }); + }, + }; + _ = try c.addToken(.r_paren, ")"); + break :blk cc_node; + } else 0; + + const return_type_expr = try renderNode(c, payload.return_type); + + const fn_proto = try blk: { + if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) { + if (params.items.len < 2) + break :blk c.addNode(.{ + .tag = .fn_proto_simple, + .main_token = fn_token, + .data = .{ + .lhs = params.items[0], + .rhs = return_type_expr, + }, + }) + else + break :blk c.addNode(.{ + .tag = .fn_proto_multi, + .main_token = fn_token, + .data = .{ + .lhs = try c.addExtra(NodeSubRange{ + .start = span.start, + .end = span.end, + }), + .rhs = return_type_expr, + }, + }); + } + if (params.items.len < 2) + break :blk c.addNode(.{ + .tag = .fn_proto_one, + .main_token = fn_token, + .data = .{ + .lhs = try c.addExtra(std.zig.Ast.Node.FnProtoOne{ + .param = params.items[0], + .align_expr = align_expr, + .addrspace_expr = 0, // TODO + .section_expr = section_expr, + .callconv_expr = callconv_expr, + }), + .rhs = return_type_expr, + }, + }) + else + break :blk c.addNode(.{ + .tag = .fn_proto, + .main_token = fn_token, + .data = .{ + .lhs = try c.addExtra(std.zig.Ast.Node.FnProto{ + .params_start = span.start, + .params_end = span.end, + .align_expr = align_expr, + .addrspace_expr = 0, // TODO + .section_expr = section_expr, + .callconv_expr = callconv_expr, + }), + .rhs = return_type_expr, + }, + }); + }; + + const payload_body = payload.body orelse { + if (payload.is_extern) { + _ = try c.addToken(.semicolon, ";"); + } + return fn_proto; + }; + const body = try renderNode(c, payload_body); + return c.addNode(.{ + .tag = .fn_decl, + .main_token = fn_token, + .data = .{ + .lhs = fn_proto, + .rhs = body, + }, + }); +} + +fn renderMacroFunc(c: *Context, node: Node) !NodeIndex { + const payload = node.castTag(.pub_inline_fn).?.data; + _ = try c.addToken(.keyword_pub, "pub"); + _ = try c.addToken(.keyword_inline, "inline"); + const fn_token = try c.addToken(.keyword_fn, "fn"); + _ = try c.addIdentifier(payload.name); + + const params = try renderParams(c, payload.params, false); + defer params.deinit(); + var span: NodeSubRange = undefined; + if (params.items.len > 1) span = try c.listToSpan(params.items); + + const return_type_expr = try renderNodeGrouped(c, payload.return_type); + + const fn_proto = blk: { + if (params.items.len < 2) { + break :blk try c.addNode(.{ + .tag = .fn_proto_simple, + .main_token = fn_token, + .data = .{ + .lhs = params.items[0], + .rhs = return_type_expr, + }, + }); + } else { + break :blk try c.addNode(.{ + .tag = .fn_proto_multi, + .main_token = fn_token, + .data = .{ + .lhs = try c.addExtra(std.zig.Ast.Node.SubRange{ + .start = span.start, + .end = span.end, + }), + .rhs = return_type_expr, + }, + }); + } + }; + return c.addNode(.{ + .tag = .fn_decl, + .main_token = fn_token, + .data = .{ + .lhs = fn_proto, + .rhs = try renderNode(c, payload.body), + }, + }); +} + +fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) { + _ = try c.addToken(.l_paren, "("); + var rendered = try std.ArrayList(NodeIndex).initCapacity(c.gpa, @max(params.len, 1)); + errdefer rendered.deinit(); + + for (params, 0..) |param, i| { + if (i != 0) _ = try c.addToken(.comma, ","); + if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias"); + if (param.name) |some| { + _ = try c.addIdentifier(some); + _ = try c.addToken(.colon, ":"); + } + if (param.type.tag() == .@"anytype") { + _ = try c.addToken(.keyword_anytype, "anytype"); + continue; + } + rendered.appendAssumeCapacity(try renderNode(c, param.type)); + } + if (is_var_args) { + if (params.len != 0) _ = try c.addToken(.comma, ","); + _ = try c.addToken(.ellipsis3, "..."); + } + _ = try c.addToken(.r_paren, ")"); + + if (rendered.items.len == 0) rendered.appendAssumeCapacity(0); + return rendered; +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/build_runner.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/build_runner.zig new file mode 100644 index 00000000..b649c010 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/build_runner.zig @@ -0,0 +1,1521 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const assert = std.debug.assert; +const io = std.io; +const fmt = std.fmt; +const mem = std.mem; +const process = std.process; +const ArrayList = std.ArrayList; +const File = std.fs.File; +const Step = std.Build.Step; +const Watch = std.Build.Watch; +const Fuzz = std.Build.Fuzz; +const Allocator = std.mem.Allocator; +const fatal = std.process.fatal; +const runner = @This(); + +pub const root = @import("@build"); +pub const dependencies = @import("@dependencies"); + +pub const std_options: std.Options = .{ + .side_channels_mitigations = .none, + .http_disable_tls = true, + .crypto_fork_safety = false, +}; + +pub fn main() !void { + // Here we use an ArenaAllocator backed by a page allocator because a build is a short-lived, + // one shot program. We don't need to waste time freeing memory and finding places to squish + // bytes into. So we free everything all at once at the very end. + var single_threaded_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer single_threaded_arena.deinit(); + + var thread_safe_arena: std.heap.ThreadSafeAllocator = .{ + .child_allocator = single_threaded_arena.allocator(), + }; + const arena = thread_safe_arena.allocator(); + + const args = try process.argsAlloc(arena); + + // skip my own exe name + var arg_idx: usize = 1; + + const zig_exe = nextArg(args, &arg_idx) orelse fatal("missing zig compiler path", .{}); + const zig_lib_dir = nextArg(args, &arg_idx) orelse fatal("missing zig lib directory path", .{}); + const build_root = nextArg(args, &arg_idx) orelse fatal("missing build root directory path", .{}); + const cache_root = nextArg(args, &arg_idx) orelse fatal("missing cache root directory path", .{}); + const global_cache_root = nextArg(args, &arg_idx) orelse fatal("missing global cache root directory path", .{}); + + const zig_lib_directory: std.Build.Cache.Directory = .{ + .path = zig_lib_dir, + .handle = try std.fs.cwd().openDir(zig_lib_dir, .{}), + }; + + const build_root_directory: std.Build.Cache.Directory = .{ + .path = build_root, + .handle = try std.fs.cwd().openDir(build_root, .{}), + }; + + const local_cache_directory: std.Build.Cache.Directory = .{ + .path = cache_root, + .handle = try std.fs.cwd().makeOpenPath(cache_root, .{}), + }; + + const global_cache_directory: std.Build.Cache.Directory = .{ + .path = global_cache_root, + .handle = try std.fs.cwd().makeOpenPath(global_cache_root, .{}), + }; + + var graph: std.Build.Graph = .{ + .arena = arena, + .cache = .{ + .gpa = arena, + .manifest_dir = try local_cache_directory.handle.makeOpenPath("h", .{}), + }, + .zig_exe = zig_exe, + .env_map = try process.getEnvMap(arena), + .global_cache_root = global_cache_directory, + .zig_lib_directory = zig_lib_directory, + .host = .{ + .query = .{}, + .result = try std.zig.system.resolveTargetQuery(.{}), + }, + }; + + graph.cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); + graph.cache.addPrefix(build_root_directory); + graph.cache.addPrefix(local_cache_directory); + graph.cache.addPrefix(global_cache_directory); + graph.cache.hash.addBytes(builtin.zig_version_string); + + const builder = try std.Build.create( + &graph, + build_root_directory, + local_cache_directory, + dependencies.root_deps, + ); + + var targets = ArrayList([]const u8).init(arena); + var debug_log_scopes = ArrayList([]const u8).init(arena); + var thread_pool_options: std.Thread.Pool.Options = .{ .allocator = arena }; + + var install_prefix: ?[]const u8 = null; + var dir_list = std.Build.DirList{}; + var summary: ?Summary = null; + var max_rss: u64 = 0; + var skip_oom_steps = false; + var color: Color = .auto; + var prominent_compile_errors = false; + var help_menu = false; + var steps_menu = false; + var output_tmp_nonce: ?[16]u8 = null; + var watch = false; + var fuzz = false; + var debounce_interval_ms: u16 = 50; + var listen_port: u16 = 0; + + while (nextArg(args, &arg_idx)) |arg| { + if (mem.startsWith(u8, arg, "-Z")) { + if (arg.len != 18) fatalWithHint("bad argument: '{s}'", .{arg}); + output_tmp_nonce = arg[2..18].*; + } else if (mem.startsWith(u8, arg, "-D")) { + const option_contents = arg[2..]; + if (option_contents.len == 0) + fatalWithHint("expected option name after '-D'", .{}); + if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { + const option_name = option_contents[0..name_end]; + const option_value = option_contents[name_end + 1 ..]; + if (try builder.addUserInputOption(option_name, option_value)) + fatal(" access the help menu with 'zig build -h'", .{}); + } else { + if (try builder.addUserInputFlag(option_contents)) + fatal(" access the help menu with 'zig build -h'", .{}); + } + } else if (mem.startsWith(u8, arg, "-")) { + if (mem.eql(u8, arg, "--verbose")) { + builder.verbose = true; + } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { + help_menu = true; + } else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) { + install_prefix = nextArgOrFatal(args, &arg_idx); + } else if (mem.eql(u8, arg, "-l") or mem.eql(u8, arg, "--list-steps")) { + steps_menu = true; + } else if (mem.startsWith(u8, arg, "-fsys=")) { + const name = arg["-fsys=".len..]; + graph.system_library_options.put(arena, name, .user_enabled) catch @panic("OOM"); + } else if (mem.startsWith(u8, arg, "-fno-sys=")) { + const name = arg["-fno-sys=".len..]; + graph.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM"); + } else if (mem.eql(u8, arg, "--release")) { + builder.release_mode = .any; + } else if (mem.startsWith(u8, arg, "--release=")) { + const text = arg["--release=".len..]; + builder.release_mode = std.meta.stringToEnum(std.Build.ReleaseMode, text) orelse { + fatalWithHint("expected [off|any|fast|safe|small] in '{s}', found '{s}'", .{ + arg, text, + }); + }; + } else if (mem.eql(u8, arg, "--prefix-lib-dir")) { + dir_list.lib_dir = nextArgOrFatal(args, &arg_idx); + } else if (mem.eql(u8, arg, "--prefix-exe-dir")) { + dir_list.exe_dir = nextArgOrFatal(args, &arg_idx); + } else if (mem.eql(u8, arg, "--prefix-include-dir")) { + dir_list.include_dir = nextArgOrFatal(args, &arg_idx); + } else if (mem.eql(u8, arg, "--sysroot")) { + builder.sysroot = nextArgOrFatal(args, &arg_idx); + } else if (mem.eql(u8, arg, "--maxrss")) { + const max_rss_text = nextArgOrFatal(args, &arg_idx); + max_rss = std.fmt.parseIntSizeSuffix(max_rss_text, 10) catch |err| { + std.debug.print("invalid byte size: '{s}': {s}\n", .{ + max_rss_text, @errorName(err), + }); + process.exit(1); + }; + } else if (mem.eql(u8, arg, "--skip-oom-steps")) { + skip_oom_steps = true; + } else if (mem.eql(u8, arg, "--search-prefix")) { + const search_prefix = nextArgOrFatal(args, &arg_idx); + builder.addSearchPrefix(search_prefix); + } else if (mem.eql(u8, arg, "--libc")) { + builder.libc_file = nextArgOrFatal(args, &arg_idx); + } else if (mem.eql(u8, arg, "--color")) { + const next_arg = nextArg(args, &arg_idx) orelse + fatalWithHint("expected [auto|on|off] after '{s}'", .{arg}); + color = std.meta.stringToEnum(Color, next_arg) orelse { + fatalWithHint("expected [auto|on|off] after '{s}', found '{s}'", .{ + arg, next_arg, + }); + }; + } else if (mem.eql(u8, arg, "--summary")) { + const next_arg = nextArg(args, &arg_idx) orelse + fatalWithHint("expected [all|new|failures|none] after '{s}'", .{arg}); + summary = std.meta.stringToEnum(Summary, next_arg) orelse { + fatalWithHint("expected [all|new|failures|none] after '{s}', found '{s}'", .{ + arg, next_arg, + }); + }; + } else if (mem.eql(u8, arg, "--seed")) { + const next_arg = nextArg(args, &arg_idx) orelse + fatalWithHint("expected u32 after '{s}'", .{arg}); + graph.random_seed = std.fmt.parseUnsigned(u32, next_arg, 0) catch |err| { + fatal("unable to parse seed '{s}' as unsigned 32-bit integer: {s}\n", .{ + next_arg, @errorName(err), + }); + }; + } else if (mem.eql(u8, arg, "--debounce")) { + const next_arg = nextArg(args, &arg_idx) orelse + fatalWithHint("expected u16 after '{s}'", .{arg}); + debounce_interval_ms = std.fmt.parseUnsigned(u16, next_arg, 0) catch |err| { + fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {s}\n", .{ + next_arg, @errorName(err), + }); + }; + } else if (mem.eql(u8, arg, "--port")) { + const next_arg = nextArg(args, &arg_idx) orelse + fatalWithHint("expected u16 after '{s}'", .{arg}); + listen_port = std.fmt.parseUnsigned(u16, next_arg, 10) catch |err| { + fatal("unable to parse port '{s}' as unsigned 16-bit integer: {s}\n", .{ + next_arg, @errorName(err), + }); + }; + } else if (mem.eql(u8, arg, "--debug-log")) { + const next_arg = nextArgOrFatal(args, &arg_idx); + try debug_log_scopes.append(next_arg); + } else if (mem.eql(u8, arg, "--debug-pkg-config")) { + builder.debug_pkg_config = true; + } else if (mem.eql(u8, arg, "--debug-rt")) { + graph.debug_compiler_runtime_libs = true; + } else if (mem.eql(u8, arg, "--debug-compile-errors")) { + builder.debug_compile_errors = true; + } else if (mem.eql(u8, arg, "--system")) { + // The usage text shows another argument after this parameter + // but it is handled by the parent process. The build runner + // only sees this flag. + graph.system_package_mode = true; + } else if (mem.eql(u8, arg, "--glibc-runtimes")) { + builder.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx); + } else if (mem.eql(u8, arg, "--verbose-link")) { + builder.verbose_link = true; + } else if (mem.eql(u8, arg, "--verbose-air")) { + builder.verbose_air = true; + } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) { + builder.verbose_llvm_ir = "-"; + } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) { + builder.verbose_llvm_ir = arg["--verbose-llvm-ir=".len..]; + } else if (mem.eql(u8, arg, "--verbose-llvm-bc=")) { + builder.verbose_llvm_bc = arg["--verbose-llvm-bc=".len..]; + } else if (mem.eql(u8, arg, "--verbose-cimport")) { + builder.verbose_cimport = true; + } else if (mem.eql(u8, arg, "--verbose-cc")) { + builder.verbose_cc = true; + } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) { + builder.verbose_llvm_cpu_features = true; + } else if (mem.eql(u8, arg, "--prominent-compile-errors")) { + prominent_compile_errors = true; + } else if (mem.eql(u8, arg, "--watch")) { + watch = true; + } else if (mem.eql(u8, arg, "--fuzz")) { + fuzz = true; + } else if (mem.eql(u8, arg, "-fincremental")) { + graph.incremental = true; + } else if (mem.eql(u8, arg, "-fno-incremental")) { + graph.incremental = false; + } else if (mem.eql(u8, arg, "-fwine")) { + builder.enable_wine = true; + } else if (mem.eql(u8, arg, "-fno-wine")) { + builder.enable_wine = false; + } else if (mem.eql(u8, arg, "-fqemu")) { + builder.enable_qemu = true; + } else if (mem.eql(u8, arg, "-fno-qemu")) { + builder.enable_qemu = false; + } else if (mem.eql(u8, arg, "-fwasmtime")) { + builder.enable_wasmtime = true; + } else if (mem.eql(u8, arg, "-fno-wasmtime")) { + builder.enable_wasmtime = false; + } else if (mem.eql(u8, arg, "-frosetta")) { + builder.enable_rosetta = true; + } else if (mem.eql(u8, arg, "-fno-rosetta")) { + builder.enable_rosetta = false; + } else if (mem.eql(u8, arg, "-fdarling")) { + builder.enable_darling = true; + } else if (mem.eql(u8, arg, "-fno-darling")) { + builder.enable_darling = false; + } else if (mem.eql(u8, arg, "-fallow-so-scripts")) { + graph.allow_so_scripts = true; + } else if (mem.eql(u8, arg, "-fno-allow-so-scripts")) { + graph.allow_so_scripts = false; + } else if (mem.eql(u8, arg, "-freference-trace")) { + builder.reference_trace = 256; + } else if (mem.startsWith(u8, arg, "-freference-trace=")) { + const num = arg["-freference-trace=".len..]; + builder.reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| { + std.debug.print("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) }); + process.exit(1); + }; + } else if (mem.eql(u8, arg, "-fno-reference-trace")) { + builder.reference_trace = null; + } else if (mem.startsWith(u8, arg, "-j")) { + const num = arg["-j".len..]; + const n_jobs = std.fmt.parseUnsigned(u32, num, 10) catch |err| { + std.debug.print("unable to parse jobs count '{s}': {s}", .{ + num, @errorName(err), + }); + process.exit(1); + }; + if (n_jobs < 1) { + std.debug.print("number of jobs must be at least 1\n", .{}); + process.exit(1); + } + thread_pool_options.n_jobs = n_jobs; + } else if (mem.eql(u8, arg, "--")) { + builder.args = argsRest(args, arg_idx); + break; + } else { + fatalWithHint("unrecognized argument: '{s}'", .{arg}); + } + } else { + try targets.append(arg); + } + } + + const stderr = std.io.getStdErr(); + const ttyconf = get_tty_conf(color, stderr); + switch (ttyconf) { + .no_color => try graph.env_map.put("NO_COLOR", "1"), + .escape_codes => try graph.env_map.put("CLICOLOR_FORCE", "1"), + .windows_api => {}, + } + + const main_progress_node = std.Progress.start(.{ + .disable_printing = (color == .off), + }); + defer main_progress_node.end(); + + builder.debug_log_scopes = debug_log_scopes.items; + builder.resolveInstallPrefix(install_prefix, dir_list); + { + var prog_node = main_progress_node.start("Configure", 0); + defer prog_node.end(); + try builder.runBuild(root); + createModuleDependencies(builder) catch @panic("OOM"); + } + + if (graph.needed_lazy_dependencies.entries.len != 0) { + var buffer: std.ArrayListUnmanaged(u8) = .empty; + for (graph.needed_lazy_dependencies.keys()) |k| { + try buffer.appendSlice(arena, k); + try buffer.append(arena, '\n'); + } + const s = std.fs.path.sep_str; + const tmp_sub_path = "tmp" ++ s ++ (output_tmp_nonce orelse fatal("missing -Z arg", .{})); + local_cache_directory.handle.writeFile(.{ + .sub_path = tmp_sub_path, + .data = buffer.items, + .flags = .{ .exclusive = true }, + }) catch |err| { + fatal("unable to write configuration results to '{}{s}': {s}", .{ + local_cache_directory, tmp_sub_path, @errorName(err), + }); + }; + process.exit(3); // Indicate configure phase failed with meaningful stdout. + } + + if (builder.validateUserInputDidItFail()) { + fatal(" access the help menu with 'zig build -h'", .{}); + } + + validateSystemLibraryOptions(builder); + + const stdout_writer = io.getStdOut().writer(); + + if (help_menu) + return usage(builder, stdout_writer); + + if (steps_menu) + return steps(builder, stdout_writer); + + var run: Run = .{ + .max_rss = max_rss, + .max_rss_is_default = false, + .max_rss_mutex = .{}, + .skip_oom_steps = skip_oom_steps, + .watch = watch, + .fuzz = fuzz, + .memory_blocked_steps = std.ArrayList(*Step).init(arena), + .step_stack = .{}, + .prominent_compile_errors = prominent_compile_errors, + + .claimed_rss = 0, + .summary = summary orelse if (watch) .new else .failures, + .ttyconf = ttyconf, + .stderr = stderr, + .thread_pool = undefined, + }; + + if (run.max_rss == 0) { + run.max_rss = process.totalSystemMemory() catch std.math.maxInt(u64); + run.max_rss_is_default = true; + } + + const gpa = arena; + prepare(gpa, arena, builder, targets.items, &run, graph.random_seed) catch |err| switch (err) { + error.UncleanExit => process.exit(1), + else => return err, + }; + + var w = if (watch) try Watch.init() else undefined; + + try run.thread_pool.init(thread_pool_options); + defer run.thread_pool.deinit(); + + rebuild: while (true) { + runStepNames( + gpa, + builder, + targets.items, + main_progress_node, + &run, + ) catch |err| switch (err) { + error.UncleanExit => { + assert(!run.watch); + process.exit(1); + }, + else => return err, + }; + if (fuzz) { + switch (builtin.os.tag) { + // Current implementation depends on two things that need to be ported to Windows: + // * Memory-mapping to share data between the fuzzer and build runner. + // * COFF/PE support added to `std.debug.Info` (it needs a batching API for resolving + // many addresses to source locations). + .windows => fatal("--fuzz not yet implemented for {s}", .{@tagName(builtin.os.tag)}), + else => {}, + } + if (@bitSizeOf(usize) != 64) { + // Current implementation depends on posix.mmap()'s second parameter, `length: usize`, + // being compatible with `std.fs.getEndPos() u64`'s return value. This is not the case + // on 32-bit platforms. + // Affects or affected by issues #5185, #22523, and #22464. + fatal("--fuzz not yet implemented on {d}-bit platforms", .{@bitSizeOf(usize)}); + } + const listen_address = std.net.Address.parseIp("127.0.0.1", listen_port) catch unreachable; + try Fuzz.start( + gpa, + arena, + global_cache_directory, + zig_lib_directory, + zig_exe, + &run.thread_pool, + run.step_stack.keys(), + run.ttyconf, + listen_address, + main_progress_node, + ); + } + + if (!watch) return cleanExit(); + + if (!Watch.have_impl) fatal("--watch not yet implemented for {s}", .{@tagName(builtin.os.tag)}); + + try w.update(gpa, run.step_stack.keys()); + + // Wait until a file system notification arrives. Read all such events + // until the buffer is empty. Then wait for a debounce interval, resetting + // if any more events come in. After the debounce interval has passed, + // trigger a rebuild on all steps with modified inputs, as well as their + // recursive dependants. + var caption_buf: [std.Progress.Node.max_name_len]u8 = undefined; + const caption = std.fmt.bufPrint(&caption_buf, "watching {d} directories, {d} processes", .{ + w.dir_table.entries.len, countSubProcesses(run.step_stack.keys()), + }) catch &caption_buf; + var debouncing_node = main_progress_node.start(caption, 0); + var debounce_timeout: Watch.Timeout = .none; + while (true) switch (try w.wait(gpa, debounce_timeout)) { + .timeout => { + debouncing_node.end(); + markFailedStepsDirty(gpa, run.step_stack.keys()); + continue :rebuild; + }, + .dirty => if (debounce_timeout == .none) { + debounce_timeout = .{ .ms = debounce_interval_ms }; + debouncing_node.end(); + debouncing_node = main_progress_node.start("Debouncing (Change Detected)", 0); + }, + .clean => {}, + }; + } +} + +fn markFailedStepsDirty(gpa: Allocator, all_steps: []const *Step) void { + for (all_steps) |step| switch (step.state) { + .dependency_failure, .failure, .skipped => step.recursiveReset(gpa), + else => continue, + }; + // Now that all dirty steps have been found, the remaining steps that + // succeeded from last run shall be marked "cached". + for (all_steps) |step| switch (step.state) { + .success => step.result_cached = true, + else => continue, + }; +} + +fn countSubProcesses(all_steps: []const *Step) usize { + var count: usize = 0; + for (all_steps) |s| { + count += @intFromBool(s.getZigProcess() != null); + } + return count; +} + +const Run = struct { + max_rss: u64, + max_rss_is_default: bool, + max_rss_mutex: std.Thread.Mutex, + skip_oom_steps: bool, + watch: bool, + fuzz: bool, + memory_blocked_steps: std.ArrayList(*Step), + step_stack: std.AutoArrayHashMapUnmanaged(*Step, void), + prominent_compile_errors: bool, + thread_pool: std.Thread.Pool, + + claimed_rss: usize, + summary: Summary, + ttyconf: std.io.tty.Config, + stderr: File, + + fn cleanExit(run: Run) void { + if (run.watch or run.fuzz) return; + return runner.cleanExit(); + } +}; + +fn prepare( + gpa: Allocator, + arena: Allocator, + b: *std.Build, + step_names: []const []const u8, + run: *Run, + seed: u32, +) !void { + const step_stack = &run.step_stack; + + if (step_names.len == 0) { + try step_stack.put(gpa, b.default_step, {}); + } else { + try step_stack.ensureUnusedCapacity(gpa, step_names.len); + for (0..step_names.len) |i| { + const step_name = step_names[step_names.len - i - 1]; + const s = b.top_level_steps.get(step_name) orelse { + std.debug.print("no step named '{s}'\n access the help menu with 'zig build -h'\n", .{step_name}); + process.exit(1); + }; + step_stack.putAssumeCapacity(&s.step, {}); + } + } + + const starting_steps = try arena.dupe(*Step, step_stack.keys()); + + var rng = std.Random.DefaultPrng.init(seed); + const rand = rng.random(); + rand.shuffle(*Step, starting_steps); + + for (starting_steps) |s| { + constructGraphAndCheckForDependencyLoop(b, s, &run.step_stack, rand) catch |err| switch (err) { + error.DependencyLoopDetected => return uncleanExit(), + else => |e| return e, + }; + } + + { + // Check that we have enough memory to complete the build. + var any_problems = false; + for (step_stack.keys()) |s| { + if (s.max_rss == 0) continue; + if (s.max_rss > run.max_rss) { + if (run.skip_oom_steps) { + s.state = .skipped_oom; + } else { + std.debug.print("{s}{s}: this step declares an upper bound of {d} bytes of memory, exceeding the available {d} bytes of memory\n", .{ + s.owner.dep_prefix, s.name, s.max_rss, run.max_rss, + }); + any_problems = true; + } + } + } + if (any_problems) { + if (run.max_rss_is_default) { + std.debug.print("note: use --maxrss to override the default", .{}); + } + return uncleanExit(); + } + } +} + +fn runStepNames( + gpa: Allocator, + b: *std.Build, + step_names: []const []const u8, + parent_prog_node: std.Progress.Node, + run: *Run, +) !void { + const step_stack = &run.step_stack; + const thread_pool = &run.thread_pool; + + { + const step_prog = parent_prog_node.start("steps", step_stack.count()); + defer step_prog.end(); + + var wait_group: std.Thread.WaitGroup = .{}; + defer wait_group.wait(); + + // Here we spawn the initial set of tasks with a nice heuristic - + // dependency order. Each worker when it finishes a step will then + // check whether it should run any dependants. + const steps_slice = step_stack.keys(); + for (0..steps_slice.len) |i| { + const step = steps_slice[steps_slice.len - i - 1]; + if (step.state == .skipped_oom) continue; + + thread_pool.spawnWg(&wait_group, workerMakeOneStep, .{ + &wait_group, b, step, step_prog, run, + }); + } + } + assert(run.memory_blocked_steps.items.len == 0); + + var test_skip_count: usize = 0; + var test_fail_count: usize = 0; + var test_pass_count: usize = 0; + var test_leak_count: usize = 0; + var test_count: usize = 0; + + var success_count: usize = 0; + var skipped_count: usize = 0; + var failure_count: usize = 0; + var pending_count: usize = 0; + var total_compile_errors: usize = 0; + + for (step_stack.keys()) |s| { + test_fail_count += s.test_results.fail_count; + test_skip_count += s.test_results.skip_count; + test_leak_count += s.test_results.leak_count; + test_pass_count += s.test_results.passCount(); + test_count += s.test_results.test_count; + + switch (s.state) { + .precheck_unstarted => unreachable, + .precheck_started => unreachable, + .running => unreachable, + .precheck_done => { + // precheck_done is equivalent to dependency_failure in the case of + // transitive dependencies. For example: + // A -> B -> C (failure) + // B will be marked as dependency_failure, while A may never be queued, and thus + // remain in the initial state of precheck_done. + s.state = .dependency_failure; + pending_count += 1; + }, + .dependency_failure => pending_count += 1, + .success => success_count += 1, + .skipped, .skipped_oom => skipped_count += 1, + .failure => { + failure_count += 1; + const compile_errors_len = s.result_error_bundle.errorMessageCount(); + if (compile_errors_len > 0) { + total_compile_errors += compile_errors_len; + } + }, + } + } + + // A proper command line application defaults to silently succeeding. + // The user may request verbose mode if they have a different preference. + const failures_only = switch (run.summary) { + .failures, .none => true, + else => false, + }; + if (failure_count == 0 and failures_only) { + return run.cleanExit(); + } + + const ttyconf = run.ttyconf; + + if (run.summary != .none) { + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); + const stderr = run.stderr; + + const total_count = success_count + failure_count + pending_count + skipped_count; + ttyconf.setColor(stderr, .cyan) catch {}; + stderr.writeAll("Build Summary:") catch {}; + ttyconf.setColor(stderr, .reset) catch {}; + stderr.writer().print(" {d}/{d} steps succeeded", .{ success_count, total_count }) catch {}; + if (skipped_count > 0) stderr.writer().print("; {d} skipped", .{skipped_count}) catch {}; + if (failure_count > 0) stderr.writer().print("; {d} failed", .{failure_count}) catch {}; + + if (test_count > 0) stderr.writer().print("; {d}/{d} tests passed", .{ test_pass_count, test_count }) catch {}; + if (test_skip_count > 0) stderr.writer().print("; {d} skipped", .{test_skip_count}) catch {}; + if (test_fail_count > 0) stderr.writer().print("; {d} failed", .{test_fail_count}) catch {}; + if (test_leak_count > 0) stderr.writer().print("; {d} leaked", .{test_leak_count}) catch {}; + + stderr.writeAll("\n") catch {}; + + // Print a fancy tree with build results. + var step_stack_copy = try step_stack.clone(gpa); + defer step_stack_copy.deinit(gpa); + + var print_node: PrintNode = .{ .parent = null }; + if (step_names.len == 0) { + print_node.last = true; + printTreeStep(b, b.default_step, run, stderr, ttyconf, &print_node, &step_stack_copy) catch {}; + } else { + const last_index = if (run.summary == .all) b.top_level_steps.count() else blk: { + var i: usize = step_names.len; + while (i > 0) { + i -= 1; + const step = b.top_level_steps.get(step_names[i]).?.step; + const found = switch (run.summary) { + .all, .none => unreachable, + .failures => step.state != .success, + .new => !step.result_cached, + }; + if (found) break :blk i; + } + break :blk b.top_level_steps.count(); + }; + for (step_names, 0..) |step_name, i| { + const tls = b.top_level_steps.get(step_name).?; + print_node.last = i + 1 == last_index; + printTreeStep(b, &tls.step, run, stderr, ttyconf, &print_node, &step_stack_copy) catch {}; + } + } + } + + if (failure_count == 0) { + return run.cleanExit(); + } + + // Finally, render compile errors at the bottom of the terminal. + if (run.prominent_compile_errors and total_compile_errors > 0) { + for (step_stack.keys()) |s| { + if (s.result_error_bundle.errorMessageCount() > 0) { + s.result_error_bundle.renderToStdErr(.{ .ttyconf = ttyconf }); + } + } + + if (!run.watch) { + // Signal to parent process that we have printed compile errors. The + // parent process may choose to omit the "following command failed" + // line in this case. + std.debug.lockStdErr(); + process.exit(2); + } + } + + if (!run.watch) return uncleanExit(); +} + +const PrintNode = struct { + parent: ?*PrintNode, + last: bool = false, +}; + +fn printPrefix(node: *PrintNode, stderr: File, ttyconf: std.io.tty.Config) !void { + const parent = node.parent orelse return; + if (parent.parent == null) return; + try printPrefix(parent, stderr, ttyconf); + if (parent.last) { + try stderr.writeAll(" "); + } else { + try stderr.writeAll(switch (ttyconf) { + .no_color, .windows_api => "| ", + .escape_codes => "\x1B\x28\x30\x78\x1B\x28\x42 ", // │ + }); + } +} + +fn printChildNodePrefix(stderr: File, ttyconf: std.io.tty.Config) !void { + try stderr.writeAll(switch (ttyconf) { + .no_color, .windows_api => "+- ", + .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─ + }); +} + +fn printStepStatus( + s: *Step, + stderr: File, + ttyconf: std.io.tty.Config, + run: *const Run, +) !void { + switch (s.state) { + .precheck_unstarted => unreachable, + .precheck_started => unreachable, + .precheck_done => unreachable, + .running => unreachable, + + .dependency_failure => { + try ttyconf.setColor(stderr, .dim); + try stderr.writeAll(" transitive failure\n"); + try ttyconf.setColor(stderr, .reset); + }, + + .success => { + try ttyconf.setColor(stderr, .green); + if (s.result_cached) { + try stderr.writeAll(" cached"); + } else if (s.test_results.test_count > 0) { + const pass_count = s.test_results.passCount(); + try stderr.writer().print(" {d} passed", .{pass_count}); + if (s.test_results.skip_count > 0) { + try ttyconf.setColor(stderr, .yellow); + try stderr.writer().print(" {d} skipped", .{s.test_results.skip_count}); + } + } else { + try stderr.writeAll(" success"); + } + try ttyconf.setColor(stderr, .reset); + if (s.result_duration_ns) |ns| { + try ttyconf.setColor(stderr, .dim); + if (ns >= std.time.ns_per_min) { + try stderr.writer().print(" {d}m", .{ns / std.time.ns_per_min}); + } else if (ns >= std.time.ns_per_s) { + try stderr.writer().print(" {d}s", .{ns / std.time.ns_per_s}); + } else if (ns >= std.time.ns_per_ms) { + try stderr.writer().print(" {d}ms", .{ns / std.time.ns_per_ms}); + } else if (ns >= std.time.ns_per_us) { + try stderr.writer().print(" {d}us", .{ns / std.time.ns_per_us}); + } else { + try stderr.writer().print(" {d}ns", .{ns}); + } + try ttyconf.setColor(stderr, .reset); + } + if (s.result_peak_rss != 0) { + const rss = s.result_peak_rss; + try ttyconf.setColor(stderr, .dim); + if (rss >= 1000_000_000) { + try stderr.writer().print(" MaxRSS:{d}G", .{rss / 1000_000_000}); + } else if (rss >= 1000_000) { + try stderr.writer().print(" MaxRSS:{d}M", .{rss / 1000_000}); + } else if (rss >= 1000) { + try stderr.writer().print(" MaxRSS:{d}K", .{rss / 1000}); + } else { + try stderr.writer().print(" MaxRSS:{d}B", .{rss}); + } + try ttyconf.setColor(stderr, .reset); + } + try stderr.writeAll("\n"); + }, + .skipped, .skipped_oom => |skip| { + try ttyconf.setColor(stderr, .yellow); + try stderr.writeAll(" skipped"); + if (skip == .skipped_oom) { + try stderr.writeAll(" (not enough memory)"); + try ttyconf.setColor(stderr, .dim); + try stderr.writer().print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss }); + try ttyconf.setColor(stderr, .yellow); + } + try stderr.writeAll("\n"); + try ttyconf.setColor(stderr, .reset); + }, + .failure => try printStepFailure(s, stderr, ttyconf), + } +} + +fn printStepFailure( + s: *Step, + stderr: File, + ttyconf: std.io.tty.Config, +) !void { + if (s.result_error_bundle.errorMessageCount() > 0) { + try ttyconf.setColor(stderr, .red); + try stderr.writer().print(" {d} errors\n", .{ + s.result_error_bundle.errorMessageCount(), + }); + try ttyconf.setColor(stderr, .reset); + } else if (!s.test_results.isSuccess()) { + try stderr.writer().print(" {d}/{d} passed", .{ + s.test_results.passCount(), s.test_results.test_count, + }); + if (s.test_results.fail_count > 0) { + try stderr.writeAll(", "); + try ttyconf.setColor(stderr, .red); + try stderr.writer().print("{d} failed", .{ + s.test_results.fail_count, + }); + try ttyconf.setColor(stderr, .reset); + } + if (s.test_results.skip_count > 0) { + try stderr.writeAll(", "); + try ttyconf.setColor(stderr, .yellow); + try stderr.writer().print("{d} skipped", .{ + s.test_results.skip_count, + }); + try ttyconf.setColor(stderr, .reset); + } + if (s.test_results.leak_count > 0) { + try stderr.writeAll(", "); + try ttyconf.setColor(stderr, .red); + try stderr.writer().print("{d} leaked", .{ + s.test_results.leak_count, + }); + try ttyconf.setColor(stderr, .reset); + } + try stderr.writeAll("\n"); + } else if (s.result_error_msgs.items.len > 0) { + try ttyconf.setColor(stderr, .red); + try stderr.writeAll(" failure\n"); + try ttyconf.setColor(stderr, .reset); + } else { + assert(s.result_stderr.len > 0); + try ttyconf.setColor(stderr, .red); + try stderr.writeAll(" stderr\n"); + try ttyconf.setColor(stderr, .reset); + } +} + +fn printTreeStep( + b: *std.Build, + s: *Step, + run: *const Run, + stderr: File, + ttyconf: std.io.tty.Config, + parent_node: *PrintNode, + step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), +) !void { + const first = step_stack.swapRemove(s); + const summary = run.summary; + const skip = switch (summary) { + .none => unreachable, + .all => false, + .new => s.result_cached, + .failures => s.state == .success, + }; + if (skip) return; + try printPrefix(parent_node, stderr, ttyconf); + + if (!first) try ttyconf.setColor(stderr, .dim); + if (parent_node.parent != null) { + if (parent_node.last) { + try printChildNodePrefix(stderr, ttyconf); + } else { + try stderr.writeAll(switch (ttyconf) { + .no_color, .windows_api => "+- ", + .escape_codes => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─ + }); + } + } + + // dep_prefix omitted here because it is redundant with the tree. + try stderr.writeAll(s.name); + + if (first) { + try printStepStatus(s, stderr, ttyconf, run); + + const last_index = if (summary == .all) s.dependencies.items.len -| 1 else blk: { + var i: usize = s.dependencies.items.len; + while (i > 0) { + i -= 1; + + const step = s.dependencies.items[i]; + const found = switch (summary) { + .all, .none => unreachable, + .failures => step.state != .success, + .new => !step.result_cached, + }; + if (found) break :blk i; + } + break :blk s.dependencies.items.len -| 1; + }; + for (s.dependencies.items, 0..) |dep, i| { + var print_node: PrintNode = .{ + .parent = parent_node, + .last = i == last_index, + }; + try printTreeStep(b, dep, run, stderr, ttyconf, &print_node, step_stack); + } + } else { + if (s.dependencies.items.len == 0) { + try stderr.writeAll(" (reused)\n"); + } else { + try stderr.writer().print(" (+{d} more reused dependencies)\n", .{ + s.dependencies.items.len, + }); + } + try ttyconf.setColor(stderr, .reset); + } +} + +/// Traverse the dependency graph depth-first and make it undirected by having +/// steps know their dependants (they only know dependencies at start). +/// Along the way, check that there is no dependency loop, and record the steps +/// in traversal order in `step_stack`. +/// Each step has its dependencies traversed in random order, this accomplishes +/// two things: +/// - `step_stack` will be in randomized-depth-first order, so the build runner +/// spawns steps in a random (but optimized) order +/// - each step's `dependants` list is also filled in a random order, so that +/// when it finishes executing in `workerMakeOneStep`, it spawns next steps +/// to run in random order +fn constructGraphAndCheckForDependencyLoop( + b: *std.Build, + s: *Step, + step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), + rand: std.Random, +) !void { + switch (s.state) { + .precheck_started => { + std.debug.print("dependency loop detected:\n {s}\n", .{s.name}); + return error.DependencyLoopDetected; + }, + .precheck_unstarted => { + s.state = .precheck_started; + + try step_stack.ensureUnusedCapacity(b.allocator, s.dependencies.items.len); + + // We dupe to avoid shuffling the steps in the summary, it depends + // on s.dependencies' order. + const deps = b.allocator.dupe(*Step, s.dependencies.items) catch @panic("OOM"); + rand.shuffle(*Step, deps); + + for (deps) |dep| { + try step_stack.put(b.allocator, dep, {}); + try dep.dependants.append(b.allocator, s); + constructGraphAndCheckForDependencyLoop(b, dep, step_stack, rand) catch |err| { + if (err == error.DependencyLoopDetected) { + std.debug.print(" {s}\n", .{s.name}); + } + return err; + }; + } + + s.state = .precheck_done; + }, + .precheck_done => {}, + + // These don't happen until we actually run the step graph. + .dependency_failure => unreachable, + .running => unreachable, + .success => unreachable, + .failure => unreachable, + .skipped => unreachable, + .skipped_oom => unreachable, + } +} + +fn workerMakeOneStep( + wg: *std.Thread.WaitGroup, + b: *std.Build, + s: *Step, + prog_node: std.Progress.Node, + run: *Run, +) void { + const thread_pool = &run.thread_pool; + + // First, check the conditions for running this step. If they are not met, + // then we return without doing the step, relying on another worker to + // queue this step up again when dependencies are met. + for (s.dependencies.items) |dep| { + switch (@atomicLoad(Step.State, &dep.state, .seq_cst)) { + .success, .skipped => continue, + .failure, .dependency_failure, .skipped_oom => { + @atomicStore(Step.State, &s.state, .dependency_failure, .seq_cst); + return; + }, + .precheck_done, .running => { + // dependency is not finished yet. + return; + }, + .precheck_unstarted => unreachable, + .precheck_started => unreachable, + } + } + + if (s.max_rss != 0) { + run.max_rss_mutex.lock(); + defer run.max_rss_mutex.unlock(); + + // Avoid running steps twice. + if (s.state != .precheck_done) { + // Another worker got the job. + return; + } + + const new_claimed_rss = run.claimed_rss + s.max_rss; + if (new_claimed_rss > run.max_rss) { + // Running this step right now could possibly exceed the allotted RSS. + // Add this step to the queue of memory-blocked steps. + run.memory_blocked_steps.append(s) catch @panic("OOM"); + return; + } + + run.claimed_rss = new_claimed_rss; + s.state = .running; + } else { + // Avoid running steps twice. + if (@cmpxchgStrong(Step.State, &s.state, .precheck_done, .running, .seq_cst, .seq_cst) != null) { + // Another worker got the job. + return; + } + } + + const sub_prog_node = prog_node.start(s.name, 0); + defer sub_prog_node.end(); + + const make_result = s.make(.{ + .progress_node = sub_prog_node, + .thread_pool = thread_pool, + .watch = run.watch, + }); + + // No matter the result, we want to display error/warning messages. + const show_compile_errors = !run.prominent_compile_errors and + s.result_error_bundle.errorMessageCount() > 0; + const show_error_msgs = s.result_error_msgs.items.len > 0; + const show_stderr = s.result_stderr.len > 0; + + if (show_error_msgs or show_compile_errors or show_stderr) { + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); + + const gpa = b.allocator; + printErrorMessages(gpa, s, .{ .ttyconf = run.ttyconf }, run.stderr, run.prominent_compile_errors) catch {}; + } + + handle_result: { + if (make_result) |_| { + @atomicStore(Step.State, &s.state, .success, .seq_cst); + } else |err| switch (err) { + error.MakeFailed => { + @atomicStore(Step.State, &s.state, .failure, .seq_cst); + break :handle_result; + }, + error.MakeSkipped => @atomicStore(Step.State, &s.state, .skipped, .seq_cst), + } + + // Successful completion of a step, so we queue up its dependants as well. + for (s.dependants.items) |dep| { + thread_pool.spawnWg(wg, workerMakeOneStep, .{ + wg, b, dep, prog_node, run, + }); + } + } + + // If this is a step that claims resources, we must now queue up other + // steps that are waiting for resources. + if (s.max_rss != 0) { + run.max_rss_mutex.lock(); + defer run.max_rss_mutex.unlock(); + + // Give the memory back to the scheduler. + run.claimed_rss -= s.max_rss; + // Avoid kicking off too many tasks that we already know will not have + // enough resources. + var remaining = run.max_rss - run.claimed_rss; + var i: usize = 0; + var j: usize = 0; + while (j < run.memory_blocked_steps.items.len) : (j += 1) { + const dep = run.memory_blocked_steps.items[j]; + assert(dep.max_rss != 0); + if (dep.max_rss <= remaining) { + remaining -= dep.max_rss; + + thread_pool.spawnWg(wg, workerMakeOneStep, .{ + wg, b, dep, prog_node, run, + }); + } else { + run.memory_blocked_steps.items[i] = dep; + i += 1; + } + } + run.memory_blocked_steps.shrinkRetainingCapacity(i); + } +} + +pub fn printErrorMessages( + gpa: Allocator, + failing_step: *Step, + options: std.zig.ErrorBundle.RenderOptions, + stderr: File, + prominent_compile_errors: bool, +) !void { + // Provide context for where these error messages are coming from by + // printing the corresponding Step subtree. + + var step_stack: std.ArrayListUnmanaged(*Step) = .empty; + defer step_stack.deinit(gpa); + try step_stack.append(gpa, failing_step); + while (step_stack.items[step_stack.items.len - 1].dependants.items.len != 0) { + try step_stack.append(gpa, step_stack.items[step_stack.items.len - 1].dependants.items[0]); + } + + // Now, `step_stack` has the subtree that we want to print, in reverse order. + const ttyconf = options.ttyconf; + try ttyconf.setColor(stderr, .dim); + var indent: usize = 0; + while (step_stack.pop()) |s| : (indent += 1) { + if (indent > 0) { + try stderr.writer().writeByteNTimes(' ', (indent - 1) * 3); + try printChildNodePrefix(stderr, ttyconf); + } + + try stderr.writeAll(s.name); + + if (s == failing_step) { + try printStepFailure(s, stderr, ttyconf); + } else { + try stderr.writeAll("\n"); + } + } + try ttyconf.setColor(stderr, .reset); + + if (failing_step.result_stderr.len > 0) { + try stderr.writeAll(failing_step.result_stderr); + if (!mem.endsWith(u8, failing_step.result_stderr, "\n")) { + try stderr.writeAll("\n"); + } + } + + if (!prominent_compile_errors and failing_step.result_error_bundle.errorMessageCount() > 0) { + try failing_step.result_error_bundle.renderToWriter(options, stderr.writer()); + } + + for (failing_step.result_error_msgs.items) |msg| { + try ttyconf.setColor(stderr, .red); + try stderr.writeAll("error: "); + try ttyconf.setColor(stderr, .reset); + try stderr.writeAll(msg); + try stderr.writeAll("\n"); + } +} + +fn steps(builder: *std.Build, out_stream: anytype) !void { + const allocator = builder.allocator; + for (builder.top_level_steps.values()) |top_level_step| { + const name = if (&top_level_step.step == builder.default_step) + try fmt.allocPrint(allocator, "{s} (default)", .{top_level_step.step.name}) + else + top_level_step.step.name; + try out_stream.print(" {s:<28} {s}\n", .{ name, top_level_step.description }); + } +} + +fn usage(b: *std.Build, out_stream: anytype) !void { + try out_stream.print( + \\Usage: {s} build [steps] [options] + \\ + \\Steps: + \\ + , .{b.graph.zig_exe}); + try steps(b, out_stream); + + try out_stream.writeAll( + \\ + \\General Options: + \\ -p, --prefix [path] Where to install files (default: zig-out) + \\ --prefix-lib-dir [path] Where to install libraries + \\ --prefix-exe-dir [path] Where to install executables + \\ --prefix-include-dir [path] Where to install C header files + \\ + \\ --release[=mode] Request release mode, optionally specifying a + \\ preferred optimization mode: fast, safe, small + \\ + \\ -fdarling, -fno-darling Integration with system-installed Darling to + \\ execute macOS programs on Linux hosts + \\ (default: no) + \\ -fqemu, -fno-qemu Integration with system-installed QEMU to execute + \\ foreign-architecture programs on Linux hosts + \\ (default: no) + \\ --glibc-runtimes [path] Enhances QEMU integration by providing glibc built + \\ for multiple foreign architectures, allowing + \\ execution of non-native programs that link with glibc. + \\ -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on + \\ ARM64 macOS hosts. (default: no) + \\ -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to + \\ execute WASI binaries. (default: no) + \\ -fwine, -fno-wine Integration with system-installed Wine to execute + \\ Windows programs on Linux hosts. (default: no) + \\ + \\ -h, --help Print this help and exit + \\ -l, --list-steps Print available steps + \\ --verbose Print commands before executing them + \\ --color [auto|off|on] Enable or disable colored error messages + \\ --prominent-compile-errors Buffer compile errors and display at end + \\ --summary [mode] Control the printing of the build summary + \\ all Print the build summary in its entirety + \\ new Omit cached steps + \\ failures (Default) Only print failed steps + \\ none Do not print the build summary + \\ -j Limit concurrent jobs (default is to use all CPU cores) + \\ --maxrss Limit memory usage (default is to use available memory) + \\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss + \\ --fetch Exit after fetching dependency tree + \\ --watch Continuously rebuild when source files are modified + \\ --fuzz Continuously search for unit test failures + \\ --debounce Delay before rebuilding after changed file detected + \\ -fincremental Enable incremental compilation + \\ -fno-incremental Disable incremental compilation + \\ + \\Project-Specific Options: + \\ + ); + + const arena = b.allocator; + if (b.available_options_list.items.len == 0) { + try out_stream.print(" (none)\n", .{}); + } else { + for (b.available_options_list.items) |option| { + const name = try fmt.allocPrint(arena, " -D{s}=[{s}]", .{ + option.name, + @tagName(option.type_id), + }); + try out_stream.print("{s:<30} {s}\n", .{ name, option.description }); + if (option.enum_options) |enum_options| { + const padding = " " ** 33; + try out_stream.writeAll(padding ++ "Supported Values:\n"); + for (enum_options) |enum_option| { + try out_stream.print(padding ++ " {s}\n", .{enum_option}); + } + } + } + } + + try out_stream.writeAll( + \\ + \\System Integration Options: + \\ --search-prefix [path] Add a path to look for binaries, libraries, headers + \\ --sysroot [path] Set the system root directory (usually /) + \\ --libc [file] Provide a file which specifies libc paths + \\ + \\ --system [pkgdir] Disable package fetching; enable all integrations + \\ -fsys=[name] Enable a system integration + \\ -fno-sys=[name] Disable a system integration + \\ + \\ Available System Integrations: Enabled: + \\ + ); + if (b.graph.system_library_options.entries.len == 0) { + try out_stream.writeAll(" (none) -\n"); + } else { + for (b.graph.system_library_options.keys(), b.graph.system_library_options.values()) |k, v| { + const status = switch (v) { + .declared_enabled => "yes", + .declared_disabled => "no", + .user_enabled, .user_disabled => unreachable, // already emitted error + }; + try out_stream.print(" {s:<43} {s}\n", .{ k, status }); + } + } + + try out_stream.writeAll( + \\ + \\Advanced Options: + \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error + \\ -fno-reference-trace Disable reference trace + \\ -fallow-so-scripts Allows .so files to be GNU ld scripts + \\ -fno-allow-so-scripts (default) .so files must be ELF files + \\ --build-file [file] Override path to build.zig + \\ --cache-dir [path] Override path to local Zig cache directory + \\ --global-cache-dir [path] Override path to global Zig cache directory + \\ --zig-lib-dir [arg] Override path to Zig lib directory + \\ --build-runner [file] Override path to build runner + \\ --seed [integer] For shuffling dependency traversal order (default: random) + \\ --debug-log [scope] Enable debugging the compiler + \\ --debug-pkg-config Fail if unknown pkg-config flags encountered + \\ --debug-rt Debug compiler runtime libraries + \\ --verbose-link Enable compiler debug output for linking + \\ --verbose-air Enable compiler debug output for Zig AIR + \\ --verbose-llvm-ir[=file] Enable compiler debug output for LLVM IR + \\ --verbose-llvm-bc=[file] Enable compiler debug output for LLVM BC + \\ --verbose-cimport Enable compiler debug output for C imports + \\ --verbose-cc Enable compiler debug output for C compilation + \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features + \\ + ); +} + +fn nextArg(args: []const [:0]const u8, idx: *usize) ?[:0]const u8 { + if (idx.* >= args.len) return null; + defer idx.* += 1; + return args[idx.*]; +} + +fn nextArgOrFatal(args: []const [:0]const u8, idx: *usize) [:0]const u8 { + return nextArg(args, idx) orelse { + std.debug.print("expected argument after '{s}'\n access the help menu with 'zig build -h'\n", .{args[idx.* - 1]}); + process.exit(1); + }; +} + +fn argsRest(args: []const [:0]const u8, idx: usize) ?[]const [:0]const u8 { + if (idx >= args.len) return null; + return args[idx..]; +} + +/// Perhaps in the future there could be an Advanced Options flag such as +/// --debug-build-runner-leaks which would make this function return instead of +/// calling exit. +fn cleanExit() void { + std.debug.lockStdErr(); + process.exit(0); +} + +/// Perhaps in the future there could be an Advanced Options flag such as +/// --debug-build-runner-leaks which would make this function return instead of +/// calling exit. +fn uncleanExit() error{UncleanExit} { + std.debug.lockStdErr(); + process.exit(1); +} + +const Color = std.zig.Color; +const Summary = enum { all, new, failures, none }; + +fn get_tty_conf(color: Color, stderr: File) std.io.tty.Config { + return switch (color) { + .auto => std.io.tty.detectConfig(stderr), + .on => .escape_codes, + .off => .no_color, + }; +} + +fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn { + std.debug.print(f ++ "\n access the help menu with 'zig build -h'\n", args); + process.exit(1); +} + +fn validateSystemLibraryOptions(b: *std.Build) void { + var bad = false; + for (b.graph.system_library_options.keys(), b.graph.system_library_options.values()) |k, v| { + switch (v) { + .user_disabled, .user_enabled => { + // The user tried to enable or disable a system library integration, but + // the build script did not recognize that option. + std.debug.print("system library name not recognized by build script: '{s}'\n", .{k}); + bad = true; + }, + .declared_disabled, .declared_enabled => {}, + } + } + if (bad) { + std.debug.print(" access the help menu with 'zig build -h'\n", .{}); + process.exit(1); + } +} + +/// Starting from all top-level steps in `b`, traverses the entire step graph +/// and adds all step dependencies implied by module graphs. +fn createModuleDependencies(b: *std.Build) Allocator.Error!void { + const arena = b.graph.arena; + + var all_steps: std.AutoArrayHashMapUnmanaged(*Step, void) = .empty; + var next_step_idx: usize = 0; + + try all_steps.ensureUnusedCapacity(arena, b.top_level_steps.count()); + for (b.top_level_steps.values()) |tls| { + all_steps.putAssumeCapacityNoClobber(&tls.step, {}); + } + + while (next_step_idx < all_steps.count()) { + const step = all_steps.keys()[next_step_idx]; + next_step_idx += 1; + + // Set up any implied dependencies for this step. It's important that we do this first, so + // that the loop below discovers steps implied by the module graph. + try createModuleDependenciesForStep(step); + + try all_steps.ensureUnusedCapacity(arena, step.dependencies.items.len); + for (step.dependencies.items) |other_step| { + all_steps.putAssumeCapacity(other_step, {}); + } + } +} + +/// If the given `Step` is a `Step.Compile`, adds any dependencies for that step which +/// are implied by the module graph rooted at `step.cast(Step.Compile).?.root_module`. +fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void { + const root_module = if (step.cast(Step.Compile)) |cs| root: { + break :root cs.root_module; + } else return; // not a compile step so no module dependencies + + // Starting from `root_module`, discover all modules in this graph. + const modules = root_module.getGraph().modules; + + // For each of those modules, set up the implied step dependencies. + for (modules) |mod| { + if (mod.root_source_file) |lp| lp.addStepDependencies(step); + for (mod.include_dirs.items) |include_dir| switch (include_dir) { + .path, + .path_system, + .path_after, + .framework_path, + .framework_path_system, + => |lp| lp.addStepDependencies(step), + + .other_step => |other| { + other.getEmittedIncludeTree().addStepDependencies(step); + step.dependOn(&other.step); + }, + + .config_header_step => |other| step.dependOn(&other.step), + }; + for (mod.lib_paths.items) |lp| lp.addStepDependencies(step); + for (mod.rpaths.items) |rpath| switch (rpath) { + .lazy_path => |lp| lp.addStepDependencies(step), + .special => {}, + }; + for (mod.link_objects.items) |link_object| switch (link_object) { + .static_path, + .assembly_file, + => |lp| lp.addStepDependencies(step), + .other_step => |other| step.dependOn(&other.step), + .system_lib => {}, + .c_source_file => |source| source.file.addStepDependencies(step), + .c_source_files => |source_files| source_files.root.addStepDependencies(step), + .win32_resource_file => |rc_source| { + rc_source.file.addStepDependencies(step); + for (rc_source.include_paths) |lp| lp.addStepDependencies(step); + }, + }; + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/libc.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/libc.zig new file mode 100644 index 00000000..866dd153 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/libc.zig @@ -0,0 +1,137 @@ +const std = @import("std"); +const mem = std.mem; +const io = std.io; +const LibCInstallation = std.zig.LibCInstallation; + +const usage_libc = + \\Usage: zig libc + \\ + \\ Detect the native libc installation and print the resulting + \\ paths to stdout. You can save this into a file and then edit + \\ the paths to create a cross compilation libc kit. Then you + \\ can pass `--libc [file]` for Zig to use it. + \\ + \\Usage: zig libc [paths_file] + \\ + \\ Parse a libc installation text file and validate it. + \\ + \\Options: + \\ -h, --help Print this help and exit + \\ -target [name] -- see the targets command + \\ -includes Print the libc include directories for the target + \\ +; + +pub fn main() !void { + var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena_instance.deinit(); + const arena = arena_instance.allocator(); + const gpa = arena; + + const args = try std.process.argsAlloc(arena); + const zig_lib_directory = args[1]; + + var input_file: ?[]const u8 = null; + var target_arch_os_abi: []const u8 = "native"; + var print_includes: bool = false; + { + var i: usize = 2; + while (i < args.len) : (i += 1) { + const arg = args[i]; + if (mem.startsWith(u8, arg, "-")) { + if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { + const stdout = std.io.getStdOut().writer(); + try stdout.writeAll(usage_libc); + return std.process.cleanExit(); + } else if (mem.eql(u8, arg, "-target")) { + if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg}); + i += 1; + target_arch_os_abi = args[i]; + } else if (mem.eql(u8, arg, "-includes")) { + print_includes = true; + } else { + fatal("unrecognized parameter: '{s}'", .{arg}); + } + } else if (input_file != null) { + fatal("unexpected extra parameter: '{s}'", .{arg}); + } else { + input_file = arg; + } + } + } + + const target_query = std.zig.parseTargetQueryOrReportFatalError(gpa, .{ + .arch_os_abi = target_arch_os_abi, + }); + const target = std.zig.resolveTargetQueryOrFatal(target_query); + + if (print_includes) { + const libc_installation: ?*LibCInstallation = libc: { + if (input_file) |libc_file| { + const libc = try arena.create(LibCInstallation); + libc.* = LibCInstallation.parse(arena, libc_file, target) catch |err| { + fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); + }; + break :libc libc; + } else { + break :libc null; + } + }; + + const is_native_abi = target_query.isNativeAbi(); + + const libc_dirs = std.zig.LibCDirs.detect( + arena, + zig_lib_directory, + target, + is_native_abi, + true, + libc_installation, + ) catch |err| { + const zig_target = try target.zigTriple(arena); + fatal("unable to detect libc for target {s}: {s}", .{ zig_target, @errorName(err) }); + }; + + if (libc_dirs.libc_include_dir_list.len == 0) { + const zig_target = try target.zigTriple(arena); + fatal("no include dirs detected for target {s}", .{zig_target}); + } + + var bw = std.io.bufferedWriter(std.io.getStdOut().writer()); + var writer = bw.writer(); + for (libc_dirs.libc_include_dir_list) |include_dir| { + try writer.writeAll(include_dir); + try writer.writeByte('\n'); + } + try bw.flush(); + return std.process.cleanExit(); + } + + if (input_file) |libc_file| { + var libc = LibCInstallation.parse(gpa, libc_file, target) catch |err| { + fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); + }; + defer libc.deinit(gpa); + } else { + if (!target_query.canDetectLibC()) { + fatal("unable to detect libc for non-native target", .{}); + } + var libc = LibCInstallation.findNative(.{ + .allocator = gpa, + .verbose = true, + .target = target, + }) catch |err| { + fatal("unable to detect native libc: {s}", .{@errorName(err)}); + }; + defer libc.deinit(gpa); + + var bw = std.io.bufferedWriter(std.io.getStdOut().writer()); + try libc.render(bw.writer()); + try bw.flush(); + } +} + +fn fatal(comptime format: []const u8, args: anytype) noreturn { + std.log.err(format, args); + std.process.exit(1); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/objcopy.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/objcopy.zig new file mode 100644 index 00000000..bf031bb3 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/objcopy.zig @@ -0,0 +1,1671 @@ +const builtin = @import("builtin"); +const std = @import("std"); +const mem = std.mem; +const fs = std.fs; +const elf = std.elf; +const Allocator = std.mem.Allocator; +const File = std.fs.File; +const assert = std.debug.assert; + +const fatal = std.zig.fatal; +const Server = std.zig.Server; + +pub fn main() !void { + var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena_instance.deinit(); + const arena = arena_instance.allocator(); + + var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; + const gpa = general_purpose_allocator.allocator(); + + const args = try std.process.argsAlloc(arena); + return cmdObjCopy(gpa, arena, args[1..]); +} + +fn cmdObjCopy( + gpa: Allocator, + arena: Allocator, + args: []const []const u8, +) !void { + var i: usize = 0; + var opt_out_fmt: ?std.Target.ObjectFormat = null; + var opt_input: ?[]const u8 = null; + var opt_output: ?[]const u8 = null; + var opt_extract: ?[]const u8 = null; + var opt_add_debuglink: ?[]const u8 = null; + var only_section: ?[]const u8 = null; + var pad_to: ?u64 = null; + var strip_all: bool = false; + var strip_debug: bool = false; + var only_keep_debug: bool = false; + var compress_debug_sections: bool = false; + var listen = false; + var add_section: ?AddSection = null; + var set_section_alignment: ?SetSectionAlignment = null; + var set_section_flags: ?SetSectionFlags = null; + while (i < args.len) : (i += 1) { + const arg = args[i]; + if (!mem.startsWith(u8, arg, "-")) { + if (opt_input == null) { + opt_input = arg; + } else if (opt_output == null) { + opt_output = arg; + } else { + fatal("unexpected positional argument: '{s}'", .{arg}); + } + } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { + return std.io.getStdOut().writeAll(usage); + } else if (mem.eql(u8, arg, "-O") or mem.eql(u8, arg, "--output-target")) { + i += 1; + if (i >= args.len) fatal("expected another argument after '{s}'", .{arg}); + const next_arg = args[i]; + if (mem.eql(u8, next_arg, "binary")) { + opt_out_fmt = .raw; + } else { + opt_out_fmt = std.meta.stringToEnum(std.Target.ObjectFormat, next_arg) orelse + fatal("invalid output format: '{s}'", .{next_arg}); + } + } else if (mem.startsWith(u8, arg, "--output-target=")) { + const next_arg = arg["--output-target=".len..]; + if (mem.eql(u8, next_arg, "binary")) { + opt_out_fmt = .raw; + } else { + opt_out_fmt = std.meta.stringToEnum(std.Target.ObjectFormat, next_arg) orelse + fatal("invalid output format: '{s}'", .{next_arg}); + } + } else if (mem.eql(u8, arg, "-j") or mem.eql(u8, arg, "--only-section")) { + i += 1; + if (i >= args.len) fatal("expected another argument after '{s}'", .{arg}); + only_section = args[i]; + } else if (mem.eql(u8, arg, "--listen=-")) { + listen = true; + } else if (mem.startsWith(u8, arg, "--only-section=")) { + only_section = arg["--only-section=".len..]; + } else if (mem.eql(u8, arg, "--pad-to")) { + i += 1; + if (i >= args.len) fatal("expected another argument after '{s}'", .{arg}); + pad_to = std.fmt.parseInt(u64, args[i], 0) catch |err| { + fatal("unable to parse: '{s}': {s}", .{ args[i], @errorName(err) }); + }; + } else if (mem.eql(u8, arg, "-g") or mem.eql(u8, arg, "--strip-debug")) { + strip_debug = true; + } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--strip-all")) { + strip_all = true; + } else if (mem.eql(u8, arg, "--only-keep-debug")) { + only_keep_debug = true; + } else if (mem.eql(u8, arg, "--compress-debug-sections")) { + compress_debug_sections = true; + } else if (mem.startsWith(u8, arg, "--add-gnu-debuglink=")) { + opt_add_debuglink = arg["--add-gnu-debuglink=".len..]; + } else if (mem.eql(u8, arg, "--add-gnu-debuglink")) { + i += 1; + if (i >= args.len) fatal("expected another argument after '{s}'", .{arg}); + opt_add_debuglink = args[i]; + } else if (mem.startsWith(u8, arg, "--extract-to=")) { + opt_extract = arg["--extract-to=".len..]; + } else if (mem.eql(u8, arg, "--extract-to")) { + i += 1; + if (i >= args.len) fatal("expected another argument after '{s}'", .{arg}); + opt_extract = args[i]; + } else if (mem.eql(u8, arg, "--set-section-alignment")) { + i += 1; + if (i >= args.len) fatal("expected section name and alignment arguments after '{s}'", .{arg}); + + if (splitOption(args[i])) |split| { + const alignment = std.fmt.parseInt(u32, split.second, 10) catch |err| { + fatal("unable to parse alignment number: '{s}': {s}", .{ split.second, @errorName(err) }); + }; + if (!std.math.isPowerOfTwo(alignment)) fatal("alignment must be a power of two", .{}); + set_section_alignment = .{ .section_name = split.first, .alignment = alignment }; + } else { + fatal("unrecognized argument: '{s}', expecting =", .{args[i]}); + } + } else if (mem.eql(u8, arg, "--set-section-flags")) { + i += 1; + if (i >= args.len) fatal("expected section name and filename arguments after '{s}'", .{arg}); + + if (splitOption(args[i])) |split| { + set_section_flags = .{ .section_name = split.first, .flags = parseSectionFlags(split.second) }; + } else { + fatal("unrecognized argument: '{s}', expecting =", .{args[i]}); + } + } else if (mem.eql(u8, arg, "--add-section")) { + i += 1; + if (i >= args.len) fatal("expected section name and filename arguments after '{s}'", .{arg}); + + if (splitOption(args[i])) |split| { + add_section = .{ .section_name = split.first, .file_path = split.second }; + } else { + fatal("unrecognized argument: '{s}', expecting =", .{args[i]}); + } + } else { + fatal("unrecognized argument: '{s}'", .{arg}); + } + } + const input = opt_input orelse fatal("expected input parameter", .{}); + const output = opt_output orelse fatal("expected output parameter", .{}); + + var in_file = fs.cwd().openFile(input, .{}) catch |err| + fatal("unable to open '{s}': {s}", .{ input, @errorName(err) }); + defer in_file.close(); + + const elf_hdr = std.elf.Header.read(in_file) catch |err| switch (err) { + error.InvalidElfMagic => fatal("not an ELF file: '{s}'", .{input}), + else => fatal("unable to read '{s}': {s}", .{ input, @errorName(err) }), + }; + + const in_ofmt = .elf; + + const out_fmt: std.Target.ObjectFormat = opt_out_fmt orelse ofmt: { + if (mem.endsWith(u8, output, ".hex") or std.mem.endsWith(u8, output, ".ihex")) { + break :ofmt .hex; + } else if (mem.endsWith(u8, output, ".bin")) { + break :ofmt .raw; + } else if (mem.endsWith(u8, output, ".elf")) { + break :ofmt .elf; + } else { + break :ofmt in_ofmt; + } + }; + + const mode = mode: { + if (out_fmt != .elf or only_keep_debug) + break :mode fs.File.default_mode; + if (in_file.stat()) |stat| + break :mode stat.mode + else |_| + break :mode fs.File.default_mode; + }; + var out_file = try fs.cwd().createFile(output, .{ .mode = mode }); + defer out_file.close(); + + switch (out_fmt) { + .hex, .raw => { + if (strip_debug or strip_all or only_keep_debug) + fatal("zig objcopy: ELF to RAW or HEX copying does not support --strip", .{}); + if (opt_extract != null) + fatal("zig objcopy: ELF to RAW or HEX copying does not support --extract-to", .{}); + if (add_section != null) + fatal("zig objcopy: ELF to RAW or HEX copying does not support --add-section", .{}); + if (set_section_alignment != null) + fatal("zig objcopy: ELF to RAW or HEX copying does not support --set_section_alignment", .{}); + if (set_section_flags != null) + fatal("zig objcopy: ELF to RAW or HEX copying does not support --set_section_flags", .{}); + + try emitElf(arena, in_file, out_file, elf_hdr, .{ + .ofmt = out_fmt, + .only_section = only_section, + .pad_to = pad_to, + }); + }, + .elf => { + if (elf_hdr.endian != builtin.target.cpu.arch.endian()) + fatal("zig objcopy: ELF to ELF copying only supports native endian", .{}); + if (elf_hdr.phoff == 0) // no program header + fatal("zig objcopy: ELF to ELF copying only supports programs", .{}); + if (only_section) |_| + fatal("zig objcopy: ELF to ELF copying does not support --only-section", .{}); + if (pad_to) |_| + fatal("zig objcopy: ELF to ELF copying does not support --pad-to", .{}); + + try stripElf(arena, in_file, out_file, elf_hdr, .{ + .strip_debug = strip_debug, + .strip_all = strip_all, + .only_keep_debug = only_keep_debug, + .add_debuglink = opt_add_debuglink, + .extract_to = opt_extract, + .compress_debug = compress_debug_sections, + .add_section = add_section, + .set_section_alignment = set_section_alignment, + .set_section_flags = set_section_flags, + }); + return std.process.cleanExit(); + }, + else => fatal("unsupported output object format: {s}", .{@tagName(out_fmt)}), + } + + if (listen) { + var server = try Server.init(.{ + .gpa = gpa, + .in = std.io.getStdIn(), + .out = std.io.getStdOut(), + .zig_version = builtin.zig_version_string, + }); + defer server.deinit(); + + var seen_update = false; + while (true) { + const hdr = try server.receiveMessage(); + switch (hdr.tag) { + .exit => { + return std.process.cleanExit(); + }, + .update => { + if (seen_update) fatal("zig objcopy only supports 1 update for now", .{}); + seen_update = true; + + // The build system already knows what the output is at this point, we + // only need to communicate that the process has finished. + // Use the empty error bundle to indicate that the update is done. + try server.serveErrorBundle(std.zig.ErrorBundle.empty); + }, + else => fatal("unsupported message: {s}", .{@tagName(hdr.tag)}), + } + } + } + return std.process.cleanExit(); +} + +const usage = + \\Usage: zig objcopy [options] input output + \\ + \\Options: + \\ -h, --help Print this help and exit + \\ --output-target= Format of the output file + \\ -O Alias for --output-target + \\ --only-section=
Remove all but
+ \\ -j Alias for --only-section + \\ --pad-to Pad the last section up to address + \\ --strip-debug, -g Remove all debug sections from the output. + \\ --strip-all, -S Remove all debug sections and symbol table from the output. + \\ --only-keep-debug Strip a file, removing contents of any sections that would not be stripped by --strip-debug and leaving the debugging sections intact. + \\ --add-gnu-debuglink= Creates a .gnu_debuglink section which contains a reference to and adds it to the output file. + \\ --extract-to Extract the removed sections into , and add a .gnu-debuglink section. + \\ --compress-debug-sections Compress DWARF debug sections with zlib + \\ --set-section-alignment = Set alignment of section to bytes. Must be a power of two. + \\ --set-section-flags = Set flags of section to represented as a comma separated set of flags. + \\ --add-section = Add file content from with the a new section named . + \\ +; + +pub const EmitRawElfOptions = struct { + ofmt: std.Target.ObjectFormat, + only_section: ?[]const u8 = null, + pad_to: ?u64 = null, + add_section: ?AddSection = null, + set_section_alignment: ?SetSectionAlignment = null, + set_section_flags: ?SetSectionFlags = null, +}; + +const AddSection = struct { + section_name: []const u8, + file_path: []const u8, +}; + +const SetSectionAlignment = struct { + section_name: []const u8, + alignment: u32, +}; + +const SetSectionFlags = struct { + section_name: []const u8, + flags: SectionFlags, +}; + +fn emitElf( + arena: Allocator, + in_file: File, + out_file: File, + elf_hdr: elf.Header, + options: EmitRawElfOptions, +) !void { + var binary_elf_output = try BinaryElfOutput.parse(arena, in_file, elf_hdr); + defer binary_elf_output.deinit(); + + if (options.ofmt == .elf) { + fatal("zig objcopy: ELF to ELF copying is not implemented yet", .{}); + } + + if (options.only_section) |target_name| { + switch (options.ofmt) { + .hex => fatal("zig objcopy: hex format with sections is not implemented yet", .{}), + .raw => { + for (binary_elf_output.sections.items) |section| { + if (section.name) |curr_name| { + if (!std.mem.eql(u8, curr_name, target_name)) + continue; + } else { + continue; + } + + try writeBinaryElfSection(in_file, out_file, section); + try padFile(out_file, options.pad_to); + return; + } + }, + else => unreachable, + } + + return error.SectionNotFound; + } + + switch (options.ofmt) { + .raw => { + for (binary_elf_output.sections.items) |section| { + try out_file.seekTo(section.binaryOffset); + try writeBinaryElfSection(in_file, out_file, section); + } + try padFile(out_file, options.pad_to); + }, + .hex => { + if (binary_elf_output.segments.items.len == 0) return; + if (!containsValidAddressRange(binary_elf_output.segments.items)) { + return error.InvalidHexfileAddressRange; + } + + var hex_writer = HexWriter{ .out_file = out_file }; + for (binary_elf_output.segments.items) |segment| { + try hex_writer.writeSegment(segment, in_file); + } + if (options.pad_to) |_| { + // Padding to a size in hex files isn't applicable + return error.InvalidArgument; + } + try hex_writer.writeEOF(); + }, + else => unreachable, + } +} + +const BinaryElfSection = struct { + elfOffset: u64, + binaryOffset: u64, + fileSize: usize, + name: ?[]const u8, + segment: ?*BinaryElfSegment, +}; + +const BinaryElfSegment = struct { + physicalAddress: u64, + virtualAddress: u64, + elfOffset: u64, + binaryOffset: u64, + fileSize: u64, + firstSection: ?*BinaryElfSection, +}; + +const BinaryElfOutput = struct { + segments: std.ArrayListUnmanaged(*BinaryElfSegment), + sections: std.ArrayListUnmanaged(*BinaryElfSection), + allocator: Allocator, + shstrtab: ?[]const u8, + + const Self = @This(); + + pub fn deinit(self: *Self) void { + if (self.shstrtab) |shstrtab| + self.allocator.free(shstrtab); + self.sections.deinit(self.allocator); + self.segments.deinit(self.allocator); + } + + pub fn parse(allocator: Allocator, elf_file: File, elf_hdr: elf.Header) !Self { + var self: Self = .{ + .segments = .{}, + .sections = .{}, + .allocator = allocator, + .shstrtab = null, + }; + errdefer self.sections.deinit(allocator); + errdefer self.segments.deinit(allocator); + + self.shstrtab = blk: { + if (elf_hdr.shstrndx >= elf_hdr.shnum) break :blk null; + + var section_headers = elf_hdr.section_header_iterator(&elf_file); + + var section_counter: usize = 0; + while (section_counter < elf_hdr.shstrndx) : (section_counter += 1) { + _ = (try section_headers.next()).?; + } + + const shstrtab_shdr = (try section_headers.next()).?; + + const buffer = try allocator.alloc(u8, @intCast(shstrtab_shdr.sh_size)); + errdefer allocator.free(buffer); + + const num_read = try elf_file.preadAll(buffer, shstrtab_shdr.sh_offset); + if (num_read != buffer.len) return error.EndOfStream; + + break :blk buffer; + }; + + errdefer if (self.shstrtab) |shstrtab| allocator.free(shstrtab); + + var section_headers = elf_hdr.section_header_iterator(&elf_file); + while (try section_headers.next()) |section| { + if (sectionValidForOutput(section)) { + const newSection = try allocator.create(BinaryElfSection); + + newSection.binaryOffset = 0; + newSection.elfOffset = section.sh_offset; + newSection.fileSize = @intCast(section.sh_size); + newSection.segment = null; + + newSection.name = if (self.shstrtab) |shstrtab| + std.mem.span(@as([*:0]const u8, @ptrCast(&shstrtab[section.sh_name]))) + else + null; + + try self.sections.append(allocator, newSection); + } + } + + var program_headers = elf_hdr.program_header_iterator(&elf_file); + while (try program_headers.next()) |phdr| { + if (phdr.p_type == elf.PT_LOAD) { + const newSegment = try allocator.create(BinaryElfSegment); + + newSegment.physicalAddress = phdr.p_paddr; + newSegment.virtualAddress = phdr.p_vaddr; + newSegment.fileSize = @intCast(phdr.p_filesz); + newSegment.elfOffset = phdr.p_offset; + newSegment.binaryOffset = 0; + newSegment.firstSection = null; + + for (self.sections.items) |section| { + if (sectionWithinSegment(section, phdr)) { + if (section.segment) |sectionSegment| { + if (sectionSegment.elfOffset > newSegment.elfOffset) { + section.segment = newSegment; + } + } else { + section.segment = newSegment; + } + + if (newSegment.firstSection == null) { + newSegment.firstSection = section; + } + } + } + + try self.segments.append(allocator, newSegment); + } + } + + mem.sort(*BinaryElfSegment, self.segments.items, {}, segmentSortCompare); + + for (self.segments.items, 0..) |firstSegment, i| { + if (firstSegment.firstSection) |firstSection| { + const diff = firstSection.elfOffset - firstSegment.elfOffset; + + firstSegment.elfOffset += diff; + firstSegment.fileSize += diff; + firstSegment.physicalAddress += diff; + + const basePhysicalAddress = firstSegment.physicalAddress; + + for (self.segments.items[i + 1 ..]) |segment| { + segment.binaryOffset = segment.physicalAddress - basePhysicalAddress; + } + break; + } + } + + for (self.sections.items) |section| { + if (section.segment) |segment| { + section.binaryOffset = segment.binaryOffset + (section.elfOffset - segment.elfOffset); + } + } + + mem.sort(*BinaryElfSection, self.sections.items, {}, sectionSortCompare); + + return self; + } + + fn sectionWithinSegment(section: *BinaryElfSection, segment: elf.Elf64_Phdr) bool { + return segment.p_offset <= section.elfOffset and (segment.p_offset + segment.p_filesz) >= (section.elfOffset + section.fileSize); + } + + fn sectionValidForOutput(shdr: anytype) bool { + return shdr.sh_type != elf.SHT_NOBITS and + ((shdr.sh_flags & elf.SHF_ALLOC) == elf.SHF_ALLOC); + } + + fn segmentSortCompare(context: void, left: *BinaryElfSegment, right: *BinaryElfSegment) bool { + _ = context; + if (left.physicalAddress < right.physicalAddress) { + return true; + } + if (left.physicalAddress > right.physicalAddress) { + return false; + } + return false; + } + + fn sectionSortCompare(context: void, left: *BinaryElfSection, right: *BinaryElfSection) bool { + _ = context; + return left.binaryOffset < right.binaryOffset; + } +}; + +fn writeBinaryElfSection(elf_file: File, out_file: File, section: *BinaryElfSection) !void { + try out_file.writeFileAll(elf_file, .{ + .in_offset = section.elfOffset, + .in_len = section.fileSize, + }); +} + +const HexWriter = struct { + prev_addr: ?u32 = null, + out_file: File, + + /// Max data bytes per line of output + const MAX_PAYLOAD_LEN: u8 = 16; + + fn addressParts(address: u16) [2]u8 { + const msb: u8 = @truncate(address >> 8); + const lsb: u8 = @truncate(address); + return [2]u8{ msb, lsb }; + } + + const Record = struct { + const Type = enum(u8) { + Data = 0, + EOF = 1, + ExtendedSegmentAddress = 2, + ExtendedLinearAddress = 4, + }; + + address: u16, + payload: union(Type) { + Data: []const u8, + EOF: void, + ExtendedSegmentAddress: [2]u8, + ExtendedLinearAddress: [2]u8, + }, + + fn EOF() Record { + return Record{ + .address = 0, + .payload = .EOF, + }; + } + + fn Data(address: u32, data: []const u8) Record { + return Record{ + .address = @intCast(address % 0x10000), + .payload = .{ .Data = data }, + }; + } + + fn Address(address: u32) Record { + assert(address > 0xFFFF); + const segment: u16 = @intCast(address / 0x10000); + if (address > 0xFFFFF) { + return Record{ + .address = 0, + .payload = .{ .ExtendedLinearAddress = addressParts(segment) }, + }; + } else { + return Record{ + .address = 0, + .payload = .{ .ExtendedSegmentAddress = addressParts(segment << 12) }, + }; + } + } + + fn getPayloadBytes(self: *const Record) []const u8 { + return switch (self.payload) { + .Data => |d| d, + .EOF => @as([]const u8, &.{}), + .ExtendedSegmentAddress, .ExtendedLinearAddress => |*seg| seg, + }; + } + + fn checksum(self: Record) u8 { + const payload_bytes = self.getPayloadBytes(); + + var sum: u8 = @intCast(payload_bytes.len); + const parts = addressParts(self.address); + sum +%= parts[0]; + sum +%= parts[1]; + sum +%= @intFromEnum(self.payload); + for (payload_bytes) |byte| { + sum +%= byte; + } + return (sum ^ 0xFF) +% 1; + } + + fn write(self: Record, file: File) File.WriteError!void { + const linesep = "\r\n"; + // colon, (length, address, type, payload, checksum) as hex, CRLF + const BUFSIZE = 1 + (1 + 2 + 1 + MAX_PAYLOAD_LEN + 1) * 2 + linesep.len; + var outbuf: [BUFSIZE]u8 = undefined; + const payload_bytes = self.getPayloadBytes(); + assert(payload_bytes.len <= MAX_PAYLOAD_LEN); + + const line = try std.fmt.bufPrint(&outbuf, ":{0X:0>2}{1X:0>4}{2X:0>2}{3s}{4X:0>2}" ++ linesep, .{ + @as(u8, @intCast(payload_bytes.len)), + self.address, + @intFromEnum(self.payload), + std.fmt.fmtSliceHexUpper(payload_bytes), + self.checksum(), + }); + try file.writeAll(line); + } + }; + + pub fn writeSegment(self: *HexWriter, segment: *const BinaryElfSegment, elf_file: File) !void { + var buf: [MAX_PAYLOAD_LEN]u8 = undefined; + var bytes_read: usize = 0; + while (bytes_read < segment.fileSize) { + const row_address: u32 = @intCast(segment.physicalAddress + bytes_read); + + const remaining = segment.fileSize - bytes_read; + const to_read: usize = @intCast(@min(remaining, MAX_PAYLOAD_LEN)); + const did_read = try elf_file.preadAll(buf[0..to_read], segment.elfOffset + bytes_read); + if (did_read < to_read) return error.UnexpectedEOF; + + try self.writeDataRow(row_address, buf[0..did_read]); + + bytes_read += did_read; + } + } + + fn writeDataRow(self: *HexWriter, address: u32, data: []const u8) File.WriteError!void { + const record = Record.Data(address, data); + if (address > 0xFFFF and (self.prev_addr == null or record.address != self.prev_addr.?)) { + try Record.Address(address).write(self.out_file); + } + try record.write(self.out_file); + self.prev_addr = @intCast(record.address + data.len); + } + + fn writeEOF(self: HexWriter) File.WriteError!void { + try Record.EOF().write(self.out_file); + } +}; + +fn containsValidAddressRange(segments: []*BinaryElfSegment) bool { + const max_address = std.math.maxInt(u32); + for (segments) |segment| { + if (segment.fileSize > max_address or + segment.physicalAddress > max_address - segment.fileSize) return false; + } + return true; +} + +fn padFile(f: File, opt_size: ?u64) !void { + const size = opt_size orelse return; + try f.setEndPos(size); +} + +test "HexWriter.Record.Address has correct payload and checksum" { + const record = HexWriter.Record.Address(0x0800_0000); + const payload = record.getPayloadBytes(); + const sum = record.checksum(); + try std.testing.expect(sum == 0xF2); + try std.testing.expect(payload.len == 2); + try std.testing.expect(payload[0] == 8); + try std.testing.expect(payload[1] == 0); +} + +test "containsValidAddressRange" { + var segment = BinaryElfSegment{ + .physicalAddress = 0, + .virtualAddress = 0, + .elfOffset = 0, + .binaryOffset = 0, + .fileSize = 0, + .firstSection = null, + }; + var buf: [1]*BinaryElfSegment = .{&segment}; + + // segment too big + segment.fileSize = std.math.maxInt(u32) + 1; + try std.testing.expect(!containsValidAddressRange(&buf)); + + // start address too big + segment.physicalAddress = std.math.maxInt(u32) + 1; + segment.fileSize = 2; + try std.testing.expect(!containsValidAddressRange(&buf)); + + // max address too big + segment.physicalAddress = std.math.maxInt(u32) - 1; + segment.fileSize = 2; + try std.testing.expect(!containsValidAddressRange(&buf)); + + // is ok + segment.physicalAddress = std.math.maxInt(u32) - 1; + segment.fileSize = 1; + try std.testing.expect(containsValidAddressRange(&buf)); +} + +// ------------- +// ELF to ELF stripping + +const StripElfOptions = struct { + extract_to: ?[]const u8 = null, + add_debuglink: ?[]const u8 = null, + strip_all: bool = false, + strip_debug: bool = false, + only_keep_debug: bool = false, + compress_debug: bool = false, + add_section: ?AddSection, + set_section_alignment: ?SetSectionAlignment, + set_section_flags: ?SetSectionFlags, +}; + +fn stripElf( + allocator: Allocator, + in_file: File, + out_file: File, + elf_hdr: elf.Header, + options: StripElfOptions, +) !void { + const Filter = ElfFileHelper.Filter; + const DebugLink = ElfFileHelper.DebugLink; + + const filter: Filter = filter: { + if (options.only_keep_debug) break :filter .debug; + if (options.strip_all) break :filter .program; + if (options.strip_debug) break :filter .program_and_symbols; + break :filter .all; + }; + + const filter_complement: ?Filter = blk: { + if (options.extract_to) |_| { + break :blk switch (filter) { + .program => .debug_and_symbols, + .debug => .program_and_symbols, + .program_and_symbols => .debug, + .debug_and_symbols => .program, + .all => fatal("zig objcopy: nothing to extract", .{}), + }; + } else { + break :blk null; + } + }; + const debuglink_path = path: { + if (options.add_debuglink) |path| break :path path; + if (options.extract_to) |path| break :path path; + break :path null; + }; + + switch (elf_hdr.is_64) { + inline else => |is_64| { + var elf_file = try ElfFile(is_64).parse(allocator, in_file, elf_hdr); + defer elf_file.deinit(); + + if (options.add_section) |user_section| { + for (elf_file.sections) |section| { + if (std.mem.eql(u8, section.name, user_section.section_name)) { + fatal("zig objcopy: unable to add section '{s}'. Section already exists in input", .{user_section.section_name}); + } + } + } + + if (filter_complement) |flt| { + // write the .dbg file and close it, so it can be read back to compute the debuglink checksum. + const path = options.extract_to.?; + const dbg_file = std.fs.cwd().createFile(path, .{}) catch |err| { + fatal("zig objcopy: unable to create '{s}': {s}", .{ path, @errorName(err) }); + }; + defer dbg_file.close(); + + try elf_file.emit(allocator, dbg_file, in_file, .{ .section_filter = flt, .compress_debug = options.compress_debug }); + } + + const debuglink: ?DebugLink = if (debuglink_path) |path| ElfFileHelper.createDebugLink(path) else null; + try elf_file.emit(allocator, out_file, in_file, .{ + .section_filter = filter, + .debuglink = debuglink, + .compress_debug = options.compress_debug, + .add_section = options.add_section, + .set_section_alignment = options.set_section_alignment, + .set_section_flags = options.set_section_flags, + }); + }, + } +} + +// note: this is "a minimal effort implementation" +// It doesn't support all possibile elf files: some sections type may need fixups, the program header may need fix up, ... +// It was written for a specific use case (strip debug info to a sperate file, for linux 64-bits executables built with `zig` or `zig c++` ) +// It moves and reoders the sections as little as possible to avoid having to do fixups. +// TODO: support non-native endianess + +fn ElfFile(comptime is_64: bool) type { + const Elf_Ehdr = if (is_64) elf.Elf64_Ehdr else elf.Elf32_Ehdr; + const Elf_Phdr = if (is_64) elf.Elf64_Phdr else elf.Elf32_Phdr; + const Elf_Shdr = if (is_64) elf.Elf64_Shdr else elf.Elf32_Shdr; + const Elf_Chdr = if (is_64) elf.Elf64_Chdr else elf.Elf32_Chdr; + const Elf_Sym = if (is_64) elf.Elf64_Sym else elf.Elf32_Sym; + const Elf_OffSize = if (is_64) elf.Elf64_Off else elf.Elf32_Off; + + return struct { + raw_elf_header: Elf_Ehdr, + program_segments: []const Elf_Phdr, + sections: []const Section, + arena: std.heap.ArenaAllocator, + + const SectionCategory = ElfFileHelper.SectionCategory; + const section_memory_align = @alignOf(Elf_Sym); // most restrictive of what we may load in memory + const Section = struct { + section: Elf_Shdr, + name: []const u8 = "", + segment: ?*const Elf_Phdr = null, // if the section is used by a program segment (there can be more than one) + payload: ?[]align(section_memory_align) const u8 = null, // if we need the data in memory + category: SectionCategory = .none, // should the section be kept in the exe or stripped to the debug database, or both. + }; + + const Self = @This(); + + pub fn parse(gpa: Allocator, in_file: File, header: elf.Header) !Self { + var arena = std.heap.ArenaAllocator.init(gpa); + errdefer arena.deinit(); + const allocator = arena.allocator(); + + var raw_header: Elf_Ehdr = undefined; + { + const bytes_read = try in_file.preadAll(std.mem.asBytes(&raw_header), 0); + if (bytes_read < @sizeOf(Elf_Ehdr)) + return error.TRUNCATED_ELF; + } + + // program header: list of segments + const program_segments = blk: { + if (@sizeOf(Elf_Phdr) != header.phentsize) + fatal("zig objcopy: unsupported ELF file, unexpected phentsize ({d})", .{header.phentsize}); + + const program_header = try allocator.alloc(Elf_Phdr, header.phnum); + const bytes_read = try in_file.preadAll(std.mem.sliceAsBytes(program_header), header.phoff); + if (bytes_read < @sizeOf(Elf_Phdr) * header.phnum) + return error.TRUNCATED_ELF; + break :blk program_header; + }; + + // section header + const sections = blk: { + if (@sizeOf(Elf_Shdr) != header.shentsize) + fatal("zig objcopy: unsupported ELF file, unexpected shentsize ({d})", .{header.shentsize}); + + const section_header = try allocator.alloc(Section, header.shnum); + + const raw_section_header = try allocator.alloc(Elf_Shdr, header.shnum); + defer allocator.free(raw_section_header); + const bytes_read = try in_file.preadAll(std.mem.sliceAsBytes(raw_section_header), header.shoff); + if (bytes_read < @sizeOf(Elf_Phdr) * header.shnum) + return error.TRUNCATED_ELF; + + for (section_header, raw_section_header) |*section, hdr| { + section.* = .{ .section = hdr }; + } + break :blk section_header; + }; + + // load data to memory for some sections: + // string tables for access + // sections than need modifications when other sections move. + for (sections, 0..) |*section, idx| { + const need_data = switch (section.section.sh_type) { + elf.DT_VERSYM => true, + elf.SHT_SYMTAB, elf.SHT_DYNSYM => true, + else => false, + }; + const need_strings = (idx == header.shstrndx); + + if (need_data or need_strings) { + const buffer = try allocator.alignedAlloc(u8, section_memory_align, @intCast(section.section.sh_size)); + const bytes_read = try in_file.preadAll(buffer, section.section.sh_offset); + if (bytes_read != section.section.sh_size) return error.TRUNCATED_ELF; + section.payload = buffer; + } + } + + // fill-in sections info: + // resolve the name + // find if a program segment uses the section + // categorize sections usage (used by program segments, debug datadase, common metadata, symbol table) + for (sections) |*section| { + section.segment = for (program_segments) |*seg| { + if (sectionWithinSegment(section.section, seg.*)) break seg; + } else null; + + if (section.section.sh_name != 0 and header.shstrndx != elf.SHN_UNDEF) + section.name = std.mem.span(@as([*:0]const u8, @ptrCast(§ions[header.shstrndx].payload.?[section.section.sh_name]))); + + const category_from_program: SectionCategory = if (section.segment != null) .exe else .debug; + section.category = switch (section.section.sh_type) { + elf.SHT_NOTE => .common, + elf.SHT_SYMTAB => .symbols, // "strip all" vs "strip only debug" + elf.SHT_DYNSYM => .exe, + elf.SHT_PROGBITS => cat: { + if (std.mem.eql(u8, section.name, ".comment")) break :cat .exe; + if (std.mem.eql(u8, section.name, ".gnu_debuglink")) break :cat .none; + break :cat category_from_program; + }, + elf.SHT_LOPROC...elf.SHT_HIPROC => .common, // don't strip unknown sections + elf.SHT_LOUSER...elf.SHT_HIUSER => .common, // don't strip unknown sections + else => category_from_program, + }; + } + + sections[0].category = .common; // mandatory null section + if (header.shstrndx != elf.SHN_UNDEF) + sections[header.shstrndx].category = .common; // string table for the headers + + // recursively propagate section categories to their linked sections, so that they are kept together + var dirty: u1 = 1; + while (dirty != 0) { + dirty = 0; + + for (sections) |*section| { + if (section.section.sh_link != elf.SHN_UNDEF) + dirty |= ElfFileHelper.propagateCategory(§ions[section.section.sh_link].category, section.category); + if ((section.section.sh_flags & elf.SHF_INFO_LINK) != 0 and section.section.sh_info != elf.SHN_UNDEF) + dirty |= ElfFileHelper.propagateCategory(§ions[section.section.sh_info].category, section.category); + } + } + + return Self{ + .arena = arena, + .raw_elf_header = raw_header, + .program_segments = program_segments, + .sections = sections, + }; + } + + pub fn deinit(self: *Self) void { + self.arena.deinit(); + } + + const Filter = ElfFileHelper.Filter; + const DebugLink = ElfFileHelper.DebugLink; + const EmitElfOptions = struct { + section_filter: Filter = .all, + debuglink: ?DebugLink = null, + compress_debug: bool = false, + add_section: ?AddSection = null, + set_section_alignment: ?SetSectionAlignment = null, + set_section_flags: ?SetSectionFlags = null, + }; + fn emit(self: *const Self, gpa: Allocator, out_file: File, in_file: File, options: EmitElfOptions) !void { + var arena = std.heap.ArenaAllocator.init(gpa); + defer arena.deinit(); + const allocator = arena.allocator(); + + // when emitting the stripped exe: + // - unused sections are removed + // when emitting the debug file: + // - all sections are kept, but some are emptied and their types is changed to SHT_NOBITS + // the program header is kept unchanged. (`strip` does update it, but `eu-strip` does not, and it still works) + + const Update = struct { + action: ElfFileHelper.Action, + + // remap the indexs after omitting the filtered sections + remap_idx: u16, + + // optionally overrides the payload from the source file + payload: ?[]align(section_memory_align) const u8 = null, + section: ?Elf_Shdr = null, + }; + const sections_update = try allocator.alloc(Update, self.sections.len); + const new_shnum = blk: { + var next_idx: u16 = 0; + for (self.sections, sections_update) |section, *update| { + const action = ElfFileHelper.selectAction(section.category, options.section_filter); + const remap_idx = idx: { + if (action == .strip) break :idx elf.SHN_UNDEF; + next_idx += 1; + break :idx next_idx - 1; + }; + update.* = Update{ .action = action, .remap_idx = remap_idx }; + } + + if (options.debuglink != null) + next_idx += 1; + + if (options.add_section != null) { + next_idx += 1; + } + + break :blk next_idx; + }; + + // add a ".gnu_debuglink" to the string table if needed + const debuglink_name: u32 = blk: { + if (options.debuglink == null) break :blk elf.SHN_UNDEF; + if (self.raw_elf_header.e_shstrndx == elf.SHN_UNDEF) + fatal("zig objcopy: no strtab, cannot add the debuglink section", .{}); // TODO add the section if needed? + + const strtab = &self.sections[self.raw_elf_header.e_shstrndx]; + const update = §ions_update[self.raw_elf_header.e_shstrndx]; + + const name: []const u8 = ".gnu_debuglink"; + const new_offset: u32 = @intCast(strtab.payload.?.len); + const buf = try allocator.alignedAlloc(u8, section_memory_align, new_offset + name.len + 1); + @memcpy(buf[0..new_offset], strtab.payload.?); + @memcpy(buf[new_offset..][0..name.len], name); + buf[new_offset + name.len] = 0; + + assert(update.action == .keep); + update.payload = buf; + + break :blk new_offset; + }; + + // add user section to the string table if needed + const user_section_name: u32 = blk: { + if (options.add_section == null) break :blk elf.SHN_UNDEF; + if (self.raw_elf_header.e_shstrndx == elf.SHN_UNDEF) + fatal("zig objcopy: no strtab, cannot add the user section", .{}); // TODO add the section if needed? + + const strtab = &self.sections[self.raw_elf_header.e_shstrndx]; + const update = §ions_update[self.raw_elf_header.e_shstrndx]; + + const name = options.add_section.?.section_name; + const new_offset: u32 = @intCast(strtab.payload.?.len); + const buf = try allocator.alignedAlloc(u8, section_memory_align, new_offset + name.len + 1); + @memcpy(buf[0..new_offset], strtab.payload.?); + @memcpy(buf[new_offset..][0..name.len], name); + buf[new_offset + name.len] = 0; + + assert(update.action == .keep); + update.payload = buf; + + break :blk new_offset; + }; + + // maybe compress .debug sections + if (options.compress_debug) { + for (self.sections[1..], sections_update[1..]) |section, *update| { + if (update.action != .keep) continue; + if (!std.mem.startsWith(u8, section.name, ".debug_")) continue; + if ((section.section.sh_flags & elf.SHF_COMPRESSED) != 0) continue; // already compressed + + const chdr = Elf_Chdr{ + .ch_type = elf.COMPRESS.ZLIB, + .ch_size = section.section.sh_size, + .ch_addralign = section.section.sh_addralign, + }; + + const compressed_payload = try ElfFileHelper.tryCompressSection(allocator, in_file, section.section.sh_offset, section.section.sh_size, std.mem.asBytes(&chdr)); + if (compressed_payload) |payload| { + update.payload = payload; + update.section = section.section; + update.section.?.sh_addralign = @alignOf(Elf_Chdr); + update.section.?.sh_size = @intCast(payload.len); + update.section.?.sh_flags |= elf.SHF_COMPRESSED; + } + } + } + + var cmdbuf = std.ArrayList(ElfFileHelper.WriteCmd).init(allocator); + defer cmdbuf.deinit(); + try cmdbuf.ensureUnusedCapacity(3 + new_shnum); + var eof_offset: Elf_OffSize = 0; // track the end of the data written so far. + + // build the updated headers + // nb: updated_elf_header will be updated before the actual write + var updated_elf_header = self.raw_elf_header; + if (updated_elf_header.e_shstrndx != elf.SHN_UNDEF) + updated_elf_header.e_shstrndx = sections_update[updated_elf_header.e_shstrndx].remap_idx; + cmdbuf.appendAssumeCapacity(.{ .write_data = .{ .data = std.mem.asBytes(&updated_elf_header), .out_offset = 0 } }); + eof_offset = @sizeOf(Elf_Ehdr); + + // program header as-is. + // nb: for only-debug files, removing it appears to work, but is invalid by ELF specifcation. + { + assert(updated_elf_header.e_phoff == @sizeOf(Elf_Ehdr)); + const data = std.mem.sliceAsBytes(self.program_segments); + assert(data.len == @as(usize, updated_elf_header.e_phentsize) * updated_elf_header.e_phnum); + cmdbuf.appendAssumeCapacity(.{ .write_data = .{ .data = data, .out_offset = updated_elf_header.e_phoff } }); + eof_offset = updated_elf_header.e_phoff + @as(Elf_OffSize, @intCast(data.len)); + } + + // update sections and queue payload writes + const updated_section_header = blk: { + const dest_sections = try allocator.alloc(Elf_Shdr, new_shnum); + + { + // the ELF format doesn't specify the order for all sections. + // this code only supports when they are in increasing file order. + var offset: u64 = eof_offset; + for (self.sections[1..]) |section| { + if (section.section.sh_type == elf.SHT_NOBITS) + continue; + if (section.section.sh_offset < offset) { + fatal("zig objcopy: unsupported ELF file", .{}); + } + offset = section.section.sh_offset; + } + } + + dest_sections[0] = self.sections[0].section; + + var dest_section_idx: u32 = 1; + for (self.sections[1..], sections_update[1..]) |section, update| { + if (update.action == .strip) continue; + assert(update.remap_idx == dest_section_idx); + + const src = if (update.section) |*s| s else §ion.section; + const dest = &dest_sections[dest_section_idx]; + const payload = if (update.payload) |data| data else section.payload; + dest_section_idx += 1; + + dest.* = src.*; + + if (src.sh_link != elf.SHN_UNDEF) + dest.sh_link = sections_update[src.sh_link].remap_idx; + if ((src.sh_flags & elf.SHF_INFO_LINK) != 0 and src.sh_info != elf.SHN_UNDEF) + dest.sh_info = sections_update[src.sh_info].remap_idx; + + if (payload) |data| + dest.sh_size = @intCast(data.len); + + const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign; + dest.sh_offset = std.mem.alignForward(Elf_OffSize, eof_offset, addralign); + if (src.sh_offset != dest.sh_offset and section.segment != null and update.action != .empty and dest.sh_type != elf.SHT_NOTE and dest.sh_type != elf.SHT_NOBITS) { + if (src.sh_offset > dest.sh_offset) { + dest.sh_offset = src.sh_offset; // add padding to avoid modifing the program segments + } else { + fatal("zig objcopy: cannot adjust program segments", .{}); + } + } + assert(dest.sh_addr % addralign == dest.sh_offset % addralign); + + if (update.action == .empty) + dest.sh_type = elf.SHT_NOBITS; + + if (dest.sh_type != elf.SHT_NOBITS) { + if (payload) |src_data| { + // update sections payload and write + const dest_data = switch (src.sh_type) { + elf.DT_VERSYM => dst_data: { + const data = try allocator.alignedAlloc(u8, section_memory_align, src_data.len); + @memcpy(data, src_data); + + const defs = @as([*]elf.Verdef, @ptrCast(data))[0 .. @as(usize, @intCast(src.sh_size)) / @sizeOf(elf.Verdef)]; + for (defs) |*def| switch (def.ndx) { + .LOCAL, .GLOBAL => {}, + else => def.ndx = @enumFromInt(sections_update[src.sh_info].remap_idx), + }; + + break :dst_data data; + }, + elf.SHT_SYMTAB, elf.SHT_DYNSYM => dst_data: { + const data = try allocator.alignedAlloc(u8, section_memory_align, src_data.len); + @memcpy(data, src_data); + + const syms = @as([*]Elf_Sym, @ptrCast(data))[0 .. @as(usize, @intCast(src.sh_size)) / @sizeOf(Elf_Sym)]; + for (syms) |*sym| { + if (sym.st_shndx != elf.SHN_UNDEF and sym.st_shndx < elf.SHN_LORESERVE) + sym.st_shndx = sections_update[sym.st_shndx].remap_idx; + } + + break :dst_data data; + }, + else => src_data, + }; + + assert(dest_data.len == dest.sh_size); + cmdbuf.appendAssumeCapacity(.{ .write_data = .{ .data = dest_data, .out_offset = dest.sh_offset } }); + eof_offset = dest.sh_offset + dest.sh_size; + } else { + // direct contents copy + cmdbuf.appendAssumeCapacity(.{ .copy_range = .{ .in_offset = src.sh_offset, .len = dest.sh_size, .out_offset = dest.sh_offset } }); + eof_offset = dest.sh_offset + dest.sh_size; + } + } else { + // account for alignment padding even in empty sections to keep logical section order + eof_offset = dest.sh_offset; + } + } + + // add a ".gnu_debuglink" section + if (options.debuglink) |link| { + const payload = payload: { + const crc_offset = std.mem.alignForward(usize, link.name.len + 1, 4); + const buf = try allocator.alignedAlloc(u8, 4, crc_offset + 4); + @memcpy(buf[0..link.name.len], link.name); + @memset(buf[link.name.len..crc_offset], 0); + @memcpy(buf[crc_offset..], std.mem.asBytes(&link.crc32)); + break :payload buf; + }; + + dest_sections[dest_section_idx] = Elf_Shdr{ + .sh_name = debuglink_name, + .sh_type = elf.SHT_PROGBITS, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = eof_offset, + .sh_size = @intCast(payload.len), + .sh_link = elf.SHN_UNDEF, + .sh_info = elf.SHN_UNDEF, + .sh_addralign = 4, + .sh_entsize = 0, + }; + dest_section_idx += 1; + + cmdbuf.appendAssumeCapacity(.{ .write_data = .{ .data = payload, .out_offset = eof_offset } }); + eof_offset += @as(Elf_OffSize, @intCast(payload.len)); + } + + // --add-section + if (options.add_section) |add_section| { + var section_file = fs.cwd().openFile(add_section.file_path, .{}) catch |err| + fatal("unable to open '{s}': {s}", .{ add_section.file_path, @errorName(err) }); + defer section_file.close(); + + const payload = try section_file.readToEndAlloc(arena.allocator(), std.math.maxInt(usize)); + + dest_sections[dest_section_idx] = Elf_Shdr{ + .sh_name = user_section_name, + .sh_type = elf.SHT_PROGBITS, + .sh_flags = 0, + .sh_addr = 0, + .sh_offset = eof_offset, + .sh_size = @intCast(payload.len), + .sh_link = elf.SHN_UNDEF, + .sh_info = elf.SHN_UNDEF, + .sh_addralign = 4, + .sh_entsize = 0, + }; + dest_section_idx += 1; + + cmdbuf.appendAssumeCapacity(.{ .write_data = .{ .data = payload, .out_offset = eof_offset } }); + eof_offset += @as(Elf_OffSize, @intCast(payload.len)); + } + + assert(dest_section_idx == new_shnum); + break :blk dest_sections; + }; + + // --set-section-alignment: overwrite alignment + if (options.set_section_alignment) |set_align| { + if (self.raw_elf_header.e_shstrndx == elf.SHN_UNDEF) + fatal("zig objcopy: no strtab, cannot add the user section", .{}); // TODO add the section if needed? + + const strtab = §ions_update[self.raw_elf_header.e_shstrndx]; + for (updated_section_header) |*section| { + const section_name = std.mem.span(@as([*:0]const u8, @ptrCast(&strtab.payload.?[section.sh_name]))); + if (std.mem.eql(u8, section_name, set_align.section_name)) { + section.sh_addralign = set_align.alignment; + break; + } + } else std.log.warn("Skipping --set-section-alignment. Section '{s}' not found", .{set_align.section_name}); + } + + // --set-section-flags: overwrite flags + if (options.set_section_flags) |set_flags| { + if (self.raw_elf_header.e_shstrndx == elf.SHN_UNDEF) + fatal("zig objcopy: no strtab, cannot add the user section", .{}); // TODO add the section if needed? + + const strtab = §ions_update[self.raw_elf_header.e_shstrndx]; + for (updated_section_header) |*section| { + const section_name = std.mem.span(@as([*:0]const u8, @ptrCast(&strtab.payload.?[section.sh_name]))); + if (std.mem.eql(u8, section_name, set_flags.section_name)) { + section.sh_flags = std.elf.SHF_WRITE; // default is writable cleared by "readonly" + const f = set_flags.flags; + + // Supporting a subset of GNU and LLVM objcopy for ELF only + // GNU: + // alloc: add SHF_ALLOC + // contents: if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing + // load: if section is SHT_NOBITS, set SHT_PROGBITS, otherwise do nothing (same as contents) + // noload: not ELF relevant + // readonly: clear default SHF_WRITE flag + // code: add SHF_EXECINSTR + // data: not ELF relevant + // rom: ignored + // exclude: add SHF_EXCLUDE + // share: not ELF relevant + // debug: not ELF relevant + // large: add SHF_X86_64_LARGE. Fatal error if target is not x86_64 + if (f.alloc) section.sh_flags |= std.elf.SHF_ALLOC; + if (f.contents or f.load) { + if (section.sh_type == std.elf.SHT_NOBITS) section.sh_type = std.elf.SHT_PROGBITS; + } + if (f.readonly) section.sh_flags &= ~@as(@TypeOf(section.sh_type), std.elf.SHF_WRITE); + if (f.code) section.sh_flags |= std.elf.SHF_EXECINSTR; + if (f.exclude) section.sh_flags |= std.elf.SHF_EXCLUDE; + if (f.large) { + if (updated_elf_header.e_machine != std.elf.EM.X86_64) + fatal("zig objcopy: 'large' section flag is only supported on x86_64 targets", .{}); + section.sh_flags |= std.elf.SHF_X86_64_LARGE; + } + + // LLVM: + // merge: add SHF_MERGE + // strings: add SHF_STRINGS + if (f.merge) section.sh_flags |= std.elf.SHF_MERGE; + if (f.strings) section.sh_flags |= std.elf.SHF_STRINGS; + break; + } + } else std.log.warn("Skipping --set-section-flags. Section '{s}' not found", .{set_flags.section_name}); + } + + // write the section header at the tail + { + const offset = std.mem.alignForward(Elf_OffSize, eof_offset, @alignOf(Elf_Shdr)); + + const data = std.mem.sliceAsBytes(updated_section_header); + assert(data.len == @as(usize, updated_elf_header.e_shentsize) * new_shnum); + updated_elf_header.e_shoff = offset; + updated_elf_header.e_shnum = new_shnum; + + cmdbuf.appendAssumeCapacity(.{ .write_data = .{ .data = data, .out_offset = updated_elf_header.e_shoff } }); + } + + try ElfFileHelper.write(allocator, out_file, in_file, cmdbuf.items); + } + + fn sectionWithinSegment(section: Elf_Shdr, segment: Elf_Phdr) bool { + const file_size = if (section.sh_type == elf.SHT_NOBITS) 0 else section.sh_size; + return segment.p_offset <= section.sh_offset and (segment.p_offset + segment.p_filesz) >= (section.sh_offset + file_size); + } + }; +} + +const ElfFileHelper = struct { + const DebugLink = struct { name: []const u8, crc32: u32 }; + const Filter = enum { all, program, debug, program_and_symbols, debug_and_symbols }; + + const SectionCategory = enum { common, exe, debug, symbols, none }; + fn propagateCategory(cur: *SectionCategory, new: SectionCategory) u1 { + const cat: SectionCategory = switch (cur.*) { + .none => new, + .common => .common, + .debug => switch (new) { + .none, .debug => .debug, + else => new, + }, + .exe => switch (new) { + .common => .common, + .none, .debug, .exe => .exe, + .symbols => .exe, + }, + .symbols => switch (new) { + .none, .common, .debug, .exe => unreachable, + .symbols => .symbols, + }, + }; + + if (cur.* != cat) { + cur.* = cat; + return 1; + } else { + return 0; + } + } + + const Action = enum { keep, strip, empty }; + fn selectAction(category: SectionCategory, filter: Filter) Action { + if (category == .none) return .strip; + return switch (filter) { + .all => switch (category) { + .none => .strip, + else => .keep, + }, + .program => switch (category) { + .common, .exe => .keep, + else => .strip, + }, + .program_and_symbols => switch (category) { + .common, .exe, .symbols => .keep, + else => .strip, + }, + .debug => switch (category) { + .exe, .symbols => .empty, + .none => .strip, + else => .keep, + }, + .debug_and_symbols => switch (category) { + .exe => .empty, + .none => .strip, + else => .keep, + }, + }; + } + + const WriteCmd = union(enum) { + copy_range: struct { in_offset: u64, len: u64, out_offset: u64 }, + write_data: struct { data: []const u8, out_offset: u64 }, + }; + fn write(allocator: Allocator, out_file: File, in_file: File, cmds: []const WriteCmd) !void { + // consolidate holes between writes: + // by coping original padding data from in_file (by fusing contiguous ranges) + // by writing zeroes otherwise + const zeroes = [1]u8{0} ** 4096; + var consolidated = std.ArrayList(WriteCmd).init(allocator); + defer consolidated.deinit(); + try consolidated.ensureUnusedCapacity(cmds.len * 2); + var offset: u64 = 0; + var fused_cmd: ?WriteCmd = null; + for (cmds) |cmd| { + switch (cmd) { + .write_data => |data| { + assert(data.out_offset >= offset); + if (fused_cmd) |prev| { + consolidated.appendAssumeCapacity(prev); + fused_cmd = null; + } + if (data.out_offset > offset) { + consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@intCast(data.out_offset - offset)], .out_offset = offset } }); + } + consolidated.appendAssumeCapacity(cmd); + offset = data.out_offset + data.data.len; + }, + .copy_range => |range| { + assert(range.out_offset >= offset); + if (fused_cmd) |prev| { + if (range.in_offset >= prev.copy_range.in_offset + prev.copy_range.len and (range.out_offset - prev.copy_range.out_offset == range.in_offset - prev.copy_range.in_offset)) { + fused_cmd = .{ .copy_range = .{ + .in_offset = prev.copy_range.in_offset, + .out_offset = prev.copy_range.out_offset, + .len = (range.out_offset + range.len) - prev.copy_range.out_offset, + } }; + } else { + consolidated.appendAssumeCapacity(prev); + if (range.out_offset > offset) { + consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@intCast(range.out_offset - offset)], .out_offset = offset } }); + } + fused_cmd = cmd; + } + } else { + fused_cmd = cmd; + } + offset = range.out_offset + range.len; + }, + } + } + if (fused_cmd) |cmd| { + consolidated.appendAssumeCapacity(cmd); + } + + // write the output file + for (consolidated.items) |cmd| { + switch (cmd) { + .write_data => |data| { + var iovec = [_]std.posix.iovec_const{.{ .base = data.data.ptr, .len = data.data.len }}; + try out_file.pwritevAll(&iovec, data.out_offset); + }, + .copy_range => |range| { + const copied_bytes = try in_file.copyRangeAll(range.in_offset, out_file, range.out_offset, range.len); + if (copied_bytes < range.len) return error.TRUNCATED_ELF; + }, + } + } + } + + fn tryCompressSection(allocator: Allocator, in_file: File, offset: u64, size: u64, prefix: []const u8) !?[]align(8) const u8 { + if (size < prefix.len) return null; + + try in_file.seekTo(offset); + var section_reader = std.io.limitedReader(in_file.reader(), size); + + // allocate as large as decompressed data. if the compression doesn't fit, keep the data uncompressed. + const compressed_data = try allocator.alignedAlloc(u8, 8, @intCast(size)); + var compressed_stream = std.io.fixedBufferStream(compressed_data); + + try compressed_stream.writer().writeAll(prefix); + + { + var compressor = try std.compress.zlib.compressor(compressed_stream.writer(), .{}); + + var buf: [8000]u8 = undefined; + while (true) { + const bytes_read = try section_reader.read(&buf); + if (bytes_read == 0) break; + const bytes_written = compressor.write(buf[0..bytes_read]) catch |err| switch (err) { + error.NoSpaceLeft => { + allocator.free(compressed_data); + return null; + }, + else => return err, + }; + std.debug.assert(bytes_written == bytes_read); + } + compressor.finish() catch |err| switch (err) { + error.NoSpaceLeft => { + allocator.free(compressed_data); + return null; + }, + else => return err, + }; + } + + const compressed_len: usize = @intCast(compressed_stream.getPos() catch unreachable); + const data = allocator.realloc(compressed_data, compressed_len) catch compressed_data; + return data[0..compressed_len]; + } + + fn createDebugLink(path: []const u8) DebugLink { + const file = std.fs.cwd().openFile(path, .{}) catch |err| { + fatal("zig objcopy: could not open `{s}`: {s}\n", .{ path, @errorName(err) }); + }; + defer file.close(); + + const crc = ElfFileHelper.computeFileCrc(file) catch |err| { + fatal("zig objcopy: could not read `{s}`: {s}\n", .{ path, @errorName(err) }); + }; + return .{ + .name = std.fs.path.basename(path), + .crc32 = crc, + }; + } + + fn computeFileCrc(file: File) !u32 { + var buf: [8000]u8 = undefined; + + try file.seekTo(0); + var hasher = std.hash.Crc32.init(); + while (true) { + const bytes_read = try file.read(&buf); + if (bytes_read == 0) break; + hasher.update(buf[0..bytes_read]); + } + return hasher.final(); + } +}; + +const SectionFlags = packed struct { + alloc: bool = false, + contents: bool = false, + load: bool = false, + noload: bool = false, + readonly: bool = false, + code: bool = false, + data: bool = false, + rom: bool = false, + exclude: bool = false, + shared: bool = false, + debug: bool = false, + large: bool = false, + merge: bool = false, + strings: bool = false, +}; + +fn parseSectionFlags(comma_separated_flags: []const u8) SectionFlags { + const P = struct { + fn parse(flags: *SectionFlags, string: []const u8) void { + if (string.len == 0) return; + + if (std.mem.eql(u8, string, "alloc")) { + flags.alloc = true; + } else if (std.mem.eql(u8, string, "contents")) { + flags.contents = true; + } else if (std.mem.eql(u8, string, "load")) { + flags.load = true; + } else if (std.mem.eql(u8, string, "noload")) { + flags.noload = true; + } else if (std.mem.eql(u8, string, "readonly")) { + flags.readonly = true; + } else if (std.mem.eql(u8, string, "code")) { + flags.code = true; + } else if (std.mem.eql(u8, string, "data")) { + flags.data = true; + } else if (std.mem.eql(u8, string, "rom")) { + flags.rom = true; + } else if (std.mem.eql(u8, string, "exclude")) { + flags.exclude = true; + } else if (std.mem.eql(u8, string, "shared")) { + flags.shared = true; + } else if (std.mem.eql(u8, string, "debug")) { + flags.debug = true; + } else if (std.mem.eql(u8, string, "large")) { + flags.large = true; + } else if (std.mem.eql(u8, string, "merge")) { + flags.merge = true; + } else if (std.mem.eql(u8, string, "strings")) { + flags.strings = true; + } else { + std.log.warn("Skipping unrecognized section flag '{s}'", .{string}); + } + } + }; + + var flags = SectionFlags{}; + var offset: usize = 0; + for (comma_separated_flags, 0..) |c, i| { + if (c == ',') { + defer offset = i + 1; + const string = comma_separated_flags[offset..i]; + P.parse(&flags, string); + } + } + P.parse(&flags, comma_separated_flags[offset..]); + return flags; +} + +test "Parse section flags" { + const F = SectionFlags; + try std.testing.expectEqual(F{}, parseSectionFlags("")); + try std.testing.expectEqual(F{}, parseSectionFlags(",")); + try std.testing.expectEqual(F{}, parseSectionFlags("abc")); + try std.testing.expectEqual(F{ .alloc = true }, parseSectionFlags("alloc")); + try std.testing.expectEqual(F{ .data = true }, parseSectionFlags("data,")); + try std.testing.expectEqual(F{ .alloc = true, .code = true }, parseSectionFlags("alloc,code")); + try std.testing.expectEqual(F{ .alloc = true, .code = true }, parseSectionFlags("alloc,code,not_supported")); +} + +const SplitResult = struct { first: []const u8, second: []const u8 }; + +fn splitOption(option: []const u8) ?SplitResult { + const separator = '='; + if (option.len < 3) return null; // minimum "a=b" + for (1..option.len - 1) |i| { + if (option[i] == separator) return .{ + .first = option[0..i], + .second = option[i + 1 ..], + }; + } + return null; +} + +test "Split option" { + { + const split = splitOption(".abc=123"); + try std.testing.expect(split != null); + try std.testing.expectEqualStrings(".abc", split.?.first); + try std.testing.expectEqualStrings("123", split.?.second); + } + + try std.testing.expectEqual(null, splitOption("")); + try std.testing.expectEqual(null, splitOption("=abc")); + try std.testing.expectEqual(null, splitOption("abc=")); + try std.testing.expectEqual(null, splitOption("abc")); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/reduce.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/reduce.zig new file mode 100644 index 00000000..826c2bcc --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/reduce.zig @@ -0,0 +1,426 @@ +const std = @import("std"); +const mem = std.mem; +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const Ast = std.zig.Ast; +const Walk = @import("reduce/Walk.zig"); +const AstGen = std.zig.AstGen; +const Zir = std.zig.Zir; + +const usage = + \\zig reduce [options] ./checker root_source_file.zig [-- [argv]] + \\ + \\root_source_file.zig is relative to --main-mod-path. + \\ + \\checker: + \\ An executable that communicates interestingness by returning these exit codes: + \\ exit(0): interesting + \\ exit(1): unknown (infinite loop or other mishap) + \\ exit(other): not interesting + \\ + \\options: + \\ --seed [integer] Override the random seed. Defaults to 0 + \\ --skip-smoke-test Skip interestingness check smoke test + \\ --mod [name]:[deps]:[src] Make a module available for dependency under the given name + \\ deps: [dep],[dep],... + \\ dep: [[import=]name] + \\ --deps [dep],[dep],... Set dependency names for the root package + \\ dep: [[import=]name] + \\ --main-mod-path Set the directory of the root module + \\ + \\argv: + \\ Forwarded directly to the interestingness script. + \\ +; + +const Interestingness = enum { interesting, unknown, boring }; + +// Roadmap: +// - add thread pool +// - add support for parsing the module flags +// - more fancy transformations +// - @import inlining of modules +// - removing statements or blocks of code +// - replacing operands of `and` and `or` with `true` and `false` +// - replacing if conditions with `true` and `false` +// - reduce flags sent to the compiler +// - integrate with the build system? + +pub fn main() !void { + var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena_instance.deinit(); + const arena = arena_instance.allocator(); + + var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; + const gpa = general_purpose_allocator.allocator(); + + const args = try std.process.argsAlloc(arena); + + var opt_checker_path: ?[]const u8 = null; + var opt_root_source_file_path: ?[]const u8 = null; + var argv: []const []const u8 = &.{}; + var seed: u32 = 0; + var skip_smoke_test = false; + + { + var i: usize = 1; + while (i < args.len) : (i += 1) { + const arg = args[i]; + if (mem.startsWith(u8, arg, "-")) { + if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { + const stdout = std.io.getStdOut().writer(); + try stdout.writeAll(usage); + return std.process.cleanExit(); + } else if (mem.eql(u8, arg, "--")) { + argv = args[i + 1 ..]; + break; + } else if (mem.eql(u8, arg, "--skip-smoke-test")) { + skip_smoke_test = true; + } else if (mem.eql(u8, arg, "--main-mod-path")) { + @panic("TODO: implement --main-mod-path"); + } else if (mem.eql(u8, arg, "--mod")) { + @panic("TODO: implement --mod"); + } else if (mem.eql(u8, arg, "--deps")) { + @panic("TODO: implement --deps"); + } else if (mem.eql(u8, arg, "--seed")) { + i += 1; + if (i >= args.len) fatal("expected 32-bit integer after {s}", .{arg}); + const next_arg = args[i]; + seed = std.fmt.parseUnsigned(u32, next_arg, 0) catch |err| { + fatal("unable to parse seed '{s}' as 32-bit integer: {s}", .{ + next_arg, @errorName(err), + }); + }; + } else { + fatal("unrecognized parameter: '{s}'", .{arg}); + } + } else if (opt_checker_path == null) { + opt_checker_path = arg; + } else if (opt_root_source_file_path == null) { + opt_root_source_file_path = arg; + } else { + fatal("unexpected extra parameter: '{s}'", .{arg}); + } + } + } + + const checker_path = opt_checker_path orelse + fatal("missing interestingness checker argument; see -h for usage", .{}); + const root_source_file_path = opt_root_source_file_path orelse + fatal("missing root source file path argument; see -h for usage", .{}); + + var interestingness_argv: std.ArrayListUnmanaged([]const u8) = .empty; + try interestingness_argv.ensureUnusedCapacity(arena, argv.len + 1); + interestingness_argv.appendAssumeCapacity(checker_path); + interestingness_argv.appendSliceAssumeCapacity(argv); + + var rendered = std.ArrayList(u8).init(gpa); + defer rendered.deinit(); + + var astgen_input = std.ArrayList(u8).init(gpa); + defer astgen_input.deinit(); + + var tree = try parse(gpa, root_source_file_path); + defer { + gpa.free(tree.source); + tree.deinit(gpa); + } + + if (!skip_smoke_test) { + std.debug.print("smoke testing the interestingness check...\n", .{}); + switch (try runCheck(arena, interestingness_argv.items)) { + .interesting => {}, + .boring, .unknown => |t| { + fatal("interestingness check returned {s} for unmodified input\n", .{ + @tagName(t), + }); + }, + } + } + + var fixups: Ast.Fixups = .{}; + defer fixups.deinit(gpa); + + var more_fixups: Ast.Fixups = .{}; + defer more_fixups.deinit(gpa); + + var rng = std.Random.DefaultPrng.init(seed); + + // 1. Walk the AST of the source file looking for independent + // reductions and collecting them all into an array list. + // 2. Randomize the list of transformations. A future enhancement will add + // priority weights to the sorting but for now they are completely + // shuffled. + // 3. Apply a subset consisting of 1/2 of the transformations and check for + // interestingness. + // 4. If not interesting, half the subset size again and check again. + // 5. Repeat until the subset size is 1, then march the transformation + // index forward by 1 with each non-interesting attempt. + // + // At any point if a subset of transformations succeeds in producing an interesting + // result, restart the whole process, reparsing the AST and re-generating the list + // of all possible transformations and shuffling it again. + + var transformations = std.ArrayList(Walk.Transformation).init(gpa); + defer transformations.deinit(); + try Walk.findTransformations(arena, &tree, &transformations); + sortTransformations(transformations.items, rng.random()); + + fresh: while (transformations.items.len > 0) { + std.debug.print("found {d} possible transformations\n", .{ + transformations.items.len, + }); + var subset_size: usize = transformations.items.len; + var start_index: usize = 0; + + while (start_index < transformations.items.len) { + const prev_subset_size = subset_size; + subset_size = @max(1, subset_size * 3 / 4); + if (prev_subset_size > 1 and subset_size == 1) + start_index = 0; + + const this_set = transformations.items[start_index..][0..subset_size]; + std.debug.print("trying {d} random transformations: ", .{subset_size}); + for (this_set[0..@min(this_set.len, 20)]) |t| { + std.debug.print("{s} ", .{@tagName(t)}); + } + std.debug.print("\n", .{}); + try transformationsToFixups(gpa, arena, root_source_file_path, this_set, &fixups); + + rendered.clearRetainingCapacity(); + try tree.renderToArrayList(&rendered, fixups); + + // The transformations we applied may have resulted in unused locals, + // in which case we would like to add the respective discards. + { + try astgen_input.resize(rendered.items.len); + @memcpy(astgen_input.items, rendered.items); + try astgen_input.append(0); + const source_with_null = astgen_input.items[0 .. astgen_input.items.len - 1 :0]; + var astgen_tree = try Ast.parse(gpa, source_with_null, .zig); + defer astgen_tree.deinit(gpa); + if (astgen_tree.errors.len != 0) { + @panic("syntax errors occurred"); + } + var zir = try AstGen.generate(gpa, astgen_tree); + defer zir.deinit(gpa); + + if (zir.hasCompileErrors()) { + more_fixups.clearRetainingCapacity(); + const payload_index = zir.extra[@intFromEnum(Zir.ExtraIndex.compile_errors)]; + assert(payload_index != 0); + const header = zir.extraData(Zir.Inst.CompileErrors, payload_index); + var extra_index = header.end; + for (0..header.data.items_len) |_| { + const item = zir.extraData(Zir.Inst.CompileErrors.Item, extra_index); + extra_index = item.end; + const msg = zir.nullTerminatedString(item.data.msg); + if (mem.eql(u8, msg, "unused local constant") or + mem.eql(u8, msg, "unused local variable") or + mem.eql(u8, msg, "unused function parameter") or + mem.eql(u8, msg, "unused capture")) + { + const ident_token = item.data.token; + try more_fixups.unused_var_decls.put(gpa, ident_token, {}); + } else { + std.debug.print("found other ZIR error: '{s}'\n", .{msg}); + } + } + if (more_fixups.count() != 0) { + rendered.clearRetainingCapacity(); + try astgen_tree.renderToArrayList(&rendered, more_fixups); + } + } + } + + try std.fs.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.items }); + // std.debug.print("trying this code:\n{s}\n", .{rendered.items}); + + const interestingness = try runCheck(arena, interestingness_argv.items); + std.debug.print("{d} random transformations: {s}. {d}/{d}\n", .{ + subset_size, @tagName(interestingness), start_index, transformations.items.len, + }); + switch (interestingness) { + .interesting => { + const new_tree = try parse(gpa, root_source_file_path); + gpa.free(tree.source); + tree.deinit(gpa); + tree = new_tree; + + try Walk.findTransformations(arena, &tree, &transformations); + sortTransformations(transformations.items, rng.random()); + + continue :fresh; + }, + .unknown, .boring => { + // Continue to try the next set of transformations. + // If we tested only one transformation, move on to the next one. + if (subset_size == 1) { + start_index += 1; + } else { + start_index += subset_size; + if (start_index + subset_size > transformations.items.len) { + start_index = 0; + } + } + }, + } + } + std.debug.print("all {d} remaining transformations are uninteresting\n", .{ + transformations.items.len, + }); + + // Revert the source back to not be transformed. + fixups.clearRetainingCapacity(); + rendered.clearRetainingCapacity(); + try tree.renderToArrayList(&rendered, fixups); + try std.fs.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.items }); + + return std.process.cleanExit(); + } + std.debug.print("no more transformations found\n", .{}); + return std.process.cleanExit(); +} + +fn sortTransformations(transformations: []Walk.Transformation, rng: std.Random) void { + rng.shuffle(Walk.Transformation, transformations); + // Stable sort based on priority to keep randomness as the secondary sort. + // TODO: introduce transformation priorities + // std.mem.sort(transformations); +} + +fn termToInteresting(term: std.process.Child.Term) Interestingness { + return switch (term) { + .Exited => |code| switch (code) { + 0 => .interesting, + 1 => .unknown, + else => .boring, + }, + else => b: { + std.debug.print("interestingness check aborted unexpectedly\n", .{}); + break :b .boring; + }, + }; +} + +fn runCheck(arena: std.mem.Allocator, argv: []const []const u8) !Interestingness { + const result = try std.process.Child.run(.{ + .allocator = arena, + .argv = argv, + }); + if (result.stderr.len != 0) + std.debug.print("{s}", .{result.stderr}); + return termToInteresting(result.term); +} + +fn transformationsToFixups( + gpa: Allocator, + arena: Allocator, + root_source_file_path: []const u8, + transforms: []const Walk.Transformation, + fixups: *Ast.Fixups, +) !void { + fixups.clearRetainingCapacity(); + + for (transforms) |t| switch (t) { + .gut_function => |fn_decl_node| { + try fixups.gut_functions.put(gpa, fn_decl_node, {}); + }, + .delete_node => |decl_node| { + try fixups.omit_nodes.put(gpa, decl_node, {}); + }, + .delete_var_decl => |delete_var_decl| { + try fixups.omit_nodes.put(gpa, delete_var_decl.var_decl_node, {}); + for (delete_var_decl.references.items) |ident_node| { + try fixups.replace_nodes_with_string.put(gpa, ident_node, "undefined"); + } + }, + .replace_with_undef => |node| { + try fixups.replace_nodes_with_string.put(gpa, node, "undefined"); + }, + .replace_with_true => |node| { + try fixups.replace_nodes_with_string.put(gpa, node, "true"); + }, + .replace_with_false => |node| { + try fixups.replace_nodes_with_string.put(gpa, node, "false"); + }, + .replace_node => |r| { + try fixups.replace_nodes_with_node.put(gpa, r.to_replace, r.replacement); + }, + .inline_imported_file => |inline_imported_file| { + const full_imported_path = try std.fs.path.join(gpa, &.{ + std.fs.path.dirname(root_source_file_path) orelse ".", + inline_imported_file.imported_string, + }); + defer gpa.free(full_imported_path); + var other_file_ast = try parse(gpa, full_imported_path); + defer { + gpa.free(other_file_ast.source); + other_file_ast.deinit(gpa); + } + + var inlined_fixups: Ast.Fixups = .{}; + defer inlined_fixups.deinit(gpa); + if (std.fs.path.dirname(inline_imported_file.imported_string)) |dirname| { + inlined_fixups.rebase_imported_paths = dirname; + } + for (inline_imported_file.in_scope_names.keys()) |name| { + // This name needs to be mangled in order to not cause an + // ambiguous reference error. + var i: u32 = 2; + const mangled = while (true) : (i += 1) { + const mangled = try std.fmt.allocPrint(gpa, "{s}{d}", .{ name, i }); + if (!inline_imported_file.in_scope_names.contains(mangled)) + break mangled; + gpa.free(mangled); + }; + try inlined_fixups.rename_identifiers.put(gpa, name, mangled); + } + defer { + for (inlined_fixups.rename_identifiers.values()) |v| { + gpa.free(v); + } + } + + var other_source = std.ArrayList(u8).init(gpa); + defer other_source.deinit(); + try other_source.appendSlice("struct {\n"); + try other_file_ast.renderToArrayList(&other_source, inlined_fixups); + try other_source.appendSlice("}"); + + try fixups.replace_nodes_with_string.put( + gpa, + inline_imported_file.builtin_call_node, + try arena.dupe(u8, other_source.items), + ); + }, + }; +} + +fn parse(gpa: Allocator, file_path: []const u8) !Ast { + const source_code = std.fs.cwd().readFileAllocOptions( + gpa, + file_path, + std.math.maxInt(u32), + null, + 1, + 0, + ) catch |err| { + fatal("unable to open '{s}': {s}", .{ file_path, @errorName(err) }); + }; + errdefer gpa.free(source_code); + + var tree = try Ast.parse(gpa, source_code, .zig); + errdefer tree.deinit(gpa); + + if (tree.errors.len != 0) { + @panic("syntax errors occurred"); + } + + return tree; +} + +fn fatal(comptime format: []const u8, args: anytype) noreturn { + std.log.err(format, args); + std.process.exit(1); +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/reduce/Walk.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/reduce/Walk.zig new file mode 100644 index 00000000..c1cabebd --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/reduce/Walk.zig @@ -0,0 +1,1098 @@ +const std = @import("std"); +const Ast = std.zig.Ast; +const Walk = @This(); +const assert = std.debug.assert; +const BuiltinFn = std.zig.BuiltinFn; + +ast: *const Ast, +transformations: *std.ArrayList(Transformation), +unreferenced_globals: std.StringArrayHashMapUnmanaged(Ast.Node.Index), +in_scope_names: std.StringArrayHashMapUnmanaged(u32), +replace_names: std.StringArrayHashMapUnmanaged(u32), +gpa: std.mem.Allocator, +arena: std.mem.Allocator, + +pub const Transformation = union(enum) { + /// Replace the fn decl AST Node with one whose body is only `@trap()` with + /// discarded parameters. + gut_function: Ast.Node.Index, + /// Omit a global declaration. + delete_node: Ast.Node.Index, + /// Delete a local variable declaration and replace all of its references + /// with `undefined`. + delete_var_decl: struct { + var_decl_node: Ast.Node.Index, + /// Identifier nodes that reference the variable. + references: std.ArrayListUnmanaged(Ast.Node.Index), + }, + /// Replace an expression with `undefined`. + replace_with_undef: Ast.Node.Index, + /// Replace an expression with `true`. + replace_with_true: Ast.Node.Index, + /// Replace an expression with `false`. + replace_with_false: Ast.Node.Index, + /// Replace a node with another node. + replace_node: struct { + to_replace: Ast.Node.Index, + replacement: Ast.Node.Index, + }, + /// Replace an `@import` with the imported file contents wrapped in a struct. + inline_imported_file: InlineImportedFile, + + pub const InlineImportedFile = struct { + builtin_call_node: Ast.Node.Index, + imported_string: []const u8, + /// Identifier names that must be renamed in the inlined code or else + /// will cause ambiguous reference errors. + in_scope_names: std.StringArrayHashMapUnmanaged(void), + }; +}; + +pub const Error = error{OutOfMemory}; + +/// The result will be priority shuffled. +pub fn findTransformations( + arena: std.mem.Allocator, + ast: *const Ast, + transformations: *std.ArrayList(Transformation), +) !void { + transformations.clearRetainingCapacity(); + + var walk: Walk = .{ + .ast = ast, + .transformations = transformations, + .gpa = transformations.allocator, + .arena = arena, + .unreferenced_globals = .{}, + .in_scope_names = .{}, + .replace_names = .{}, + }; + defer { + walk.unreferenced_globals.deinit(walk.gpa); + walk.in_scope_names.deinit(walk.gpa); + walk.replace_names.deinit(walk.gpa); + } + + try walkMembers(&walk, walk.ast.rootDecls()); + + const unreferenced_globals = walk.unreferenced_globals.values(); + try transformations.ensureUnusedCapacity(unreferenced_globals.len); + for (unreferenced_globals) |node| { + transformations.appendAssumeCapacity(.{ .delete_node = node }); + } +} + +fn walkMembers(w: *Walk, members: []const Ast.Node.Index) Error!void { + // First we scan for globals so that we can delete them while walking. + try scanDecls(w, members, .add); + + for (members) |member| { + try walkMember(w, member); + } + + try scanDecls(w, members, .remove); +} + +const ScanDeclsAction = enum { add, remove }; + +fn scanDecls(w: *Walk, members: []const Ast.Node.Index, action: ScanDeclsAction) Error!void { + const ast = w.ast; + const gpa = w.gpa; + const node_tags = ast.nodes.items(.tag); + const main_tokens = ast.nodes.items(.main_token); + const token_tags = ast.tokens.items(.tag); + + for (members) |member_node| { + const name_token = switch (node_tags[member_node]) { + .global_var_decl, + .local_var_decl, + .simple_var_decl, + .aligned_var_decl, + => main_tokens[member_node] + 1, + + .fn_proto_simple, + .fn_proto_multi, + .fn_proto_one, + .fn_proto, + .fn_decl, + => main_tokens[member_node] + 1, + + else => continue, + }; + + assert(token_tags[name_token] == .identifier); + const name_bytes = ast.tokenSlice(name_token); + + switch (action) { + .add => { + try w.unreferenced_globals.put(gpa, name_bytes, member_node); + + const gop = try w.in_scope_names.getOrPut(gpa, name_bytes); + if (!gop.found_existing) gop.value_ptr.* = 0; + gop.value_ptr.* += 1; + }, + .remove => { + const entry = w.in_scope_names.getEntry(name_bytes).?; + if (entry.value_ptr.* <= 1) { + assert(w.in_scope_names.swapRemove(name_bytes)); + } else { + entry.value_ptr.* -= 1; + } + }, + } + } +} + +fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { + const ast = w.ast; + const datas = ast.nodes.items(.data); + switch (ast.nodes.items(.tag)[decl]) { + .fn_decl => { + const fn_proto = datas[decl].lhs; + try walkExpression(w, fn_proto); + const body_node = datas[decl].rhs; + if (!isFnBodyGutted(ast, body_node)) { + w.replace_names.clearRetainingCapacity(); + try w.transformations.append(.{ .gut_function = decl }); + try walkExpression(w, body_node); + } + }, + .fn_proto_simple, + .fn_proto_multi, + .fn_proto_one, + .fn_proto, + => { + try walkExpression(w, decl); + }, + + .@"usingnamespace" => { + try w.transformations.append(.{ .delete_node = decl }); + const expr = datas[decl].lhs; + try walkExpression(w, expr); + }, + + .global_var_decl, + .local_var_decl, + .simple_var_decl, + .aligned_var_decl, + => try walkGlobalVarDecl(w, decl, ast.fullVarDecl(decl).?), + + .test_decl => { + try w.transformations.append(.{ .delete_node = decl }); + try walkExpression(w, datas[decl].rhs); + }, + + .container_field_init, + .container_field_align, + .container_field, + => { + try w.transformations.append(.{ .delete_node = decl }); + try walkContainerField(w, ast.fullContainerField(decl).?); + }, + + .@"comptime" => { + try w.transformations.append(.{ .delete_node = decl }); + try walkExpression(w, decl); + }, + + .root => unreachable, + else => unreachable, + } +} + +fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { + const ast = w.ast; + const token_tags = ast.tokens.items(.tag); + const main_tokens = ast.nodes.items(.main_token); + const node_tags = ast.nodes.items(.tag); + const datas = ast.nodes.items(.data); + switch (node_tags[node]) { + .identifier => { + const name_ident = main_tokens[node]; + assert(token_tags[name_ident] == .identifier); + const name_bytes = ast.tokenSlice(name_ident); + _ = w.unreferenced_globals.swapRemove(name_bytes); + if (w.replace_names.get(name_bytes)) |index| { + try w.transformations.items[index].delete_var_decl.references.append(w.arena, node); + } + }, + + .number_literal, + .char_literal, + .unreachable_literal, + .anyframe_literal, + .string_literal, + => {}, + + .multiline_string_literal => {}, + + .error_value => {}, + + .block_two, + .block_two_semicolon, + => { + const statements = [2]Ast.Node.Index{ datas[node].lhs, datas[node].rhs }; + if (datas[node].lhs == 0) { + return walkBlock(w, node, statements[0..0]); + } else if (datas[node].rhs == 0) { + return walkBlock(w, node, statements[0..1]); + } else { + return walkBlock(w, node, statements[0..2]); + } + }, + .block, + .block_semicolon, + => { + const statements = ast.extra_data[datas[node].lhs..datas[node].rhs]; + return walkBlock(w, node, statements); + }, + + .@"errdefer" => { + const expr = datas[node].rhs; + return walkExpression(w, expr); + }, + + .@"defer" => { + const expr = datas[node].rhs; + return walkExpression(w, expr); + }, + .@"comptime", .@"nosuspend" => { + const block = datas[node].lhs; + return walkExpression(w, block); + }, + + .@"suspend" => { + const body = datas[node].lhs; + return walkExpression(w, body); + }, + + .@"catch" => { + try walkExpression(w, datas[node].lhs); // target + try walkExpression(w, datas[node].rhs); // fallback + }, + + .field_access => { + const field_access = datas[node]; + try walkExpression(w, field_access.lhs); + }, + + .error_union, + .switch_range, + => { + const infix = datas[node]; + try walkExpression(w, infix.lhs); + return walkExpression(w, infix.rhs); + }, + .for_range => { + const infix = datas[node]; + try walkExpression(w, infix.lhs); + if (infix.rhs != 0) { + return walkExpression(w, infix.rhs); + } + }, + + .add, + .add_wrap, + .add_sat, + .array_cat, + .array_mult, + .assign, + .assign_bit_and, + .assign_bit_or, + .assign_shl, + .assign_shl_sat, + .assign_shr, + .assign_bit_xor, + .assign_div, + .assign_sub, + .assign_sub_wrap, + .assign_sub_sat, + .assign_mod, + .assign_add, + .assign_add_wrap, + .assign_add_sat, + .assign_mul, + .assign_mul_wrap, + .assign_mul_sat, + .bang_equal, + .bit_and, + .bit_or, + .shl, + .shl_sat, + .shr, + .bit_xor, + .bool_and, + .bool_or, + .div, + .equal_equal, + .greater_or_equal, + .greater_than, + .less_or_equal, + .less_than, + .merge_error_sets, + .mod, + .mul, + .mul_wrap, + .mul_sat, + .sub, + .sub_wrap, + .sub_sat, + .@"orelse", + => { + const infix = datas[node]; + try walkExpression(w, infix.lhs); + try walkExpression(w, infix.rhs); + }, + + .assign_destructure => { + const full = ast.assignDestructure(node); + for (full.ast.variables) |variable_node| { + switch (node_tags[variable_node]) { + .global_var_decl, + .local_var_decl, + .simple_var_decl, + .aligned_var_decl, + => try walkLocalVarDecl(w, ast.fullVarDecl(variable_node).?), + + else => try walkExpression(w, variable_node), + } + } + return walkExpression(w, full.ast.value_expr); + }, + + .bit_not, + .bool_not, + .negation, + .negation_wrap, + .optional_type, + .address_of, + => { + return walkExpression(w, datas[node].lhs); + }, + + .@"try", + .@"resume", + .@"await", + => { + return walkExpression(w, datas[node].lhs); + }, + + .array_type, + .array_type_sentinel, + => {}, + + .ptr_type_aligned, + .ptr_type_sentinel, + .ptr_type, + .ptr_type_bit_range, + => {}, + + .array_init_one, + .array_init_one_comma, + .array_init_dot_two, + .array_init_dot_two_comma, + .array_init_dot, + .array_init_dot_comma, + .array_init, + .array_init_comma, + => { + var elements: [2]Ast.Node.Index = undefined; + return walkArrayInit(w, ast.fullArrayInit(&elements, node).?); + }, + + .struct_init_one, + .struct_init_one_comma, + .struct_init_dot_two, + .struct_init_dot_two_comma, + .struct_init_dot, + .struct_init_dot_comma, + .struct_init, + .struct_init_comma, + => { + var buf: [2]Ast.Node.Index = undefined; + return walkStructInit(w, node, ast.fullStructInit(&buf, node).?); + }, + + .call_one, + .call_one_comma, + .async_call_one, + .async_call_one_comma, + .call, + .call_comma, + .async_call, + .async_call_comma, + => { + var buf: [1]Ast.Node.Index = undefined; + return walkCall(w, ast.fullCall(&buf, node).?); + }, + + .array_access => { + const suffix = datas[node]; + try walkExpression(w, suffix.lhs); + try walkExpression(w, suffix.rhs); + }, + + .slice_open, .slice, .slice_sentinel => return walkSlice(w, node, ast.fullSlice(node).?), + + .deref => { + try walkExpression(w, datas[node].lhs); + }, + + .unwrap_optional => { + try walkExpression(w, datas[node].lhs); + }, + + .@"break" => { + const label_token = datas[node].lhs; + const target = datas[node].rhs; + if (label_token == 0 and target == 0) { + // no expressions + } else if (label_token == 0 and target != 0) { + try walkExpression(w, target); + } else if (label_token != 0 and target == 0) { + try walkIdentifier(w, label_token); + } else if (label_token != 0 and target != 0) { + try walkExpression(w, target); + } + }, + + .@"continue" => { + const label = datas[node].lhs; + if (label != 0) { + return walkIdentifier(w, label); // label + } + }, + + .@"return" => { + if (datas[node].lhs != 0) { + try walkExpression(w, datas[node].lhs); + } + }, + + .grouped_expression => { + try walkExpression(w, datas[node].lhs); + }, + + .container_decl, + .container_decl_trailing, + .container_decl_arg, + .container_decl_arg_trailing, + .container_decl_two, + .container_decl_two_trailing, + .tagged_union, + .tagged_union_trailing, + .tagged_union_enum_tag, + .tagged_union_enum_tag_trailing, + .tagged_union_two, + .tagged_union_two_trailing, + => { + var buf: [2]Ast.Node.Index = undefined; + return walkContainerDecl(w, node, ast.fullContainerDecl(&buf, node).?); + }, + + .error_set_decl => { + const error_token = main_tokens[node]; + const lbrace = error_token + 1; + const rbrace = datas[node].rhs; + + var i = lbrace + 1; + while (i < rbrace) : (i += 1) { + switch (token_tags[i]) { + .doc_comment => unreachable, // TODO + .identifier => try walkIdentifier(w, i), + .comma => {}, + else => unreachable, + } + } + }, + + .builtin_call_two, .builtin_call_two_comma => { + if (datas[node].lhs == 0) { + return walkBuiltinCall(w, node, &.{}); + } else if (datas[node].rhs == 0) { + return walkBuiltinCall(w, node, &.{datas[node].lhs}); + } else { + return walkBuiltinCall(w, node, &.{ datas[node].lhs, datas[node].rhs }); + } + }, + .builtin_call, .builtin_call_comma => { + const params = ast.extra_data[datas[node].lhs..datas[node].rhs]; + return walkBuiltinCall(w, node, params); + }, + + .fn_proto_simple, + .fn_proto_multi, + .fn_proto_one, + .fn_proto, + => { + var buf: [1]Ast.Node.Index = undefined; + return walkFnProto(w, ast.fullFnProto(&buf, node).?); + }, + + .anyframe_type => { + if (datas[node].rhs != 0) { + return walkExpression(w, datas[node].rhs); + } + }, + + .@"switch", + .switch_comma, + => { + const condition = datas[node].lhs; + const extra = ast.extraData(datas[node].rhs, Ast.Node.SubRange); + const cases = ast.extra_data[extra.start..extra.end]; + + try walkExpression(w, condition); // condition expression + try walkExpressions(w, cases); + }, + + .switch_case_one, + .switch_case_inline_one, + .switch_case, + .switch_case_inline, + => return walkSwitchCase(w, ast.fullSwitchCase(node).?), + + .while_simple, + .while_cont, + .@"while", + => return walkWhile(w, node, ast.fullWhile(node).?), + + .for_simple, + .@"for", + => return walkFor(w, ast.fullFor(node).?), + + .if_simple, + .@"if", + => return walkIf(w, node, ast.fullIf(node).?), + + .asm_simple, + .@"asm", + => return walkAsm(w, ast.fullAsm(node).?), + + .enum_literal => { + return walkIdentifier(w, main_tokens[node]); // name + }, + + .fn_decl => unreachable, + .container_field => unreachable, + .container_field_init => unreachable, + .container_field_align => unreachable, + .root => unreachable, + .global_var_decl => unreachable, + .local_var_decl => unreachable, + .simple_var_decl => unreachable, + .aligned_var_decl => unreachable, + .@"usingnamespace" => unreachable, + .test_decl => unreachable, + .asm_output => unreachable, + .asm_input => unreachable, + } +} + +fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.VarDecl) Error!void { + _ = decl_node; + + if (var_decl.ast.type_node != 0) { + try walkExpression(w, var_decl.ast.type_node); + } + + if (var_decl.ast.align_node != 0) { + try walkExpression(w, var_decl.ast.align_node); + } + + if (var_decl.ast.addrspace_node != 0) { + try walkExpression(w, var_decl.ast.addrspace_node); + } + + if (var_decl.ast.section_node != 0) { + try walkExpression(w, var_decl.ast.section_node); + } + + if (var_decl.ast.init_node != 0) { + if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { + try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); + } + try walkExpression(w, var_decl.ast.init_node); + } +} + +fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { + try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name + + if (var_decl.ast.type_node != 0) { + try walkExpression(w, var_decl.ast.type_node); + } + + if (var_decl.ast.align_node != 0) { + try walkExpression(w, var_decl.ast.align_node); + } + + if (var_decl.ast.addrspace_node != 0) { + try walkExpression(w, var_decl.ast.addrspace_node); + } + + if (var_decl.ast.section_node != 0) { + try walkExpression(w, var_decl.ast.section_node); + } + + if (var_decl.ast.init_node != 0) { + if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { + try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); + } + try walkExpression(w, var_decl.ast.init_node); + } +} + +fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { + if (field.ast.type_expr != 0) { + try walkExpression(w, field.ast.type_expr); // type + } + if (field.ast.align_expr != 0) { + try walkExpression(w, field.ast.align_expr); // alignment + } + if (field.ast.value_expr != 0) { + try walkExpression(w, field.ast.value_expr); // value + } +} + +fn walkBlock( + w: *Walk, + block_node: Ast.Node.Index, + statements: []const Ast.Node.Index, +) Error!void { + _ = block_node; + const ast = w.ast; + const node_tags = ast.nodes.items(.tag); + + for (statements) |stmt| { + switch (node_tags[stmt]) { + .global_var_decl, + .local_var_decl, + .simple_var_decl, + .aligned_var_decl, + => { + const var_decl = ast.fullVarDecl(stmt).?; + if (var_decl.ast.init_node != 0 and + isUndefinedIdent(w.ast, var_decl.ast.init_node)) + { + try w.transformations.append(.{ .delete_var_decl = .{ + .var_decl_node = stmt, + .references = .{}, + } }); + const name_tok = var_decl.ast.mut_token + 1; + const name_bytes = ast.tokenSlice(name_tok); + try w.replace_names.put(w.gpa, name_bytes, @intCast(w.transformations.items.len - 1)); + } else { + try walkLocalVarDecl(w, var_decl); + } + }, + + else => { + switch (categorizeStmt(ast, stmt)) { + // Don't try to remove `_ = foo;` discards; those are handled separately. + .discard_identifier => {}, + // definitely try to remove `_ = undefined;` though. + .discard_undefined, .trap_call, .other => { + try w.transformations.append(.{ .delete_node = stmt }); + }, + } + try walkExpression(w, stmt); + }, + } + } +} + +fn walkArrayType(w: *Walk, array_type: Ast.full.ArrayType) Error!void { + try walkExpression(w, array_type.ast.elem_count); + if (array_type.ast.sentinel != 0) { + try walkExpression(w, array_type.ast.sentinel); + } + return walkExpression(w, array_type.ast.elem_type); +} + +fn walkArrayInit(w: *Walk, array_init: Ast.full.ArrayInit) Error!void { + if (array_init.ast.type_expr != 0) { + try walkExpression(w, array_init.ast.type_expr); // T + } + for (array_init.ast.elements) |elem_init| { + try walkExpression(w, elem_init); + } +} + +fn walkStructInit( + w: *Walk, + struct_node: Ast.Node.Index, + struct_init: Ast.full.StructInit, +) Error!void { + _ = struct_node; + if (struct_init.ast.type_expr != 0) { + try walkExpression(w, struct_init.ast.type_expr); // T + } + for (struct_init.ast.fields) |field_init| { + try walkExpression(w, field_init); + } +} + +fn walkCall(w: *Walk, call: Ast.full.Call) Error!void { + try walkExpression(w, call.ast.fn_expr); + try walkParamList(w, call.ast.params); +} + +fn walkSlice( + w: *Walk, + slice_node: Ast.Node.Index, + slice: Ast.full.Slice, +) Error!void { + _ = slice_node; + try walkExpression(w, slice.ast.sliced); + try walkExpression(w, slice.ast.start); + if (slice.ast.end != 0) { + try walkExpression(w, slice.ast.end); + } + if (slice.ast.sentinel != 0) { + try walkExpression(w, slice.ast.sentinel); + } +} + +fn walkIdentifier(w: *Walk, name_ident: Ast.TokenIndex) Error!void { + const ast = w.ast; + const token_tags = ast.tokens.items(.tag); + assert(token_tags[name_ident] == .identifier); + const name_bytes = ast.tokenSlice(name_ident); + _ = w.unreferenced_globals.swapRemove(name_bytes); +} + +fn walkIdentifierNew(w: *Walk, name_ident: Ast.TokenIndex) Error!void { + _ = w; + _ = name_ident; +} + +fn walkContainerDecl( + w: *Walk, + container_decl_node: Ast.Node.Index, + container_decl: Ast.full.ContainerDecl, +) Error!void { + _ = container_decl_node; + if (container_decl.ast.arg != 0) { + try walkExpression(w, container_decl.ast.arg); + } + try walkMembers(w, container_decl.ast.members); +} + +fn walkBuiltinCall( + w: *Walk, + call_node: Ast.Node.Index, + params: []const Ast.Node.Index, +) Error!void { + const ast = w.ast; + const main_tokens = ast.nodes.items(.main_token); + const builtin_token = main_tokens[call_node]; + const builtin_name = ast.tokenSlice(builtin_token); + const info = BuiltinFn.list.get(builtin_name).?; + switch (info.tag) { + .import => { + const operand_node = params[0]; + const str_lit_token = main_tokens[operand_node]; + const token_bytes = ast.tokenSlice(str_lit_token); + if (std.mem.endsWith(u8, token_bytes, ".zig\"")) { + const imported_string = std.zig.string_literal.parseAlloc(w.arena, token_bytes) catch + unreachable; + try w.transformations.append(.{ .inline_imported_file = .{ + .builtin_call_node = call_node, + .imported_string = imported_string, + .in_scope_names = try std.StringArrayHashMapUnmanaged(void).init( + w.arena, + w.in_scope_names.keys(), + &.{}, + ), + } }); + } + }, + else => {}, + } + for (params) |param_node| { + try walkExpression(w, param_node); + } +} + +fn walkFnProto(w: *Walk, fn_proto: Ast.full.FnProto) Error!void { + const ast = w.ast; + + { + var it = fn_proto.iterate(ast); + while (it.next()) |param| { + if (param.type_expr != 0) { + try walkExpression(w, param.type_expr); + } + } + } + + if (fn_proto.ast.align_expr != 0) { + try walkExpression(w, fn_proto.ast.align_expr); + } + + if (fn_proto.ast.addrspace_expr != 0) { + try walkExpression(w, fn_proto.ast.addrspace_expr); + } + + if (fn_proto.ast.section_expr != 0) { + try walkExpression(w, fn_proto.ast.section_expr); + } + + if (fn_proto.ast.callconv_expr != 0) { + try walkExpression(w, fn_proto.ast.callconv_expr); + } + + try walkExpression(w, fn_proto.ast.return_type); +} + +fn walkExpressions(w: *Walk, expressions: []const Ast.Node.Index) Error!void { + for (expressions) |expression| { + try walkExpression(w, expression); + } +} + +fn walkSwitchCase(w: *Walk, switch_case: Ast.full.SwitchCase) Error!void { + for (switch_case.ast.values) |value_expr| { + try walkExpression(w, value_expr); + } + try walkExpression(w, switch_case.ast.target_expr); +} + +fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) Error!void { + assert(while_node.ast.cond_expr != 0); + assert(while_node.ast.then_expr != 0); + + // Perform these transformations in this priority order: + // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. + // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. + // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. + // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. + if (!isTrueIdent(w.ast, while_node.ast.cond_expr) and + (while_node.ast.else_expr == 0 or isEmptyBlock(w.ast, while_node.ast.else_expr))) + { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_with_true = while_node.ast.cond_expr }); + } else if (!isFalseIdent(w.ast, while_node.ast.cond_expr) and isEmptyBlock(w.ast, while_node.ast.then_expr)) { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_with_false = while_node.ast.cond_expr }); + } else if (isTrueIdent(w.ast, while_node.ast.cond_expr)) { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_node = .{ + .to_replace = node_index, + .replacement = while_node.ast.then_expr, + } }); + } else if (isFalseIdent(w.ast, while_node.ast.cond_expr)) { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_node = .{ + .to_replace = node_index, + .replacement = while_node.ast.else_expr, + } }); + } + + try walkExpression(w, while_node.ast.cond_expr); // condition + + if (while_node.ast.cont_expr != 0) { + try walkExpression(w, while_node.ast.cont_expr); + } + + if (while_node.ast.then_expr != 0) { + try walkExpression(w, while_node.ast.then_expr); + } + if (while_node.ast.else_expr != 0) { + try walkExpression(w, while_node.ast.else_expr); + } +} + +fn walkFor(w: *Walk, for_node: Ast.full.For) Error!void { + try walkParamList(w, for_node.ast.inputs); + if (for_node.ast.then_expr != 0) { + try walkExpression(w, for_node.ast.then_expr); + } + if (for_node.ast.else_expr != 0) { + try walkExpression(w, for_node.ast.else_expr); + } +} + +fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void { + assert(if_node.ast.cond_expr != 0); + assert(if_node.ast.then_expr != 0); + + // Perform these transformations in this priority order: + // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. + // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. + // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. + // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. + if (!isTrueIdent(w.ast, if_node.ast.cond_expr) and + (if_node.ast.else_expr == 0 or isEmptyBlock(w.ast, if_node.ast.else_expr))) + { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_with_true = if_node.ast.cond_expr }); + } else if (!isFalseIdent(w.ast, if_node.ast.cond_expr) and isEmptyBlock(w.ast, if_node.ast.then_expr)) { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_with_false = if_node.ast.cond_expr }); + } else if (isTrueIdent(w.ast, if_node.ast.cond_expr)) { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_node = .{ + .to_replace = node_index, + .replacement = if_node.ast.then_expr, + } }); + } else if (isFalseIdent(w.ast, if_node.ast.cond_expr)) { + try w.transformations.ensureUnusedCapacity(1); + w.transformations.appendAssumeCapacity(.{ .replace_node = .{ + .to_replace = node_index, + .replacement = if_node.ast.else_expr, + } }); + } + + try walkExpression(w, if_node.ast.cond_expr); // condition + + if (if_node.ast.then_expr != 0) { + try walkExpression(w, if_node.ast.then_expr); + } + if (if_node.ast.else_expr != 0) { + try walkExpression(w, if_node.ast.else_expr); + } +} + +fn walkAsm(w: *Walk, asm_node: Ast.full.Asm) Error!void { + try walkExpression(w, asm_node.ast.template); + for (asm_node.ast.items) |item| { + try walkExpression(w, item); + } +} + +fn walkParamList(w: *Walk, params: []const Ast.Node.Index) Error!void { + for (params) |param_node| { + try walkExpression(w, param_node); + } +} + +/// Check if it is already gutted (i.e. its body replaced with `@trap()`). +fn isFnBodyGutted(ast: *const Ast, body_node: Ast.Node.Index) bool { + // skip over discards + const node_tags = ast.nodes.items(.tag); + const datas = ast.nodes.items(.data); + var statements_buf: [2]Ast.Node.Index = undefined; + const statements = switch (node_tags[body_node]) { + .block_two, + .block_two_semicolon, + => blk: { + statements_buf[0..2].* = .{ datas[body_node].lhs, datas[body_node].rhs }; + break :blk if (datas[body_node].lhs == 0) + statements_buf[0..0] + else if (datas[body_node].rhs == 0) + statements_buf[0..1] + else + statements_buf[0..2]; + }, + + .block, + .block_semicolon, + => ast.extra_data[datas[body_node].lhs..datas[body_node].rhs], + + else => return false, + }; + var i: usize = 0; + while (i < statements.len) : (i += 1) { + switch (categorizeStmt(ast, statements[i])) { + .discard_identifier => continue, + .trap_call => return i + 1 == statements.len, + else => return false, + } + } + return false; +} + +const StmtCategory = enum { + discard_undefined, + discard_identifier, + trap_call, + other, +}; + +fn categorizeStmt(ast: *const Ast, stmt: Ast.Node.Index) StmtCategory { + const node_tags = ast.nodes.items(.tag); + const datas = ast.nodes.items(.data); + const main_tokens = ast.nodes.items(.main_token); + switch (node_tags[stmt]) { + .builtin_call_two, .builtin_call_two_comma => { + if (datas[stmt].lhs == 0) { + return categorizeBuiltinCall(ast, main_tokens[stmt], &.{}); + } else if (datas[stmt].rhs == 0) { + return categorizeBuiltinCall(ast, main_tokens[stmt], &.{datas[stmt].lhs}); + } else { + return categorizeBuiltinCall(ast, main_tokens[stmt], &.{ datas[stmt].lhs, datas[stmt].rhs }); + } + }, + .builtin_call, .builtin_call_comma => { + const params = ast.extra_data[datas[stmt].lhs..datas[stmt].rhs]; + return categorizeBuiltinCall(ast, main_tokens[stmt], params); + }, + .assign => { + const infix = datas[stmt]; + if (isDiscardIdent(ast, infix.lhs) and node_tags[infix.rhs] == .identifier) { + const name_bytes = ast.tokenSlice(main_tokens[infix.rhs]); + if (std.mem.eql(u8, name_bytes, "undefined")) { + return .discard_undefined; + } else { + return .discard_identifier; + } + } + return .other; + }, + else => return .other, + } +} + +fn categorizeBuiltinCall( + ast: *const Ast, + builtin_token: Ast.TokenIndex, + params: []const Ast.Node.Index, +) StmtCategory { + if (params.len != 0) return .other; + const name_bytes = ast.tokenSlice(builtin_token); + if (std.mem.eql(u8, name_bytes, "@trap")) + return .trap_call; + return .other; +} + +fn isDiscardIdent(ast: *const Ast, node: Ast.Node.Index) bool { + return isMatchingIdent(ast, node, "_"); +} + +fn isUndefinedIdent(ast: *const Ast, node: Ast.Node.Index) bool { + return isMatchingIdent(ast, node, "undefined"); +} + +fn isTrueIdent(ast: *const Ast, node: Ast.Node.Index) bool { + return isMatchingIdent(ast, node, "true"); +} + +fn isFalseIdent(ast: *const Ast, node: Ast.Node.Index) bool { + return isMatchingIdent(ast, node, "false"); +} + +fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bool { + const node_tags = ast.nodes.items(.tag); + const main_tokens = ast.nodes.items(.main_token); + switch (node_tags[node]) { + .identifier => { + const token_index = main_tokens[node]; + const name_bytes = ast.tokenSlice(token_index); + return std.mem.eql(u8, name_bytes, string); + }, + else => return false, + } +} + +fn isEmptyBlock(ast: *const Ast, node: Ast.Node.Index) bool { + const node_tags = ast.nodes.items(.tag); + const node_data = ast.nodes.items(.data); + switch (node_tags[node]) { + .block_two => { + return node_data[node].lhs == 0 and node_data[node].rhs == 0; + }, + else => return false, + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/ani.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/ani.zig new file mode 100644 index 00000000..77035135 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/ani.zig @@ -0,0 +1,58 @@ +//! https://en.wikipedia.org/wiki/Resource_Interchange_File_Format +//! https://www.moon-soft.com/program/format/windows/ani.htm +//! https://www.gdgsoft.com/anituner/help/aniformat.htm +//! https://www.lomont.org/software/aniexploit/ExploitANI.pdf +//! +//! RIFF( 'ACON' +//! [LIST( 'INFO' )] +//! [] +//! anih( ) +//! [rate( )] +//! ['seq '( )] +//! LIST( 'fram' icon( ) ... ) +//! ) + +const std = @import("std"); + +const AF_ICON: u32 = 1; + +pub fn isAnimatedIcon(reader: anytype) bool { + const flags = getAniheaderFlags(reader) catch return false; + return flags & AF_ICON == AF_ICON; +} + +fn getAniheaderFlags(reader: anytype) !u32 { + const riff_header = try reader.readBytesNoEof(4); + if (!std.mem.eql(u8, &riff_header, "RIFF")) return error.InvalidFormat; + + _ = try reader.readInt(u32, .little); // size of RIFF chunk + + const form_type = try reader.readBytesNoEof(4); + if (!std.mem.eql(u8, &form_type, "ACON")) return error.InvalidFormat; + + while (true) { + const chunk_id = try reader.readBytesNoEof(4); + const chunk_len = try reader.readInt(u32, .little); + if (!std.mem.eql(u8, &chunk_id, "anih")) { + // TODO: Move file cursor instead of skipBytes + try reader.skipBytes(chunk_len, .{}); + continue; + } + + const aniheader = try reader.readStruct(ANIHEADER); + return std.mem.nativeToLittle(u32, aniheader.flags); + } +} + +/// From Microsoft Multimedia Data Standards Update April 15, 1994 +const ANIHEADER = extern struct { + cbSizeof: u32, + cFrames: u32, + cSteps: u32, + cx: u32, + cy: u32, + cBitCount: u32, + cPlanes: u32, + jifRate: u32, + flags: u32, +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/ast.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/ast.zig new file mode 100644 index 00000000..20eedb65 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/ast.zig @@ -0,0 +1,1081 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const Token = @import("lex.zig").Token; +const SupportedCodePage = @import("code_pages.zig").SupportedCodePage; + +pub const Tree = struct { + node: *Node, + input_code_pages: CodePageLookup, + output_code_pages: CodePageLookup, + + /// not owned by the tree + source: []const u8, + + arena: std.heap.ArenaAllocator.State, + allocator: Allocator, + + pub fn deinit(self: *Tree) void { + self.arena.promote(self.allocator).deinit(); + } + + pub fn root(self: *Tree) *Node.Root { + return @alignCast(@fieldParentPtr("base", self.node)); + } + + pub fn dump(self: *Tree, writer: anytype) @TypeOf(writer).Error!void { + try self.node.dump(self, writer, 0); + } +}; + +pub const CodePageLookup = struct { + lookup: std.ArrayListUnmanaged(SupportedCodePage) = .empty, + allocator: Allocator, + default_code_page: SupportedCodePage, + + pub fn init(allocator: Allocator, default_code_page: SupportedCodePage) CodePageLookup { + return .{ + .allocator = allocator, + .default_code_page = default_code_page, + }; + } + + pub fn deinit(self: *CodePageLookup) void { + self.lookup.deinit(self.allocator); + } + + /// line_num is 1-indexed + pub fn setForLineNum(self: *CodePageLookup, line_num: usize, code_page: SupportedCodePage) !void { + const index = line_num - 1; + if (index >= self.lookup.items.len) { + const new_size = line_num; + const missing_lines_start_index = self.lookup.items.len; + try self.lookup.resize(self.allocator, new_size); + + // If there are any gaps created, we need to fill them in with the value of the + // last line before the gap. This can happen for e.g. string literals that + // span multiple lines, or if the start of a file has multiple empty lines. + const fill_value = if (missing_lines_start_index > 0) + self.lookup.items[missing_lines_start_index - 1] + else + self.default_code_page; + var i: usize = missing_lines_start_index; + while (i < new_size - 1) : (i += 1) { + self.lookup.items[i] = fill_value; + } + } + self.lookup.items[index] = code_page; + } + + pub fn setForToken(self: *CodePageLookup, token: Token, code_page: SupportedCodePage) !void { + return self.setForLineNum(token.line_number, code_page); + } + + /// line_num is 1-indexed + pub fn getForLineNum(self: CodePageLookup, line_num: usize) SupportedCodePage { + return self.lookup.items[line_num - 1]; + } + + pub fn getForToken(self: CodePageLookup, token: Token) SupportedCodePage { + return self.getForLineNum(token.line_number); + } +}; + +test "CodePageLookup" { + var lookup = CodePageLookup.init(std.testing.allocator, .windows1252); + defer lookup.deinit(); + + try lookup.setForLineNum(5, .utf8); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(1)); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(2)); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(3)); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(4)); + try std.testing.expectEqual(SupportedCodePage.utf8, lookup.getForLineNum(5)); + try std.testing.expectEqual(@as(usize, 5), lookup.lookup.items.len); + + try lookup.setForLineNum(7, .windows1252); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(1)); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(2)); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(3)); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(4)); + try std.testing.expectEqual(SupportedCodePage.utf8, lookup.getForLineNum(5)); + try std.testing.expectEqual(SupportedCodePage.utf8, lookup.getForLineNum(6)); + try std.testing.expectEqual(SupportedCodePage.windows1252, lookup.getForLineNum(7)); + try std.testing.expectEqual(@as(usize, 7), lookup.lookup.items.len); +} + +pub const Node = struct { + id: Id, + + pub const Id = enum { + root, + resource_external, + resource_raw_data, + literal, + binary_expression, + grouped_expression, + not_expression, + accelerators, + accelerator, + dialog, + control_statement, + toolbar, + menu, + menu_item, + menu_item_separator, + menu_item_ex, + popup, + popup_ex, + version_info, + version_statement, + block, + block_value, + block_value_value, + string_table, + string_table_string, + language_statement, + font_statement, + simple_statement, + invalid, + + pub fn Type(comptime id: Id) type { + return switch (id) { + .root => Root, + .resource_external => ResourceExternal, + .resource_raw_data => ResourceRawData, + .literal => Literal, + .binary_expression => BinaryExpression, + .grouped_expression => GroupedExpression, + .not_expression => NotExpression, + .accelerators => Accelerators, + .accelerator => Accelerator, + .dialog => Dialog, + .control_statement => ControlStatement, + .toolbar => Toolbar, + .menu => Menu, + .menu_item => MenuItem, + .menu_item_separator => MenuItemSeparator, + .menu_item_ex => MenuItemEx, + .popup => Popup, + .popup_ex => PopupEx, + .version_info => VersionInfo, + .version_statement => VersionStatement, + .block => Block, + .block_value => BlockValue, + .block_value_value => BlockValueValue, + .string_table => StringTable, + .string_table_string => StringTableString, + .language_statement => LanguageStatement, + .font_statement => FontStatement, + .simple_statement => SimpleStatement, + .invalid => Invalid, + }; + } + }; + + pub fn cast(base: *Node, comptime id: Id) ?*id.Type() { + if (base.id == id) { + return @alignCast(@fieldParentPtr("base", base)); + } + return null; + } + + pub const Root = struct { + base: Node = .{ .id = .root }, + body: []*Node, + }; + + pub const ResourceExternal = struct { + base: Node = .{ .id = .resource_external }, + id: Token, + type: Token, + common_resource_attributes: []Token, + filename: *Node, + }; + + pub const ResourceRawData = struct { + base: Node = .{ .id = .resource_raw_data }, + id: Token, + type: Token, + common_resource_attributes: []Token, + begin_token: Token, + raw_data: []*Node, + end_token: Token, + }; + + pub const Literal = struct { + base: Node = .{ .id = .literal }, + token: Token, + }; + + pub const BinaryExpression = struct { + base: Node = .{ .id = .binary_expression }, + operator: Token, + left: *Node, + right: *Node, + }; + + pub const GroupedExpression = struct { + base: Node = .{ .id = .grouped_expression }, + open_token: Token, + expression: *Node, + close_token: Token, + }; + + pub const NotExpression = struct { + base: Node = .{ .id = .not_expression }, + not_token: Token, + number_token: Token, + }; + + pub const Accelerators = struct { + base: Node = .{ .id = .accelerators }, + id: Token, + type: Token, + common_resource_attributes: []Token, + optional_statements: []*Node, + begin_token: Token, + accelerators: []*Node, + end_token: Token, + }; + + pub const Accelerator = struct { + base: Node = .{ .id = .accelerator }, + event: *Node, + idvalue: *Node, + type_and_options: []Token, + }; + + pub const Dialog = struct { + base: Node = .{ .id = .dialog }, + id: Token, + type: Token, + common_resource_attributes: []Token, + x: *Node, + y: *Node, + width: *Node, + height: *Node, + help_id: ?*Node, + optional_statements: []*Node, + begin_token: Token, + controls: []*Node, + end_token: Token, + }; + + pub const ControlStatement = struct { + base: Node = .{ .id = .control_statement }, + type: Token, + text: ?Token, + /// Only relevant for the user-defined CONTROL control + class: ?*Node, + id: *Node, + x: *Node, + y: *Node, + width: *Node, + height: *Node, + style: ?*Node, + exstyle: ?*Node, + help_id: ?*Node, + extra_data_begin: ?Token, + extra_data: []*Node, + extra_data_end: ?Token, + + /// Returns true if this node describes a user-defined CONTROL control + /// https://learn.microsoft.com/en-us/windows/win32/menurc/control-control + pub fn isUserDefined(self: *const ControlStatement) bool { + return self.class != null; + } + }; + + pub const Toolbar = struct { + base: Node = .{ .id = .toolbar }, + id: Token, + type: Token, + common_resource_attributes: []Token, + button_width: *Node, + button_height: *Node, + begin_token: Token, + /// Will contain Literal and SimpleStatement nodes + buttons: []*Node, + end_token: Token, + }; + + pub const Menu = struct { + base: Node = .{ .id = .menu }, + id: Token, + type: Token, + common_resource_attributes: []Token, + optional_statements: []*Node, + /// `help_id` will never be non-null if `type` is MENU + help_id: ?*Node, + begin_token: Token, + items: []*Node, + end_token: Token, + }; + + pub const MenuItem = struct { + base: Node = .{ .id = .menu_item }, + menuitem: Token, + text: Token, + result: *Node, + option_list: []Token, + }; + + pub const MenuItemSeparator = struct { + base: Node = .{ .id = .menu_item_separator }, + menuitem: Token, + separator: Token, + }; + + pub const MenuItemEx = struct { + base: Node = .{ .id = .menu_item_ex }, + menuitem: Token, + text: Token, + id: ?*Node, + type: ?*Node, + state: ?*Node, + }; + + pub const Popup = struct { + base: Node = .{ .id = .popup }, + popup: Token, + text: Token, + option_list: []Token, + begin_token: Token, + items: []*Node, + end_token: Token, + }; + + pub const PopupEx = struct { + base: Node = .{ .id = .popup_ex }, + popup: Token, + text: Token, + id: ?*Node, + type: ?*Node, + state: ?*Node, + help_id: ?*Node, + begin_token: Token, + items: []*Node, + end_token: Token, + }; + + pub const VersionInfo = struct { + base: Node = .{ .id = .version_info }, + id: Token, + versioninfo: Token, + common_resource_attributes: []Token, + /// Will contain VersionStatement and/or SimpleStatement nodes + fixed_info: []*Node, + begin_token: Token, + block_statements: []*Node, + end_token: Token, + }; + + /// Used for FILEVERSION and PRODUCTVERSION statements + pub const VersionStatement = struct { + base: Node = .{ .id = .version_statement }, + type: Token, + /// Between 1-4 parts + parts: []*Node, + }; + + pub const Block = struct { + base: Node = .{ .id = .block }, + /// The BLOCK token itself + identifier: Token, + key: Token, + /// This is undocumented but BLOCK statements support values after + /// the key just like VALUE statements. + values: []*Node, + begin_token: Token, + children: []*Node, + end_token: Token, + }; + + pub const BlockValue = struct { + base: Node = .{ .id = .block_value }, + /// The VALUE token itself + identifier: Token, + key: Token, + /// These will be BlockValueValue nodes + values: []*Node, + }; + + pub const BlockValueValue = struct { + base: Node = .{ .id = .block_value_value }, + expression: *Node, + /// Whether or not the value has a trailing comma is relevant + trailing_comma: bool, + }; + + pub const StringTable = struct { + base: Node = .{ .id = .string_table }, + type: Token, + common_resource_attributes: []Token, + optional_statements: []*Node, + begin_token: Token, + strings: []*Node, + end_token: Token, + }; + + pub const StringTableString = struct { + base: Node = .{ .id = .string_table_string }, + id: *Node, + maybe_comma: ?Token, + string: Token, + }; + + pub const LanguageStatement = struct { + base: Node = .{ .id = .language_statement }, + /// The LANGUAGE token itself + language_token: Token, + primary_language_id: *Node, + sublanguage_id: *Node, + }; + + pub const FontStatement = struct { + base: Node = .{ .id = .font_statement }, + /// The FONT token itself + identifier: Token, + point_size: *Node, + typeface: Token, + weight: ?*Node, + italic: ?*Node, + char_set: ?*Node, + }; + + /// A statement with one value associated with it. + /// Used for CAPTION, CHARACTERISTICS, CLASS, EXSTYLE, MENU, STYLE, VERSION, + /// as well as VERSIONINFO-specific statements FILEFLAGSMASK, FILEFLAGS, FILEOS, + /// FILETYPE, FILESUBTYPE + pub const SimpleStatement = struct { + base: Node = .{ .id = .simple_statement }, + identifier: Token, + value: *Node, + }; + + pub const Invalid = struct { + base: Node = .{ .id = .invalid }, + context: []Token, + }; + + pub fn isNumberExpression(node: *const Node) bool { + switch (node.id) { + .literal => { + const literal: *const Node.Literal = @alignCast(@fieldParentPtr("base", node)); + return switch (literal.token.id) { + .number => true, + else => false, + }; + }, + .binary_expression, .grouped_expression, .not_expression => return true, + else => return false, + } + } + + pub fn isStringLiteral(node: *const Node) bool { + switch (node.id) { + .literal => { + const literal: *const Node.Literal = @alignCast(@fieldParentPtr("base", node)); + return switch (literal.token.id) { + .quoted_ascii_string, .quoted_wide_string => true, + else => false, + }; + }, + else => return false, + } + } + + pub fn getFirstToken(node: *const Node) Token { + switch (node.id) { + .root => unreachable, + .resource_external => { + const casted: *const Node.ResourceExternal = @alignCast(@fieldParentPtr("base", node)); + return casted.id; + }, + .resource_raw_data => { + const casted: *const Node.ResourceRawData = @alignCast(@fieldParentPtr("base", node)); + return casted.id; + }, + .literal => { + const casted: *const Node.Literal = @alignCast(@fieldParentPtr("base", node)); + return casted.token; + }, + .binary_expression => { + const casted: *const Node.BinaryExpression = @alignCast(@fieldParentPtr("base", node)); + return casted.left.getFirstToken(); + }, + .grouped_expression => { + const casted: *const Node.GroupedExpression = @alignCast(@fieldParentPtr("base", node)); + return casted.open_token; + }, + .not_expression => { + const casted: *const Node.NotExpression = @alignCast(@fieldParentPtr("base", node)); + return casted.not_token; + }, + .accelerators => { + const casted: *const Node.Accelerators = @alignCast(@fieldParentPtr("base", node)); + return casted.id; + }, + .accelerator => { + const casted: *const Node.Accelerator = @alignCast(@fieldParentPtr("base", node)); + return casted.event.getFirstToken(); + }, + .dialog => { + const casted: *const Node.Dialog = @alignCast(@fieldParentPtr("base", node)); + return casted.id; + }, + .control_statement => { + const casted: *const Node.ControlStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.type; + }, + .toolbar => { + const casted: *const Node.Toolbar = @alignCast(@fieldParentPtr("base", node)); + return casted.id; + }, + .menu => { + const casted: *const Node.Menu = @alignCast(@fieldParentPtr("base", node)); + return casted.id; + }, + inline .menu_item, .menu_item_separator, .menu_item_ex => |menu_item_type| { + const casted: *const menu_item_type.Type() = @alignCast(@fieldParentPtr("base", node)); + return casted.menuitem; + }, + inline .popup, .popup_ex => |popup_type| { + const casted: *const popup_type.Type() = @alignCast(@fieldParentPtr("base", node)); + return casted.popup; + }, + .version_info => { + const casted: *const Node.VersionInfo = @alignCast(@fieldParentPtr("base", node)); + return casted.id; + }, + .version_statement => { + const casted: *const Node.VersionStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.type; + }, + .block => { + const casted: *const Node.Block = @alignCast(@fieldParentPtr("base", node)); + return casted.identifier; + }, + .block_value => { + const casted: *const Node.BlockValue = @alignCast(@fieldParentPtr("base", node)); + return casted.identifier; + }, + .block_value_value => { + const casted: *const Node.BlockValueValue = @alignCast(@fieldParentPtr("base", node)); + return casted.expression.getFirstToken(); + }, + .string_table => { + const casted: *const Node.StringTable = @alignCast(@fieldParentPtr("base", node)); + return casted.type; + }, + .string_table_string => { + const casted: *const Node.StringTableString = @alignCast(@fieldParentPtr("base", node)); + return casted.id.getFirstToken(); + }, + .language_statement => { + const casted: *const Node.LanguageStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.language_token; + }, + .font_statement => { + const casted: *const Node.FontStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.identifier; + }, + .simple_statement => { + const casted: *const Node.SimpleStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.identifier; + }, + .invalid => { + const casted: *const Node.Invalid = @alignCast(@fieldParentPtr("base", node)); + return casted.context[0]; + }, + } + } + + pub fn getLastToken(node: *const Node) Token { + switch (node.id) { + .root => unreachable, + .resource_external => { + const casted: *const Node.ResourceExternal = @alignCast(@fieldParentPtr("base", node)); + return casted.filename.getLastToken(); + }, + .resource_raw_data => { + const casted: *const Node.ResourceRawData = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .literal => { + const casted: *const Node.Literal = @alignCast(@fieldParentPtr("base", node)); + return casted.token; + }, + .binary_expression => { + const casted: *const Node.BinaryExpression = @alignCast(@fieldParentPtr("base", node)); + return casted.right.getLastToken(); + }, + .grouped_expression => { + const casted: *const Node.GroupedExpression = @alignCast(@fieldParentPtr("base", node)); + return casted.close_token; + }, + .not_expression => { + const casted: *const Node.NotExpression = @alignCast(@fieldParentPtr("base", node)); + return casted.number_token; + }, + .accelerators => { + const casted: *const Node.Accelerators = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .accelerator => { + const casted: *const Node.Accelerator = @alignCast(@fieldParentPtr("base", node)); + if (casted.type_and_options.len > 0) return casted.type_and_options[casted.type_and_options.len - 1]; + return casted.idvalue.getLastToken(); + }, + .dialog => { + const casted: *const Node.Dialog = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .control_statement => { + const casted: *const Node.ControlStatement = @alignCast(@fieldParentPtr("base", node)); + if (casted.extra_data_end) |token| return token; + if (casted.help_id) |help_id_node| return help_id_node.getLastToken(); + if (casted.exstyle) |exstyle_node| return exstyle_node.getLastToken(); + // For user-defined CONTROL controls, the style comes before 'x', but + // otherwise it comes after 'height' so it could be the last token if + // it's present. + if (!casted.isUserDefined()) { + if (casted.style) |style_node| return style_node.getLastToken(); + } + return casted.height.getLastToken(); + }, + .toolbar => { + const casted: *const Node.Toolbar = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .menu => { + const casted: *const Node.Menu = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .menu_item => { + const casted: *const Node.MenuItem = @alignCast(@fieldParentPtr("base", node)); + if (casted.option_list.len > 0) return casted.option_list[casted.option_list.len - 1]; + return casted.result.getLastToken(); + }, + .menu_item_separator => { + const casted: *const Node.MenuItemSeparator = @alignCast(@fieldParentPtr("base", node)); + return casted.separator; + }, + .menu_item_ex => { + const casted: *const Node.MenuItemEx = @alignCast(@fieldParentPtr("base", node)); + if (casted.state) |state_node| return state_node.getLastToken(); + if (casted.type) |type_node| return type_node.getLastToken(); + if (casted.id) |id_node| return id_node.getLastToken(); + return casted.text; + }, + inline .popup, .popup_ex => |popup_type| { + const casted: *const popup_type.Type() = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .version_info => { + const casted: *const Node.VersionInfo = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .version_statement => { + const casted: *const Node.VersionStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.parts[casted.parts.len - 1].getLastToken(); + }, + .block => { + const casted: *const Node.Block = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .block_value => { + const casted: *const Node.BlockValue = @alignCast(@fieldParentPtr("base", node)); + if (casted.values.len > 0) return casted.values[casted.values.len - 1].getLastToken(); + return casted.key; + }, + .block_value_value => { + const casted: *const Node.BlockValueValue = @alignCast(@fieldParentPtr("base", node)); + return casted.expression.getLastToken(); + }, + .string_table => { + const casted: *const Node.StringTable = @alignCast(@fieldParentPtr("base", node)); + return casted.end_token; + }, + .string_table_string => { + const casted: *const Node.StringTableString = @alignCast(@fieldParentPtr("base", node)); + return casted.string; + }, + .language_statement => { + const casted: *const Node.LanguageStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.sublanguage_id.getLastToken(); + }, + .font_statement => { + const casted: *const Node.FontStatement = @alignCast(@fieldParentPtr("base", node)); + if (casted.char_set) |char_set_node| return char_set_node.getLastToken(); + if (casted.italic) |italic_node| return italic_node.getLastToken(); + if (casted.weight) |weight_node| return weight_node.getLastToken(); + return casted.typeface; + }, + .simple_statement => { + const casted: *const Node.SimpleStatement = @alignCast(@fieldParentPtr("base", node)); + return casted.value.getLastToken(); + }, + .invalid => { + const casted: *const Node.Invalid = @alignCast(@fieldParentPtr("base", node)); + return casted.context[casted.context.len - 1]; + }, + } + } + + pub fn dump( + node: *const Node, + tree: *const Tree, + writer: anytype, + indent: usize, + ) @TypeOf(writer).Error!void { + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(@tagName(node.id)); + switch (node.id) { + .root => { + try writer.writeAll("\n"); + const root: *const Node.Root = @alignCast(@fieldParentPtr("base", node)); + for (root.body) |body_node| { + try body_node.dump(tree, writer, indent + 1); + } + }, + .resource_external => { + const resource: *const Node.ResourceExternal = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} common_resource_attributes]\n", .{ resource.id.slice(tree.source), resource.type.slice(tree.source), resource.common_resource_attributes.len }); + try resource.filename.dump(tree, writer, indent + 1); + }, + .resource_raw_data => { + const resource: *const Node.ResourceRawData = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} common_resource_attributes] raw data: {}\n", .{ resource.id.slice(tree.source), resource.type.slice(tree.source), resource.common_resource_attributes.len, resource.raw_data.len }); + for (resource.raw_data) |data_expression| { + try data_expression.dump(tree, writer, indent + 1); + } + }, + .literal => { + const literal: *const Node.Literal = @alignCast(@fieldParentPtr("base", node)); + try writer.writeAll(" "); + try writer.writeAll(literal.token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .binary_expression => { + const binary: *const Node.BinaryExpression = @alignCast(@fieldParentPtr("base", node)); + try writer.writeAll(" "); + try writer.writeAll(binary.operator.slice(tree.source)); + try writer.writeAll("\n"); + try binary.left.dump(tree, writer, indent + 1); + try binary.right.dump(tree, writer, indent + 1); + }, + .grouped_expression => { + const grouped: *const Node.GroupedExpression = @alignCast(@fieldParentPtr("base", node)); + try writer.writeAll("\n"); + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(grouped.open_token.slice(tree.source)); + try writer.writeAll("\n"); + try grouped.expression.dump(tree, writer, indent + 1); + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(grouped.close_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .not_expression => { + const not: *const Node.NotExpression = @alignCast(@fieldParentPtr("base", node)); + try writer.writeAll(" "); + try writer.writeAll(not.not_token.slice(tree.source)); + try writer.writeAll(" "); + try writer.writeAll(not.number_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .accelerators => { + const accelerators: *const Node.Accelerators = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} common_resource_attributes]\n", .{ accelerators.id.slice(tree.source), accelerators.type.slice(tree.source), accelerators.common_resource_attributes.len }); + for (accelerators.optional_statements) |statement| { + try statement.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(accelerators.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (accelerators.accelerators) |accelerator| { + try accelerator.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(accelerators.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .accelerator => { + const accelerator: *const Node.Accelerator = @alignCast(@fieldParentPtr("base", node)); + for (accelerator.type_and_options, 0..) |option, i| { + if (i != 0) try writer.writeAll(","); + try writer.writeByte(' '); + try writer.writeAll(option.slice(tree.source)); + } + try writer.writeAll("\n"); + try accelerator.event.dump(tree, writer, indent + 1); + try accelerator.idvalue.dump(tree, writer, indent + 1); + }, + .dialog => { + const dialog: *const Node.Dialog = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} common_resource_attributes]\n", .{ dialog.id.slice(tree.source), dialog.type.slice(tree.source), dialog.common_resource_attributes.len }); + inline for (.{ "x", "y", "width", "height" }) |arg| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll(arg ++ ":\n"); + try @field(dialog, arg).dump(tree, writer, indent + 2); + } + if (dialog.help_id) |help_id| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll("help_id:\n"); + try help_id.dump(tree, writer, indent + 2); + } + for (dialog.optional_statements) |statement| { + try statement.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(dialog.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (dialog.controls) |control| { + try control.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(dialog.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .control_statement => { + const control: *const Node.ControlStatement = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s}", .{control.type.slice(tree.source)}); + if (control.text) |text| { + try writer.print(" text: {s}", .{text.slice(tree.source)}); + } + try writer.writeByte('\n'); + if (control.class) |class| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll("class:\n"); + try class.dump(tree, writer, indent + 2); + } + inline for (.{ "id", "x", "y", "width", "height" }) |arg| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll(arg ++ ":\n"); + try @field(control, arg).dump(tree, writer, indent + 2); + } + inline for (.{ "style", "exstyle", "help_id" }) |arg| { + if (@field(control, arg)) |val_node| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll(arg ++ ":\n"); + try val_node.dump(tree, writer, indent + 2); + } + } + if (control.extra_data_begin != null) { + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(control.extra_data_begin.?.slice(tree.source)); + try writer.writeAll("\n"); + for (control.extra_data) |data_node| { + try data_node.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(control.extra_data_end.?.slice(tree.source)); + try writer.writeAll("\n"); + } + }, + .toolbar => { + const toolbar: *const Node.Toolbar = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} common_resource_attributes]\n", .{ toolbar.id.slice(tree.source), toolbar.type.slice(tree.source), toolbar.common_resource_attributes.len }); + inline for (.{ "button_width", "button_height" }) |arg| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll(arg ++ ":\n"); + try @field(toolbar, arg).dump(tree, writer, indent + 2); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(toolbar.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (toolbar.buttons) |button_or_sep| { + try button_or_sep.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(toolbar.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .menu => { + const menu: *const Node.Menu = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} common_resource_attributes]\n", .{ menu.id.slice(tree.source), menu.type.slice(tree.source), menu.common_resource_attributes.len }); + for (menu.optional_statements) |statement| { + try statement.dump(tree, writer, indent + 1); + } + if (menu.help_id) |help_id| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll("help_id:\n"); + try help_id.dump(tree, writer, indent + 2); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(menu.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (menu.items) |item| { + try item.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(menu.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .menu_item => { + const menu_item: *const Node.MenuItem = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} options]\n", .{ menu_item.menuitem.slice(tree.source), menu_item.text.slice(tree.source), menu_item.option_list.len }); + try menu_item.result.dump(tree, writer, indent + 1); + }, + .menu_item_separator => { + const menu_item: *const Node.MenuItemSeparator = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s}\n", .{ menu_item.menuitem.slice(tree.source), menu_item.separator.slice(tree.source) }); + }, + .menu_item_ex => { + const menu_item: *const Node.MenuItemEx = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s}\n", .{ menu_item.menuitem.slice(tree.source), menu_item.text.slice(tree.source) }); + inline for (.{ "id", "type", "state" }) |arg| { + if (@field(menu_item, arg)) |val_node| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll(arg ++ ":\n"); + try val_node.dump(tree, writer, indent + 2); + } + } + }, + .popup => { + const popup: *const Node.Popup = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} options]\n", .{ popup.popup.slice(tree.source), popup.text.slice(tree.source), popup.option_list.len }); + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(popup.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (popup.items) |item| { + try item.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(popup.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .popup_ex => { + const popup: *const Node.PopupEx = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s}\n", .{ popup.popup.slice(tree.source), popup.text.slice(tree.source) }); + inline for (.{ "id", "type", "state", "help_id" }) |arg| { + if (@field(popup, arg)) |val_node| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll(arg ++ ":\n"); + try val_node.dump(tree, writer, indent + 2); + } + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(popup.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (popup.items) |item| { + try item.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(popup.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .version_info => { + const version_info: *const Node.VersionInfo = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s} [{d} common_resource_attributes]\n", .{ version_info.id.slice(tree.source), version_info.versioninfo.slice(tree.source), version_info.common_resource_attributes.len }); + for (version_info.fixed_info) |fixed_info| { + try fixed_info.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(version_info.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (version_info.block_statements) |block| { + try block.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(version_info.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .version_statement => { + const version_statement: *const Node.VersionStatement = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s}\n", .{version_statement.type.slice(tree.source)}); + for (version_statement.parts) |part| { + try part.dump(tree, writer, indent + 1); + } + }, + .block => { + const block: *const Node.Block = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s}\n", .{ block.identifier.slice(tree.source), block.key.slice(tree.source) }); + for (block.values) |value| { + try value.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(block.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (block.children) |child| { + try child.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(block.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .block_value => { + const block_value: *const Node.BlockValue = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} {s}\n", .{ block_value.identifier.slice(tree.source), block_value.key.slice(tree.source) }); + for (block_value.values) |value| { + try value.dump(tree, writer, indent + 1); + } + }, + .block_value_value => { + const block_value: *const Node.BlockValueValue = @alignCast(@fieldParentPtr("base", node)); + if (block_value.trailing_comma) { + try writer.writeAll(" ,"); + } + try writer.writeAll("\n"); + try block_value.expression.dump(tree, writer, indent + 1); + }, + .string_table => { + const string_table: *const Node.StringTable = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} [{d} common_resource_attributes]\n", .{ string_table.type.slice(tree.source), string_table.common_resource_attributes.len }); + for (string_table.optional_statements) |statement| { + try statement.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(string_table.begin_token.slice(tree.source)); + try writer.writeAll("\n"); + for (string_table.strings) |string| { + try string.dump(tree, writer, indent + 1); + } + try writer.writeByteNTimes(' ', indent); + try writer.writeAll(string_table.end_token.slice(tree.source)); + try writer.writeAll("\n"); + }, + .string_table_string => { + try writer.writeAll("\n"); + const string: *const Node.StringTableString = @alignCast(@fieldParentPtr("base", node)); + try string.id.dump(tree, writer, indent + 1); + try writer.writeByteNTimes(' ', indent + 1); + try writer.print("{s}\n", .{string.string.slice(tree.source)}); + }, + .language_statement => { + const language: *const Node.LanguageStatement = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s}\n", .{language.language_token.slice(tree.source)}); + try language.primary_language_id.dump(tree, writer, indent + 1); + try language.sublanguage_id.dump(tree, writer, indent + 1); + }, + .font_statement => { + const font: *const Node.FontStatement = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s} typeface: {s}\n", .{ font.identifier.slice(tree.source), font.typeface.slice(tree.source) }); + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll("point_size:\n"); + try font.point_size.dump(tree, writer, indent + 2); + inline for (.{ "weight", "italic", "char_set" }) |arg| { + if (@field(font, arg)) |arg_node| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.writeAll(arg ++ ":\n"); + try arg_node.dump(tree, writer, indent + 2); + } + } + }, + .simple_statement => { + const statement: *const Node.SimpleStatement = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" {s}\n", .{statement.identifier.slice(tree.source)}); + try statement.value.dump(tree, writer, indent + 1); + }, + .invalid => { + const invalid: *const Node.Invalid = @alignCast(@fieldParentPtr("base", node)); + try writer.print(" context.len: {}\n", .{invalid.context.len}); + for (invalid.context) |context_token| { + try writer.writeByteNTimes(' ', indent + 1); + try writer.print("{s}:{s}", .{ @tagName(context_token.id), context_token.slice(tree.source) }); + try writer.writeByte('\n'); + } + }, + } + } +}; diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/bmp.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/bmp.zig new file mode 100644 index 00000000..c9a0c29d --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/bmp.zig @@ -0,0 +1,277 @@ +//! https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader +//! https://learn.microsoft.com/en-us/previous-versions//dd183376(v=vs.85) +//! https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfo +//! https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapcoreheader +//! https://archive.org/details/mac_Graphics_File_Formats_Second_Edition_1996/page/n607/mode/2up +//! https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapv5header +//! +//! Notes: +//! - The Microsoft documentation is incredibly unclear about the color table when the +//! bit depth is >= 16. +//! + For bit depth 24 it says "the bmiColors member of BITMAPINFO is NULL" but also +//! says "the bmiColors color table is used for optimizing colors used on palette-based +//! devices, and must contain the number of entries specified by the bV5ClrUsed member" +//! + For bit depth 16 and 32, it seems to imply that if the compression is BI_BITFIELDS +//! or BI_ALPHABITFIELDS, then the color table *only* consists of the bit masks, but +//! doesn't really say this outright and the Wikipedia article seems to disagree +//! For the purposes of this implementation, color tables can always be present for any +//! bit depth and compression, and the color table follows the header + any optional +//! bit mask fields dictated by the specified compression. + +const std = @import("std"); +const BitmapHeader = @import("ico.zig").BitmapHeader; +const builtin = @import("builtin"); +const native_endian = builtin.cpu.arch.endian(); + +pub const windows_format_id = std.mem.readInt(u16, "BM", native_endian); +pub const file_header_len = 14; + +pub const ReadError = error{ + UnexpectedEOF, + InvalidFileHeader, + ImpossiblePixelDataOffset, + UnknownBitmapVersion, + InvalidBitsPerPixel, + TooManyColorsInPalette, + MissingBitfieldMasks, +}; + +pub const BitmapInfo = struct { + dib_header_size: u32, + /// Contains the interpreted number of colors in the palette (e.g. + /// if the field's value is zero and the bit depth is <= 8, this + /// will contain the maximum number of colors for the bit depth + /// rather than the field's value directly). + colors_in_palette: u32, + bytes_per_color_palette_element: u8, + pixel_data_offset: u32, + compression: Compression, + + pub fn getExpectedPaletteByteLen(self: *const BitmapInfo) u64 { + return @as(u64, self.colors_in_palette) * self.bytes_per_color_palette_element; + } + + pub fn getActualPaletteByteLen(self: *const BitmapInfo) u64 { + return self.getByteLenBetweenHeadersAndPixels() - self.getBitmasksByteLen(); + } + + pub fn getByteLenBetweenHeadersAndPixels(self: *const BitmapInfo) u64 { + return @as(u64, self.pixel_data_offset) - self.dib_header_size - file_header_len; + } + + pub fn getBitmasksByteLen(self: *const BitmapInfo) u8 { + // Only BITMAPINFOHEADER (3.1) has trailing bytes for the BITFIELDS + // The 2.0 format doesn't have a compression field and 4.0+ has dedicated + // fields for the masks in the header. + const dib_version = BitmapHeader.Version.get(self.dib_header_size); + return switch (dib_version) { + .@"nt3.1" => switch (self.compression) { + .BI_BITFIELDS => 12, + .BI_ALPHABITFIELDS => 16, + else => 0, + }, + else => 0, + }; + } + + pub fn getMissingPaletteByteLen(self: *const BitmapInfo) u64 { + if (self.getActualPaletteByteLen() >= self.getExpectedPaletteByteLen()) return 0; + return self.getExpectedPaletteByteLen() - self.getActualPaletteByteLen(); + } + + /// Returns the full byte len of the DIB header + optional bitmasks + color palette + pub fn getExpectedByteLenBeforePixelData(self: *const BitmapInfo) u64 { + return @as(u64, self.dib_header_size) + self.getBitmasksByteLen() + self.getExpectedPaletteByteLen(); + } + + /// Returns the full expected byte len + pub fn getExpectedByteLen(self: *const BitmapInfo, file_size: u64) u64 { + return self.getExpectedByteLenBeforePixelData() + self.getPixelDataLen(file_size); + } + + pub fn getPixelDataLen(self: *const BitmapInfo, file_size: u64) u64 { + return file_size - self.pixel_data_offset; + } +}; + +pub fn read(reader: anytype, max_size: u64) ReadError!BitmapInfo { + var bitmap_info: BitmapInfo = undefined; + const file_header = reader.readBytesNoEof(file_header_len) catch return error.UnexpectedEOF; + + const id = std.mem.readInt(u16, file_header[0..2], native_endian); + if (id != windows_format_id) return error.InvalidFileHeader; + + bitmap_info.pixel_data_offset = std.mem.readInt(u32, file_header[10..14], .little); + if (bitmap_info.pixel_data_offset > max_size) return error.ImpossiblePixelDataOffset; + + bitmap_info.dib_header_size = reader.readInt(u32, .little) catch return error.UnexpectedEOF; + if (bitmap_info.pixel_data_offset < file_header_len + bitmap_info.dib_header_size) return error.ImpossiblePixelDataOffset; + const dib_version = BitmapHeader.Version.get(bitmap_info.dib_header_size); + switch (dib_version) { + .@"nt3.1", .@"nt4.0", .@"nt5.0" => { + var dib_header_buf: [@sizeOf(BITMAPINFOHEADER)]u8 align(@alignOf(BITMAPINFOHEADER)) = undefined; + std.mem.writeInt(u32, dib_header_buf[0..4], bitmap_info.dib_header_size, .little); + reader.readNoEof(dib_header_buf[4..]) catch return error.UnexpectedEOF; + var dib_header: *BITMAPINFOHEADER = @ptrCast(&dib_header_buf); + structFieldsLittleToNative(BITMAPINFOHEADER, dib_header); + + bitmap_info.colors_in_palette = try dib_header.numColorsInTable(); + bitmap_info.bytes_per_color_palette_element = 4; + bitmap_info.compression = @enumFromInt(dib_header.biCompression); + + if (bitmap_info.getByteLenBetweenHeadersAndPixels() < bitmap_info.getBitmasksByteLen()) { + return error.MissingBitfieldMasks; + } + }, + .@"win2.0" => { + var dib_header_buf: [@sizeOf(BITMAPCOREHEADER)]u8 align(@alignOf(BITMAPCOREHEADER)) = undefined; + std.mem.writeInt(u32, dib_header_buf[0..4], bitmap_info.dib_header_size, .little); + reader.readNoEof(dib_header_buf[4..]) catch return error.UnexpectedEOF; + const dib_header: *BITMAPCOREHEADER = @ptrCast(&dib_header_buf); + structFieldsLittleToNative(BITMAPCOREHEADER, dib_header); + + // > The size of the color palette is calculated from the BitsPerPixel value. + // > The color palette has 2, 16, 256, or 0 entries for a BitsPerPixel of + // > 1, 4, 8, and 24, respectively. + bitmap_info.colors_in_palette = switch (dib_header.bcBitCount) { + inline 1, 4, 8 => |bit_count| 1 << bit_count, + 24 => 0, + else => return error.InvalidBitsPerPixel, + }; + bitmap_info.bytes_per_color_palette_element = 3; + + bitmap_info.compression = .BI_RGB; + }, + .unknown => return error.UnknownBitmapVersion, + } + + return bitmap_info; +} + +/// https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapcoreheader +pub const BITMAPCOREHEADER = extern struct { + bcSize: u32, + bcWidth: u16, + bcHeight: u16, + bcPlanes: u16, + bcBitCount: u16, +}; + +/// https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader +pub const BITMAPINFOHEADER = extern struct { + bcSize: u32, + biWidth: i32, + biHeight: i32, + biPlanes: u16, + biBitCount: u16, + biCompression: u32, + biSizeImage: u32, + biXPelsPerMeter: i32, + biYPelsPerMeter: i32, + biClrUsed: u32, + biClrImportant: u32, + + /// Returns error.TooManyColorsInPalette if the number of colors specified + /// exceeds the number of possible colors referenced in the pixel data (i.e. + /// if 1 bit is used per pixel, then the color table can't have more than 2 colors + /// since any more couldn't possibly be indexed in the pixel data) + /// + /// Returns error.InvalidBitsPerPixel if the bit depth is not 1, 4, 8, 16, 24, or 32. + pub fn numColorsInTable(self: BITMAPINFOHEADER) !u32 { + switch (self.biBitCount) { + inline 1, 4, 8 => |bit_count| switch (self.biClrUsed) { + // > If biClrUsed is zero, the array contains the maximum number of + // > colors for the given bitdepth; that is, 2^biBitCount colors + 0 => return 1 << bit_count, + // > If biClrUsed is nonzero and the biBitCount member is less than 16, + // > the biClrUsed member specifies the actual number of colors the + // > graphics engine or device driver accesses. + else => { + const max_colors = 1 << bit_count; + if (self.biClrUsed > max_colors) { + return error.TooManyColorsInPalette; + } + return self.biClrUsed; + }, + }, + // > If biBitCount is 16 or greater, the biClrUsed member specifies + // > the size of the color table used to optimize performance of the + // > system color palettes. + // + // Note: Bit depths >= 16 only use the color table 'for optimizing colors + // used on palette-based devices', but it still makes sense to limit their + // colors since the pixel data is still limited to this number of colors + // (i.e. even though the color table is not indexed by the pixel data, + // the color table having more colors than the pixel data can represent + // would never make sense and indicates a malformed bitmap). + inline 16, 24, 32 => |bit_count| { + const max_colors = 1 << bit_count; + if (self.biClrUsed > max_colors) { + return error.TooManyColorsInPalette; + } + return self.biClrUsed; + }, + else => return error.InvalidBitsPerPixel, + } + } +}; + +pub const Compression = enum(u32) { + BI_RGB = 0, + BI_RLE8 = 1, + BI_RLE4 = 2, + BI_BITFIELDS = 3, + BI_JPEG = 4, + BI_PNG = 5, + BI_ALPHABITFIELDS = 6, + BI_CMYK = 11, + BI_CMYKRLE8 = 12, + BI_CMYKRLE4 = 13, + _, +}; + +fn structFieldsLittleToNative(comptime T: type, x: *T) void { + inline for (@typeInfo(T).@"struct".fields) |field| { + @field(x, field.name) = std.mem.littleToNative(field.type, @field(x, field.name)); + } +} + +test "read" { + var bmp_data = "BM<\x00\x00\x00\x00\x00\x00\x006\x00\x00\x00(\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x10\x00\x00\x00\x00\x00\x06\x00\x00\x00\x12\x0b\x00\x00\x12\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x7f\x00\x00\x00\x00".*; + var fbs = std.io.fixedBufferStream(&bmp_data); + + { + const bitmap = try read(fbs.reader(), bmp_data.len); + try std.testing.expectEqual(@as(u32, BitmapHeader.Version.@"nt3.1".len()), bitmap.dib_header_size); + } + + { + fbs.reset(); + bmp_data[file_header_len] = 11; + try std.testing.expectError(error.UnknownBitmapVersion, read(fbs.reader(), bmp_data.len)); + + // restore + bmp_data[file_header_len] = BitmapHeader.Version.@"nt3.1".len(); + } + + { + fbs.reset(); + bmp_data[0] = 'b'; + try std.testing.expectError(error.InvalidFileHeader, read(fbs.reader(), bmp_data.len)); + + // restore + bmp_data[0] = 'B'; + } + + { + const cutoff_len = file_header_len + BitmapHeader.Version.@"nt3.1".len() - 1; + var dib_cutoff_fbs = std.io.fixedBufferStream(bmp_data[0..cutoff_len]); + try std.testing.expectError(error.UnexpectedEOF, read(dib_cutoff_fbs.reader(), bmp_data.len)); + } + + { + const cutoff_len = file_header_len - 1; + var bmp_cutoff_fbs = std.io.fixedBufferStream(bmp_data[0..cutoff_len]); + try std.testing.expectError(error.UnexpectedEOF, read(bmp_cutoff_fbs.reader(), bmp_data.len)); + } +} diff --git a/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/cli.zig b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/cli.zig new file mode 100644 index 00000000..ea867524 --- /dev/null +++ b/tools/zig-x86_64-windows-0.14.1/lib/compiler/resinator/cli.zig @@ -0,0 +1,2080 @@ +const std = @import("std"); +const code_pages = @import("code_pages.zig"); +const SupportedCodePage = code_pages.SupportedCodePage; +const lang = @import("lang.zig"); +const res = @import("res.zig"); +const Allocator = std.mem.Allocator; +const lex = @import("lex.zig"); +const cvtres = @import("cvtres.zig"); + +/// This is what /SL 100 will set the maximum string literal length to +pub const max_string_literal_length_100_percent = 8192; + +pub const usage_string_after_command_name = + \\ [options] [--] [] + \\ + \\The sequence -- can be used to signify when to stop parsing options. + \\This is necessary when the input path begins with a forward slash. + \\ + \\Supported option prefixes are /, -, and --, so e.g. /h, -h, and --h all work. + \\Drop-in compatible with the Microsoft Resource Compiler. + \\ + \\Supported Win32 RC Options: + \\ /?, /h Print this help and exit. + \\ /v Verbose (print progress messages). + \\ /d [=] Define a symbol (during preprocessing). + \\ /u Undefine a symbol (during preprocessing). + \\ /fo Specify output file path. + \\ /l Set default language using hexadecimal id (ex: 409). + \\ /ln Set default language using language name (ex: en-us). + \\ /i Add an include path. + \\ /x Ignore INCLUDE environment variable. + \\ /c Set default code page (ex: 65001). + \\ /w Warn on invalid code page in .rc (instead of error). + \\ /y Suppress warnings for duplicate control IDs. + \\ /n Null-terminate all strings in string tables. + \\ /sl Specify string literal length limit in percentage (1-100) + \\ where 100 corresponds to a limit of 8192. If the /sl + \\ option is not specified, the default limit is 4097. + \\ /p Only run the preprocessor and output a .rcpp file. + \\ + \\No-op Win32 RC Options: + \\ /nologo, /a, /r Options that are recognized but do nothing. + \\ + \\Unsupported Win32 RC Options: + \\ /fm, /q, /g, /gn, /g1, /g2 Unsupported MUI-related options. + \\ /?c, /hc, /t, /tp:, Unsupported LCX/LCE-related options. + \\ /tn, /tm, /tc, /tw, /te, + \\ /ti, /ta + \\ /z Unsupported font-substitution-related option. + \\ /s Unsupported HWB-related option. + \\ + \\Custom Options (resinator-specific): + \\ /:no-preprocess Do not run the preprocessor. + \\ /:debug Output the preprocessed .rc file and the parsed AST. + \\ /:auto-includes Set the automatic include path detection behavior. + \\ any (default) Use MSVC if available, fall back to MinGW + \\ msvc Use MSVC include paths (must be present on the system) + \\ gnu Use MinGW include paths + \\ none Do not use any autodetected include paths + \\ /:depfile Output a file containing a list of all the files that + \\ the .rc includes or otherwise depends on. + \\ /:depfile-fmt Output format of the depfile, if /:depfile is set. + \\ json (default) A top-level JSON array of paths + \\ /:input-format If not specified, the input format is inferred. + \\ rc (default if input format cannot be inferred) + \\ res Compiled .rc file, implies /:output-format coff + \\ rcpp Preprocessed .rc file, implies /:no-preprocess + \\ /:output-format If not specified, the output format is inferred. + \\ res (default if output format cannot be inferred) + \\ coff COFF object file (extension: .obj or .o) + \\ rcpp Preprocessed .rc file, implies /p + \\ /:target Set the target machine for COFF object files. + \\ Can be specified either as PE/COFF machine constant + \\ name (X64, ARM64, etc) or Zig/LLVM CPU name (x86_64, + \\ aarch64, etc). The default is X64 (aka x86_64). + \\ Also accepts a full Zig/LLVM triple, but everything + \\ except the architecture is ignored. + \\ + \\Note: For compatibility reasons, all custom options start with : + \\ +; + +pub fn writeUsage(writer: anytype, command_name: []const u8) !void { + try writer.writeAll("Usage: "); + try writer.writeAll(command_name); + try writer.writeAll(usage_string_after_command_name); +} + +pub const Diagnostics = struct { + errors: std.ArrayListUnmanaged(ErrorDetails) = .empty, + allocator: Allocator, + + pub const ErrorDetails = struct { + arg_index: usize, + arg_span: ArgSpan = .{}, + msg: std.ArrayListUnmanaged(u8) = .empty, + type: Type = .err, + print_args: bool = true, + + pub const Type = enum { err, warning, note }; + pub const ArgSpan = struct { + point_at_next_arg: bool = false, + name_offset: usize = 0, + prefix_len: usize = 0, + value_offset: usize = 0, + name_len: usize = 0, + }; + }; + + pub fn init(allocator: Allocator) Diagnostics { + return .{ + .allocator = allocator, + }; + } + + pub fn deinit(self: *Diagnostics) void { + for (self.errors.items) |*details| { + details.msg.deinit(self.allocator); + } + self.errors.deinit(self.allocator); + } + + pub fn append(self: *Diagnostics, error_details: ErrorDetails) !void { + try self.errors.append(self.allocator, error_details); + } + + pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8, config: std.io.tty.Config) void { + std.debug.lockStdErr(); + defer std.debug.unlockStdErr(); + const stderr = std.io.getStdErr().writer(); + self.renderToWriter(args, stderr, config) catch return; + } + + pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: anytype, config: std.io.tty.Config) !void { + for (self.errors.items) |err_details| { + try renderErrorMessage(writer, config, err_details, args); + } + } + + pub fn hasError(self: *const Diagnostics) bool { + for (self.errors.items) |err| { + if (err.type == .err) return true; + } + return false; + } +}; + +pub const Options = struct { + allocator: Allocator, + input_source: IoSource = .{ .filename = &[_]u8{} }, + output_source: IoSource = .{ .filename = &[_]u8{} }, + extra_include_paths: std.ArrayListUnmanaged([]const u8) = .empty, + ignore_include_env_var: bool = false, + preprocess: Preprocess = .yes, + default_language_id: ?u16 = null, + default_code_page: ?SupportedCodePage = null, + verbose: bool = false, + symbols: std.StringArrayHashMapUnmanaged(SymbolValue) = .empty, + null_terminate_string_table_strings: bool = false, + max_string_literal_codepoints: u15 = lex.default_max_string_literal_codepoints, + silent_duplicate_control_ids: bool = false, + warn_instead_of_error_on_invalid_code_page: bool = false, + debug: bool = false, + print_help_and_exit: bool = false, + auto_includes: AutoIncludes = .any, + depfile_path: ?[]const u8 = null, + depfile_fmt: DepfileFormat = .json, + input_format: InputFormat = .rc, + output_format: OutputFormat = .res, + coff_options: cvtres.CoffOptions = .{}, + + pub const IoSource = union(enum) { + stdio: std.fs.File, + filename: []const u8, + }; + pub const AutoIncludes = enum { any, msvc, gnu, none }; + pub const DepfileFormat = enum { json }; + pub const InputFormat = enum { rc, res, rcpp }; + pub const OutputFormat = enum { + res, + coff, + rcpp, + + pub fn extension(format: OutputFormat) []const u8 { + return switch (format) { + .rcpp => ".rcpp", + .coff => ".obj", + .res => ".res", + }; + } + }; + pub const Preprocess = enum { no, yes, only }; + pub const SymbolAction = enum { define, undefine }; + pub const SymbolValue = union(SymbolAction) { + define: []const u8, + undefine: void, + + pub fn deinit(self: SymbolValue, allocator: Allocator) void { + switch (self) { + .define => |value| allocator.free(value), + .undefine => {}, + } + } + }; + + /// Does not check that identifier contains only valid characters + pub fn define(self: *Options, identifier: []const u8, value: []const u8) !void { + if (self.symbols.getPtr(identifier)) |val_ptr| { + // If the symbol is undefined, then that always takes precedence so + // we shouldn't change anything. + if (val_ptr.* == .undefine) return; + // Otherwise, the new value takes precedence. + const duped_value = try self.allocator.dupe(u8, value); + errdefer self.allocator.free(duped_value); + val_ptr.deinit(self.allocator); + val_ptr.* = .{ .define = duped_value }; + return; + } + const duped_key = try self.allocator.dupe(u8, identifier); + errdefer self.allocator.free(duped_key); + const duped_value = try self.allocator.dupe(u8, value); + errdefer self.allocator.free(duped_value); + try self.symbols.put(self.allocator, duped_key, .{ .define = duped_value }); + } + + /// Does not check that identifier contains only valid characters + pub fn undefine(self: *Options, identifier: []const u8) !void { + if (self.symbols.getPtr(identifier)) |action| { + action.deinit(self.allocator); + action.* = .{ .undefine = {} }; + return; + } + const duped_key = try self.allocator.dupe(u8, identifier); + errdefer self.allocator.free(duped_key); + try self.symbols.put(self.allocator, duped_key, .{ .undefine = {} }); + } + + /// If the current input filename: + /// - does not have an extension, and + /// - does not exist in the cwd, and + /// - the input format is .rc + /// then this function will append `.rc` to the input filename + /// + /// Note: This behavior is different from the Win32 compiler. + /// It always appends .RC if the filename does not have + /// a `.` in it and it does not even try the verbatim name + /// in that scenario. + /// + /// The approach taken here is meant to give us a 'best of both + /// worlds' situation where we'll be compatible with most use-cases + /// of the .rc extension being omitted from the CLI args, but still + /// work fine if the file itself does not have an extension. + pub fn maybeAppendRC(options: *Options, cwd: std.fs.Dir) !void { + switch (options.input_source) { + .stdio => return, + .filename => {}, + } + if (options.input_format == .rc and std.fs.path.extension(options.input_source.filename).len == 0) { + cwd.access(options.input_source.filename, .{}) catch |err| switch (err) { + error.FileNotFound => { + var filename_bytes = try options.allocator.alloc(u8, options.input_source.filename.len + 3); + @memcpy(filename_bytes[0..options.input_source.filename.len], options.input_source.filename); + @memcpy(filename_bytes[filename_bytes.len - 3 ..], ".rc"); + options.allocator.free(options.input_source.filename); + options.input_source = .{ .filename = filename_bytes }; + }, + else => {}, + }; + } + } + + pub fn deinit(self: *Options) void { + for (self.extra_include_paths.items) |extra_include_path| { + self.allocator.free(extra_include_path); + } + self.extra_include_paths.deinit(self.allocator); + switch (self.input_source) { + .stdio => {}, + .filename => |filename| self.allocator.free(filename), + } + switch (self.output_source) { + .stdio => {}, + .filename => |filename| self.allocator.free(filename), + } + var symbol_it = self.symbols.iterator(); + while (symbol_it.next()) |entry| { + self.allocator.free(entry.key_ptr.*); + entry.value_ptr.deinit(self.allocator); + } + self.symbols.deinit(self.allocator); + if (self.depfile_path) |depfile_path| { + self.allocator.free(depfile_path); + } + if (self.coff_options.define_external_symbol) |symbol_name| { + self.allocator.free(symbol_name); + } + } + + pub fn dumpVerbose(self: *const Options, writer: anytype) !void { + const input_source_name = switch (self.input_source) { + .stdio => "", + .filename => |filename| filename, + }; + const output_source_name = switch (self.output_source) { + .stdio => "", + .filename => |filename| filename, + }; + try writer.print("Input filename: {s} (format={s})\n", .{ input_source_name, @tagName(self.input_format) }); + try writer.print("Output filename: {s} (format={s})\n", .{ output_source_name, @tagName(self.output_format) }); + if (self.output_format == .coff) { + try writer.print(" Target machine type for COFF: {s}\n", .{@tagName(self.coff_options.target)}); + } + + if (self.extra_include_paths.items.len > 0) { + try writer.writeAll(" Extra include paths:\n"); + for (self.extra_include_paths.items) |extra_include_path| { + try writer.print(" \"{s}\"\n", .{extra_include_path}); + } + } + if (self.ignore_include_env_var) { + try writer.writeAll(" The INCLUDE environment variable will be ignored\n"); + } + if (self.preprocess == .no) { + try writer.writeAll(" The preprocessor will not be invoked\n"); + } else if (self.preprocess == .only) { + try writer.writeAll(" Only the preprocessor will be invoked\n"); + } + if (self.symbols.count() > 0) { + try writer.writeAll(" Symbols:\n"); + var it = self.symbols.iterator(); + while (it.next()) |symbol| { + try writer.print(" {s} {s}", .{ switch (symbol.value_ptr.*) { + .define => "#define", + .undefine => "#undef", + }, symbol.key_ptr.* }); + if (symbol.value_ptr.* == .define) { + try writer.print(" {s}", .{symbol.value_ptr.define}); + } + try writer.writeAll("\n"); + } + } + if (self.null_terminate_string_table_strings) { + try writer.writeAll(" Strings in string tables will be null-terminated\n"); + } + if (self.max_string_literal_codepoints != lex.default_max_string_literal_codepoints) { + try writer.print(" Max string literal length: {}\n", .{self.max_string_literal_codepoints}); + } + if (self.silent_duplicate_control_ids) { + try writer.writeAll(" Duplicate control IDs will not emit warnings\n"); + } + if (self.silent_duplicate_control_ids) { + try writer.writeAll(" Invalid code page in .rc will produce a warning (instead of an error)\n"); + } + + const language_id = self.default_language_id orelse res.Language.default; + const language_name = language_name: { + if (std.meta.intToEnum(lang.LanguageId, language_id)) |lang_enum_val| { + break :language_name @tagName(lang_enum_val); + } else |_| {} + if (language_id == lang.LOCALE_CUSTOM_UNSPECIFIED) { + break :language_name "LOCALE_CUSTOM_UNSPECIFIED"; + } + break :language_name ""; + }; + try writer.print("Default language: {s} (id=0x{x})\n", .{ language_name, language_id }); + + const code_page = self.default_code_page orelse .windows1252; + try writer.print("Default codepage: {s} (id={})\n", .{ @tagName(code_page), @intFromEnum(code_page) }); + } +}; + +pub const Arg = struct { + prefix: enum { long, short, slash }, + name_offset: usize, + full: []const u8, + + pub fn fromString(str: []const u8) ?@This() { + if (std.mem.startsWith(u8, str, "--")) { + return .{ .prefix = .long, .name_offset = 2, .full = str }; + } else if (std.mem.startsWith(u8, str, "-")) { + return .{ .prefix = .short, .name_offset = 1, .full = str }; + } else if (std.mem.startsWith(u8, str, "/")) { + return .{ .prefix = .slash, .name_offset = 1, .full = str }; + } + return null; + } + + pub fn prefixSlice(self: Arg) []const u8 { + return self.full[0..(if (self.prefix == .long) 2 else 1)]; + } + + pub fn name(self: Arg) []const u8 { + return self.full[self.name_offset..]; + } + + pub fn optionWithoutPrefix(self: Arg, option_len: usize) []const u8 { + if (option_len == 0) return self.name(); + return self.name()[0..option_len]; + } + + pub fn missingSpan(self: Arg) Diagnostics.ErrorDetails.ArgSpan { + return .{ + .point_at_next_arg = true, + .value_offset = 0, + .name_offset = self.name_offset, + .prefix_len = self.prefixSlice().len, + }; + } + + pub fn optionAndAfterSpan(self: Arg) Diagnostics.ErrorDetails.ArgSpan { + return self.optionSpan(0); + } + + pub fn optionSpan(self: Arg, option_len: usize) Diagnostics.ErrorDetails.ArgSpan { + return .{ + .name_offset = self.name_offset, + .prefix_len = self.prefixSlice().len, + .name_len = option_len, + }; + } + + pub fn looksLikeFilepath(self: Arg) bool { + const meets_min_requirements = self.prefix == .slash and isSupportedInputExtension(std.fs.path.extension(self.full)); + if (!meets_min_requirements) return false; + + const could_be_fo_option = could_be_fo_option: { + var window_it = std.mem.window(u8, self.full[1..], 2, 1); + while (window_it.next()) |window| { + if (std.ascii.eqlIgnoreCase(window, "fo")) break :could_be_fo_option true; + // If we see '/' before "fo", then it's not possible for this to be a valid + // `/fo` option. + if (window[0] == '/') break; + } + break :could_be_fo_option false; + }; + if (!could_be_fo_option) return true; + + // It's still possible for a file path to look like a /fo option but not actually + // be one, e.g. `/foo/bar.rc`. As a last ditch effort to reduce false negatives, + // check if the file path exists and, if so, then we ignore the 'could be /fo option'-ness + std.fs.accessAbsolute(self.full, .{}) catch return false; + return true; + } + + pub const Value = struct { + slice: []const u8, + /// Amount to increment the arg index to skip over both the option and the value arg(s) + /// e.g. 1 if /