1//! Zig Intermediate Representation. Astgen.zig converts AST nodes to these
2//! untyped IR instructions. Next, Sema.zig processes these into AIR.
3//! The minimum amount of information needed to represent a list of ZIR instructions.
4//! Once this structure is completed, it can be used to generate AIR, followed by
5//! machine code, without any memory access into the AST tree token list, node list,
6//! or source bytes. Exceptions include:
7//!  * Compile errors, which may need to reach into these data structures to
8//!    create a useful report.
9//!  * In the future, possibly inline assembly, which needs to get parsed and
10//!    handled by the codegen backend, and errors reported there. However for now,
11//!    inline assembly is not an exception.
12
13const std = @import("std");
14const builtin = @import("builtin");
15const mem = std.mem;
16const Allocator = std.mem.Allocator;
17const assert = std.debug.assert;
18const BigIntConst = std.math.big.int.Const;
19const BigIntMutable = std.math.big.int.Mutable;
20const Ast = std.zig.Ast;
21
22const Zir = @This();
23const Type = @import("type.zig").Type;
24const Value = @import("value.zig").Value;
25const TypedValue = @import("TypedValue.zig");
26const Module = @import("Module.zig");
27const LazySrcLoc = Module.LazySrcLoc;
28
29instructions: std.MultiArrayList(Inst).Slice,
30/// In order to store references to strings in fewer bytes, we copy all
31/// string bytes into here. String bytes can be null. It is up to whomever
32/// is referencing the data here whether they want to store both index and length,
33/// thus allowing null bytes, or store only index, and use null-termination. The
34/// `string_bytes` array is agnostic to either usage.
35/// Indexes 0 and 1 are reserved for special cases.
36string_bytes: []u8,
37/// The meaning of this data is determined by `Inst.Tag` value.
38/// The first few indexes are reserved. See `ExtraIndex` for the values.
39extra: []u32,
40
41/// The data stored at byte offset 0 when ZIR is stored in a file.
42pub const Header = extern struct {
43    instructions_len: u32,
44    string_bytes_len: u32,
45    extra_len: u32,
46
47    stat_inode: std.fs.File.INode,
48    stat_size: u64,
49    stat_mtime: i128,
50};
51
52pub const ExtraIndex = enum(u32) {
53    /// If this is 0, no compile errors. Otherwise there is a `CompileErrors`
54    /// payload at this index.
55    compile_errors,
56    /// If this is 0, this file contains no imports. Otherwise there is a `Imports`
57    /// payload at this index.
58    imports,
59
60    _,
61};
62
63/// Returns the requested data, as well as the new index which is at the start of the
64/// trailers for the object.
65pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, end: usize } {
66    const fields = std.meta.fields(T);
67    var i: usize = index;
68    var result: T = undefined;
69    inline for (fields) |field| {
70        @field(result, field.name) = switch (field.field_type) {
71            u32 => code.extra[i],
72            Inst.Ref => @intToEnum(Inst.Ref, code.extra[i]),
73            i32 => @bitCast(i32, code.extra[i]),
74            Inst.Call.Flags => @bitCast(Inst.Call.Flags, code.extra[i]),
75            Inst.SwitchBlock.Bits => @bitCast(Inst.SwitchBlock.Bits, code.extra[i]),
76            else => @compileError("bad field type"),
77        };
78        i += 1;
79    }
80    return .{
81        .data = result,
82        .end = i,
83    };
84}
85
86/// Given an index into `string_bytes` returns the null-terminated string found there.
87pub fn nullTerminatedString(code: Zir, index: usize) [:0]const u8 {
88    var end: usize = index;
89    while (code.string_bytes[end] != 0) {
90        end += 1;
91    }
92    return code.string_bytes[index..end :0];
93}
94
95pub fn refSlice(code: Zir, start: usize, len: usize) []Inst.Ref {
96    const raw_slice = code.extra[start..][0..len];
97    return @bitCast([]Inst.Ref, raw_slice);
98}
99
100pub fn hasCompileErrors(code: Zir) bool {
101    return code.extra[@enumToInt(ExtraIndex.compile_errors)] != 0;
102}
103
104pub fn deinit(code: *Zir, gpa: Allocator) void {
105    code.instructions.deinit(gpa);
106    gpa.free(code.string_bytes);
107    gpa.free(code.extra);
108    code.* = undefined;
109}
110
111/// ZIR is structured so that the outermost "main" struct of any file
112/// is always at index 0.
113pub const main_struct_inst: Inst.Index = 0;
114
115/// These are untyped instructions generated from an Abstract Syntax Tree.
116/// The data here is immutable because it is possible to have multiple
117/// analyses on the same ZIR happening at the same time.
118pub const Inst = struct {
119    tag: Tag,
120    data: Data,
121
122    /// These names are used directly as the instruction names in the text format.
123    /// See `data_field_map` for a list of which `Data` fields are used by each `Tag`.
124    pub const Tag = enum(u8) {
125        /// Arithmetic addition, asserts no integer overflow.
126        /// Uses the `pl_node` union field. Payload is `Bin`.
127        add,
128        /// Twos complement wrapping integer addition.
129        /// Uses the `pl_node` union field. Payload is `Bin`.
130        addwrap,
131        /// Saturating addition.
132        /// Uses the `pl_node` union field. Payload is `Bin`.
133        add_sat,
134        /// Arithmetic subtraction. Asserts no integer overflow.
135        /// Uses the `pl_node` union field. Payload is `Bin`.
136        sub,
137        /// Twos complement wrapping integer subtraction.
138        /// Uses the `pl_node` union field. Payload is `Bin`.
139        subwrap,
140        /// Saturating subtraction.
141        /// Uses the `pl_node` union field. Payload is `Bin`.
142        sub_sat,
143        /// Arithmetic multiplication. Asserts no integer overflow.
144        /// Uses the `pl_node` union field. Payload is `Bin`.
145        mul,
146        /// Twos complement wrapping integer multiplication.
147        /// Uses the `pl_node` union field. Payload is `Bin`.
148        mulwrap,
149        /// Saturating multiplication.
150        /// Uses the `pl_node` union field. Payload is `Bin`.
151        mul_sat,
152        /// Implements the `@divExact` builtin.
153        /// Uses the `pl_node` union field with payload `Bin`.
154        div_exact,
155        /// Implements the `@divFloor` builtin.
156        /// Uses the `pl_node` union field with payload `Bin`.
157        div_floor,
158        /// Implements the `@divTrunc` builtin.
159        /// Uses the `pl_node` union field with payload `Bin`.
160        div_trunc,
161        /// Implements the `@mod` builtin.
162        /// Uses the `pl_node` union field with payload `Bin`.
163        mod,
164        /// Implements the `@rem` builtin.
165        /// Uses the `pl_node` union field with payload `Bin`.
166        rem,
167        /// Ambiguously remainder division or modulus. If the computation would possibly have
168        /// a different value depending on whether the operation is remainder division or modulus,
169        /// a compile error is emitted. Otherwise the computation is performed.
170        /// Uses the `pl_node` union field. Payload is `Bin`.
171        mod_rem,
172        /// Integer shift-left. Zeroes are shifted in from the right hand side.
173        /// Uses the `pl_node` union field. Payload is `Bin`.
174        shl,
175        /// Implements the `@shlExact` builtin.
176        /// Uses the `pl_node` union field with payload `Bin`.
177        shl_exact,
178        /// Saturating shift-left.
179        /// Uses the `pl_node` union field. Payload is `Bin`.
180        shl_sat,
181        /// Integer shift-right. Arithmetic or logical depending on the signedness of
182        /// the integer type.
183        /// Uses the `pl_node` union field. Payload is `Bin`.
184        shr,
185        /// Implements the `@shrExact` builtin.
186        /// Uses the `pl_node` union field with payload `Bin`.
187        shr_exact,
188
189        /// Declares a parameter of the current function. Used for:
190        /// * debug info
191        /// * checking shadowing against declarations in the current namespace
192        /// * parameter type expressions referencing other parameters
193        /// These occur in the block outside a function body (the same block as
194        /// contains the func instruction).
195        /// Uses the `pl_tok` field. Token is the parameter name, payload is a `Param`.
196        param,
197        /// Same as `param` except the parameter is marked comptime.
198        param_comptime,
199        /// Same as `param` except the parameter is marked anytype.
200        /// Uses the `str_tok` field. Token is the parameter name. String is the parameter name.
201        param_anytype,
202        /// Same as `param` except the parameter is marked both comptime and anytype.
203        /// Uses the `str_tok` field. Token is the parameter name. String is the parameter name.
204        param_anytype_comptime,
205        /// Array concatenation. `a ++ b`
206        /// Uses the `pl_node` union field. Payload is `Bin`.
207        array_cat,
208        /// Array multiplication `a ** b`
209        /// Uses the `pl_node` union field. Payload is `Bin`.
210        array_mul,
211        /// `[N]T` syntax. No source location provided.
212        /// Uses the `bin` union field. lhs is length, rhs is element type.
213        array_type,
214        /// `[N:S]T` syntax. Source location is the array type expression node.
215        /// Uses the `pl_node` union field. Payload is `ArrayTypeSentinel`.
216        array_type_sentinel,
217        /// `@Vector` builtin.
218        /// Uses the `pl_node` union field with `Bin` payload.
219        /// lhs is length, rhs is element type.
220        vector_type,
221        /// Given an array type, returns the element type.
222        /// Uses the `un_node` union field.
223        elem_type,
224        /// Given a pointer to an indexable object, returns the len property. This is
225        /// used by for loops. This instruction also emits a for-loop specific compile
226        /// error if the indexable object is not indexable.
227        /// Uses the `un_node` field. The AST node is the for loop node.
228        indexable_ptr_len,
229        /// Create a `anyframe->T` type.
230        /// Uses the `un_node` field.
231        anyframe_type,
232        /// Type coercion. No source location attached.
233        /// Uses the `bin` field.
234        as,
235        /// Type coercion to the function's return type.
236        /// Uses the `pl_node` field. Payload is `As`. AST node could be many things.
237        as_node,
238        /// Bitwise AND. `&`
239        bit_and,
240        /// Reinterpret the memory representation of a value as a different type.
241        /// Uses the pl_node field with payload `Bin`.
242        bitcast,
243        /// Bitwise NOT. `~`
244        /// Uses `un_node`.
245        bit_not,
246        /// Bitwise OR. `|`
247        bit_or,
248        /// A labeled block of code, which can return a value.
249        /// Uses the `pl_node` union field. Payload is `Block`.
250        block,
251        /// A list of instructions which are analyzed in the parent context, without
252        /// generating a runtime block. Must terminate with an "inline" variant of
253        /// a noreturn instruction.
254        /// Uses the `pl_node` union field. Payload is `Block`.
255        block_inline,
256        /// Implements `suspend {...}`.
257        /// Uses the `pl_node` union field. Payload is `Block`.
258        suspend_block,
259        /// Boolean NOT. See also `bit_not`.
260        /// Uses the `un_node` field.
261        bool_not,
262        /// Short-circuiting boolean `and`. `lhs` is a boolean `Ref` and the other operand
263        /// is a block, which is evaluated if `lhs` is `true`.
264        /// Uses the `bool_br` union field.
265        bool_br_and,
266        /// Short-circuiting boolean `or`. `lhs` is a boolean `Ref` and the other operand
267        /// is a block, which is evaluated if `lhs` is `false`.
268        /// Uses the `bool_br` union field.
269        bool_br_or,
270        /// Return a value from a block.
271        /// Uses the `break` union field.
272        /// Uses the source information from previous instruction.
273        @"break",
274        /// Return a value from a block. This instruction is used as the terminator
275        /// of a `block_inline`. It allows using the return value from `Sema.analyzeBody`.
276        /// This instruction may also be used when it is known that there is only one
277        /// break instruction in a block, and the target block is the parent.
278        /// Uses the `break` union field.
279        break_inline,
280        /// Uses the `node` union field.
281        breakpoint,
282        /// Function call.
283        /// Uses `pl_node`. AST node is the function call. Payload is `Call`.
284        call,
285        /// `<`
286        /// Uses the `pl_node` union field. Payload is `Bin`.
287        cmp_lt,
288        /// `<=`
289        /// Uses the `pl_node` union field. Payload is `Bin`.
290        cmp_lte,
291        /// `==`
292        /// Uses the `pl_node` union field. Payload is `Bin`.
293        cmp_eq,
294        /// `>=`
295        /// Uses the `pl_node` union field. Payload is `Bin`.
296        cmp_gte,
297        /// `>`
298        /// Uses the `pl_node` union field. Payload is `Bin`.
299        cmp_gt,
300        /// `!=`
301        /// Uses the `pl_node` union field. Payload is `Bin`.
302        cmp_neq,
303        /// Coerces a result location pointer to a new element type. It is evaluated "backwards"-
304        /// as type coercion from the new element type to the old element type.
305        /// Uses the `bin` union field.
306        /// LHS is destination element type, RHS is result pointer.
307        coerce_result_ptr,
308        /// Conditional branch. Splits control flow based on a boolean condition value.
309        /// Uses the `pl_node` union field. AST node is an if, while, for, etc.
310        /// Payload is `CondBr`.
311        condbr,
312        /// Same as `condbr`, except the condition is coerced to a comptime value, and
313        /// only the taken branch is analyzed. The then block and else block must
314        /// terminate with an "inline" variant of a noreturn instruction.
315        condbr_inline,
316        /// An error set type definition. Contains a list of field names.
317        /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`.
318        error_set_decl,
319        error_set_decl_anon,
320        error_set_decl_func,
321        /// Declares the beginning of a statement. Used for debug info.
322        /// Uses the `dbg_stmt` union field. The line and column are offset
323        /// from the parent declaration.
324        dbg_stmt,
325        /// Uses a name to identify a Decl and takes a pointer to it.
326        /// Uses the `str_tok` union field.
327        decl_ref,
328        /// Uses a name to identify a Decl and uses it as a value.
329        /// Uses the `str_tok` union field.
330        decl_val,
331        /// Load the value from a pointer. Assumes `x.*` syntax.
332        /// Uses `un_node` field. AST node is the `x.*` syntax.
333        load,
334        /// Arithmetic division. Asserts no integer overflow.
335        /// Uses the `pl_node` union field. Payload is `Bin`.
336        div,
337        /// Given a pointer to an array, slice, or pointer, returns a pointer to the element at
338        /// the provided index. Uses the `bin` union field. Source location is implied
339        /// to be the same as the previous instruction.
340        elem_ptr,
341        /// Same as `elem_ptr` except also stores a source location node.
342        /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`.
343        elem_ptr_node,
344        /// Same as `elem_ptr_node` except the index is stored immediately rather than
345        /// as a reference to another ZIR instruction.
346        /// Uses the `pl_node` union field. AST node is an element inside array initialization
347        /// syntax. Payload is `ElemPtrImm`.
348        elem_ptr_imm,
349        /// Given an array, slice, or pointer, returns the element at the provided index.
350        /// Uses the `bin` union field. Source location is implied to be the same
351        /// as the previous instruction.
352        elem_val,
353        /// Same as `elem_val` except also stores a source location node.
354        /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`.
355        elem_val_node,
356        /// Emits a compile error if the operand is not `void`.
357        /// Uses the `un_node` field.
358        ensure_result_used,
359        /// Emits a compile error if an error is ignored.
360        /// Uses the `un_node` field.
361        ensure_result_non_error,
362        /// Create a `E!T` type.
363        /// Uses the `pl_node` field with `Bin` payload.
364        error_union_type,
365        /// `error.Foo` syntax. Uses the `str_tok` field of the Data union.
366        error_value,
367        /// Implements the `@export` builtin function, based on either an identifier to a Decl,
368        /// or field access of a Decl. The thing being exported is the Decl.
369        /// Uses the `pl_node` union field. Payload is `Export`.
370        @"export",
371        /// Implements the `@export` builtin function, based on a comptime-known value.
372        /// The thing being exported is the comptime-known value which is the operand.
373        /// Uses the `pl_node` union field. Payload is `ExportValue`.
374        export_value,
375        /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
376        /// to the named field. The field name is stored in string_bytes. Used by a.b syntax.
377        /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field.
378        field_ptr,
379        /// Given a struct or object that contains virtual fields, returns the named field.
380        /// The field name is stored in string_bytes. Used by a.b syntax.
381        /// This instruction also accepts a pointer.
382        /// Uses `pl_node` field. The AST node is the a.b syntax. Payload is Field.
383        field_val,
384        /// Given a pointer to a struct or object that contains virtual fields, returns the
385        /// named field.  If there is no named field, searches in the type for a decl that
386        /// matches the field name.  The decl is resolved and we ensure that it's a function
387        /// which can accept the object as the first parameter, with one pointer fixup.  If
388        /// all of that works, this instruction produces a special "bound function" value
389        /// which contains both the function and the saved first parameter value.
390        /// Bound functions may only be used as the function parameter to a `call` or
391        /// `builtin_call` instruction.  Any other use is invalid zir and may crash the compiler.
392        field_call_bind,
393        /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
394        /// to the named field. The field name is a comptime instruction. Used by @field.
395        /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed.
396        field_ptr_named,
397        /// Given a struct or object that contains virtual fields, returns the named field.
398        /// The field name is a comptime instruction. Used by @field.
399        /// Uses `pl_node` field. The AST node is the builtin call. Payload is FieldNamed.
400        field_val_named,
401        /// Given a pointer to a struct or object that contains virtual fields, returns the
402        /// named field.  If there is no named field, searches in the type for a decl that
403        /// matches the field name.  The decl is resolved and we ensure that it's a function
404        /// which can accept the object as the first parameter, with one pointer fixup.  If
405        /// all of that works, this instruction produces a special "bound function" value
406        /// which contains both the function and the saved first parameter value.
407        /// Bound functions may only be used as the function parameter to a `call` or
408        /// `builtin_call` instruction.  Any other use is invalid zir and may crash the compiler.
409        field_call_bind_named,
410        /// Returns a function type, or a function instance, depending on whether
411        /// the body_len is 0. Calling convention is auto.
412        /// Uses the `pl_node` union field. `payload_index` points to a `Func`.
413        func,
414        /// Same as `func` but has an inferred error set.
415        func_inferred,
416        /// Implements the `@import` builtin.
417        /// Uses the `str_tok` field.
418        import,
419        /// Integer literal that fits in a u64. Uses the `int` union field.
420        int,
421        /// Arbitrary sized integer literal. Uses the `str` union field.
422        int_big,
423        /// A float literal that fits in a f64. Uses the float union value.
424        float,
425        /// A float literal that fits in a f128. Uses the `pl_node` union value.
426        /// Payload is `Float128`.
427        float128,
428        /// Make an integer type out of signedness and bit count.
429        /// Payload is `int_type`
430        int_type,
431        /// Return a boolean false if an optional is null. `x != null`
432        /// Uses the `un_node` field.
433        is_non_null,
434        /// Return a boolean false if an optional is null. `x.* != null`
435        /// Uses the `un_node` field.
436        is_non_null_ptr,
437        /// Return a boolean false if value is an error
438        /// Uses the `un_node` field.
439        is_non_err,
440        /// Return a boolean false if dereferenced pointer is an error
441        /// Uses the `un_node` field.
442        is_non_err_ptr,
443        /// A labeled block of code that loops forever. At the end of the body will have either
444        /// a `repeat` instruction or a `repeat_inline` instruction.
445        /// Uses the `pl_node` field. The AST node is either a for loop or while loop.
446        /// This ZIR instruction is needed because AIR does not (yet?) match ZIR, and Sema
447        /// needs to emit more than 1 AIR block for this instruction.
448        /// The payload is `Block`.
449        loop,
450        /// Sends runtime control flow back to the beginning of the current block.
451        /// Uses the `node` field.
452        repeat,
453        /// Sends comptime control flow back to the beginning of the current block.
454        /// Uses the `node` field.
455        repeat_inline,
456        /// Merge two error sets into one, `E1 || E2`.
457        /// Uses the `pl_node` field with payload `Bin`.
458        merge_error_sets,
459        /// Turns an R-Value into a const L-Value. In other words, it takes a value,
460        /// stores it in a memory location, and returns a const pointer to it. If the value
461        /// is `comptime`, the memory location is global static constant data. Otherwise,
462        /// the memory location is in the stack frame, local to the scope containing the
463        /// instruction.
464        /// Uses the `un_tok` union field.
465        ref,
466        /// Sends control flow back to the function's callee.
467        /// Includes an operand as the return value.
468        /// Includes an AST node source location.
469        /// Uses the `un_node` union field.
470        ret_node,
471        /// Sends control flow back to the function's callee.
472        /// The operand is a `ret_ptr` instruction, where the return value can be found.
473        /// Includes an AST node source location.
474        /// Uses the `un_node` union field.
475        ret_load,
476        /// Sends control flow back to the function's callee.
477        /// Includes an operand as the return value.
478        /// Includes a token source location.
479        /// Uses the `un_tok` union field.
480        /// The operand needs to get coerced to the function's return type.
481        /// TODO rename this to `ret_tok` because coercion is now done unconditionally in Sema.
482        ret_coerce,
483        /// Sends control flow back to the function's callee.
484        /// The return operand is `error.foo` where `foo` is given by the string.
485        /// If the current function has an inferred error set, the error given by the
486        /// name is added to it.
487        /// Uses the `str_tok` union field.
488        ret_err_value,
489        /// A string name is provided which is an anonymous error set value.
490        /// If the current function has an inferred error set, the error given by the
491        /// name is added to it.
492        /// Results in the error code. Note that control flow is not diverted with
493        /// this instruction; a following 'ret' instruction will do the diversion.
494        /// Uses the `str_tok` union field.
495        ret_err_value_code,
496        /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.
497        /// Uses the `ptr_type_simple` union field.
498        ptr_type_simple,
499        /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.
500        /// Uses the `ptr_type` union field.
501        ptr_type,
502        /// Slice operation `lhs[rhs..]`. No sentinel and no end offset.
503        /// Returns a pointer to the subslice.
504        /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceStart`.
505        slice_start,
506        /// Slice operation `array_ptr[start..end]`. No sentinel.
507        /// Returns a pointer to the subslice.
508        /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceEnd`.
509        slice_end,
510        /// Slice operation `array_ptr[start..end:sentinel]`.
511        /// Returns a pointer to the subslice.
512        /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceSentinel`.
513        slice_sentinel,
514        /// Write a value to a pointer. For loading, see `load`.
515        /// Source location is assumed to be same as previous instruction.
516        /// Uses the `bin` union field.
517        store,
518        /// Same as `store` except provides a source location.
519        /// Uses the `pl_node` union field. Payload is `Bin`.
520        store_node,
521        /// Same as `store` but the type of the value being stored will be used to infer
522        /// the block type. The LHS is the pointer to store to.
523        /// Uses the `bin` union field.
524        /// If the pointer is none, it means this instruction has been elided in
525        /// AstGen, but AstGen was unable to actually omit it from the ZIR code.
526        store_to_block_ptr,
527        /// Same as `store` but the type of the value being stored will be used to infer
528        /// the pointer type.
529        /// Uses the `bin` union field - Astgen.zig depends on the ability to change
530        /// the tag of an instruction from `store_to_block_ptr` to `store_to_inferred_ptr`
531        /// without changing the data.
532        store_to_inferred_ptr,
533        /// String Literal. Makes an anonymous Decl and then takes a pointer to it.
534        /// Uses the `str` union field.
535        str,
536        /// Arithmetic negation. Asserts no integer overflow.
537        /// Same as sub with a lhs of 0, split into a separate instruction to save memory.
538        /// Uses `un_node`.
539        negate,
540        /// Twos complement wrapping integer negation.
541        /// Same as subwrap with a lhs of 0, split into a separate instruction to save memory.
542        /// Uses `un_node`.
543        negate_wrap,
544        /// Returns the type of a value.
545        /// Uses the `un_node` field.
546        typeof,
547        /// Given a value, look at the type of it, which must be an integer type.
548        /// Returns the integer type for the RHS of a shift operation.
549        /// Uses the `un_node` field.
550        typeof_log2_int_type,
551        /// Given an integer type, returns the integer type for the RHS of a shift operation.
552        /// Uses the `un_node` field.
553        log2_int_type,
554        /// Asserts control-flow will not reach this instruction (`unreachable`).
555        /// Uses the `unreachable` union field.
556        @"unreachable",
557        /// Bitwise XOR. `^`
558        /// Uses the `pl_node` union field. Payload is `Bin`.
559        xor,
560        /// Create an optional type '?T'
561        /// Uses the `un_node` field.
562        optional_type,
563        /// ?T => T with safety.
564        /// Given an optional value, returns the payload value, with a safety check that
565        /// the value is non-null. Used for `orelse`, `if` and `while`.
566        /// Uses the `un_node` field.
567        optional_payload_safe,
568        /// ?T => T without safety.
569        /// Given an optional value, returns the payload value. No safety checks.
570        /// Uses the `un_node` field.
571        optional_payload_unsafe,
572        /// *?T => *T with safety.
573        /// Given a pointer to an optional value, returns a pointer to the payload value,
574        /// with a safety check that the value is non-null. Used for `orelse`, `if` and `while`.
575        /// Uses the `un_node` field.
576        optional_payload_safe_ptr,
577        /// *?T => *T without safety.
578        /// Given a pointer to an optional value, returns a pointer to the payload value.
579        /// No safety checks.
580        /// Uses the `un_node` field.
581        optional_payload_unsafe_ptr,
582        /// E!T => T with safety.
583        /// Given an error union value, returns the payload value, with a safety check
584        /// that the value is not an error. Used for catch, if, and while.
585        /// Uses the `un_node` field.
586        err_union_payload_safe,
587        /// E!T => T without safety.
588        /// Given an error union value, returns the payload value. No safety checks.
589        /// Uses the `un_node` field.
590        err_union_payload_unsafe,
591        /// *E!T => *T with safety.
592        /// Given a pointer to an error union value, returns a pointer to the payload value,
593        /// with a safety check that the value is not an error. Used for catch, if, and while.
594        /// Uses the `un_node` field.
595        err_union_payload_safe_ptr,
596        /// *E!T => *T without safety.
597        /// Given a pointer to a error union value, returns a pointer to the payload value.
598        /// No safety checks.
599        /// Uses the `un_node` field.
600        err_union_payload_unsafe_ptr,
601        /// E!T => E without safety.
602        /// Given an error union value, returns the error code. No safety checks.
603        /// Uses the `un_node` field.
604        err_union_code,
605        /// *E!T => E without safety.
606        /// Given a pointer to an error union value, returns the error code. No safety checks.
607        /// Uses the `un_node` field.
608        err_union_code_ptr,
609        /// Takes a *E!T and raises a compiler error if T != void
610        /// Uses the `un_tok` field.
611        ensure_err_payload_void,
612        /// An enum literal. Uses the `str_tok` union field.
613        enum_literal,
614        /// A switch expression. Uses the `pl_node` union field.
615        /// AST node is the switch, payload is `SwitchBlock`.
616        switch_block,
617        /// Produces the value that will be switched on. For example, for
618        /// integers, it returns the integer with no modifications. For tagged unions, it
619        /// returns the active enum tag.
620        /// Uses the `un_node` union field.
621        switch_cond,
622        /// Same as `switch_cond`, except the input operand is a pointer to
623        /// what will be switched on.
624        /// Uses the `un_node` union field.
625        switch_cond_ref,
626        /// Produces the capture value for a switch prong.
627        /// Uses the `switch_capture` field.
628        switch_capture,
629        /// Produces the capture value for a switch prong.
630        /// Result is a pointer to the value.
631        /// Uses the `switch_capture` field.
632        switch_capture_ref,
633        /// Produces the capture value for a switch prong.
634        /// The prong is one of the multi cases.
635        /// Uses the `switch_capture` field.
636        switch_capture_multi,
637        /// Produces the capture value for a switch prong.
638        /// The prong is one of the multi cases.
639        /// Result is a pointer to the value.
640        /// Uses the `switch_capture` field.
641        switch_capture_multi_ref,
642        /// Produces the capture value for the else/'_' switch prong.
643        /// Uses the `switch_capture` field.
644        switch_capture_else,
645        /// Produces the capture value for the else/'_' switch prong.
646        /// Result is a pointer to the value.
647        /// Uses the `switch_capture` field.
648        switch_capture_else_ref,
649        /// Given a set of `field_ptr` instructions, assumes they are all part of a struct
650        /// initialization expression, and emits compile errors for duplicate fields
651        /// as well as missing fields, if applicable.
652        /// This instruction asserts that there is at least one field_ptr instruction,
653        /// because it must use one of them to find out the struct type.
654        /// Uses the `pl_node` field. Payload is `Block`.
655        validate_struct_init,
656        /// Given a set of `elem_ptr_imm` instructions, assumes they are all part of an
657        /// array initialization expression, and emits a compile error if the number of
658        /// elements does not match the array type.
659        /// This instruction asserts that there is at least one `elem_ptr_imm` instruction,
660        /// because it must use one of them to find out the array type.
661        /// Uses the `pl_node` field. Payload is `Block`.
662        validate_array_init,
663        /// A struct literal with a specified type, with no fields.
664        /// Uses the `un_node` field.
665        struct_init_empty,
666        /// Given a struct or union, and a field name as a string index,
667        /// returns the field type. Uses the `pl_node` field. Payload is `FieldType`.
668        field_type,
669        /// Given a struct or union, and a field name as a Ref,
670        /// returns the field type. Uses the `pl_node` field. Payload is `FieldTypeRef`.
671        field_type_ref,
672        /// Finalizes a typed struct or union initialization, performs validation, and returns the
673        /// struct or union value.
674        /// Uses the `pl_node` field. Payload is `StructInit`.
675        struct_init,
676        /// Struct initialization syntax, make the result a pointer.
677        /// Uses the `pl_node` field. Payload is `StructInit`.
678        struct_init_ref,
679        /// Struct initialization without a type.
680        /// Uses the `pl_node` field. Payload is `StructInitAnon`.
681        struct_init_anon,
682        /// Anonymous struct initialization syntax, make the result a pointer.
683        /// Uses the `pl_node` field. Payload is `StructInitAnon`.
684        struct_init_anon_ref,
685        /// Array initialization syntax.
686        /// Uses the `pl_node` field. Payload is `MultiOp`.
687        array_init,
688        /// Anonymous array initialization syntax.
689        /// Uses the `pl_node` field. Payload is `MultiOp`.
690        array_init_anon,
691        /// Array initialization syntax, make the result a pointer.
692        /// Uses the `pl_node` field. Payload is `MultiOp`.
693        array_init_ref,
694        /// Anonymous array initialization syntax, make the result a pointer.
695        /// Uses the `pl_node` field. Payload is `MultiOp`.
696        array_init_anon_ref,
697        /// Given a pointer to a union and a comptime known field name, activates that field
698        /// and returns a pointer to it.
699        /// Uses the `pl_node` field. Payload is `UnionInitPtr`.
700        union_init_ptr,
701        /// Implements the `@typeInfo` builtin. Uses `un_node`.
702        type_info,
703        /// Implements the `@sizeOf` builtin. Uses `un_node`.
704        size_of,
705        /// Implements the `@bitSizeOf` builtin. Uses `un_node`.
706        bit_size_of,
707        /// Implements the `@fence` builtin. Uses `un_node`.
708        fence,
709
710        /// Implement builtin `@ptrToInt`. Uses `un_node`.
711        /// Convert a pointer to a `usize` integer.
712        ptr_to_int,
713        /// Implement builtin `@errToInt`. Uses `un_node`.
714        error_to_int,
715        /// Implement builtin `@intToError`. Uses `un_node`.
716        int_to_error,
717        /// Emit an error message and fail compilation.
718        /// Uses the `un_node` field.
719        compile_error,
720        /// Changes the maximum number of backwards branches that compile-time
721        /// code execution can use before giving up and making a compile error.
722        /// Uses the `un_node` union field.
723        set_eval_branch_quota,
724        /// Converts an enum value into an integer. Resulting type will be the tag type
725        /// of the enum. Uses `un_node`.
726        enum_to_int,
727        /// Implement builtin `@alignOf`. Uses `un_node`.
728        align_of,
729        /// Implement builtin `@boolToInt`. Uses `un_node`.
730        bool_to_int,
731        /// Implement builtin `@embedFile`. Uses `un_node`.
732        embed_file,
733        /// Implement builtin `@errorName`. Uses `un_node`.
734        error_name,
735        /// Implement builtin `@panic`. Uses `un_node`.
736        panic,
737        /// Implement builtin `@setAlignStack`. Uses `un_node`.
738        set_align_stack,
739        /// Implement builtin `@setCold`. Uses `un_node`.
740        set_cold,
741        /// Implement builtin `@setFloatMode`. Uses `un_node`.
742        set_float_mode,
743        /// Implement builtin `@setRuntimeSafety`. Uses `un_node`.
744        set_runtime_safety,
745        /// Implement builtin `@sqrt`. Uses `un_node`.
746        sqrt,
747        /// Implement builtin `@sin`. Uses `un_node`.
748        sin,
749        /// Implement builtin `@cos`. Uses `un_node`.
750        cos,
751        /// Implement builtin `@exp`. Uses `un_node`.
752        exp,
753        /// Implement builtin `@exp2`. Uses `un_node`.
754        exp2,
755        /// Implement builtin `@log`. Uses `un_node`.
756        log,
757        /// Implement builtin `@log2`. Uses `un_node`.
758        log2,
759        /// Implement builtin `@log10`. Uses `un_node`.
760        log10,
761        /// Implement builtin `@fabs`. Uses `un_node`.
762        fabs,
763        /// Implement builtin `@floor`. Uses `un_node`.
764        floor,
765        /// Implement builtin `@ceil`. Uses `un_node`.
766        ceil,
767        /// Implement builtin `@trunc`. Uses `un_node`.
768        trunc,
769        /// Implement builtin `@round`. Uses `un_node`.
770        round,
771        /// Implement builtin `@tagName`. Uses `un_node`.
772        tag_name,
773        /// Implement builtin `@Type`. Uses `un_node`.
774        reify,
775        /// Implement builtin `@typeName`. Uses `un_node`.
776        type_name,
777        /// Implement builtin `@Frame`. Uses `un_node`.
778        frame_type,
779        /// Implement builtin `@frameSize`. Uses `un_node`.
780        frame_size,
781
782        /// Implements the `@floatToInt` builtin.
783        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
784        float_to_int,
785        /// Implements the `@intToFloat` builtin.
786        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
787        int_to_float,
788        /// Implements the `@intToPtr` builtin.
789        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
790        int_to_ptr,
791        /// Converts an integer into an enum value.
792        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
793        int_to_enum,
794        /// Convert a larger float type to any other float type, possibly causing
795        /// a loss of precision.
796        /// Uses the `pl_node` field. AST is the `@floatCast` syntax.
797        /// Payload is `Bin` with lhs as the dest type, rhs the operand.
798        float_cast,
799        /// Implements the `@intCast` builtin.
800        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
801        /// Convert an integer value to another integer type, asserting that the destination type
802        /// can hold the same mathematical value.
803        int_cast,
804        /// Implements the `@errSetCast` builtin.
805        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
806        err_set_cast,
807        /// Implements the `@ptrCast` builtin.
808        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
809        ptr_cast,
810        /// Implements the `@truncate` builtin.
811        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
812        truncate,
813        /// Implements the `@alignCast` builtin.
814        /// Uses `pl_node` with payload `Bin`. `lhs` is dest alignment, `rhs` is operand.
815        align_cast,
816
817        /// Implements the `@hasDecl` builtin.
818        /// Uses the `pl_node` union field. Payload is `Bin`.
819        has_decl,
820        /// Implements the `@hasField` builtin.
821        /// Uses the `pl_node` union field. Payload is `Bin`.
822        has_field,
823
824        /// Implements the `@clz` builtin. Uses the `un_node` union field.
825        clz,
826        /// Implements the `@ctz` builtin. Uses the `un_node` union field.
827        ctz,
828        /// Implements the `@popCount` builtin. Uses the `un_node` union field.
829        pop_count,
830        /// Implements the `@byteSwap` builtin. Uses the `un_node` union field.
831        byte_swap,
832        /// Implements the `@bitReverse` builtin. Uses the `un_node` union field.
833        bit_reverse,
834
835        /// Implements the `@bitOffsetOf` builtin.
836        /// Uses the `pl_node` union field with payload `Bin`.
837        bit_offset_of,
838        /// Implements the `@offsetOf` builtin.
839        /// Uses the `pl_node` union field with payload `Bin`.
840        offset_of,
841        /// Implements the `@cmpxchgStrong` builtin.
842        /// Uses the `pl_node` union field with payload `Cmpxchg`.
843        cmpxchg_strong,
844        /// Implements the `@cmpxchgWeak` builtin.
845        /// Uses the `pl_node` union field with payload `Cmpxchg`.
846        cmpxchg_weak,
847        /// Implements the `@splat` builtin.
848        /// Uses the `pl_node` union field with payload `Bin`.
849        splat,
850        /// Implements the `@reduce` builtin.
851        /// Uses the `pl_node` union field with payload `Bin`.
852        reduce,
853        /// Implements the `@shuffle` builtin.
854        /// Uses the `pl_node` union field with payload `Shuffle`.
855        shuffle,
856        /// Implements the `@select` builtin.
857        /// Uses the `pl_node` union field with payload `Select`.
858        select,
859        /// Implements the `@atomicLoad` builtin.
860        /// Uses the `pl_node` union field with payload `Bin`.
861        atomic_load,
862        /// Implements the `@atomicRmw` builtin.
863        /// Uses the `pl_node` union field with payload `AtomicRmw`.
864        atomic_rmw,
865        /// Implements the `@atomicStore` builtin.
866        /// Uses the `pl_node` union field with payload `AtomicStore`.
867        atomic_store,
868        /// Implements the `@mulAdd` builtin.
869        /// Uses the `pl_node` union field with payload `MulAdd`.
870        mul_add,
871        /// Implements the `@call` builtin.
872        /// Uses the `pl_node` union field with payload `BuiltinCall`.
873        builtin_call,
874        /// Given a type and a field name, returns a pointer to the field type.
875        /// Assumed to be part of a `@fieldParentPtr` builtin call.
876        /// Uses the `bin` union field. LHS is type, RHS is field name.
877        field_ptr_type,
878        /// Implements the `@fieldParentPtr` builtin.
879        /// Uses the `pl_node` union field with payload `FieldParentPtr`.
880        field_parent_ptr,
881        /// Implements the `@memcpy` builtin.
882        /// Uses the `pl_node` union field with payload `Memcpy`.
883        memcpy,
884        /// Implements the `@memset` builtin.
885        /// Uses the `pl_node` union field with payload `Memset`.
886        memset,
887        /// Implements the `@minimum` builtin.
888        /// Uses the `pl_node` union field with payload `Bin`
889        minimum,
890        /// Implements the `@maximum` builtin.
891        /// Uses the `pl_node` union field with payload `Bin`
892        maximum,
893        /// Implements the `@asyncCall` builtin.
894        /// Uses the `pl_node` union field with payload `AsyncCall`.
895        builtin_async_call,
896        /// Implements the `@cImport` builtin.
897        /// Uses the `pl_node` union field with payload `Block`.
898        c_import,
899
900        /// Allocates stack local memory.
901        /// Uses the `un_node` union field. The operand is the type of the allocated object.
902        /// The node source location points to a var decl node.
903        alloc,
904        /// Same as `alloc` except mutable.
905        alloc_mut,
906        /// Allocates comptime-mutable memory.
907        /// Uses the `un_node` union field. The operand is the type of the allocated object.
908        /// The node source location points to a var decl node.
909        alloc_comptime,
910        /// Same as `alloc` except the type is inferred.
911        /// Uses the `node` union field.
912        alloc_inferred,
913        /// Same as `alloc_inferred` except mutable.
914        alloc_inferred_mut,
915        /// Same as `alloc_comptime` except the type is inferred.
916        alloc_inferred_comptime,
917        /// Each `store_to_inferred_ptr` puts the type of the stored value into a set,
918        /// and then `resolve_inferred_alloc` triggers peer type resolution on the set.
919        /// The operand is a `alloc_inferred` or `alloc_inferred_mut` instruction, which
920        /// is the allocation that needs to have its type inferred.
921        /// Uses the `un_node` field. The AST node is the var decl.
922        resolve_inferred_alloc,
923
924        /// Implements `resume` syntax. Uses `un_node` field.
925        @"resume",
926        @"await",
927        await_nosuspend,
928
929        /// When a type or function refers to a comptime value from an outer
930        /// scope, that forms a closure over comptime value.  The outer scope
931        /// will record a capture of that value, which encodes its current state
932        /// and marks it to persist.  Uses `un_tok` field.  Operand is the
933        /// instruction value to capture.
934        closure_capture,
935        /// The inner scope of a closure uses closure_get to retrieve the value
936        /// stored by the outer scope.  Uses `inst_node` field.  Operand is the
937        /// closure_capture instruction ref.
938        closure_get,
939
940        /// The ZIR instruction tag is one of the `Extended` ones.
941        /// Uses the `extended` union field.
942        extended,
943
944        /// Returns whether the instruction is one of the control flow "noreturn" types.
945        /// Function calls do not count.
946        pub fn isNoReturn(tag: Tag) bool {
947            return switch (tag) {
948                .param,
949                .param_comptime,
950                .param_anytype,
951                .param_anytype_comptime,
952                .add,
953                .addwrap,
954                .add_sat,
955                .alloc,
956                .alloc_mut,
957                .alloc_comptime,
958                .alloc_inferred,
959                .alloc_inferred_mut,
960                .alloc_inferred_comptime,
961                .array_cat,
962                .array_mul,
963                .array_type,
964                .array_type_sentinel,
965                .vector_type,
966                .elem_type,
967                .indexable_ptr_len,
968                .anyframe_type,
969                .as,
970                .as_node,
971                .bit_and,
972                .bitcast,
973                .bit_or,
974                .block,
975                .block_inline,
976                .suspend_block,
977                .loop,
978                .bool_br_and,
979                .bool_br_or,
980                .bool_not,
981                .breakpoint,
982                .fence,
983                .call,
984                .cmp_lt,
985                .cmp_lte,
986                .cmp_eq,
987                .cmp_gte,
988                .cmp_gt,
989                .cmp_neq,
990                .coerce_result_ptr,
991                .error_set_decl,
992                .error_set_decl_anon,
993                .error_set_decl_func,
994                .dbg_stmt,
995                .decl_ref,
996                .decl_val,
997                .load,
998                .div,
999                .elem_ptr,
1000                .elem_val,
1001                .elem_ptr_node,
1002                .elem_ptr_imm,
1003                .elem_val_node,
1004                .ensure_result_used,
1005                .ensure_result_non_error,
1006                .@"export",
1007                .export_value,
1008                .field_ptr,
1009                .field_val,
1010                .field_call_bind,
1011                .field_ptr_named,
1012                .field_val_named,
1013                .field_call_bind_named,
1014                .func,
1015                .func_inferred,
1016                .has_decl,
1017                .int,
1018                .int_big,
1019                .float,
1020                .float128,
1021                .int_type,
1022                .is_non_null,
1023                .is_non_null_ptr,
1024                .is_non_err,
1025                .is_non_err_ptr,
1026                .mod_rem,
1027                .mul,
1028                .mulwrap,
1029                .mul_sat,
1030                .ref,
1031                .shl,
1032                .shl_sat,
1033                .shr,
1034                .store,
1035                .store_node,
1036                .store_to_block_ptr,
1037                .store_to_inferred_ptr,
1038                .str,
1039                .sub,
1040                .subwrap,
1041                .sub_sat,
1042                .negate,
1043                .negate_wrap,
1044                .typeof,
1045                .xor,
1046                .optional_type,
1047                .optional_payload_safe,
1048                .optional_payload_unsafe,
1049                .optional_payload_safe_ptr,
1050                .optional_payload_unsafe_ptr,
1051                .err_union_payload_safe,
1052                .err_union_payload_unsafe,
1053                .err_union_payload_safe_ptr,
1054                .err_union_payload_unsafe_ptr,
1055                .err_union_code,
1056                .err_union_code_ptr,
1057                .error_to_int,
1058                .int_to_error,
1059                .ptr_type,
1060                .ptr_type_simple,
1061                .ensure_err_payload_void,
1062                .enum_literal,
1063                .merge_error_sets,
1064                .error_union_type,
1065                .bit_not,
1066                .error_value,
1067                .slice_start,
1068                .slice_end,
1069                .slice_sentinel,
1070                .import,
1071                .typeof_log2_int_type,
1072                .log2_int_type,
1073                .resolve_inferred_alloc,
1074                .set_eval_branch_quota,
1075                .switch_capture,
1076                .switch_capture_ref,
1077                .switch_capture_multi,
1078                .switch_capture_multi_ref,
1079                .switch_capture_else,
1080                .switch_capture_else_ref,
1081                .switch_block,
1082                .switch_cond,
1083                .switch_cond_ref,
1084                .validate_struct_init,
1085                .validate_array_init,
1086                .struct_init_empty,
1087                .struct_init,
1088                .struct_init_ref,
1089                .struct_init_anon,
1090                .struct_init_anon_ref,
1091                .array_init,
1092                .array_init_anon,
1093                .array_init_ref,
1094                .array_init_anon_ref,
1095                .union_init_ptr,
1096                .field_type,
1097                .field_type_ref,
1098                .int_to_enum,
1099                .enum_to_int,
1100                .type_info,
1101                .size_of,
1102                .bit_size_of,
1103                .ptr_to_int,
1104                .align_of,
1105                .bool_to_int,
1106                .embed_file,
1107                .error_name,
1108                .set_align_stack,
1109                .set_cold,
1110                .set_float_mode,
1111                .set_runtime_safety,
1112                .sqrt,
1113                .sin,
1114                .cos,
1115                .exp,
1116                .exp2,
1117                .log,
1118                .log2,
1119                .log10,
1120                .fabs,
1121                .floor,
1122                .ceil,
1123                .trunc,
1124                .round,
1125                .tag_name,
1126                .reify,
1127                .type_name,
1128                .frame_type,
1129                .frame_size,
1130                .float_to_int,
1131                .int_to_float,
1132                .int_to_ptr,
1133                .float_cast,
1134                .int_cast,
1135                .err_set_cast,
1136                .ptr_cast,
1137                .truncate,
1138                .align_cast,
1139                .has_field,
1140                .clz,
1141                .ctz,
1142                .pop_count,
1143                .byte_swap,
1144                .bit_reverse,
1145                .div_exact,
1146                .div_floor,
1147                .div_trunc,
1148                .mod,
1149                .rem,
1150                .shl_exact,
1151                .shr_exact,
1152                .bit_offset_of,
1153                .offset_of,
1154                .cmpxchg_strong,
1155                .cmpxchg_weak,
1156                .splat,
1157                .reduce,
1158                .shuffle,
1159                .select,
1160                .atomic_load,
1161                .atomic_rmw,
1162                .atomic_store,
1163                .mul_add,
1164                .builtin_call,
1165                .field_ptr_type,
1166                .field_parent_ptr,
1167                .maximum,
1168                .memcpy,
1169                .memset,
1170                .minimum,
1171                .builtin_async_call,
1172                .c_import,
1173                .@"resume",
1174                .@"await",
1175                .await_nosuspend,
1176                .ret_err_value_code,
1177                .extended,
1178                .closure_get,
1179                .closure_capture,
1180                => false,
1181
1182                .@"break",
1183                .break_inline,
1184                .condbr,
1185                .condbr_inline,
1186                .compile_error,
1187                .ret_node,
1188                .ret_load,
1189                .ret_coerce,
1190                .ret_err_value,
1191                .@"unreachable",
1192                .repeat,
1193                .repeat_inline,
1194                .panic,
1195                => true,
1196            };
1197        }
1198
1199        /// Used by debug safety-checking code.
1200        pub const data_tags = list: {
1201            @setEvalBranchQuota(2000);
1202            break :list std.enums.directEnumArray(Tag, Data.FieldEnum, 0, .{
1203                .add = .pl_node,
1204                .addwrap = .pl_node,
1205                .add_sat = .pl_node,
1206                .sub = .pl_node,
1207                .subwrap = .pl_node,
1208                .sub_sat = .pl_node,
1209                .mul = .pl_node,
1210                .mulwrap = .pl_node,
1211                .mul_sat = .pl_node,
1212
1213                .param = .pl_tok,
1214                .param_comptime = .pl_tok,
1215                .param_anytype = .str_tok,
1216                .param_anytype_comptime = .str_tok,
1217                .array_cat = .pl_node,
1218                .array_mul = .pl_node,
1219                .array_type = .bin,
1220                .array_type_sentinel = .pl_node,
1221                .vector_type = .pl_node,
1222                .elem_type = .un_node,
1223                .indexable_ptr_len = .un_node,
1224                .anyframe_type = .un_node,
1225                .as = .bin,
1226                .as_node = .pl_node,
1227                .bit_and = .pl_node,
1228                .bitcast = .pl_node,
1229                .bit_not = .un_node,
1230                .bit_or = .pl_node,
1231                .block = .pl_node,
1232                .block_inline = .pl_node,
1233                .suspend_block = .pl_node,
1234                .bool_not = .un_node,
1235                .bool_br_and = .bool_br,
1236                .bool_br_or = .bool_br,
1237                .@"break" = .@"break",
1238                .break_inline = .@"break",
1239                .breakpoint = .node,
1240                .call = .pl_node,
1241                .cmp_lt = .pl_node,
1242                .cmp_lte = .pl_node,
1243                .cmp_eq = .pl_node,
1244                .cmp_gte = .pl_node,
1245                .cmp_gt = .pl_node,
1246                .cmp_neq = .pl_node,
1247                .coerce_result_ptr = .bin,
1248                .condbr = .pl_node,
1249                .condbr_inline = .pl_node,
1250                .error_set_decl = .pl_node,
1251                .error_set_decl_anon = .pl_node,
1252                .error_set_decl_func = .pl_node,
1253                .dbg_stmt = .dbg_stmt,
1254                .decl_ref = .str_tok,
1255                .decl_val = .str_tok,
1256                .load = .un_node,
1257                .div = .pl_node,
1258                .elem_ptr = .bin,
1259                .elem_ptr_node = .pl_node,
1260                .elem_ptr_imm = .pl_node,
1261                .elem_val = .bin,
1262                .elem_val_node = .pl_node,
1263                .ensure_result_used = .un_node,
1264                .ensure_result_non_error = .un_node,
1265                .error_union_type = .pl_node,
1266                .error_value = .str_tok,
1267                .@"export" = .pl_node,
1268                .export_value = .pl_node,
1269                .field_ptr = .pl_node,
1270                .field_val = .pl_node,
1271                .field_ptr_named = .pl_node,
1272                .field_val_named = .pl_node,
1273                .field_call_bind = .pl_node,
1274                .field_call_bind_named = .pl_node,
1275                .func = .pl_node,
1276                .func_inferred = .pl_node,
1277                .import = .str_tok,
1278                .int = .int,
1279                .int_big = .str,
1280                .float = .float,
1281                .float128 = .pl_node,
1282                .int_type = .int_type,
1283                .is_non_null = .un_node,
1284                .is_non_null_ptr = .un_node,
1285                .is_non_err = .un_node,
1286                .is_non_err_ptr = .un_node,
1287                .loop = .pl_node,
1288                .repeat = .node,
1289                .repeat_inline = .node,
1290                .merge_error_sets = .pl_node,
1291                .mod_rem = .pl_node,
1292                .ref = .un_tok,
1293                .ret_node = .un_node,
1294                .ret_load = .un_node,
1295                .ret_coerce = .un_tok,
1296                .ret_err_value = .str_tok,
1297                .ret_err_value_code = .str_tok,
1298                .ptr_type_simple = .ptr_type_simple,
1299                .ptr_type = .ptr_type,
1300                .slice_start = .pl_node,
1301                .slice_end = .pl_node,
1302                .slice_sentinel = .pl_node,
1303                .store = .bin,
1304                .store_node = .pl_node,
1305                .store_to_block_ptr = .bin,
1306                .store_to_inferred_ptr = .bin,
1307                .str = .str,
1308                .negate = .un_node,
1309                .negate_wrap = .un_node,
1310                .typeof = .un_node,
1311                .typeof_log2_int_type = .un_node,
1312                .log2_int_type = .un_node,
1313                .@"unreachable" = .@"unreachable",
1314                .xor = .pl_node,
1315                .optional_type = .un_node,
1316                .optional_payload_safe = .un_node,
1317                .optional_payload_unsafe = .un_node,
1318                .optional_payload_safe_ptr = .un_node,
1319                .optional_payload_unsafe_ptr = .un_node,
1320                .err_union_payload_safe = .un_node,
1321                .err_union_payload_unsafe = .un_node,
1322                .err_union_payload_safe_ptr = .un_node,
1323                .err_union_payload_unsafe_ptr = .un_node,
1324                .err_union_code = .un_node,
1325                .err_union_code_ptr = .un_node,
1326                .ensure_err_payload_void = .un_tok,
1327                .enum_literal = .str_tok,
1328                .switch_block = .pl_node,
1329                .switch_cond = .un_node,
1330                .switch_cond_ref = .un_node,
1331                .switch_capture = .switch_capture,
1332                .switch_capture_ref = .switch_capture,
1333                .switch_capture_multi = .switch_capture,
1334                .switch_capture_multi_ref = .switch_capture,
1335                .switch_capture_else = .switch_capture,
1336                .switch_capture_else_ref = .switch_capture,
1337                .validate_struct_init = .pl_node,
1338                .validate_array_init = .pl_node,
1339                .struct_init_empty = .un_node,
1340                .field_type = .pl_node,
1341                .field_type_ref = .pl_node,
1342                .struct_init = .pl_node,
1343                .struct_init_ref = .pl_node,
1344                .struct_init_anon = .pl_node,
1345                .struct_init_anon_ref = .pl_node,
1346                .array_init = .pl_node,
1347                .array_init_anon = .pl_node,
1348                .array_init_ref = .pl_node,
1349                .array_init_anon_ref = .pl_node,
1350                .union_init_ptr = .pl_node,
1351                .type_info = .un_node,
1352                .size_of = .un_node,
1353                .bit_size_of = .un_node,
1354                .fence = .un_node,
1355
1356                .ptr_to_int = .un_node,
1357                .error_to_int = .un_node,
1358                .int_to_error = .un_node,
1359                .compile_error = .un_node,
1360                .set_eval_branch_quota = .un_node,
1361                .enum_to_int = .un_node,
1362                .align_of = .un_node,
1363                .bool_to_int = .un_node,
1364                .embed_file = .un_node,
1365                .error_name = .un_node,
1366                .panic = .un_node,
1367                .set_align_stack = .un_node,
1368                .set_cold = .un_node,
1369                .set_float_mode = .un_node,
1370                .set_runtime_safety = .un_node,
1371                .sqrt = .un_node,
1372                .sin = .un_node,
1373                .cos = .un_node,
1374                .exp = .un_node,
1375                .exp2 = .un_node,
1376                .log = .un_node,
1377                .log2 = .un_node,
1378                .log10 = .un_node,
1379                .fabs = .un_node,
1380                .floor = .un_node,
1381                .ceil = .un_node,
1382                .trunc = .un_node,
1383                .round = .un_node,
1384                .tag_name = .un_node,
1385                .reify = .un_node,
1386                .type_name = .un_node,
1387                .frame_type = .un_node,
1388                .frame_size = .un_node,
1389
1390                .float_to_int = .pl_node,
1391                .int_to_float = .pl_node,
1392                .int_to_ptr = .pl_node,
1393                .int_to_enum = .pl_node,
1394                .float_cast = .pl_node,
1395                .int_cast = .pl_node,
1396                .err_set_cast = .pl_node,
1397                .ptr_cast = .pl_node,
1398                .truncate = .pl_node,
1399                .align_cast = .pl_node,
1400
1401                .has_decl = .pl_node,
1402                .has_field = .pl_node,
1403
1404                .clz = .un_node,
1405                .ctz = .un_node,
1406                .pop_count = .un_node,
1407                .byte_swap = .un_node,
1408                .bit_reverse = .un_node,
1409
1410                .div_exact = .pl_node,
1411                .div_floor = .pl_node,
1412                .div_trunc = .pl_node,
1413                .mod = .pl_node,
1414                .rem = .pl_node,
1415
1416                .shl = .pl_node,
1417                .shl_exact = .pl_node,
1418                .shl_sat = .pl_node,
1419                .shr = .pl_node,
1420                .shr_exact = .pl_node,
1421
1422                .bit_offset_of = .pl_node,
1423                .offset_of = .pl_node,
1424                .cmpxchg_strong = .pl_node,
1425                .cmpxchg_weak = .pl_node,
1426                .splat = .pl_node,
1427                .reduce = .pl_node,
1428                .shuffle = .pl_node,
1429                .select = .pl_node,
1430                .atomic_load = .pl_node,
1431                .atomic_rmw = .pl_node,
1432                .atomic_store = .pl_node,
1433                .mul_add = .pl_node,
1434                .builtin_call = .pl_node,
1435                .field_ptr_type = .bin,
1436                .field_parent_ptr = .pl_node,
1437                .maximum = .pl_node,
1438                .memcpy = .pl_node,
1439                .memset = .pl_node,
1440                .minimum = .pl_node,
1441                .builtin_async_call = .pl_node,
1442                .c_import = .pl_node,
1443
1444                .alloc = .un_node,
1445                .alloc_mut = .un_node,
1446                .alloc_comptime = .un_node,
1447                .alloc_inferred = .node,
1448                .alloc_inferred_mut = .node,
1449                .alloc_inferred_comptime = .node,
1450                .resolve_inferred_alloc = .un_node,
1451
1452                .@"resume" = .un_node,
1453                .@"await" = .un_node,
1454                .await_nosuspend = .un_node,
1455
1456                .closure_capture = .un_tok,
1457                .closure_get = .inst_node,
1458
1459                .extended = .extended,
1460            });
1461        };
1462    };
1463
1464    /// Rarer instructions are here; ones that do not fit in the 8-bit `Tag` enum.
1465    /// `noreturn` instructions may not go here; they must be part of the main `Tag` enum.
1466    pub const Extended = enum(u16) {
1467        /// Represents a function declaration or function prototype, depending on
1468        /// whether body_len is 0.
1469        /// `operand` is payload index to `ExtendedFunc`.
1470        /// `small` is `ExtendedFunc.Small`.
1471        func,
1472        /// Declares a global variable.
1473        /// `operand` is payload index to `ExtendedVar`.
1474        /// `small` is `ExtendedVar.Small`.
1475        variable,
1476        /// A struct type definition. Contains references to ZIR instructions for
1477        /// the field types, defaults, and alignments.
1478        /// `operand` is payload index to `StructDecl`.
1479        /// `small` is `StructDecl.Small`.
1480        struct_decl,
1481        /// An enum type definition. Contains references to ZIR instructions for
1482        /// the field value expressions and optional type tag expression.
1483        /// `operand` is payload index to `EnumDecl`.
1484        /// `small` is `EnumDecl.Small`.
1485        enum_decl,
1486        /// A union type definition. Contains references to ZIR instructions for
1487        /// the field types and optional type tag expression.
1488        /// `operand` is payload index to `UnionDecl`.
1489        /// `small` is `UnionDecl.Small`.
1490        union_decl,
1491        /// An opaque type definition. Contains references to decls and captures.
1492        /// `operand` is payload index to `OpaqueDecl`.
1493        /// `small` is `OpaqueDecl.Small`.
1494        opaque_decl,
1495        /// Obtains a pointer to the return value.
1496        /// `operand` is `src_node: i32`.
1497        ret_ptr,
1498        /// Obtains the return type of the in-scope function.
1499        /// `operand` is `src_node: i32`.
1500        ret_type,
1501        /// Implements the `@This` builtin.
1502        /// `operand` is `src_node: i32`.
1503        this,
1504        /// Implements the `@returnAddress` builtin.
1505        /// `operand` is `src_node: i32`.
1506        ret_addr,
1507        /// Implements the `@src` builtin.
1508        /// `operand` is `src_node: i32`.
1509        builtin_src,
1510        /// Implements the `@errorReturnTrace` builtin.
1511        /// `operand` is `src_node: i32`.
1512        error_return_trace,
1513        /// Implements the `@frame` builtin.
1514        /// `operand` is `src_node: i32`.
1515        frame,
1516        /// Implements the `@frameAddress` builtin.
1517        /// `operand` is `src_node: i32`.
1518        frame_address,
1519        /// Same as `alloc` from `Tag` but may contain an alignment instruction.
1520        /// `operand` is payload index to `AllocExtended`.
1521        /// `small`:
1522        ///  * 0b000X - has type
1523        ///  * 0b00X0 - has alignment
1524        ///  * 0b0X00 - 1=const, 0=var
1525        ///  * 0bX000 - is comptime
1526        alloc,
1527        /// The `@extern` builtin.
1528        /// `operand` is payload index to `BinNode`.
1529        builtin_extern,
1530        /// Inline assembly.
1531        /// `small`:
1532        ///  * 0b00000000_000XXXXX - `outputs_len`.
1533        ///  * 0b000000XX_XXX00000 - `inputs_len`.
1534        ///  * 0b0XXXXX00_00000000 - `clobbers_len`.
1535        ///  * 0bX0000000_00000000 - is volatile
1536        /// `operand` is payload index to `Asm`.
1537        @"asm",
1538        /// Log compile time variables and emit an error message.
1539        /// `operand` is payload index to `NodeMultiOp`.
1540        /// `small` is `operands_len`.
1541        /// The AST node is the compile log builtin call.
1542        compile_log,
1543        /// The builtin `@TypeOf` which returns the type after Peer Type Resolution
1544        /// of one or more params.
1545        /// `operand` is payload index to `NodeMultiOp`.
1546        /// `small` is `operands_len`.
1547        /// The AST node is the builtin call.
1548        typeof_peer,
1549        /// Implements the `@addWithOverflow` builtin.
1550        /// `operand` is payload index to `OverflowArithmetic`.
1551        /// `small` is unused.
1552        add_with_overflow,
1553        /// Implements the `@subWithOverflow` builtin.
1554        /// `operand` is payload index to `OverflowArithmetic`.
1555        /// `small` is unused.
1556        sub_with_overflow,
1557        /// Implements the `@mulWithOverflow` builtin.
1558        /// `operand` is payload index to `OverflowArithmetic`.
1559        /// `small` is unused.
1560        mul_with_overflow,
1561        /// Implements the `@shlWithOverflow` builtin.
1562        /// `operand` is payload index to `OverflowArithmetic`.
1563        /// `small` is unused.
1564        shl_with_overflow,
1565        /// `operand` is payload index to `UnNode`.
1566        c_undef,
1567        /// `operand` is payload index to `UnNode`.
1568        c_include,
1569        /// `operand` is payload index to `BinNode`.
1570        c_define,
1571        /// `operand` is payload index to `UnNode`.
1572        wasm_memory_size,
1573        /// `operand` is payload index to `BinNode`.
1574        wasm_memory_grow,
1575        /// The `@prefetch` builtin.
1576        /// `operand` is payload index to `BinNode`.
1577        prefetch,
1578
1579        pub const InstData = struct {
1580            opcode: Extended,
1581            small: u16,
1582            operand: u32,
1583        };
1584    };
1585
1586    /// The position of a ZIR instruction within the `Zir` instructions array.
1587    pub const Index = u32;
1588
1589    /// A reference to a TypedValue or ZIR instruction.
1590    ///
1591    /// If the Ref has a tag in this enum, it refers to a TypedValue which may be
1592    /// retrieved with Ref.toTypedValue().
1593    ///
1594    /// If the value of a Ref does not have a tag, it refers to a ZIR instruction.
1595    ///
1596    /// The first values after the the last tag refer to ZIR instructions which may
1597    /// be derived by subtracting `typed_value_map.len`.
1598    ///
1599    /// When adding a tag to this enum, consider adding a corresponding entry to
1600    /// `primitives` in astgen.
1601    ///
1602    /// The tag type is specified so that it is safe to bitcast between `[]u32`
1603    /// and `[]Ref`.
1604    pub const Ref = enum(u32) {
1605        /// This Ref does not correspond to any ZIR instruction or constant
1606        /// value and may instead be used as a sentinel to indicate null.
1607        none,
1608
1609        u1_type,
1610        u8_type,
1611        i8_type,
1612        u16_type,
1613        i16_type,
1614        u32_type,
1615        i32_type,
1616        u64_type,
1617        i64_type,
1618        u128_type,
1619        i128_type,
1620        usize_type,
1621        isize_type,
1622        c_short_type,
1623        c_ushort_type,
1624        c_int_type,
1625        c_uint_type,
1626        c_long_type,
1627        c_ulong_type,
1628        c_longlong_type,
1629        c_ulonglong_type,
1630        c_longdouble_type,
1631        f16_type,
1632        f32_type,
1633        f64_type,
1634        f128_type,
1635        anyopaque_type,
1636        bool_type,
1637        void_type,
1638        type_type,
1639        anyerror_type,
1640        comptime_int_type,
1641        comptime_float_type,
1642        noreturn_type,
1643        anyframe_type,
1644        null_type,
1645        undefined_type,
1646        enum_literal_type,
1647        atomic_order_type,
1648        atomic_rmw_op_type,
1649        calling_convention_type,
1650        address_space_type,
1651        float_mode_type,
1652        reduce_op_type,
1653        call_options_type,
1654        prefetch_options_type,
1655        export_options_type,
1656        extern_options_type,
1657        type_info_type,
1658        manyptr_u8_type,
1659        manyptr_const_u8_type,
1660        fn_noreturn_no_args_type,
1661        fn_void_no_args_type,
1662        fn_naked_noreturn_no_args_type,
1663        fn_ccc_void_no_args_type,
1664        single_const_pointer_to_comptime_int_type,
1665        const_slice_u8_type,
1666        anyerror_void_error_union_type,
1667        generic_poison_type,
1668
1669        /// `undefined` (untyped)
1670        undef,
1671        /// `0` (comptime_int)
1672        zero,
1673        /// `1` (comptime_int)
1674        one,
1675        /// `{}`
1676        void_value,
1677        /// `unreachable` (noreturn type)
1678        unreachable_value,
1679        /// `null` (untyped)
1680        null_value,
1681        /// `true`
1682        bool_true,
1683        /// `false`
1684        bool_false,
1685        /// `.{}` (untyped)
1686        empty_struct,
1687        /// `0` (usize)
1688        zero_usize,
1689        /// `1` (usize)
1690        one_usize,
1691        /// `std.builtin.CallingConvention.C`
1692        calling_convention_c,
1693        /// `std.builtin.CallingConvention.Inline`
1694        calling_convention_inline,
1695        /// Used for generic parameters where the type and value
1696        /// is not known until generic function instantiation.
1697        generic_poison,
1698
1699        _,
1700
1701        pub const typed_value_map = std.enums.directEnumArray(Ref, TypedValue, 0, .{
1702            .none = undefined,
1703
1704            .u1_type = .{
1705                .ty = Type.initTag(.type),
1706                .val = Value.initTag(.u1_type),
1707            },
1708            .u8_type = .{
1709                .ty = Type.initTag(.type),
1710                .val = Value.initTag(.u8_type),
1711            },
1712            .i8_type = .{
1713                .ty = Type.initTag(.type),
1714                .val = Value.initTag(.i8_type),
1715            },
1716            .u16_type = .{
1717                .ty = Type.initTag(.type),
1718                .val = Value.initTag(.u16_type),
1719            },
1720            .i16_type = .{
1721                .ty = Type.initTag(.type),
1722                .val = Value.initTag(.i16_type),
1723            },
1724            .u32_type = .{
1725                .ty = Type.initTag(.type),
1726                .val = Value.initTag(.u32_type),
1727            },
1728            .i32_type = .{
1729                .ty = Type.initTag(.type),
1730                .val = Value.initTag(.i32_type),
1731            },
1732            .u64_type = .{
1733                .ty = Type.initTag(.type),
1734                .val = Value.initTag(.u64_type),
1735            },
1736            .i64_type = .{
1737                .ty = Type.initTag(.type),
1738                .val = Value.initTag(.i64_type),
1739            },
1740            .u128_type = .{
1741                .ty = Type.initTag(.type),
1742                .val = Value.initTag(.u128_type),
1743            },
1744            .i128_type = .{
1745                .ty = Type.initTag(.type),
1746                .val = Value.initTag(.i128_type),
1747            },
1748            .usize_type = .{
1749                .ty = Type.initTag(.type),
1750                .val = Value.initTag(.usize_type),
1751            },
1752            .isize_type = .{
1753                .ty = Type.initTag(.type),
1754                .val = Value.initTag(.isize_type),
1755            },
1756            .c_short_type = .{
1757                .ty = Type.initTag(.type),
1758                .val = Value.initTag(.c_short_type),
1759            },
1760            .c_ushort_type = .{
1761                .ty = Type.initTag(.type),
1762                .val = Value.initTag(.c_ushort_type),
1763            },
1764            .c_int_type = .{
1765                .ty = Type.initTag(.type),
1766                .val = Value.initTag(.c_int_type),
1767            },
1768            .c_uint_type = .{
1769                .ty = Type.initTag(.type),
1770                .val = Value.initTag(.c_uint_type),
1771            },
1772            .c_long_type = .{
1773                .ty = Type.initTag(.type),
1774                .val = Value.initTag(.c_long_type),
1775            },
1776            .c_ulong_type = .{
1777                .ty = Type.initTag(.type),
1778                .val = Value.initTag(.c_ulong_type),
1779            },
1780            .c_longlong_type = .{
1781                .ty = Type.initTag(.type),
1782                .val = Value.initTag(.c_longlong_type),
1783            },
1784            .c_ulonglong_type = .{
1785                .ty = Type.initTag(.type),
1786                .val = Value.initTag(.c_ulonglong_type),
1787            },
1788            .c_longdouble_type = .{
1789                .ty = Type.initTag(.type),
1790                .val = Value.initTag(.c_longdouble_type),
1791            },
1792            .f16_type = .{
1793                .ty = Type.initTag(.type),
1794                .val = Value.initTag(.f16_type),
1795            },
1796            .f32_type = .{
1797                .ty = Type.initTag(.type),
1798                .val = Value.initTag(.f32_type),
1799            },
1800            .f64_type = .{
1801                .ty = Type.initTag(.type),
1802                .val = Value.initTag(.f64_type),
1803            },
1804            .f128_type = .{
1805                .ty = Type.initTag(.type),
1806                .val = Value.initTag(.f128_type),
1807            },
1808            .anyopaque_type = .{
1809                .ty = Type.initTag(.type),
1810                .val = Value.initTag(.anyopaque_type),
1811            },
1812            .bool_type = .{
1813                .ty = Type.initTag(.type),
1814                .val = Value.initTag(.bool_type),
1815            },
1816            .void_type = .{
1817                .ty = Type.initTag(.type),
1818                .val = Value.initTag(.void_type),
1819            },
1820            .type_type = .{
1821                .ty = Type.initTag(.type),
1822                .val = Value.initTag(.type_type),
1823            },
1824            .anyerror_type = .{
1825                .ty = Type.initTag(.type),
1826                .val = Value.initTag(.anyerror_type),
1827            },
1828            .comptime_int_type = .{
1829                .ty = Type.initTag(.type),
1830                .val = Value.initTag(.comptime_int_type),
1831            },
1832            .comptime_float_type = .{
1833                .ty = Type.initTag(.type),
1834                .val = Value.initTag(.comptime_float_type),
1835            },
1836            .noreturn_type = .{
1837                .ty = Type.initTag(.type),
1838                .val = Value.initTag(.noreturn_type),
1839            },
1840            .anyframe_type = .{
1841                .ty = Type.initTag(.type),
1842                .val = Value.initTag(.anyframe_type),
1843            },
1844            .null_type = .{
1845                .ty = Type.initTag(.type),
1846                .val = Value.initTag(.null_type),
1847            },
1848            .undefined_type = .{
1849                .ty = Type.initTag(.type),
1850                .val = Value.initTag(.undefined_type),
1851            },
1852            .fn_noreturn_no_args_type = .{
1853                .ty = Type.initTag(.type),
1854                .val = Value.initTag(.fn_noreturn_no_args_type),
1855            },
1856            .fn_void_no_args_type = .{
1857                .ty = Type.initTag(.type),
1858                .val = Value.initTag(.fn_void_no_args_type),
1859            },
1860            .fn_naked_noreturn_no_args_type = .{
1861                .ty = Type.initTag(.type),
1862                .val = Value.initTag(.fn_naked_noreturn_no_args_type),
1863            },
1864            .fn_ccc_void_no_args_type = .{
1865                .ty = Type.initTag(.type),
1866                .val = Value.initTag(.fn_ccc_void_no_args_type),
1867            },
1868            .single_const_pointer_to_comptime_int_type = .{
1869                .ty = Type.initTag(.type),
1870                .val = Value.initTag(.single_const_pointer_to_comptime_int_type),
1871            },
1872            .const_slice_u8_type = .{
1873                .ty = Type.initTag(.type),
1874                .val = Value.initTag(.const_slice_u8_type),
1875            },
1876            .anyerror_void_error_union_type = .{
1877                .ty = Type.initTag(.type),
1878                .val = Value.initTag(.anyerror_void_error_union_type),
1879            },
1880            .generic_poison_type = .{
1881                .ty = Type.initTag(.type),
1882                .val = Value.initTag(.generic_poison_type),
1883            },
1884            .enum_literal_type = .{
1885                .ty = Type.initTag(.type),
1886                .val = Value.initTag(.enum_literal_type),
1887            },
1888            .manyptr_u8_type = .{
1889                .ty = Type.initTag(.type),
1890                .val = Value.initTag(.manyptr_u8_type),
1891            },
1892            .manyptr_const_u8_type = .{
1893                .ty = Type.initTag(.type),
1894                .val = Value.initTag(.manyptr_const_u8_type),
1895            },
1896            .atomic_order_type = .{
1897                .ty = Type.initTag(.type),
1898                .val = Value.initTag(.atomic_order_type),
1899            },
1900            .atomic_rmw_op_type = .{
1901                .ty = Type.initTag(.type),
1902                .val = Value.initTag(.atomic_rmw_op_type),
1903            },
1904            .calling_convention_type = .{
1905                .ty = Type.initTag(.type),
1906                .val = Value.initTag(.calling_convention_type),
1907            },
1908            .address_space_type = .{
1909                .ty = Type.initTag(.type),
1910                .val = Value.initTag(.address_space_type),
1911            },
1912            .float_mode_type = .{
1913                .ty = Type.initTag(.type),
1914                .val = Value.initTag(.float_mode_type),
1915            },
1916            .reduce_op_type = .{
1917                .ty = Type.initTag(.type),
1918                .val = Value.initTag(.reduce_op_type),
1919            },
1920            .call_options_type = .{
1921                .ty = Type.initTag(.type),
1922                .val = Value.initTag(.call_options_type),
1923            },
1924            .prefetch_options_type = .{
1925                .ty = Type.initTag(.type),
1926                .val = Value.initTag(.prefetch_options_type),
1927            },
1928            .export_options_type = .{
1929                .ty = Type.initTag(.type),
1930                .val = Value.initTag(.export_options_type),
1931            },
1932            .extern_options_type = .{
1933                .ty = Type.initTag(.type),
1934                .val = Value.initTag(.extern_options_type),
1935            },
1936            .type_info_type = .{
1937                .ty = Type.initTag(.type),
1938                .val = Value.initTag(.type_info_type),
1939            },
1940
1941            .undef = .{
1942                .ty = Type.initTag(.@"undefined"),
1943                .val = Value.initTag(.undef),
1944            },
1945            .zero = .{
1946                .ty = Type.initTag(.comptime_int),
1947                .val = Value.initTag(.zero),
1948            },
1949            .zero_usize = .{
1950                .ty = Type.initTag(.usize),
1951                .val = Value.initTag(.zero),
1952            },
1953            .one = .{
1954                .ty = Type.initTag(.comptime_int),
1955                .val = Value.initTag(.one),
1956            },
1957            .one_usize = .{
1958                .ty = Type.initTag(.usize),
1959                .val = Value.initTag(.one),
1960            },
1961            .void_value = .{
1962                .ty = Type.initTag(.void),
1963                .val = Value.initTag(.void_value),
1964            },
1965            .unreachable_value = .{
1966                .ty = Type.initTag(.noreturn),
1967                .val = Value.initTag(.unreachable_value),
1968            },
1969            .null_value = .{
1970                .ty = Type.initTag(.@"null"),
1971                .val = Value.initTag(.null_value),
1972            },
1973            .bool_true = .{
1974                .ty = Type.initTag(.bool),
1975                .val = Value.initTag(.bool_true),
1976            },
1977            .bool_false = .{
1978                .ty = Type.initTag(.bool),
1979                .val = Value.initTag(.bool_false),
1980            },
1981            .empty_struct = .{
1982                .ty = Type.initTag(.empty_struct_literal),
1983                .val = Value.initTag(.empty_struct_value),
1984            },
1985            .calling_convention_c = .{
1986                .ty = Type.initTag(.calling_convention),
1987                .val = .{ .ptr_otherwise = &calling_convention_c_payload.base },
1988            },
1989            .calling_convention_inline = .{
1990                .ty = Type.initTag(.calling_convention),
1991                .val = .{ .ptr_otherwise = &calling_convention_inline_payload.base },
1992            },
1993            .generic_poison = .{
1994                .ty = Type.initTag(.generic_poison),
1995                .val = Value.initTag(.generic_poison),
1996            },
1997        });
1998    };
1999
2000    /// We would like this to be const but `Value` wants a mutable pointer for
2001    /// its payload field. Nothing should mutate this though.
2002    var calling_convention_c_payload: Value.Payload.U32 = .{
2003        .base = .{ .tag = .enum_field_index },
2004        .data = @enumToInt(std.builtin.CallingConvention.C),
2005    };
2006
2007    /// We would like this to be const but `Value` wants a mutable pointer for
2008    /// its payload field. Nothing should mutate this though.
2009    var calling_convention_inline_payload: Value.Payload.U32 = .{
2010        .base = .{ .tag = .enum_field_index },
2011        .data = @enumToInt(std.builtin.CallingConvention.Inline),
2012    };
2013
2014    /// All instructions have an 8-byte payload, which is contained within
2015    /// this union. `Tag` determines which union field is active, as well as
2016    /// how to interpret the data within.
2017    pub const Data = union {
2018        /// Used for `Tag.extended`. The extended opcode determines the meaning
2019        /// of the `small` and `operand` fields.
2020        extended: Extended.InstData,
2021        /// Used for unary operators, with an AST node source location.
2022        un_node: struct {
2023            /// Offset from Decl AST node index.
2024            src_node: i32,
2025            /// The meaning of this operand depends on the corresponding `Tag`.
2026            operand: Ref,
2027
2028            pub fn src(self: @This()) LazySrcLoc {
2029                return .{ .node_offset = self.src_node };
2030            }
2031        },
2032        /// Used for unary operators, with a token source location.
2033        un_tok: struct {
2034            /// Offset from Decl AST token index.
2035            src_tok: Ast.TokenIndex,
2036            /// The meaning of this operand depends on the corresponding `Tag`.
2037            operand: Ref,
2038
2039            pub fn src(self: @This()) LazySrcLoc {
2040                return .{ .token_offset = self.src_tok };
2041            }
2042        },
2043        pl_node: struct {
2044            /// Offset from Decl AST node index.
2045            /// `Tag` determines which kind of AST node this points to.
2046            src_node: i32,
2047            /// index into extra.
2048            /// `Tag` determines what lives there.
2049            payload_index: u32,
2050
2051            pub fn src(self: @This()) LazySrcLoc {
2052                return .{ .node_offset = self.src_node };
2053            }
2054        },
2055        pl_tok: struct {
2056            /// Offset from Decl AST token index.
2057            src_tok: Ast.TokenIndex,
2058            /// index into extra.
2059            /// `Tag` determines what lives there.
2060            payload_index: u32,
2061
2062            pub fn src(self: @This()) LazySrcLoc {
2063                return .{ .token_offset = self.src_tok };
2064            }
2065        },
2066        bin: Bin,
2067        /// For strings which may contain null bytes.
2068        str: struct {
2069            /// Offset into `string_bytes`.
2070            start: u32,
2071            /// Number of bytes in the string.
2072            len: u32,
2073
2074            pub fn get(self: @This(), code: Zir) []const u8 {
2075                return code.string_bytes[self.start..][0..self.len];
2076            }
2077        },
2078        str_tok: struct {
2079            /// Offset into `string_bytes`. Null-terminated.
2080            start: u32,
2081            /// Offset from Decl AST token index.
2082            src_tok: u32,
2083
2084            pub fn get(self: @This(), code: Zir) [:0]const u8 {
2085                return code.nullTerminatedString(self.start);
2086            }
2087
2088            pub fn src(self: @This()) LazySrcLoc {
2089                return .{ .token_offset = self.src_tok };
2090            }
2091        },
2092        /// Offset from Decl AST token index.
2093        tok: Ast.TokenIndex,
2094        /// Offset from Decl AST node index.
2095        node: i32,
2096        int: u64,
2097        float: f64,
2098        ptr_type_simple: struct {
2099            is_allowzero: bool,
2100            is_mutable: bool,
2101            is_volatile: bool,
2102            size: std.builtin.TypeInfo.Pointer.Size,
2103            elem_type: Ref,
2104        },
2105        ptr_type: struct {
2106            flags: packed struct {
2107                is_allowzero: bool,
2108                is_mutable: bool,
2109                is_volatile: bool,
2110                has_sentinel: bool,
2111                has_align: bool,
2112                has_addrspace: bool,
2113                has_bit_range: bool,
2114                _: u1 = undefined,
2115            },
2116            size: std.builtin.TypeInfo.Pointer.Size,
2117            /// Index into extra. See `PtrType`.
2118            payload_index: u32,
2119        },
2120        int_type: struct {
2121            /// Offset from Decl AST node index.
2122            /// `Tag` determines which kind of AST node this points to.
2123            src_node: i32,
2124            signedness: std.builtin.Signedness,
2125            bit_count: u16,
2126
2127            pub fn src(self: @This()) LazySrcLoc {
2128                return .{ .node_offset = self.src_node };
2129            }
2130        },
2131        bool_br: struct {
2132            lhs: Ref,
2133            /// Points to a `Block`.
2134            payload_index: u32,
2135        },
2136        @"unreachable": struct {
2137            /// Offset from Decl AST node index.
2138            /// `Tag` determines which kind of AST node this points to.
2139            src_node: i32,
2140            /// `false`: Not safety checked - the compiler will assume the
2141            /// correctness of this instruction.
2142            /// `true`: In safety-checked modes, this will generate a call
2143            /// to the panic function unless it can be proven unreachable by the compiler.
2144            safety: bool,
2145
2146            pub fn src(self: @This()) LazySrcLoc {
2147                return .{ .node_offset = self.src_node };
2148            }
2149        },
2150        @"break": struct {
2151            block_inst: Index,
2152            operand: Ref,
2153        },
2154        switch_capture: struct {
2155            switch_inst: Index,
2156            prong_index: u32,
2157        },
2158        dbg_stmt: struct {
2159            line: u32,
2160            column: u32,
2161        },
2162        /// Used for unary operators which reference an inst,
2163        /// with an AST node source location.
2164        inst_node: struct {
2165            /// Offset from Decl AST node index.
2166            src_node: i32,
2167            /// The meaning of this operand depends on the corresponding `Tag`.
2168            inst: Index,
2169
2170            pub fn src(self: @This()) LazySrcLoc {
2171                return .{ .node_offset = self.src_node };
2172            }
2173        },
2174
2175        // Make sure we don't accidentally add a field to make this union
2176        // bigger than expected. Note that in Debug builds, Zig is allowed
2177        // to insert a secret field for safety checks.
2178        comptime {
2179            if (builtin.mode != .Debug) {
2180                assert(@sizeOf(Data) == 8);
2181            }
2182        }
2183
2184        /// TODO this has to be kept in sync with `Data` which we want to be an untagged
2185        /// union. There is some kind of language awkwardness here and it has to do with
2186        /// deserializing an untagged union (in this case `Data`) from a file, and trying
2187        /// to preserve the hidden safety field.
2188        pub const FieldEnum = enum {
2189            extended,
2190            un_node,
2191            un_tok,
2192            pl_node,
2193            pl_tok,
2194            bin,
2195            str,
2196            str_tok,
2197            tok,
2198            node,
2199            int,
2200            float,
2201            ptr_type_simple,
2202            ptr_type,
2203            int_type,
2204            bool_br,
2205            @"unreachable",
2206            @"break",
2207            switch_capture,
2208            dbg_stmt,
2209            inst_node,
2210        };
2211    };
2212
2213    /// Trailing:
2214    /// 0. Output for every outputs_len
2215    /// 1. Input for every inputs_len
2216    /// 2. clobber: u32 // index into string_bytes (null terminated) for every clobbers_len.
2217    pub const Asm = struct {
2218        src_node: i32,
2219        // null-terminated string index
2220        asm_source: u32,
2221        /// 1 bit for each outputs_len: whether it uses `-> T` or not.
2222        ///   0b0 - operand is a pointer to where to store the output.
2223        ///   0b1 - operand is a type; asm expression has the output as the result.
2224        /// 0b0X is the first output, 0bX0 is the second, etc.
2225        output_type_bits: u32,
2226
2227        pub const Output = struct {
2228            /// index into string_bytes (null terminated)
2229            name: u32,
2230            /// index into string_bytes (null terminated)
2231            constraint: u32,
2232            /// How to interpret this is determined by `output_type_bits`.
2233            operand: Ref,
2234        };
2235
2236        pub const Input = struct {
2237            /// index into string_bytes (null terminated)
2238            name: u32,
2239            /// index into string_bytes (null terminated)
2240            constraint: u32,
2241            operand: Ref,
2242        };
2243    };
2244
2245    /// Trailing:
2246    /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set
2247    /// 1. cc: Ref, // if has_cc is set
2248    /// 2. align: Ref, // if has_align is set
2249    /// 3. return_type: Index // for each ret_body_len
2250    /// 4. body: Index // for each body_len
2251    /// 5. src_locs: Func.SrcLocs // if body_len != 0
2252    pub const ExtendedFunc = struct {
2253        src_node: i32,
2254        /// If this is 0 it means a void return type.
2255        ret_body_len: u32,
2256        /// Points to the block that contains the param instructions for this function.
2257        param_block: Index,
2258        body_len: u32,
2259
2260        pub const Small = packed struct {
2261            is_var_args: bool,
2262            is_inferred_error: bool,
2263            has_lib_name: bool,
2264            has_cc: bool,
2265            has_align: bool,
2266            is_test: bool,
2267            is_extern: bool,
2268            _: u9 = undefined,
2269        };
2270    };
2271
2272    /// Trailing:
2273    /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set
2274    /// 1. align: Ref, // if has_align is set
2275    /// 2. init: Ref // if has_init is set
2276    /// The source node is obtained from the containing `block_inline`.
2277    pub const ExtendedVar = struct {
2278        var_type: Ref,
2279
2280        pub const Small = packed struct {
2281            has_lib_name: bool,
2282            has_align: bool,
2283            has_init: bool,
2284            is_extern: bool,
2285            is_threadlocal: bool,
2286            _: u11 = undefined,
2287        };
2288    };
2289
2290    /// Trailing:
2291    /// 0. return_type: Index // for each ret_body_len
2292    /// 1. body: Index // for each body_len
2293    /// 2. src_locs: SrcLocs // if body_len != 0
2294    pub const Func = struct {
2295        /// If this is 0 it means a void return type.
2296        ret_body_len: u32,
2297        /// Points to the block that contains the param instructions for this function.
2298        param_block: Index,
2299        body_len: u32,
2300
2301        pub const SrcLocs = struct {
2302            /// Absolute line index in the source file.
2303            lbrace_line: u32,
2304            /// Absolute line index in the source file.
2305            rbrace_line: u32,
2306            /// lbrace_column is least significant bits u16
2307            /// rbrace_column is most significant bits u16
2308            columns: u32,
2309        };
2310    };
2311
2312    /// This data is stored inside extra, with trailing operands according to `operands_len`.
2313    /// Each operand is a `Ref`.
2314    pub const MultiOp = struct {
2315        operands_len: u32,
2316    };
2317
2318    /// Trailing: operand: Ref, // for each `operands_len` (stored in `small`).
2319    pub const NodeMultiOp = struct {
2320        src_node: i32,
2321    };
2322
2323    /// This data is stored inside extra, with trailing operands according to `body_len`.
2324    /// Each operand is an `Index`.
2325    pub const Block = struct {
2326        body_len: u32,
2327    };
2328
2329    /// Stored inside extra, with trailing arguments according to `args_len`.
2330    /// Each argument is a `Ref`.
2331    pub const Call = struct {
2332        // Note: Flags *must* come first so that unusedResultExpr
2333        // can find it when it goes to modify them.
2334        flags: Flags,
2335        callee: Ref,
2336
2337        pub const Flags = packed struct {
2338            /// std.builtin.CallOptions.Modifier in packed form
2339            pub const PackedModifier = u3;
2340            pub const PackedArgsLen = u28;
2341
2342            packed_modifier: PackedModifier,
2343            ensure_result_used: bool = false,
2344            args_len: PackedArgsLen,
2345
2346            comptime {
2347                if (@sizeOf(Flags) != 4 or @bitSizeOf(Flags) != 32)
2348                    @compileError("Layout of Call.Flags needs to be updated!");
2349                if (@bitSizeOf(std.builtin.CallOptions.Modifier) != @bitSizeOf(PackedModifier))
2350                    @compileError("Call.Flags.PackedModifier needs to be updated!");
2351            }
2352        };
2353    };
2354
2355    pub const BuiltinCall = struct {
2356        options: Ref,
2357        callee: Ref,
2358        args: Ref,
2359    };
2360
2361    /// This data is stored inside extra, with two sets of trailing `Ref`:
2362    /// * 0. the then body, according to `then_body_len`.
2363    /// * 1. the else body, according to `else_body_len`.
2364    pub const CondBr = struct {
2365        condition: Ref,
2366        then_body_len: u32,
2367        else_body_len: u32,
2368    };
2369
2370    /// Stored in extra. Depending on the flags in Data, there will be up to 5
2371    /// trailing Ref fields:
2372    /// 0. sentinel: Ref // if `has_sentinel` flag is set
2373    /// 1. align: Ref // if `has_align` flag is set
2374    /// 2. address_space: Ref // if `has_addrspace` flag is set
2375    /// 3. bit_start: Ref // if `has_bit_range` flag is set
2376    /// 4. bit_end: Ref // if `has_bit_range` flag is set
2377    pub const PtrType = struct {
2378        elem_type: Ref,
2379    };
2380
2381    pub const ArrayTypeSentinel = struct {
2382        len: Ref,
2383        sentinel: Ref,
2384        elem_type: Ref,
2385    };
2386
2387    pub const SliceStart = struct {
2388        lhs: Ref,
2389        start: Ref,
2390    };
2391
2392    pub const SliceEnd = struct {
2393        lhs: Ref,
2394        start: Ref,
2395        end: Ref,
2396    };
2397
2398    pub const SliceSentinel = struct {
2399        lhs: Ref,
2400        start: Ref,
2401        end: Ref,
2402        sentinel: Ref,
2403    };
2404
2405    /// The meaning of these operands depends on the corresponding `Tag`.
2406    pub const Bin = struct {
2407        lhs: Ref,
2408        rhs: Ref,
2409    };
2410
2411    pub const BinNode = struct {
2412        node: i32,
2413        lhs: Ref,
2414        rhs: Ref,
2415    };
2416
2417    pub const UnNode = struct {
2418        node: i32,
2419        operand: Ref,
2420    };
2421
2422    pub const ElemPtrImm = struct {
2423        ptr: Ref,
2424        index: u32,
2425    };
2426
2427    /// 0. multi_cases_len: u32 // If has_multi_cases is set.
2428    /// 1. else_body { // If has_else or has_under is set.
2429    ///        body_len: u32,
2430    ///        body member Index for every body_len
2431    ///     }
2432    /// 2. scalar_cases: { // for every scalar_cases_len
2433    ///        item: Ref,
2434    ///        body_len: u32,
2435    ///        body member Index for every body_len
2436    ///     }
2437    /// 3. multi_cases: { // for every multi_cases_len
2438    ///        items_len: u32,
2439    ///        ranges_len: u32,
2440    ///        body_len: u32,
2441    ///        item: Ref // for every items_len
2442    ///        ranges: { // for every ranges_len
2443    ///            item_first: Ref,
2444    ///            item_last: Ref,
2445    ///        }
2446    ///        body member Index for every body_len
2447    ///    }
2448    pub const SwitchBlock = struct {
2449        /// This is always a `switch_cond` or `switch_cond_ref` instruction.
2450        /// If it is a `switch_cond_ref` instruction, bits.is_ref is always true.
2451        /// If it is a `switch_cond` instruction, bits.is_ref is always false.
2452        /// Both `switch_cond` and `switch_cond_ref` return a value, not a pointer,
2453        /// that is useful for the case items, but cannot be used for capture values.
2454        /// For the capture values, Sema is expected to find the operand of this operand
2455        /// and use that.
2456        operand: Ref,
2457        bits: Bits,
2458
2459        pub const Bits = packed struct {
2460            /// If true, one or more prongs have multiple items.
2461            has_multi_cases: bool,
2462            /// If true, there is an else prong. This is mutually exclusive with `has_under`.
2463            has_else: bool,
2464            /// If true, there is an underscore prong. This is mutually exclusive with `has_else`.
2465            has_under: bool,
2466            /// If true, the `operand` is a pointer to the value being switched on.
2467            /// TODO this flag is redundant with the tag of operand and can be removed.
2468            is_ref: bool,
2469            scalar_cases_len: ScalarCasesLen,
2470
2471            pub const ScalarCasesLen = u28;
2472
2473            pub fn specialProng(bits: Bits) SpecialProng {
2474                const has_else: u2 = @boolToInt(bits.has_else);
2475                const has_under: u2 = @boolToInt(bits.has_under);
2476                return switch ((has_else << 1) | has_under) {
2477                    0b00 => .none,
2478                    0b01 => .under,
2479                    0b10 => .@"else",
2480                    0b11 => unreachable,
2481                };
2482            }
2483        };
2484
2485        pub const ScalarProng = struct {
2486            item: Ref,
2487            body: []const Index,
2488        };
2489
2490        /// TODO performance optimization: instead of having this helper method
2491        /// change the definition of switch_capture instruction to store extra_index
2492        /// instead of prong_index. This way, Sema won't be doing O(N^2) iterations
2493        /// over the switch prongs.
2494        pub fn getScalarProng(
2495            self: SwitchBlock,
2496            zir: Zir,
2497            extra_end: usize,
2498            prong_index: usize,
2499        ) ScalarProng {
2500            var extra_index: usize = extra_end;
2501
2502            if (self.bits.has_multi_cases) {
2503                extra_index += 1;
2504            }
2505
2506            if (self.bits.specialProng() != .none) {
2507                const body_len = zir.extra[extra_index];
2508                extra_index += 1;
2509                const body = zir.extra[extra_index..][0..body_len];
2510                extra_index += body.len;
2511            }
2512
2513            var scalar_i: usize = 0;
2514            while (true) : (scalar_i += 1) {
2515                const item = @intToEnum(Ref, zir.extra[extra_index]);
2516                extra_index += 1;
2517                const body_len = zir.extra[extra_index];
2518                extra_index += 1;
2519                const body = zir.extra[extra_index..][0..body_len];
2520                extra_index += body.len;
2521
2522                if (scalar_i < prong_index) continue;
2523
2524                return .{
2525                    .item = item,
2526                    .body = body,
2527                };
2528            }
2529        }
2530    };
2531
2532    pub const Field = struct {
2533        lhs: Ref,
2534        /// Offset into `string_bytes`.
2535        field_name_start: u32,
2536    };
2537
2538    pub const FieldNamed = struct {
2539        lhs: Ref,
2540        field_name: Ref,
2541    };
2542
2543    pub const As = struct {
2544        dest_type: Ref,
2545        operand: Ref,
2546    };
2547
2548    /// Trailing:
2549    /// 0. src_node: i32, // if has_src_node
2550    /// 1. body_len: u32, // if has_body_len
2551    /// 2. fields_len: u32, // if has_fields_len
2552    /// 3. decls_len: u32, // if has_decls_len
2553    /// 4. decl_bits: u32 // for every 8 decls
2554    ///    - sets of 4 bits:
2555    ///      0b000X: whether corresponding decl is pub
2556    ///      0b00X0: whether corresponding decl is exported
2557    ///      0b0X00: whether corresponding decl has an align expression
2558    ///      0bX000: whether corresponding decl has a linksection or an address space expression
2559    /// 5. decl: { // for every decls_len
2560    ///        src_hash: [4]u32, // hash of source bytes
2561    ///        line: u32, // line number of decl, relative to parent
2562    ///        name: u32, // null terminated string index
2563    ///        - 0 means comptime or usingnamespace decl.
2564    ///          - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
2565    ///        - 1 means test decl with no name.
2566    ///        - if there is a 0 byte at the position `name` indexes, it indicates
2567    ///          this is a test decl, and the name starts at `name+1`.
2568    ///        value: Index,
2569    ///        align: Ref, // if corresponding bit is set
2570    ///        link_section_or_address_space: { // if corresponding bit is set.
2571    ///            link_section: Ref,
2572    ///            address_space: Ref,
2573    ///        }
2574    ///    }
2575    /// 6. inst: Index // for every body_len
2576    /// 7. flags: u32 // for every 8 fields
2577    ///    - sets of 4 bits:
2578    ///      0b000X: whether corresponding field has an align expression
2579    ///      0b00X0: whether corresponding field has a default expression
2580    ///      0b0X00: whether corresponding field is comptime
2581    ///      0bX000: unused
2582    /// 8. fields: { // for every fields_len
2583    ///        field_name: u32,
2584    ///        field_type: Ref,
2585    ///        - if none, means `anytype`.
2586    ///        align: Ref, // if corresponding bit is set
2587    ///        default_value: Ref, // if corresponding bit is set
2588    ///    }
2589    pub const StructDecl = struct {
2590        pub const Small = packed struct {
2591            has_src_node: bool,
2592            has_body_len: bool,
2593            has_fields_len: bool,
2594            has_decls_len: bool,
2595            known_has_bits: bool,
2596            name_strategy: NameStrategy,
2597            layout: std.builtin.TypeInfo.ContainerLayout,
2598            _: u7 = undefined,
2599        };
2600    };
2601
2602    pub const NameStrategy = enum(u2) {
2603        /// Use the same name as the parent declaration name.
2604        /// e.g. `const Foo = struct {...};`.
2605        parent,
2606        /// Use the name of the currently executing comptime function call,
2607        /// with the current parameters. e.g. `ArrayList(i32)`.
2608        func,
2609        /// Create an anonymous name for this declaration.
2610        /// Like this: "ParentDeclName_struct_69"
2611        anon,
2612    };
2613
2614    /// Trailing:
2615    /// 0. src_node: i32, // if has_src_node
2616    /// 1. tag_type: Ref, // if has_tag_type
2617    /// 2. body_len: u32, // if has_body_len
2618    /// 3. fields_len: u32, // if has_fields_len
2619    /// 4. decls_len: u32, // if has_decls_len
2620    /// 5. decl_bits: u32 // for every 8 decls
2621    ///    - sets of 4 bits:
2622    ///      0b000X: whether corresponding decl is pub
2623    ///      0b00X0: whether corresponding decl is exported
2624    ///      0b0X00: whether corresponding decl has an align expression
2625    ///      0bX000: whether corresponding decl has a linksection or an address space expression
2626    /// 6. decl: { // for every decls_len
2627    ///        src_hash: [4]u32, // hash of source bytes
2628    ///        line: u32, // line number of decl, relative to parent
2629    ///        name: u32, // null terminated string index
2630    ///        - 0 means comptime or usingnamespace decl.
2631    ///          - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
2632    ///        - 1 means test decl with no name.
2633    ///        - if there is a 0 byte at the position `name` indexes, it indicates
2634    ///          this is a test decl, and the name starts at `name+1`.
2635    ///        value: Index,
2636    ///        align: Ref, // if corresponding bit is set
2637    ///        link_section_or_address_space: { // if corresponding bit is set.
2638    ///            link_section: Ref,
2639    ///            address_space: Ref,
2640    ///        }
2641    ///    }
2642    /// 7. inst: Index // for every body_len
2643    /// 8. has_bits: u32 // for every 32 fields
2644    ///    - the bit is whether corresponding field has an value expression
2645    /// 9. fields: { // for every fields_len
2646    ///        field_name: u32,
2647    ///        value: Ref, // if corresponding bit is set
2648    ///    }
2649    pub const EnumDecl = struct {
2650        pub const Small = packed struct {
2651            has_src_node: bool,
2652            has_tag_type: bool,
2653            has_body_len: bool,
2654            has_fields_len: bool,
2655            has_decls_len: bool,
2656            name_strategy: NameStrategy,
2657            nonexhaustive: bool,
2658            _: u8 = undefined,
2659        };
2660    };
2661
2662    /// Trailing:
2663    /// 0. src_node: i32, // if has_src_node
2664    /// 1. tag_type: Ref, // if has_tag_type
2665    /// 2. body_len: u32, // if has_body_len
2666    /// 3. fields_len: u32, // if has_fields_len
2667    /// 4. decls_len: u32, // if has_decls_len
2668    /// 5. decl_bits: u32 // for every 8 decls
2669    ///    - sets of 4 bits:
2670    ///      0b000X: whether corresponding decl is pub
2671    ///      0b00X0: whether corresponding decl is exported
2672    ///      0b0X00: whether corresponding decl has an align expression
2673    ///      0bX000: whether corresponding decl has a linksection or an address space expression
2674    /// 6. decl: { // for every decls_len
2675    ///        src_hash: [4]u32, // hash of source bytes
2676    ///        line: u32, // line number of decl, relative to parent
2677    ///        name: u32, // null terminated string index
2678    ///        - 0 means comptime or usingnamespace decl.
2679    ///          - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
2680    ///        - 1 means test decl with no name.
2681    ///        - if there is a 0 byte at the position `name` indexes, it indicates
2682    ///          this is a test decl, and the name starts at `name+1`.
2683    ///        value: Index,
2684    ///        align: Ref, // if corresponding bit is set
2685    ///        link_section_or_address_space: { // if corresponding bit is set.
2686    ///            link_section: Ref,
2687    ///            address_space: Ref,
2688    ///        }
2689    ///    }
2690    /// 7. inst: Index // for every body_len
2691    /// 8. has_bits: u32 // for every 8 fields
2692    ///    - sets of 4 bits:
2693    ///      0b000X: whether corresponding field has a type expression
2694    ///      0b00X0: whether corresponding field has a align expression
2695    ///      0b0X00: whether corresponding field has a tag value expression
2696    ///      0bX000: unused
2697    /// 9. fields: { // for every fields_len
2698    ///        field_name: u32, // null terminated string index
2699    ///        field_type: Ref, // if corresponding bit is set
2700    ///        - if none, means `anytype`.
2701    ///        align: Ref, // if corresponding bit is set
2702    ///        tag_value: Ref, // if corresponding bit is set
2703    ///    }
2704    pub const UnionDecl = struct {
2705        pub const Small = packed struct {
2706            has_src_node: bool,
2707            has_tag_type: bool,
2708            has_body_len: bool,
2709            has_fields_len: bool,
2710            has_decls_len: bool,
2711            name_strategy: NameStrategy,
2712            layout: std.builtin.TypeInfo.ContainerLayout,
2713            /// has_tag_type | auto_enum_tag | result
2714            /// -------------------------------------
2715            ///    false     | false         |  union { }
2716            ///    false     | true          |  union(enum) { }
2717            ///    true      | true          |  union(enum(T)) { }
2718            ///    true      | false         |  union(T) { }
2719            auto_enum_tag: bool,
2720            _: u6 = undefined,
2721        };
2722    };
2723
2724    /// Trailing:
2725    /// 0. src_node: i32, // if has_src_node
2726    /// 1. decls_len: u32, // if has_decls_len
2727    /// 2. decl_bits: u32 // for every 8 decls
2728    ///    - sets of 4 bits:
2729    ///      0b000X: whether corresponding decl is pub
2730    ///      0b00X0: whether corresponding decl is exported
2731    ///      0b0X00: whether corresponding decl has an align expression
2732    ///      0bX000: whether corresponding decl has a linksection or an address space expression
2733    /// 3. decl: { // for every decls_len
2734    ///        src_hash: [4]u32, // hash of source bytes
2735    ///        line: u32, // line number of decl, relative to parent
2736    ///        name: u32, // null terminated string index
2737    ///        - 0 means comptime or usingnamespace decl.
2738    ///          - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
2739    ///        - 1 means test decl with no name.
2740    ///        - if there is a 0 byte at the position `name` indexes, it indicates
2741    ///          this is a test decl, and the name starts at `name+1`.
2742    ///        value: Index,
2743    ///        align: Ref, // if corresponding bit is set
2744    ///        link_section_or_address_space: { // if corresponding bit is set.
2745    ///            link_section: Ref,
2746    ///            address_space: Ref,
2747    ///        }
2748    ///    }
2749    pub const OpaqueDecl = struct {
2750        pub const Small = packed struct {
2751            has_src_node: bool,
2752            has_decls_len: bool,
2753            name_strategy: NameStrategy,
2754            _: u12 = undefined,
2755        };
2756    };
2757
2758    /// Trailing: field_name: u32 // for every field: null terminated string index
2759    pub const ErrorSetDecl = struct {
2760        fields_len: u32,
2761    };
2762
2763    /// A f128 value, broken up into 4 u32 parts.
2764    pub const Float128 = struct {
2765        piece0: u32,
2766        piece1: u32,
2767        piece2: u32,
2768        piece3: u32,
2769
2770        pub fn get(self: Float128) f128 {
2771            const int_bits = @as(u128, self.piece0) |
2772                (@as(u128, self.piece1) << 32) |
2773                (@as(u128, self.piece2) << 64) |
2774                (@as(u128, self.piece3) << 96);
2775            return @bitCast(f128, int_bits);
2776        }
2777    };
2778
2779    /// Trailing is an item per field.
2780    pub const StructInit = struct {
2781        fields_len: u32,
2782
2783        pub const Item = struct {
2784            /// The `field_type` ZIR instruction for this field init.
2785            field_type: Index,
2786            /// The field init expression to be used as the field value.
2787            init: Ref,
2788        };
2789    };
2790
2791    /// Trailing is an item per field.
2792    pub const StructInitAnon = struct {
2793        fields_len: u32,
2794
2795        pub const Item = struct {
2796            /// Null-terminated string table index.
2797            field_name: u32,
2798            /// The field init expression to be used as the field value.
2799            init: Ref,
2800        };
2801    };
2802
2803    pub const FieldType = struct {
2804        container_type: Ref,
2805        /// Offset into `string_bytes`, null terminated.
2806        name_start: u32,
2807    };
2808
2809    pub const FieldTypeRef = struct {
2810        container_type: Ref,
2811        field_name: Ref,
2812    };
2813
2814    pub const OverflowArithmetic = struct {
2815        node: i32,
2816        lhs: Ref,
2817        rhs: Ref,
2818        ptr: Ref,
2819    };
2820
2821    pub const Cmpxchg = struct {
2822        ptr: Ref,
2823        expected_value: Ref,
2824        new_value: Ref,
2825        success_order: Ref,
2826        failure_order: Ref,
2827    };
2828
2829    pub const AtomicRmw = struct {
2830        ptr: Ref,
2831        operation: Ref,
2832        operand: Ref,
2833        ordering: Ref,
2834    };
2835
2836    pub const UnionInitPtr = struct {
2837        result_ptr: Ref,
2838        union_type: Ref,
2839        field_name: Ref,
2840    };
2841
2842    pub const AtomicStore = struct {
2843        ptr: Ref,
2844        operand: Ref,
2845        ordering: Ref,
2846    };
2847
2848    pub const MulAdd = struct {
2849        mulend1: Ref,
2850        mulend2: Ref,
2851        addend: Ref,
2852    };
2853
2854    pub const FieldParentPtr = struct {
2855        parent_type: Ref,
2856        field_name: Ref,
2857        field_ptr: Ref,
2858    };
2859
2860    pub const Memcpy = struct {
2861        dest: Ref,
2862        source: Ref,
2863        byte_count: Ref,
2864    };
2865
2866    pub const Memset = struct {
2867        dest: Ref,
2868        byte: Ref,
2869        byte_count: Ref,
2870    };
2871
2872    pub const Shuffle = struct {
2873        elem_type: Ref,
2874        a: Ref,
2875        b: Ref,
2876        mask: Ref,
2877    };
2878
2879    pub const Select = struct {
2880        elem_type: Ref,
2881        pred: Ref,
2882        a: Ref,
2883        b: Ref,
2884    };
2885
2886    pub const AsyncCall = struct {
2887        frame_buffer: Ref,
2888        result_ptr: Ref,
2889        fn_ptr: Ref,
2890        args: Ref,
2891    };
2892
2893    /// Trailing: inst: Index // for every body_len
2894    pub const Param = struct {
2895        /// Null-terminated string index.
2896        name: u32,
2897        /// The body contains the type of the parameter.
2898        body_len: u32,
2899    };
2900
2901    /// Trailing:
2902    /// 0. type_inst: Ref,  // if small 0b000X is set
2903    /// 1. align_inst: Ref, // if small 0b00X0 is set
2904    pub const AllocExtended = struct {
2905        src_node: i32,
2906
2907        pub const Small = packed struct {
2908            has_type: bool,
2909            has_align: bool,
2910            is_const: bool,
2911            is_comptime: bool,
2912            _: u12 = undefined,
2913        };
2914    };
2915
2916    pub const Export = struct {
2917        /// If present, this is referring to a Decl via field access, e.g. `a.b`.
2918        /// If omitted, this is referring to a Decl via identifier, e.g. `a`.
2919        namespace: Ref,
2920        /// Null-terminated string index.
2921        decl_name: u32,
2922        options: Ref,
2923    };
2924
2925    pub const ExportValue = struct {
2926        /// The comptime value to export.
2927        operand: Ref,
2928        options: Ref,
2929    };
2930
2931    /// Trailing: `CompileErrors.Item` for each `items_len`.
2932    pub const CompileErrors = struct {
2933        items_len: u32,
2934
2935        /// Trailing: `note_payload_index: u32` for each `notes_len`.
2936        /// It's a payload index of another `Item`.
2937        pub const Item = struct {
2938            /// null terminated string index
2939            msg: u32,
2940            node: Ast.Node.Index,
2941            /// If node is 0 then this will be populated.
2942            token: Ast.TokenIndex,
2943            /// Can be used in combination with `token`.
2944            byte_offset: u32,
2945            /// 0 or a payload index of a `Block`, each is a payload
2946            /// index of another `Item`.
2947            notes: u32,
2948        };
2949    };
2950
2951    /// Trailing: for each `imports_len` there is an Item
2952    pub const Imports = struct {
2953        imports_len: Inst.Index,
2954
2955        pub const Item = struct {
2956            /// null terminated string index
2957            name: u32,
2958            /// points to the import name
2959            token: Ast.TokenIndex,
2960        };
2961    };
2962};
2963
2964pub const SpecialProng = enum { none, @"else", under };
2965
2966pub const DeclIterator = struct {
2967    extra_index: usize,
2968    bit_bag_index: usize,
2969    cur_bit_bag: u32,
2970    decl_i: u32,
2971    decls_len: u32,
2972    zir: Zir,
2973
2974    pub const Item = struct {
2975        name: [:0]const u8,
2976        sub_index: u32,
2977    };
2978
2979    pub fn next(it: *DeclIterator) ?Item {
2980        if (it.decl_i >= it.decls_len) return null;
2981
2982        if (it.decl_i % 8 == 0) {
2983            it.cur_bit_bag = it.zir.extra[it.bit_bag_index];
2984            it.bit_bag_index += 1;
2985        }
2986        it.decl_i += 1;
2987
2988        const flags = @truncate(u4, it.cur_bit_bag);
2989        it.cur_bit_bag >>= 4;
2990
2991        const sub_index = @intCast(u32, it.extra_index);
2992        it.extra_index += 5; // src_hash(4) + line(1)
2993        const name = it.zir.nullTerminatedString(it.zir.extra[it.extra_index]);
2994        it.extra_index += 2; // name(1) + value(1)
2995        it.extra_index += @truncate(u1, flags >> 2);
2996        it.extra_index += @truncate(u1, flags >> 3);
2997
2998        return Item{
2999            .sub_index = sub_index,
3000            .name = name,
3001        };
3002    }
3003};
3004
3005pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator {
3006    const tags = zir.instructions.items(.tag);
3007    const datas = zir.instructions.items(.data);
3008    switch (tags[decl_inst]) {
3009        // Functions are allowed and yield no iterations.
3010        // There is one case matching this in the extended instruction set below.
3011        .func,
3012        .func_inferred,
3013        => return declIteratorInner(zir, 0, 0),
3014
3015        .extended => {
3016            const extended = datas[decl_inst].extended;
3017            switch (extended.opcode) {
3018                .func => return declIteratorInner(zir, 0, 0),
3019                .struct_decl => {
3020                    const small = @bitCast(Inst.StructDecl.Small, extended.small);
3021                    var extra_index: usize = extended.operand;
3022                    extra_index += @boolToInt(small.has_src_node);
3023                    extra_index += @boolToInt(small.has_body_len);
3024                    extra_index += @boolToInt(small.has_fields_len);
3025                    const decls_len = if (small.has_decls_len) decls_len: {
3026                        const decls_len = zir.extra[extra_index];
3027                        extra_index += 1;
3028                        break :decls_len decls_len;
3029                    } else 0;
3030
3031                    return declIteratorInner(zir, extra_index, decls_len);
3032                },
3033                .enum_decl => {
3034                    const small = @bitCast(Inst.EnumDecl.Small, extended.small);
3035                    var extra_index: usize = extended.operand;
3036                    extra_index += @boolToInt(small.has_src_node);
3037                    extra_index += @boolToInt(small.has_tag_type);
3038                    extra_index += @boolToInt(small.has_body_len);
3039                    extra_index += @boolToInt(small.has_fields_len);
3040                    const decls_len = if (small.has_decls_len) decls_len: {
3041                        const decls_len = zir.extra[extra_index];
3042                        extra_index += 1;
3043                        break :decls_len decls_len;
3044                    } else 0;
3045
3046                    return declIteratorInner(zir, extra_index, decls_len);
3047                },
3048                .union_decl => {
3049                    const small = @bitCast(Inst.UnionDecl.Small, extended.small);
3050                    var extra_index: usize = extended.operand;
3051                    extra_index += @boolToInt(small.has_src_node);
3052                    extra_index += @boolToInt(small.has_tag_type);
3053                    extra_index += @boolToInt(small.has_body_len);
3054                    extra_index += @boolToInt(small.has_fields_len);
3055                    const decls_len = if (small.has_decls_len) decls_len: {
3056                        const decls_len = zir.extra[extra_index];
3057                        extra_index += 1;
3058                        break :decls_len decls_len;
3059                    } else 0;
3060
3061                    return declIteratorInner(zir, extra_index, decls_len);
3062                },
3063                .opaque_decl => {
3064                    const small = @bitCast(Inst.OpaqueDecl.Small, extended.small);
3065                    var extra_index: usize = extended.operand;
3066                    extra_index += @boolToInt(small.has_src_node);
3067                    const decls_len = if (small.has_decls_len) decls_len: {
3068                        const decls_len = zir.extra[extra_index];
3069                        extra_index += 1;
3070                        break :decls_len decls_len;
3071                    } else 0;
3072
3073                    return declIteratorInner(zir, extra_index, decls_len);
3074                },
3075                else => unreachable,
3076            }
3077        },
3078        else => unreachable,
3079    }
3080}
3081
3082pub fn declIteratorInner(zir: Zir, extra_index: usize, decls_len: u32) DeclIterator {
3083    const bit_bags_count = std.math.divCeil(usize, decls_len, 8) catch unreachable;
3084    return .{
3085        .zir = zir,
3086        .extra_index = extra_index + bit_bags_count,
3087        .bit_bag_index = extra_index,
3088        .cur_bit_bag = undefined,
3089        .decl_i = 0,
3090        .decls_len = decls_len,
3091    };
3092}
3093
3094/// The iterator would have to allocate memory anyway to iterate. So here we populate
3095/// an ArrayList as the result.
3096pub fn findDecls(zir: Zir, list: *std.ArrayList(Inst.Index), decl_sub_index: u32) !void {
3097    const block_inst = zir.extra[decl_sub_index + 6];
3098    list.clearRetainingCapacity();
3099
3100    return zir.findDeclsInner(list, block_inst);
3101}
3102
3103fn findDeclsInner(
3104    zir: Zir,
3105    list: *std.ArrayList(Inst.Index),
3106    inst: Inst.Index,
3107) Allocator.Error!void {
3108    const tags = zir.instructions.items(.tag);
3109    const datas = zir.instructions.items(.data);
3110
3111    switch (tags[inst]) {
3112        // Functions instructions are interesting and have a body.
3113        .func,
3114        .func_inferred,
3115        => {
3116            try list.append(inst);
3117
3118            const inst_data = datas[inst].pl_node;
3119            const extra = zir.extraData(Inst.Func, inst_data.payload_index);
3120            const body = zir.extra[extra.end..][0..extra.data.body_len];
3121            return zir.findDeclsBody(list, body);
3122        },
3123        .extended => {
3124            const extended = datas[inst].extended;
3125            switch (extended.opcode) {
3126                .func => {
3127                    try list.append(inst);
3128
3129                    const extra = zir.extraData(Inst.ExtendedFunc, extended.operand);
3130                    const small = @bitCast(Inst.ExtendedFunc.Small, extended.small);
3131                    var extra_index: usize = extra.end;
3132                    extra_index += @boolToInt(small.has_lib_name);
3133                    extra_index += @boolToInt(small.has_cc);
3134                    extra_index += @boolToInt(small.has_align);
3135                    const body = zir.extra[extra_index..][0..extra.data.body_len];
3136                    return zir.findDeclsBody(list, body);
3137                },
3138
3139                // Decl instructions are interesting but have no body.
3140                // TODO yes they do have a body actually. recurse over them just like block instructions.
3141                .struct_decl,
3142                .union_decl,
3143                .enum_decl,
3144                .opaque_decl,
3145                => return list.append(inst),
3146
3147                else => return,
3148            }
3149        },
3150
3151        // Block instructions, recurse over the bodies.
3152
3153        .block, .block_inline => {
3154            const inst_data = datas[inst].pl_node;
3155            const extra = zir.extraData(Inst.Block, inst_data.payload_index);
3156            const body = zir.extra[extra.end..][0..extra.data.body_len];
3157            return zir.findDeclsBody(list, body);
3158        },
3159        .condbr, .condbr_inline => {
3160            const inst_data = datas[inst].pl_node;
3161            const extra = zir.extraData(Inst.CondBr, inst_data.payload_index);
3162            const then_body = zir.extra[extra.end..][0..extra.data.then_body_len];
3163            const else_body = zir.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
3164            try zir.findDeclsBody(list, then_body);
3165            try zir.findDeclsBody(list, else_body);
3166        },
3167        .switch_block => return findDeclsSwitch(zir, list, inst),
3168
3169        .suspend_block => @panic("TODO iterate suspend block"),
3170
3171        else => return, // Regular instruction, not interesting.
3172    }
3173}
3174
3175fn findDeclsSwitch(
3176    zir: Zir,
3177    list: *std.ArrayList(Inst.Index),
3178    inst: Inst.Index,
3179) Allocator.Error!void {
3180    const inst_data = zir.instructions.items(.data)[inst].pl_node;
3181    const extra = zir.extraData(Inst.SwitchBlock, inst_data.payload_index);
3182
3183    var extra_index: usize = extra.end;
3184
3185    const multi_cases_len = if (extra.data.bits.has_multi_cases) blk: {
3186        const multi_cases_len = zir.extra[extra_index];
3187        extra_index += 1;
3188        break :blk multi_cases_len;
3189    } else 0;
3190
3191    const special_prong = extra.data.bits.specialProng();
3192    if (special_prong != .none) {
3193        const body_len = zir.extra[extra_index];
3194        extra_index += 1;
3195        const body = zir.extra[extra_index..][0..body_len];
3196        extra_index += body.len;
3197
3198        try zir.findDeclsBody(list, body);
3199    }
3200
3201    {
3202        const scalar_cases_len = extra.data.bits.scalar_cases_len;
3203        var scalar_i: usize = 0;
3204        while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
3205            extra_index += 1;
3206            const body_len = zir.extra[extra_index];
3207            extra_index += 1;
3208            const body = zir.extra[extra_index..][0..body_len];
3209            extra_index += body_len;
3210
3211            try zir.findDeclsBody(list, body);
3212        }
3213    }
3214    {
3215        var multi_i: usize = 0;
3216        while (multi_i < multi_cases_len) : (multi_i += 1) {
3217            const items_len = zir.extra[extra_index];
3218            extra_index += 1;
3219            const ranges_len = zir.extra[extra_index];
3220            extra_index += 1;
3221            const body_len = zir.extra[extra_index];
3222            extra_index += 1;
3223            const items = zir.refSlice(extra_index, items_len);
3224            extra_index += items_len;
3225            _ = items;
3226
3227            var range_i: usize = 0;
3228            while (range_i < ranges_len) : (range_i += 1) {
3229                extra_index += 1;
3230                extra_index += 1;
3231            }
3232
3233            const body = zir.extra[extra_index..][0..body_len];
3234            extra_index += body_len;
3235
3236            try zir.findDeclsBody(list, body);
3237        }
3238    }
3239}
3240
3241fn findDeclsBody(
3242    zir: Zir,
3243    list: *std.ArrayList(Inst.Index),
3244    body: []const Inst.Index,
3245) Allocator.Error!void {
3246    for (body) |member| {
3247        try zir.findDeclsInner(list, member);
3248    }
3249}
3250
3251pub const FnInfo = struct {
3252    param_body: []const Inst.Index,
3253    ret_ty_body: []const Inst.Index,
3254    body: []const Inst.Index,
3255    total_params_len: u32,
3256};
3257
3258pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
3259    const tags = zir.instructions.items(.tag);
3260    const datas = zir.instructions.items(.data);
3261    const info: struct {
3262        param_block: Inst.Index,
3263        body: []const Inst.Index,
3264        ret_ty_body: []const Inst.Index,
3265    } = switch (tags[fn_inst]) {
3266        .func, .func_inferred => blk: {
3267            const inst_data = datas[fn_inst].pl_node;
3268            const extra = zir.extraData(Inst.Func, inst_data.payload_index);
3269            var extra_index: usize = extra.end;
3270
3271            const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len];
3272            extra_index += ret_ty_body.len;
3273
3274            const body = zir.extra[extra_index..][0..extra.data.body_len];
3275            extra_index += body.len;
3276
3277            break :blk .{
3278                .param_block = extra.data.param_block,
3279                .ret_ty_body = ret_ty_body,
3280                .body = body,
3281            };
3282        },
3283        .extended => blk: {
3284            const extended = datas[fn_inst].extended;
3285            assert(extended.opcode == .func);
3286            const extra = zir.extraData(Inst.ExtendedFunc, extended.operand);
3287            const small = @bitCast(Inst.ExtendedFunc.Small, extended.small);
3288            var extra_index: usize = extra.end;
3289            extra_index += @boolToInt(small.has_lib_name);
3290            extra_index += @boolToInt(small.has_cc);
3291            extra_index += @boolToInt(small.has_align);
3292            const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len];
3293            extra_index += ret_ty_body.len;
3294            const body = zir.extra[extra_index..][0..extra.data.body_len];
3295            extra_index += body.len;
3296            break :blk .{
3297                .param_block = extra.data.param_block,
3298                .ret_ty_body = ret_ty_body,
3299                .body = body,
3300            };
3301        },
3302        else => unreachable,
3303    };
3304    assert(tags[info.param_block] == .block or tags[info.param_block] == .block_inline);
3305    const param_block = zir.extraData(Inst.Block, datas[info.param_block].pl_node.payload_index);
3306    const param_body = zir.extra[param_block.end..][0..param_block.data.body_len];
3307    var total_params_len: u32 = 0;
3308    for (param_body) |inst| {
3309        switch (tags[inst]) {
3310            .param, .param_comptime, .param_anytype, .param_anytype_comptime => {
3311                total_params_len += 1;
3312            },
3313            else => continue,
3314        }
3315    }
3316    return .{
3317        .param_body = param_body,
3318        .ret_ty_body = info.ret_ty_body,
3319        .body = info.body,
3320        .total_params_len = total_params_len,
3321    };
3322}
3323
3324const ref_start_index: u32 = Inst.Ref.typed_value_map.len;
3325
3326pub fn indexToRef(inst: Inst.Index) Inst.Ref {
3327    return @intToEnum(Inst.Ref, ref_start_index + inst);
3328}
3329
3330pub fn refToIndex(inst: Inst.Ref) ?Inst.Index {
3331    const ref_int = @enumToInt(inst);
3332    if (ref_int >= ref_start_index) {
3333        return ref_int - ref_start_index;
3334    } else {
3335        return null;
3336    }
3337}
3338