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